# Give a multiple choice test

I present to you a test! Your test is to test. The test is to test the testee with tests a tester gives you, in the shortest amount of code. Specifically, you will give a multiple choice test that you have recieved as input.

In this challenge, you must take an input like this:

1. Our site is called Programming Puzzles & Code ________.
A: Debugging
*B: Golf
C: Hockey
D: Programming
2. What is the *most* popular tag on our site?
A: [debug]
B: [program]
*C: [code-golf]
D: [number]
E: [c++]
3. We are part of the ________ Exchange network.
*A: Stack
B: Code
C: Programmer
D: Hockey
4. Is this the first question?
A: Yes
*B: No
5. Is this the last question?
*A: Yes
B: No


And here is an example of the test being taken:

1. Our site is called Programming Puzzles & Code ________.
A: Debugging
B: Golf
C: Hockey
D: Programming
correct!

2. What is the *most* popular tag on our site?
A: [debug]
B: [program]
C: [code-golf]
D: [number]
E: [c++]
correct!

3. We are part of the ________ Exchange network.
A: Stack
B: Code
C: Programmer
D: Hockey

4. Is this the first question?
A: Yes
B: No
correct!

5. Is this the last question?
A: Yes
B: No

overview:
3 correct, 2 incorrect (60%)

3. We are part of the ________ Exchange network.
you chose B: Code

5. Is this the last question?
you chose B: No


Formal specification:

• Input
• If a line begins with a number followed by a dot and a space, it is a question with that number. Numbers will always start from 1 and go up 1 each question.
• If a line begins with an optional asterisk, a letter, a colon, and then a space, it is an answer. Answers will also always be sequential. There will be only one correct answer per question.
• A line will not begin in any other way than the previously mentioned ways.
• Input may be accepted in any way (reading from a file, stdin, etc.) but must not be hardcoded into your program.
• Output (test-taking phase)
• First, print out each question sequentially. Print the question and its answers as recieved in input, but do not print the asterisk indicating correct answers.
• Then, print a newline and "answer: ". Wait for user input. User input will always correspond to an answer.
• If the correct answer (the one with an asterisk) is the same as the one the user input, output "correct!". Otherwise, output "incorrect! the answer was " + correct_letter.
• Separate each question with a blank line, then repeat the previous output steps until there are no more questions.
• Output (overview phase)
• Print "overview: " and then a newline.
• Print "{number of correct answers} correct, {incorrect answers} incorrect ({percent correct, rounded to the nearest whole number}%)" (of course substituting the phrases in curly braces with their respective values). Then print a blank line for spacing.
• Now, for each question that was wrong, print the question (not its answers), then on a new line "you chose " + answer_you_chose, and on another line "the answer was " + correct_answer. Separate each wrong answer's overview with a blank line.
• In order to reduce cheating by interpreting things literally, when given the same output here, and the same input in the test-taking phase, your program must output exactly the same thing as the sample output.

This is ; shortest code wins! (And gets an A+ (green checkmark)!)

• Nice challenge, but I wish the sample test to contain possibly tricky situations, like \d\. , \w:  and \* in the middle of questions/answers. (For example currently the * can be eliminated with y/*//, while the correct way is lengthy as s/^\*//.) – manatwork Dec 16 '13 at 14:43
• Do we need to allow line continuation? I mean, will there be lines not starting with “1. ” or “A: ”? If yes, please include such cases in the sample test. – manatwork Dec 16 '13 at 14:51
• @manatwork (first comment) Ok, editing (second comment) no, you do not. I will clarify. – Doorknob Dec 16 '13 at 22:42
• So how are you going to test this test test? – Joe Z. Dec 16 '13 at 22:45
• @JoeZ. Umm... not sure what you mean... I did provide a test test case for the test to test your tester – Doorknob Dec 16 '13 at 22:46

## Perl 5, 279

$y=correct;@w=(the,$n=answer,was);map{s/^\*((.+?):.+)/$a=$1/me;print"$_$n: ";chop($@=<>);print$@eq($l=$2)?++$d&&"$y!

":(/^\d.+/,$o.=$&,/^$@.+/m,$o.="
you chose: $& @w$a

")&&"in$y! @w$l

"}@_=split/(?=^\d)/m,join"",<>;printf"overview:
$d$y, %d in$y (%d%)$o",@_-$d,$d/@_*100


Note: The newlines are required for output formatting.

Every time I think I can't golf it any more, I learn something new! It's slowly becoming more punctuation than legible text... I think that's a good thing?

Usage: perl -e '...' test.txt or perl test.pl test.txt.

If you choose an option not presented in the list, you will get incorrect output in the overview (it will say you chose: 1. Our site is called Programming Puzzles & Code ________. for example).

Example run

• Kindly show an example of input and output. – DavidC Dec 17 '13 at 19:57
• @DavidCarraher added an updated link to output via showterm.io. Thought that would be marginally better than static output, although it still doesn't capture it exactly the same as it is in the terminal. – Dom Hastings Dec 17 '13 at 22:00
• That gives a fairly good view of how your program works. – DavidC Dec 18 '13 at 0:27

# Mathematica 144

This may be an invalid attempt. I separated the question from each answer in the input. I also indicated the correct answer by a letter in a separate field, rather than an asterisk before the alternative.

Anyway...

The Data

questions={{{"\n1. Our site is called Programming Puzzles & Code ________.\n","A: Bugging\n","B: Golf\n","C: Hockey\n","D: Programming\n"},"B"},{{"\n2. What is the most popular tag on our site? \n","A: [debug]\n","B: [program]\n","C: [code golf]\n","D: [number]\n"},"C"},{{"\n3. We are part of the _______ Exchange network. \n","A: Stack\n","B: Code\n","C: Programmer\n","D: Hockey\n"},"A"},{{"\n4. Is this the first question? \n","A: Yes\n","B: No\n"},"B"},{{"\n5. Is this the last question? \n","A: Yes\n","B: No\n"},"A"}};


Code

An answer to each question is entered through a dialog box. Questions, answers, and feedback are printed.

f@x_:=
r<>"\ncorrect!", r<>"\nincorrect, the answer is "<>#2]&@@x]


Test

f /@ questions


• wow, impressive! the input is not in the correct form though... still, that is very remarkable for the brevity of the code and how much it does! – Doorknob Dec 18 '13 at 0:26
• Thanks. Massaging the input string into a Mathematica-friendly structure is of course possible, but it would have hidden the elegance underlying the present, ineligible solution. – DavidC Dec 21 '13 at 14:09
• Nice. Four characters shorter: g@{a_,b_}:=Print[If[(r=ChoiceDialog[Print[""<>a,"\nanswer: "];""<>a,Rest@a~StringTake~1])==b,r<>"\ncorrect!",r<>"\nincorrect, the answer is "<>b]] – Mr.Wizard Dec 22 '13 at 19:23
• And save one more by using Print@If[...] rather than Print[If[...]]. – Mr.Wizard Dec 22 '13 at 19:43

Java - 1210

int i,o;String q;String[]s={"1. Our site is called Programming Puzzles & Code ________.\n","2. What is the most popular tag on our site?\n","3. We are part of the ________ Exchange network.\n","4. Is this the first question?\n","5. Is this the last question?\n"},b={"B","C","A","B","A"},p=new String[5];String[][]a={{"A: Debugging\n","B: Golf\n","C: Hockey\n","D: Programming\n","answer: "},{"A: [debug]\n","B: [program]\n","C: [code-golf]\n","D: [number]\n","E: [c++]\n","answer: "},{"A: Stack\n","B: Code\n","C: Programmer\n","D: Hockey\n","answer: "},{"A: Yes\n","B: No\n","answer: "},{"A: Yes\n","B: No\n","answer: "}};java.util.Map<String,Integer>m=new java.util.HashMap(){{put("A",0);put("B",1);put("C",2);put("D",3);put("E",4);}};java.util.Scanner u=new java.util.Scanner(System.in);for(i=0;i<5;i++){q=s[i];for(o=0;o<a[i].length;)q+=a[i][o++];System.out.print(q);if(b[i].equals(p[i]=u.nextLine()))q="correct!";else q="incorrect! the answer was "+b[i];System.out.println(q+"\n");}q="";o=0;for(i=0;i<5;i++)if(b[i].equals(p[i]))o++;else q+=s[i]+"you chose "+a[i][m.get(p[i])]+"the answer was "+a[i][m.get(b[i])]+"\n";System.out.println("overview:\n"+o+" correct, "+(5-o)+" incorrect ("+o*100/5+"%)\n\n"+q);


formatted: 1980

String[] s = {"1. Our site is called Programming Puzzles & Code ________.\n",
"2. What is the most popular tag on our site?\n",
"3. We are part of the ________ Exchange network.\n",
"4. Is this the first question?\n",
"5. Is this the last question?\n"};
String[][] a = {
{"A: Debugging\n", "B: Golf\n", "C: Hockey\n", "D: Programming\n", "answer: "},
{"A: [debug]\n", "B: [program]\n", "C: [code-golf]\n", "D: [number]\n", "E: [c++]\n", "answer: "},
{"A: Stack\n", "B: Code\n", "C: Programmer\n", "D: Hockey\n", "answer: "},
{"A: Yes\n", "B: No\n", "answer: "},
{"A: Yes\n", "B: No\n", "answer: "}};

java.util.Map<String, Integer> m = new java.util.HashMap<String, Integer>() {
{
put("A", 0);
put("B", 1);
put("C", 2);
put("D", 3);
put("E", 4);
}
};
String[] b = {"B", "C", "A", "B", "A"};
String[] p = new String[5];
java.util.Scanner u = new java.util.Scanner(System.in);
String q;
int i;
int o;
for (i = 0; i < 5; i++) {
q = s[i];
for (o = 0; o < a[i].length;) {
q += a[i][o++];
}
System.out.print(q);
if (b[i].equals(p[i] = u.nextLine())) {
q = "correct!";
} else {
q = "incorrect! the answer was " + b[i];
}
System.out.println(q + "\n");
}
q = "";
o = 0;
for (i = 0; i < 5; i++) {
if (b[i].equals(p[i])) {
o++;
} else {
q += s[i] + "you chose " + a[i][m.get(p[i])] + "the answer was " + a[i][m.get(b[i])] + "\n";
}
}
System.out.println("overview:\n" + " correct, " + (5 - o) + " incorrect (" + o * 100 / 5 + "%)\n\n" + q);


This certainly won’t be the shortest but it is all self-contained

import System.Environment
import System.IO
n=putStrLn
p=putStr
d#s=p$show d++s v&(m:a)=n m>>q[]""a>>= \(r,(s,t))->n s>>n"">>b v m t&r (r,w,s)&[]=n"overview:">>r#" correct, ">>w#" incorrect (">>((100*r)div(r+w))#"%)\n">>mapM_ n s b(r,w,s)m t|null t=(r+1,w,s)|1<3=(r,w+1,s++"":m:t) q u c(('*':a):r)=q u a(a:r) q u c(a@(o:':':_):r)=n a>>q(([o],a):u)c r q u c r=p"answer: ">>hFlush stdout>>(\i->(r,a(maybe i id$lookup i u)c))fmapgetLine


Way longer than I'd like. It's set wiki so have at it!

Alas, we lose 32 characters to flushing stdout. Another 38 characters could be saved if the test script were read from a fixed file named "t" rather than specified on the command line.

When run on the input given in the question:

& runhaskell 15961-Tester.hs 15961-test.txt
1. Our site is called Programming Puzzles & Code ________.
A: Debugging
B: Golf
C: Hockey
D: Programming
correct!

2. What is the *most* popular tag on our site?
A: [debug]
B: [program]
C: [code-golf]
D: [number]
E: [c++]
correct!

3. We are part of the ________ Exchange network.
A: Stack
B: Code
C: Programmer
D: Hockey

4. Is this the first question?
A: Yes
B: No
correct!

5. Is this the last question?
A: Yes
B: No