#!/usr/bin/env tclsh source ../prelude.tcl proc read-input {gridp input} { upvar $gridp grid set i 0 while {[gets $input line] >= 0} { set j 0 foreach c [split $line ""] { set grid($i,$j) $c incr j } incr i } } proc mark-visited {visitp x y d} { if {$x < 0} {return 0} upvar $visitp visit set v [switch -exact -- $d n {expr 1} s {expr 2} w {expr 4} e {expr 8} default {error "invalid dir '$d'"}] incr visit($y,$x) 0 set result [expr {($visit($y,$x) & $v) != 0}] set visit($y,$x) [expr {$visit($y,$x)|$v}] return $result } proc follow {gridp visitp beams} { upvar $gridp grid upvar $visitp visit set newbeams {} foreach {x y d} $beams { if { [mark-visited visit $x $y $d] } continue switch $d { n { incr y -1 } s { incr y +1 } w { incr x -1 } e { incr x +1 } } if {![info exists grid($y,$x)]} continue switch -exact "$grid($y,$x) $d" { {\ n} { set d w } {\ s} { set d e } {\ e} { set d s } {\ w} { set d n } {/ n} { set d e } {/ s} { set d w } {/ e} { set d n } {/ w} { set d s } {| w} { set d {n s} } {| e} { set d {n s} } {- n} { set d {w e} } {- s} { set d {w e} } } foreach d' [split $d] { lappend newbeams $x $y ${d'} } } return $newbeams } proc solve {} { global grid set beams {-1 0 e} while {[llen $beams] > 0} { set beams [follow grid visit $beams] } set t 0 for {set i 0} {$i < 110} {incr i} { set row {} for {set j 0} {$j < 110} {incr j} { if {[info exists visit($i,$j)] && $visit($i,$j)} { lappend row "#" incr t } else { lappend row "." } } puts [join $row ""] } puts [array size visit] } read-input grid stdin puts [array get grid] puts [follow grid visit {0 0 e}] solve