#!/usr/bin/env tclsh while {[gets stdin line] >= 0} { if {[scan $line {%s %s bags contain %[^.].} c1 c2 rest] != 3} continue set color "$c1 $c2" if {$rest eq "no other bags"} { set contain($color) {} continue } set words [split $rest { }] while {[llength $words]} { set c2 "[lindex $words 1] [lindex $words 2]" lappend contain($color) [list $c2 [lindex $words 0]] lappend canbein($c2) $color set words [lrange $words 4 end] } } proc holders {bag} { global canbein if {! [info exists canbein($bag)]} {return {}} set h $canbein($bag) foreach b $canbein($bag) { lappend h {*}[holders $b] } return [lsort -unique $h] } proc holds {bag} { global contain if {! [info exists contain($bag)]} {return 0} set total 0 foreach bn $contain($bag) { lassign $bn b n incr total $n set total [expr {$total + $n * [holds $b]}] } return $total } puts [holds {shiny gold}]