#!/usr/bin/env tclsh proc calculate {s} { # puts "calculate: $s" while {[string match *(* $s]} { # Find the first ) and the ( which matches it. set i 0 foreach c [split $s {}] { switch -- $c { ( {set left $i} ) {set right $i; break} } incr i } set n [calculate [string range $s $left+1 $right-1]] set s "[string range $s 0 $left-1]$n[string range $s $right+1 end]" # puts " reduce to: $s" } # Split expression into tokens. set tokens {} set tmp "" foreach c [split $s {}] { switch -glob -- $c { [0-9] {append tmp $c} default {lappend tokens $tmp $c; set tmp ""} } } lappend tokens $tmp # puts " tokens: $tokens" # If operators are all + or all *, just do it now. if {"+" ni $tokens} { set tmp {} foreach t $tokens { if {$t ne "*"} {lappend tmp $t} } # puts " all times: $tmp" return [::tcl::mathop::* {*}$tmp] } elseif {"*" ni $tokens} { set tmp {} foreach t $tokens { if {$t ne "+"} {lappend tmp $t} } # puts " all plus: $tmp" return [::tcl::mathop::+ {*}$tmp] } # Generate a fully parenthesized string and recurse. set stack {} set plus 0 foreach t $tokens { if {$plus} { set prev [lindex $stack end] lset stack end "($prev+$t)" set plus 0 continue } switch -- $t { + {set plus 1} * {lappend stack $t} default {lappend stack $t} } } # puts " stack: $stack" calculate [join $stack {}] } set sum 0 while {[gets stdin line] >= 0} { if {$line eq ""} continue set line [string map {{ } {}} $line] incr sum [calculate $line] } puts $sum