# 15110 Spring 2012 [Touretzky/Kaynar]

## Lab 3 - Thursday, September 13, 2012

### Deliverables

1. rpsls.rb
2. sundaes.rb
3. num_to_words.rb

Place the files in a lab3 folder, zip it up, and hand in the zip file.

### CA Demonstration

• Array expressions: creating with inital values, accessing elements
• Comparison operators: <, <=, ==, >, >=
• Boolean constants and operators: true, false, and, or, not.
• Control flow: if statement, if/else, while loop
• Nested for loop example using ranges:
   for i in 1..3 do
for j in "a".."c" do
print i, j, "\n"
end
end


### Activities

1. Program Logic

Here is code to play the children's game rock-paper-scissors:

    def rps(x,y)
if x == y then
return "tie"
elsif (x == "paper" and y == "rock") or
(x == "scissors" and y == "paper") or
(x == "rock" and y == "scissors")
return x + " wins"
else
return y + " wins"
end
end

Enter this code in the file rps.rb and try it out.

Rock-paper-scissors has a high rate of ties. The game rock-paper-scissors-lizard-Spock, made popular by the TV show The Big Bang Theory, was invented by two CMU alums, Sam Kass and Karen Bryla. You can find the rules in this Wikipedia article. Write the shortest function you can that determines the winner of a round of this game. Examples:

1. rpsls("spock","scissors") should return "spock wins"
2. rpsls("spock","lizard") should return "lizard wins"
3. rpsls("spock","spock") should return "tie"

A warning about operator precedence: and and or have the same precedence in Ruby, and both are left associative, so these two lines of code will produce different results if x is 2 and y is 3:

   x == 1 and y == 2 or y == 3  means  (x == 1 and y == 2) or y == 3

x == 1 and (y == 2 or y == 3)


2. Nested Loops

Let's make some ice cream sundaes. We have four flavors of ice cream: vanilla, chocolate, strawberry, and pistacchio. We have three sauces: caramel, butterscotch, and chocolate. And we have three toppings: nuts, crushed oreos, and sprinkles. How many different ice cream sundaes can we make? Write a method sundaes() to systematically print out every possible combination, one per line. For example, the first line should say "vanilla ice cream sundae with caramel sauce and nuts". Make an array to hold each class of ingredient, and use nested for loops to iterate over these arrays to generate the combinations. At the end, your function should return an integer giving the total number of combinations.

3. Numbers to Text

The rules for pronouncing integers in English are very regular, with only a few special cases in the "teens". For example, 72 is pronounced "seventy two", and 118 is pronounced "one hundred eighteen". The entire vocabulary is only about 30 words:

  digits = ["zero", "one", "two", "three", "four", "five",
"six", "seven", "eight", "nine"]

tens = ["error", "ten", "twenty", "thirty", "forty", "fifty",
"sixty", "seventy", "eighty", "ninety"]

teens = ["ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen",
"sixteen", "seventeen", "eighteen", "nineteen"]

The above arrays have a nice property: note for example that digits[2] is equal to the string "two", and tens[2] is equal to the string "twenty".

Write a function num_to_words(n) that takes an integer n as input and uses these arrays to compute a string giving the English pronunciation of that number. For example, num_to_words(27) should return the string "twenty seven", while num_to_words(17) should return the string "seventeen".

Hints: n % 10 will give you the ones digit of any number, while (n / 10) % 10 will give you the tens digit of any number. Also, to add some string v on to the end of a string s, you can write s=s+v.

1. Write num_to_words(n) that works correctly for any value from 0 to 99, including special cases like 10..

2. Extend your function to also cover negative values, e.g., num_to_words(-42) should return "negative forty two".

3. (Ambitious students): Extend your function to include a hundreds digit, so it covers values from -999 to 999. For example, num_to_words(123) should return "one hundred twenty three". Make sure your function handles special cases like 100 correctly, i.e., it should return "one hundred", not "one hundred zero".

4. (Experts only): Extend your function to cover values from -999,999 to 999,999. So num_to_words(12507) should return "twelve thousand five hundred seven", and num_to_words(12007) should return "twelve thousand and seven". To do this, you should rename your original function to num_helper(n) and write a new num_to_words(n) function that calls num_helper(n) twice: once to handle the thousands digits, and again to handle the ones through hundreds digits.

Remember to hand in your work before leaving the lab session.