Skip to content

Instantly share code, notes, and snippets.

@martende
Last active August 29, 2015 14:02
Show Gist options
  • Save martende/651760e7278752984f6d to your computer and use it in GitHub Desktop.
Save martende/651760e7278752984f6d to your computer and use it in GitHub Desktop.
#!/bin/sh
exec scala "$0" "$@"
!#
object HelloWorld {
abstract class OCard {
val v:Int
val c:Int
def matchV(x:OCard):Boolean
def matchAll(x:OCard):Boolean
}
class Joker() extends OCard {
val v:Int = -1
val c:Int = -1
def matchV(x:OCard):Boolean = true
def matchAll(x:OCard):Boolean = true
override def toString = "(*)"
}
class Card(val c:Int,val v:Int) extends OCard {
def matchV(x:OCard):Boolean = x.v == -1 || v == x.v
def matchAll(x:OCard):Boolean = x.v == -1 || ( v == x.v && c == x.c)
override def toString = s"($c,$v)"
}
case class VMask(xs:Set[OCard],taken:Int,telsDebug:Set[OCard]) {
override def toString = s"$taken = $telsDebug"
}
val SAMEVAL = 0x01
val ASCVAL = 0x02
val SAMEEL = 0x08
def newColor(t:Set[OCard],c:Int) = c == -1 || ! t.exists(_.c == c )
def sameColor(t:Set[OCard],c:Int) = c == -1 || t.forall { x=>
x.c == c || x.c == -1
}
def sameVal(t:Set[OCard],v:Int) = v == -1 || t.forall { x=>
x.v == v || x.v == -1
}
def canTakeAsk(taken:Set[OCard],v:Int):Boolean = {
def isAsc(tf:List[Int],jokerCnt:Int):Boolean = {
( jokerCnt >= 0 ) && (
tf match {
case a :: b :: xs =>
val diff = (b - a - 1)
if ( diff < 0 ) false else isAsc(tf.tail,jokerCnt - diff )
case _ => true
}
)
}
if (v == -1) true
else {
var jokerCnt = taken.count(_.v == -1)
if ( jokerCnt == taken.size ) true
else {
val tf = ( v :: taken.filter(_.v != -1 ).map(_.v).toList ).sorted
val valid = if ( tf.head == 1 && tf.last >= 10 ) {
isAsc( tf.tail :+ 14,jokerCnt)
} else isAsc(tf,jokerCnt)
valid
}
}
}
case class Interval(min:Int,max:Int)
def colorMasks(s:Set[OCard]):List[VMask] = {
def _colorMasks(taken:Set[OCard],avail:Set[OCard],mask:Int):List[VMask] = {
val len = taken.size
val cur = if ( len > 2 || ( (mask & SAMEEL) != 0 && len == 2 ) ) List(VMask(avail,len,taken)) else List()
val deep = avail.flatMap {
t =>
val newSameVal = if (
(mask & SAMEVAL) != 0 &&
len < 4 &&
sameVal(taken,t.v) &&
newColor(taken,t.c)
) SAMEVAL else 0
val newSameEl = if (
(mask & SAMEEL) != 0 &&
len < 2 && taken.head.matchAll(t)
) SAMEEL else 0
val newAscVal = if (
(mask & ASCVAL) != 0 &&
len < 5 &&
canTakeAsk(taken,t.v) && sameColor(taken,t.c)
) ASCVAL else 0
val newmask = newSameVal | newSameEl | newAscVal
if ( newmask != 0 )
_colorMasks(taken + t,avail - t , newmask )
else List()
}
cur ++ deep
}
val v = s.head
_colorMasks(Set(v),s.toSet - v, SAMEVAL | SAMEEL | ASCVAL )
}
def masks(s:Set[OCard]) = colorMasks(s).distinct
def check_reveal(v:Set[OCard]) = {
def _check_reveal(v:Set[OCard],result:Map[Int,Int],debugTracer:List[VMask]):Boolean = {
if ( v.isEmpty ) {
//println(result,debugTracer)
(result == Map(2->7) || result == Map(3->3,5->1) || result == Map(3->2,4->2) || result == Map(4->1,5->2))
} else masks(v).exists(x => {
val newResult = result + ( x.taken -> ( result.getOrElse(x.taken,0) + 1 ) )
_check_reveal(x.xs,newResult,x::debugTracer )
})
}
_check_reveal(v,Map[Int,Int](),List())
}
def testAll() {
assert( canTakeAsk( Set( new Card(1,13), new Card(1,12) , new Joker() , new Card(1,11) ), 1 ) == true )
assert( canTakeAsk( Set( new Card(1,1), new Card(1,2) , new Joker() , new Joker() ), 13 ) == false )
assert( canTakeAsk( Set( new Card(1,1), new Joker() , new Joker() , new Joker() ), 10 ) == true )
assert( canTakeAsk( Set( new Card(1,1), new Card (2,13) ), 12 ) == true )
assert( canTakeAsk( Set( new Card(1,1), new Card (2,13) , new Joker() ), 11 ) == true )
assert( canTakeAsk( Set( new Card(1,1), new Card (2,11) , new Joker() , new Joker() ), 11 ) == false )
assert( canTakeAsk( Set( new Card(1,1), new Card (2,11) , new Joker() , new Joker() ), 10 ) == true )
assert( canTakeAsk( Set( new Card(1,1), new Joker() , new Joker() , new Joker() ), 9 ) == false )
assert( canTakeAsk( Set( new Card(1,1), new Card (2,2) , new Joker() ), 4 ) == true )
assert( canTakeAsk( Set( new Card(1,1), new Card (2,2) , new Joker() ), 3 ) == true )
assert( canTakeAsk( Set( new Card(1,1), new Card (2,13) ), 1 ) == false )
assert( canTakeAsk( Set( new Card(1,1), new Card (2,13) ), 2 ) == false )
assert {
val part = Set(
new Card(1,7), new Card(1,6),
new Card(2,1), new Card(2,2), new Card(2,3),
new Card(3,1), new Card(3,2), new Card(3,3), new Card(3,4), new Card(3,10),
new Joker(), new Joker(), new Joker(), new Joker()
)
check_reveal(part) == true
}
assert {
val part = Set(
new Card(1,7), new Card(1,6), new Joker(), new Card(1,4), new Card(1,3),
new Card(2,2), new Card(2,10), new Card(2,11), new Card(2,12), new Card(2,13),
new Card(1,1), new Joker(), new Joker(), new Card(4,1))
check_reveal(part) == false
}
assert {
val part = Set[OCard](
new Card(1,11), new Card(1,12), new Card(1,13), new Card(1,1), new Card(1,10),
new Card(2,9), new Card(2,10), new Card(2,11), new Card(2,12), new Card(2,13),
new Card(1,5), new Card(2,5), new Card(3,5), new Card(4,5))
check_reveal(part) == true
}
assert {
val part = Set[OCard](
new Card(1,7), new Card(1,6), new Card(1,5), new Card(1,4), new Card(1,3),
new Card(2,9), new Card(2,10), new Card(2,11), new Card(2,12), new Card(2,13),
new Card(1,1), new Card(2,1), new Card(3,1), new Card(4,1))
check_reveal(part) == true
}
assert {
val r = for (i <- 1 to 11) yield check_reveal(Set[OCard](new Card(1,1), new Card(2,1), new Card(3,1),
new Card(1,3),new Card(2,3),new Card(3,3),
new Card(1,5),new Card(2,5),new Card(3,5),
new Card(1,7),new Card(2,7),new Card(3,7),
new Joker(),
new Joker() ))
r.forall(x => x)
/*val t = for (i <- 1 to 11) {
val s =
yield check_reveal(s)
}//.forall(_)
*/
}
println("Tests ok")
}
def main(args: Array[String]) {
testAll()
val cards = List(new Joker(),new Joker(),new Joker(),new Joker()) ++ (for(C<-List(1,2,3,4); V<-1 to 13; _ <-List(1,2)) yield new Card(C,V))
val part = scala.util.Random.shuffle(cards).take(14).toSet
println(part)
println(check_reveal(part))
}
}
HelloWorld.main(args)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment