88 lines
2.1 KiB
Tcl
88 lines
2.1 KiB
Tcl
|
#!/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
|