I wrote the following program to help my kid learn to do simple math
problems quickly and correctly. He is 7. A professor down the hall has a
9 year old, he tried the program and wanted instructions to install ruby
on his linux box at home so that his kid can try it out. You need readline
support or comment the readline bits out and do your own thing in the
prompt_and_read routine. I have no idea if there will be any problems on
non-*nix OS's.


  Pete
__
#!/usr/bin/env ruby
# do simple math problems as fast as you can
# $Id: speed-math.rb,v 1.4 2001/11/12 19:47:51 pete Exp $

require 'readline'
require 'timeout'

include Readline

$high_score , $score = 0, 0
$questions, $skipped, $correct = 0,0,0
$program = $0.sub(/.*\//,'').sub(/\.[^.]*$/,'')

def prompt_and_read (prompt)
  readline(prompt,TRUE)
end

def math_problem (maxint=12)

  arg1 = rand (maxint + 1)
  arg2 = rand (maxint + 1)

  type = rand
  question, answer = "",""
  if type > .75
    #addition
    question = "#{arg1} + #{arg2} = "
    answer = (arg1 + arg2).to_s
  elsif type > .5
    #subtraction
    question = "#{arg1} - #{arg2} = "
    answer = (arg1 - arg2).to_s
  elsif type > .25
    #multiplication
    question = "#{arg1} * #{arg2} = " 
    answer = (arg1 * arg2).to_s
  else
    #division
    if arg1 == 0
      if arg2 == 0
	arg2 = 1 + rand (maxint)
      end
      arg1, arg2 = arg2, arg1
    end
    mult = arg1 * arg2
    question = "#{mult} / #{arg1} = "
    answer = arg2.to_s
  end
  return question, answer
end

def new_game
  $questions, $correct, $skipped = 0,0,0

  loop {
    q, a = math_problem
    response = prompt_and_read("\t#{q} ")
     $questions += 1
     case response.strip
      when a
	$correct += 1
      when ""
        $skipped += 1
        puts "SKIPPED (#{q} #{a})"
      else
        puts "WRONG (#{q} #{a})"
    end
  }
end

def show_score

  missed = $questions - $correct -$skipped
  score = $correct - 5*missed - $skipped
  congrats = if score > $high_score
             $high_score = score
             "Congratulations, you set a new high score!" 
           else
	     ""
	   end
  print <<-SCORE

You scored #{score} 
  Of #{$questions} questions you answered #{$correct} correctly 
  and skipped #{$skipped}

The high score is #{$high_score}
	#{congrats}
  SCORE
end


$time_limit = ARGV[0].to_i.nonzero? || 60

print <<-START
Welcome to #{$program}.
	You will be given math questions. Answer as fast as you can,
but try to get the answers right.

  	You have #{$time_limit} seconds to get as many right as you can.
  Correct answers are worth 1 point, wrong answers cost 5 points. You
  can skip a question, but it costs 1 point.

START

loop {
  begin
    response = prompt_and_read ("#{$program} Go/quit ?> ")
    case response.strip.downcase
      when "go"
        timeout($time_limit) {
          new_game
        }
      when "quit"
        puts "bye"
        exit
      else
        puts "huh?"
    end
  rescue TimeoutError
    show_score
    retry
  rescue NameError
    puts "\nMade a mistake, eh?"
    retry
  rescue Interrupt
    puts "\nbye"
    exit
  end
}