wox
8/9/2012 - 12:32 PM

Solitare

Solitare

``````import math.{max,min}
import util.Random.shuffle

case class Card(suit:Int, rank:Int) {
def switchableWith(c:Card) = suit==c.suit || rank==c.rank
}

case class Deck(cards: List[Card]) {
def switchable(i: Int, dx: Int) = (dx <= i && (cards(i) switchableWith cards(i-dx)) )

def switch(i: Int, dx: Int) = {
val(head, rest) = cards splitAt i-dx
val(mid, tail) = rest splitAt dx
Deck( head ::: tail.take(1) ::: mid.drop(1) ::: tail.drop(1) )
}
}

object Deck {
val cards = for (suit <- 1 to 4; rank <- 1 to 13) yield Card(suit,rank)

def apply(seed: Int): Deck = {
util.Random.setSeed(seed)
Deck( shuffle(cards.toList) )
}
}

def play(deck: Deck, i: Int): Boolean = {
if (deck.cards.length == 1) {
true
} else if (i >= deck.cards.length ) {
false
} else {
val s1 = deck.switchable(i,1)
val s3 = deck.switchable(i,3)

if (!s1 && !s3)
play( deck, i+1 )
else
( if (s1) play( deck.switch(i, 1), max(i-1,1) ) else false ) ||
( if (s3) play( deck.switch(i, 3), max(i-3,1) ) else false )
}
}

def run(numberOfRuns: Int) = (1 to numberOfRuns).foldLeft(0) {
(acc,i) => { if( play(Deck(i), 1) ) acc+1 else acc }
}

println( run(100) )``````