Jump Into Ruby

### Jump Into Ruby

Due by midnight on Monday Jan 27th

### Objectives

This assignment should get you started on the basics of Ruby programming — assignment (no pun intended), variables, expressions, classes, methods, lists, arithmetic, and extending existing classes. This assignment should also familiarize you with using `irb` for running code and doing simple testing.

### Description

While it might be quite nice to "get your feet wet" with Ruby first, there just isn't enough time in the semester to dilly dally. So let's just jump right on in. Don't worry, the water's fine.

1. Funkonacci Numbers!

Recall the example from class about calculating Fibonacci numbers. Define the Funkonacci numbers as follows:

 0 if n < 1 funk(n) = 1 if n = 1 funk(n - 1) - (2 × funk(n - 2)) otherwise

Write a method `funk(n)` that calculates the nth Funkonacci number recursively. Generate a few Funkonacci numbers. Pretty funky, eh? Now write a second method, `fastfunk(n)` that calculates the nth Funkonacci number more quickly, using one of the techniques shown in class. Put your methods in a file named `funk.rb`.

2. Vegas, Baby!

The Boolaggio Hotel and Casino in fabulous Las Vegas, NV spends a large portion of their yearly revenue on playing cards. Business hasn't been too great lately, and the shareholders are looking to cut costs. They've hired you to design a program to replace their aging, obsolete paper playing cards.

Your program should include a class `Card` (or a `Struct` if you want to get fancy) that represents a card, as well as a class `Deck` that represents a deck of playing cards. The `Card` class should have a `to_s` method that returns a succinct, easily readible `String` representation of the card. The `Deck` class constructor should make a deck of 52 playing cards, of rank 2 through Ace, with suits of spades, hearts, diamonds, and clubs. Your `Deck` class should respond to the following methods:

• `shuffle`, which randomizes the order of the cards and returns the recently shuffled deck. You may not use `Array#shuffle`.
• `empty?`, which returns a `true` value if the deck has no cards in it, and a `false` value otherwise
• `deal`, which when called with the default argument of `1`, deals a card from the top of the deck. If called with an integer argument of `2` or greater, it should return an `Array` of cards of that size, dealt from the top of the deck. If there are not enough cards, it should deal as many as possible. If the deck is empty to begin with, it should return `nil`.
• `size`, which returns the number of cards left

Put your code in a file named `deck.rb`. When executed (but not when loaded), `deck.rb` should take one command-line parameter (print a usage message if it isn't a positive integer), and print out that many random cards. If the parameter is greater than 52, it should print out 52 cards. Here is an example trace to give you an idea of how your program should behave:

```\$ ./deck.rb
usage: ./deck.rb num_cards
\$ ./deck.rb foobar
usage: ./deck.rb num_cards
\$ ./deck.rb 3
3s, Tc, 2h
\$ ./deck.rb 15
Ac, 5s, 7d, Tc, 7h, 8c, Jh, 9d, Qs, 5c, Ts, Jd, 7s, 3d, 6c
\$ ./deck.rb 52
7c, 5c, 4h, Jc, Th, Ac, 6d, 2c, 9s, Kd, 2d, Js, 6s, 2h, 8h, 4s, 5s, Tc,
9h, Td, 4d, 3d, Jh, 9c, Ts, Qd, 8s, 3h, Qh, 9d, 8c, 3s, 2s, Jd, Qs, Kc,
Ks, 5h, 6h, 7d, 8d, 7h, Qc, Kh, 5d, Ah, As, 7s, 4c, 3c, 6c, Ad
\$ ./deck.rb 5200
3c, Qs, Tc, Ah, 2c, 8s, 3h, 4d, 7s, 2d, 8c, Qd, Js, Kc, 5s, 7h, 4s, 4h,
Jc, As, 5h, 7d, 9s, 2s, 3d, Ac, Ks, 3s, 7c, 9d, Td, Th, 6h, Ts, Kh, Ad,
Qh, 6s, 5c, Qc, 6c, Jh, 9c, 4c, Jd, 2h, 9h, 8h, Kd, 6d, 8d, 5d
```

3. Set Operations

The `Array` class in Ruby defines some set operations, such as union (`|`), intersection (`&`), and difference (`-`).

The symmetric difference of two sets is defined as the set of items that is in exactly one of the sets. This is usually denoted with a small, upward pointing triangle. However, since we don't have that character, add the operator `^` to the `Array` class such that, if `a` and `b` are `Array`s, ```a ^ b``` returns an `Array` that represents their symmetric difference.

The Cartesian product of two sets is defined as the set of all pairs such that the first element is in the first set and the second element is in the second set. Add the operator `**` to the `Array` class such that `a ** b` returns an `Array` that represents their Cartesian product. You may not use the method `Array#product`.

The power set of a set is the set of all subsets of the set (which always includes the empty set). Define a method `powerset` in class `Array` such that `a.powerset` returns the powerset of `a`. The `powerset` method must not use recursion. Define another method `powersetr` that behaves identically to `powerset` but does use recursion. You may not use the method `Array#combination`.

Put your methods in a file called `setops.rb`

4. Optional Extra Credit: More Set Operations

The permutations of a set is the set of all possible orderings of the elements of that set. So the permutations of {1,2,3} are {<1,2,3>, <1,3,2>, <2,1,3>, <2,3,1>, <3,1,2>, <3,2,1>}. Define a method `permute` in class `Array` such that `a.permute` returns the permutations of `a`. You may do this recursively or non-recursively or both! Which do you think is more efficient? How many permutations of n set elements are there? Could this lead to practical problems at runtime? and if so how might we address them? Use the `setops.rb` file for this method.

• `funk.rb`
• `deck.rb`
• `setops.rb`