#!/usr/bin/env tclsh9.0 namespace import ::tcl::mathop::+ proc input {} { global grid rows cols gr gc set grid [list] set rows 0 set gr -1; set gc -1 while {[gets stdin line] >= 0} { if {$line eq ""} continue set cols [string length $line] lappend grid [split $line ""] if {$gr == -1} { set gc [string first ^ $line] if {$gc > -1} {set gr $rows} } incr rows } } proc isloop {} { global grid rows cols gr gc set face 0 ;# 0=N 1=E 2=S 3=W array set facing {0 {-1 0} 1 {0 1} 2 {1 0} 3 {0 -1}} set been [dict create] set r $gr; set c $gc dict set been "$r,$c,$face" 1 # set step 0 while 1 { lassign $facing($face) dr dc set r2 [+ $r $dr] if {$r2 < 0 || $r2 >= $rows} {return 0} set c2 [+ $c $dc] if {$c2 < 0 || $c2 >= $cols} {return 0} if {[lindex $grid $r2 $c2] eq "#"} { set face [expr {($face + 1) % 4}] continue } set r $r2; set c $c2 set key "$r,$c,$face" if {[dict exists $been $key]} {return 1} dict set been $key 1 } } proc tryall {} { global grid rows cols set count 0 set tried 0 for {set r 0} {$r < $rows} {incr r} { for {set c 0} {$c < $cols} {incr c} { incr tried set here [lindex $grid $r $c] if {$here ne "."} continue lset grid $r $c # # if {$r == 6 && $c == 3} show if {[isloop]} {incr count; puts -nonewline .; flush stdout} lset grid $r $c . } } puts "\ntried=<$tried> count=<$count>" } proc show {} { global grid rows cols for {set r 0} {$r < $rows} {incr r} { for {set c 0} {$c < $cols} {incr c} { puts -nonewline "[lindex $grid $r $c] " } puts "" } } input # show tryall