#!/usr/local/bin/tclsh foreach r [split [read stdin] \n] { if {[scan $r {%[^=] => %d %s} a b c] != 3} continue set qty($c) $b foreach i [split [string map {{ } {}} $a] ,] { scan $i {%d%s} j k lappend inputs($c) [list $j $k] set made($c) 0 } } set made(ORE) 0 set dug 0 proc make {n chem} { global qty inputs made dug #puts "making: $n $chem" if {$chem eq "ORE"} { incr made(ORE) $n incr dug $n #puts "dig $n ORE" return } # Find the reaction we need to run, and then calculate how many times # to run it. if {$n == $qty($chem)} { set times 1 } else { set times [expr {($n + $qty($chem) - 1) / $qty($chem)}] } #puts "make $times batches of $chem" # Produce enough of each input chemical. # Consume them *as we go* so they don't get double-used. foreach i $inputs($chem) { lassign $i n2 chem2 if {$made($chem2) < ($times * $n2)} { make [expr {($times * $n2) - $made($chem2)}] $chem2 } else { #puts "already have $made($chem2) $chem2 (need [expr {$times*$n2}])" } incr made($chem2) [expr {-1 * $times * $n2}] #puts "consumed [expr {$times * $n2}] $chem2 ($made($chem2) left)" } # Inputs have been consumed, so create output. incr made($chem) [expr {$times * $qty($chem)}] #puts "created [expr {$times * $qty($chem)}] $chem" } make 1 FUEL puts "dug $dug ORE"