Last active
August 29, 2015 14:02
-
-
Save martende/651760e7278752984f6d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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