#!/usr/bin/env tclsh source ../prelude.tcl proc slurp filename { set fd [open $filename] set data [read $fd] close $fd return $data } set sample "rn=1,cm-,qp=3,cm=2,qp-,pc=4,ot=9,ab=5,pc-,pc=6,ot=7" set input [trim [slurp ./input]] proc ord c { return [scan $c "%c"] } proc hash s { set h 0 foreach c [split $s ""] { set h [expr {(($h + [ord $c]) * 17) % 256}] } return $h } proc sum s { set t 0 foreach part [split $s ","] { incr t [hash $part] } return $t } puts [hash HASH] puts [sum $sample] puts [sum $input] proc place {boxp lens} { upvar $boxp box set i [string first "=" $lens] if {$i >= 0} { set label [string range $lens 0 $i-1] set num [string range $lens $i+1 end] set h [hash $label] set i 0 set found 0 if {![info exists box($h)]} { set box($h) {} } foreach {l n} $box($h) { if {$l eq $label} { lset box($h) $i+1 $num set found 1 break } incr i 2 } if {!$found} { lappend box($h) $label $num } } else { set label [trim $lens "-"] set h [hash $label] #puts "$lens $label $h" if {[info exists box($h)]} { set i 0 foreach {l n} $box($h) { if {$l eq $label} { #puts "removing $i from $h" set box($h) [lreplace $box($h) $i $i+1] break } incr i 2 } } } } proc solve input { set parts [split $input ","] foreach part $parts { place box $part #puts [array get box] } set t 0 foreach {h elems} [array get box] { set slot 0 foreach {l n} $elems { incr slot incr t [expr {($h+1) * $slot * $n}] } } puts $t } solve $sample solve $input