Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Repeating a List in Scala

Tags:

scala

I am a Scala noob. I have decided to write a spider solitaire solver as a first exercise to learn the language and functional programming in general.

I would like to generate a randomly shuffled deck of cards containing 1, 2, or 4 suits. Here is what I came up with:

val numberOfSuits = 1
(List("clubs", "diamonds", "hearts", "spades").take(numberOfSuits) * 4).take(4)

which should return

List("clubs", "clubs", "clubs", "clubs")
List("clubs", "diamonds", "clubs", "diamonds")
List("clubs", "diamonds", "hearts", "spades")

depending on the value of numberOfSuits, except there is no List "multiply" operation that I can find. Did I miss it? Is there a better way to generate the complete deck before shuffling?

BTW, I plan on using an Enumeration for the suits, but it was easier to type my question with strings. I will take the List generated above and using a for comprehension, iterate over the suits and a similar List of card "ranks" to generate a complete deck.

like image 279
Ralph Avatar asked Mar 22 '10 11:03

Ralph


2 Answers

Flatten a finite lists of lists:

scala> List.fill(2)(List(1, 2, 3, 4)).flatten
res18: List[Int] = List(1, 2, 3, 4, 1, 2, 3, 4)

Flatten an infinite Stream of lists, take the first N elements:

scala> Stream.continually(List(1, 2, 3, 4)).flatten.take(8).toList
res19: List[Int] = List(1, 2, 3, 4, 1, 2, 3, 4)
like image 142
retronym Avatar answered Oct 16 '22 16:10

retronym


You should look up the scaladoc for the object List. It has all manners of interesting methods for creation of lists. For instance, the following does exactly what you were trying to:

List.flatten(List.make(4, List("clubs", "diamonds", "hearts", "spades").take(numberOfSuits))).take(4)

A much nicer code, however, would be this (Scala 2.7):

val suits = List("clubs", "diamonds", "hearts", "spades")
List.tabulate(4, i => suits.apply(i % numberOfSuits))

On Scala 2.8 tabulate is curried, so the correct syntax would be:

List.tabulate(4)(i => suits.apply(i % numberOfSuits))
like image 32
Daniel C. Sobral Avatar answered Oct 16 '22 16:10

Daniel C. Sobral