#!/usr/bin/env tclsh8.6 namespace import ::tcl::mathop::* array set cardmap {2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 T 10 J 1 Q 12 K 13 A 14} while {[gets stdin line] >= 0} { lassign [split $line { }] hand bid set cards {} foreach card [split $hand {}] { lappend cards $cardmap($card) } lappend hands $cards lappend bids $bid } # For simplicity of ranking the hands, let's assign a "score" to each hand. # Each card's individual value fits in a hex digit, so we'll work in hex. # A score is dominated by the hand type ("two pair" etc.), so that has to # be the highest digit. Then there are 5 hex digits after that, one for # each card's value. proc score {hand} { set score 0 # Get the individual card digits first. Also track jokers indices. set jokers [list] set i 0 foreach card $hand { set score [expr {($score << 4) | $card}] if {$card == 1} {lappend jokers $i} incr i } # If there are 4 or 5 jokers, it's five of a kind automatically. if {[llength $jokers] >= 4} {return [| $score 0x600000]} # If there are 3 or fewer, iterate all the possible hands to determine # the type. set deck [list 2 3 4 5 6 7 8 9 10 12 13 14] if {[llength $jokers] == 3} { set maxtype 0 foreach i $deck { foreach j $deck { foreach k $deck { set h $hand lset h [lindex $jokers 0] $i lset h [lindex $jokers 1] $j lset h [lindex $jokers 2] $k set type [type $h] if {$type == 0x600000} {return [| $score $type]} if {$type > $maxtype} {set maxtype $type} } } } return [| $score $maxtype] } if {[llength $jokers] == 2} { set maxtype 0 foreach i $deck { foreach j $deck { set h $hand lset h [lindex $jokers 0] $i lset h [lindex $jokers 1] $j set type [type $h] if {$type == 0x600000} {return [| $score $type]} if {$type > $maxtype} {set maxtype $type} } } return [| $score $maxtype] } if {[llength $jokers] == 1} { set maxtype 0 foreach i $deck { set h $hand lset h [lindex $jokers 0] $i set type [type $h] if {$type == 0x600000} {return [| $score $type]} if {$type > $maxtype} {set maxtype $type} } return [| $score $maxtype] } return [| $score [type $hand]] } # Return the type ("two pair") for a given hand, which contains no jokers. proc type {hand} { lassign [lsort -integer $hand] a b c d e if {$a == $b && $b == $c && $c == $d && $d == $e} { # Five of a kind. return 0x600000 } if { ($a == $b && $b == $c && $c == $d) || ($b == $c && $c == $d && $d == $e) } { # Four of a kind. return 0x500000 } if { ($a == $b && $b == $c && $d == $e) || ($a == $b && $c == $d && $d == $e) } { # Full house. return 0x400000 } if { ($a == $b && $b == $c) || ($b == $c && $c == $d) || ($c == $d && $d == $e) } { # Three of a kind. return 0x300000 } if { ($a == $b && $c == $d) || ($a == $b && $d == $e) || ($b == $c && $d == $e) } { # Two pair. return 0x200000 } if { $a == $b || $b == $c || $c == $d || $d == $e } { # One pair. return 0x100000 } # High card only. return 0 } # Build a list of (score, bid) pairs for sorting. for {set i 0} {$i < [llength $hands]} {incr i} { lappend pairs [list [score [lindex $hands $i]] [lindex $bids $i]] } set total 0 set rank 0 foreach pair [lsort -integer -index 0 $pairs] { incr rank incr total [* $rank [lindex $pair 1]] } puts $total