#!/usr/bin/env tclsh9.0 namespace import ::tcl::mathop::* # Put a margin of ... around the input. # Legit garden plot tiles will therefore be 1..rows and 1..cols. proc input {} { global rows cols grid set grid [list] set rows 0 while {[gets stdin line] >= 0} { if {$line eq ""} continue if {$rows == 0} { set margin [list .] foreach c [split $line ""] {lappend margin .} lappend margin . lappend grid $margin set cols [string length $line] } set row [list .] lappend row {*}[split $line ""] lappend row . lappend grid $row incr rows } lappend grid $margin } proc show {} { global rows cols grid for {set r 0} {$r <= [+ $rows 1]} {incr r} { for {set c 0} {$c <= [+ $cols 1]} {incr c} { puts -nonewline [lindex $grid $r $c] } puts "" } puts "rows=$rows cols=$cols" } proc count {} { global rows cols grid global region set total 0 for {set r 1} {$r <= $rows} {incr r} { for {set c 1} {$c <= $cols} {incr c} { if {[lindex $grid $r $c] eq "."} continue # Find the region starting here. set region [dict create] flood $r $c # puts "region=$region" set area [dict size $region] set p [perimeter $region] incr total [* $area $p] # puts "area=$area p=$p" # Mark the region as dots so we won't re-find it. foreach rc [dict keys $region] { lassign $rc r1 c1 lset grid $r1 $c1 . } } } puts $total } proc flood {r c} { global grid region if {[dict exists $region [list $r $c]]} return set plant [lindex $grid $r $c] dict set region [list $r $c] 1 foreach {dr dc} {0 1 0 -1 1 0 -1 0} { set r1 [+ $r $dr] set c1 [+ $c $dc] if {[lindex $grid $r1 $c1] eq $plant} {flood $r1 $c1} } } proc perimeter {region} { global grid set p 0 set plant "" foreach rc [dict keys $region] { lassign $rc r c if {$plant eq ""} {set plant [lindex $grid $r $c]} foreach {dr dc} {0 1 0 -1 1 0 -1 0} { set r1 [+ $r $dr] set c1 [+ $c $dc] if {[lindex $grid $r1 $c1] ne $plant} {incr p} } } return $p } input # show count