On Fri, 24 Oct 2008 09:25:45 -0500, Matthew Moss wrote:

> Apologies for not having the Long Division quiz summary done yet. It
> will come sometime today or tomorrow. Meanwhile, I have the next quiz
> ready...
> 
> -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
> 
> The three rules of Ruby Quiz 2:
> 
> 1.  Please do not post any solutions or spoiler discussion for this quiz
> until 48 hours have passed from the time on this message.
> 
> 2.  Support Ruby Quiz 2 by submitting ideas as often as you can! (A
> permanent, new website is in the works for Ruby Quiz 2. Until then,
> please visit the temporary website at
> 
>    <http://splatbang.com/rubyquiz/>.
> 
> 3.  Enjoy!
> 
> Suggestion:  A [QUIZ] in the subject of emails about the problem helps
> everyone on Ruby Talk follow the discussion.  Please reply to the
> original quiz message, if you can.
> 
> -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
> 
> ## Bowling Scores (#181)
> 
> 
> Whether it is real or on the Wii, bowling is a fun game. (Okay, for the
> sake of the quiz, let's assume it's a fun game.) But I've known folks
> who just don't understand [how to score properly][1]. They can count
> pins knocked down, and know that getting all ten pins in one roll is
> good, but they still can't keep score.
> 
> Your task this week is to tally scores for these people. The input will
> be the player's name and the number of pins felled from each roll. For
> example:
> 
>      ruby bowling_scores.rb John 6 2 7 1 10 9 0 8 2 10 10 3 5 7 2 5 5 8
> 
> Your should tally the per-frame scores and generate output in table
> form, such as:
> 
>      John's final score: 140
> 
>      Frame     Roll  Roll    Score
>         1        6     2        8
>         2        7     1       16
>         3        X             35
>         4        9     -       44
>         5        8     /       64
>         6        X             87
>         7        X            105
>         8        3     5      113
>         9        7     2      122
>        10        5     /      140
>         *        8
> 
> 
> Note that you should make use of typical bowling symbols: `X` for a
> strike, `/` for a spare, and `-` for zero. Also, if extra balls were
> thrown at the end (to supplement a strike or spare in the final frame),
> list those as frame `*` like the above, but without a score.
> 
> Extra credit: Generate ascii or graphical output that looks more like
> the traditional bowling score form, which can be seen on [this page][1].
> 
> 
> [1]: http://www.bowling2u.com/trivia/game/scoring.asp

#!/usr/bin/env ruby
#Requires Ruby 1.8.7

class Fixnum
  def to_bowl
    return '-' if self==0
    return 'X' if self==10
    return self.to_s
  end
end

class Array
  def strike?
    self[0]==10
  end
  def spare?
    self[0]+self[1]==10
  end
end

module Enumerable
  #each cons is almost what I want, but it won't generate partial cons at the end
  def mycons n
    result=[]
    each_with_index do |f,i|
      result << self[i,n]
    end
    result
  end
end

ARGV.map!(&:to_i)
fail if ARGV.any?{|x| x>10}
frames=ARGV.mycons(3)
frames.delete_at(-1)

frames.each_with_index do |f,i|
  frames[i+1]=nil if f and not f.strike? 
end
frames.compact!
totals=frames.inject([]) do |h,frame|
  last = h[-1] || 0
  frame.delete_at(2) unless frame.spare? or frame.strike?
  h+[last+frame.inject(&:+)]
end
printf "%8s%8s%8s%8s\n", "Frame", "Roll", "Roll", "Score"
frames.each_with_index do |f,i|
  spare='/' if f[0]+f[1]==10
  printf "%8s%8s%8s%8s\n", i+1, f[0].to_bowl, (spare or f[1].to_bowl unless f.strike?), totals[i]
  if i==9 and f.spare?
    printf "%8s%8s\n", '*', f[2].to_bowl
  elsif i==9 and f.strike?
    printf "%8s%8s%8s\n", '*', f[1].to_bowl, f[2].to_bowl
  end
end




-- 
Chanoch (Ken) Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu/~kbloom1/