Generate math problems
Post-mortem update:

Perl 130 bytes

Combining techniques from dan1111's excellent solution with my own, I was able to squeeze one more byte:

@b=qw(Score: 0 correct | 0 wrong);$b[$#x=eval^&lt;&gt;?4:1]++while print"$b[@x]!
@b

"x/./,$_=(0|rand 11).chr(41^2+rand 3).~~rand 11,'='


There's a few things that might not be immediately obvious. If @x is an array, then $#x (the largest index of @x) will be one smaller than the length of @x. In this way, I can use $#x to point to the appropriate counting variable, and the length of @x to the corresponding message in a single assignment, without having to +1. The score string is repeating by /./, which will return 1 if an only if $_ is non-empty.



Perl 131 bytes

Here's my Perl attempt, which is more or less a direct translation of my PHP solution below.

@r=correct,${_^($n=eval^&lt;&gt;?z:r)}++while@z=wrong,print"@$n!
Score: $- @r | $% @z

"x@r,$_=(0|rand 11).chr(41^2+rand 3).~~rand 11,'='


$- and $% are used for counting variables as they default to 0, alleviating the need for a printf, and at the same time allowing me to combine the print statements into one. The score string is not printed the first iteration because @r has not yet been defined, and therefore x@r (repeat by the length of the array @r) repeats the string zero times, resulting in an empty string.

Once again using chr(41^2+rand 3) to generate +*-, as well as a bitwise xor _^ to switch between r&rarr;- and z&rarr;%. I would have liked to use a type glob for *n=eval^&lt;&gt;?z:r, saving a byte @$n&rarr;@n, but unfortunately typed as a string this comes back as either *main::r or *main::z, which isn't very useful.

&lt;/bandwagon>



PHP 157 (155) bytes

Just to get a smattering of languages:

&lt;?for($X=$Y=+$x=correct;$y=wrong;)echo$q=rand(0,10).chr(rand(2,4)^41).rand(0,10),'=',eval("\${_&amp;\$n=$q^fgets(STDIN)?y:x}++;"),$$n,"!
Score: $X $x | $Y $y

";


The initial $X=$Y=+ is necessary, because undefined variables print as an empty string, instead of 0. Unfortunate, but still shorter than using a printf. One thing to notice is the 'magic formula' chr(rand(2,4)^41). 2^41 = 43 (+), 3^41 = 42 (*) and 4^41 = 45 (-). chr(rand(3,5)^46) would also work, but in a different order.

This can be made 2 bytes shorter by using a few binary characters:

&lt;?for($‡=$†=+$x=correct;$y=wrong;)echo$q=rand(0,10).chr(rand(2,4)^41).rand(0,10),~Â,eval("\${~\$n=$q^fgets(STDIN)?y:x}++;"),$$n,"!
Score: $‡ $x | $† $y

";


where †, ‡ and Â are characters 134, 135 and 194 respectively.