#!/usr/bin/env tclsh8.6 # The 2-letter input is "1". # The 3-letter input is "7". # The 4-letter input is "4". # The 7-letter input is "8". # (Whichever letter appears in "7" and not in "1" is the top segment.) # The 6-letter input which does NOT have both letters of "1" is "6". # Whichever letter is missing from "6" is the top-right segment. # (The other letter in "1" is the bottom-right segment.) # The 6-letter input which contains all letters from "4" is "9". # The remaining 6-letter input is "0". # (The letter that's missing from "9" is the bottom-left segment.) # (The letter that's missing from "0" is the center segment.) # The 5-letter input which contains all the letters of "7" is "3". # The 5-letter input which contains the top-right segment is "2". # The remaining 5-letter input is "5". proc sorted {word} { join [lsort [split $word {}]] {} } proc decode {words} { foreach w [lrange $words 0 9] { set w [sorted $w] set digit($w) "" switch -- [string length $w] { 2 {set digit($w) 1; set from(1) $w} 3 {set digit($w) 7; set from(7) $w} 4 {set digit($w) 4; set from(4) $w} 5 {lappend fives $w} 6 {lappend sixes $w} 7 {set digit($w) 8; set from(8) $w} } } # The 6-letter input which does NOT have both letters of "1" is "6". set x [string index $from(1) 0] set y [string index $from(1) 1] foreach w $sixes { array unset has foreach c [split $w {}] {set has($c) 1} if {! [info exists has($x)] || ! [info exists has($y)]} { set digit($w) 6; set from(6) $w break } } set tmp {} foreach w $sixes { if {$w ne $from(6)} {lappend tmp $w} } set sixes $tmp # Whichever letter is missing from "6" is the top-right segment. array unset has foreach c [split $from(6) {}] {set has($c) 1} foreach c {a b c d e f g} { if {! [info exists has($c)]} { set topright $c break } } # The 6-letter input which contains all letters from "4" is "9". # The remaining 6-letter input is "0". array unset has foreach c [split [lindex $sixes 0] {}] {set has($c) 1} set hasall 1 foreach c [split $from(4) {}] { if {! [info exists has($c)]} { set hasall 0 break } } if {$hasall} { set digit([lindex $sixes 0]) 9 set from(9) [lindex $sixes 0] set digit([lindex $sixes 1]) 0 set from(0) [lindex $sixes 1] } else { set digit([lindex $sixes 0]) 0 set from(0) [lindex $sixes 0] set digit([lindex $sixes 1]) 9 set from(9) [lindex $sixes 1] } # The 5-letter input which contains all the letters of "7" is "3". foreach w $fives { array unset has foreach c [split $w {}] {set has($c) 1} set hasall 1 foreach c [split $from(7) {}] { if {! [info exists has($c)]} { set hasall 0 break } } if {$hasall} { set digit($w) 3 set from(3) $w break } } set tmp {} foreach w $fives { if {$w ne $from(3)} {lappend tmp $w} } set fives $tmp # The 5-letter input which contains the top-right segment is "2". # The remaining 5-letter input is "5". if {[string match *$topright* [lindex $fives 0]]} { set digit([lindex $fives 0]) 2 set from(2) [lindex $fives 0] set digit([lindex $fives 1]) 5 set from(5) [lindex $fives 1] } else { set digit([lindex $fives 0]) 5 set from(5) [lindex $fives 0] set digit([lindex $fives 1]) 2 set from(2) [lindex $fives 1] } # Return output (stripping leading zeroes). set out "" foreach w [lrange $words 11 14] { append out $digit([sorted $w]) } scan $out %d out return $out } set n 0 while {[gets stdin line] >= 0} { set words [split $line { }] incr n [decode $words] } puts $n