2023-12-16 05:43:57 +00:00
|
|
|
#!/usr/bin/env tclsh
|
|
|
|
source ../prelude.tcl
|
|
|
|
|
2023-12-17 06:24:26 +00:00
|
|
|
proc read-input {input} {
|
|
|
|
global grid
|
|
|
|
global width
|
|
|
|
global height
|
2023-12-16 05:43:57 +00:00
|
|
|
set i 0
|
|
|
|
while {[gets $input line] >= 0} {
|
|
|
|
set j 0
|
|
|
|
foreach c [split $line ""] {
|
|
|
|
set grid($i,$j) $c
|
|
|
|
incr j
|
|
|
|
}
|
|
|
|
incr i
|
|
|
|
}
|
2023-12-17 06:24:26 +00:00
|
|
|
set height $i
|
|
|
|
set width $j
|
|
|
|
}
|
|
|
|
|
|
|
|
proc reset-visited {} {
|
|
|
|
global visit
|
2023-12-19 04:57:53 +00:00
|
|
|
set visit [dict create]
|
2023-12-16 05:43:57 +00:00
|
|
|
}
|
|
|
|
|
2023-12-17 06:24:26 +00:00
|
|
|
proc mark-visited {x y d} {
|
|
|
|
global visit
|
2023-12-16 05:43:57 +00:00
|
|
|
set v [switch -exact -- $d n {expr 1} s {expr 2} w {expr 4} e {expr 8} default {error "invalid dir '$d'"}]
|
2023-12-19 04:57:53 +00:00
|
|
|
dict incr visit $y,$x 0
|
|
|
|
set old [dict get $visit $y,$x]
|
|
|
|
dict set visit $y,$x [expr {$old | $v}]
|
|
|
|
return [expr {($old & $v) != 0}]
|
2023-12-16 05:43:57 +00:00
|
|
|
}
|
|
|
|
|
2023-12-17 06:24:26 +00:00
|
|
|
proc print-visited {} {
|
|
|
|
global visit
|
|
|
|
global width
|
|
|
|
global height
|
|
|
|
for {set i 0} {$i < $height} {incr i} {
|
|
|
|
set row {}
|
|
|
|
for {set j 0} {$j < $width} {incr j} {
|
2023-12-19 04:57:53 +00:00
|
|
|
if {[dict exists $visit $i,$j] && [dict get $visit $i,$j]} {
|
2023-12-17 06:24:26 +00:00
|
|
|
lappend row "#"
|
|
|
|
} else {
|
|
|
|
lappend row "."
|
|
|
|
}
|
|
|
|
}
|
|
|
|
puts [join $row ""]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
proc follow {beams {first 0}} {
|
|
|
|
global grid
|
2023-12-16 05:43:57 +00:00
|
|
|
set newbeams {}
|
|
|
|
foreach {x y d} $beams {
|
2023-12-16 06:02:16 +00:00
|
|
|
if {!$first} {
|
2023-12-17 06:24:26 +00:00
|
|
|
if { [mark-visited $x $y $d] } continue
|
2023-12-16 06:02:16 +00:00
|
|
|
switch $d {
|
|
|
|
n { incr y -1 }
|
|
|
|
s { incr y +1 }
|
|
|
|
w { incr x -1 }
|
|
|
|
e { incr x +1 }
|
|
|
|
}
|
2023-12-16 05:43:57 +00:00
|
|
|
}
|
2023-12-17 06:24:26 +00:00
|
|
|
if {[info exists grid($y,$x)]} {
|
|
|
|
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'}
|
|
|
|
}
|
2023-12-16 05:43:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return $newbeams
|
|
|
|
}
|
|
|
|
|
|
|
|
proc solve {} {
|
2023-12-17 06:24:26 +00:00
|
|
|
global visit
|
|
|
|
reset-visited
|
|
|
|
set beams [follow {0 0 e} 1]
|
2023-12-16 05:43:57 +00:00
|
|
|
while {[llen $beams] > 0} {
|
2023-12-17 06:24:26 +00:00
|
|
|
set beams [follow $beams]
|
2023-12-16 05:43:57 +00:00
|
|
|
}
|
2023-12-17 06:24:26 +00:00
|
|
|
print-visited
|
2023-12-19 04:57:53 +00:00
|
|
|
puts [dict size $visit]
|
2023-12-16 05:43:57 +00:00
|
|
|
}
|
|
|
|
|
2023-12-16 06:02:16 +00:00
|
|
|
proc lmax {list} {
|
|
|
|
set t 0
|
|
|
|
foreach x $list { if {$t < $x} {set t $x} }
|
|
|
|
return $t
|
|
|
|
}
|
|
|
|
|
2023-12-17 06:24:26 +00:00
|
|
|
proc solve2 {} {
|
2023-12-16 06:02:16 +00:00
|
|
|
global grid
|
2023-12-17 06:24:26 +00:00
|
|
|
global width
|
|
|
|
global height
|
|
|
|
global visit
|
|
|
|
puts "width=$width height=$height"
|
|
|
|
|
2023-12-16 06:02:16 +00:00
|
|
|
set edges {}
|
|
|
|
foreach k [array names grid] {
|
|
|
|
lassign [split $k ","] y x
|
|
|
|
if {$x == 0} { lappend edges [list $x $y e] }
|
|
|
|
if {$y == 0} { lappend edges [list $x $y s] }
|
|
|
|
if {$x == $width - 1} { lappend edges [list $x $y n] }
|
|
|
|
if {$y == $height - 1} { lappend edges [list $x $y w] }
|
|
|
|
}
|
|
|
|
|
|
|
|
set l {}
|
|
|
|
foreach beams $edges {
|
2023-12-17 06:24:26 +00:00
|
|
|
reset-visited
|
|
|
|
set beams [follow $beams 1]
|
2023-12-16 06:02:16 +00:00
|
|
|
while {[llen $beams] > 0} {
|
2023-12-17 06:24:26 +00:00
|
|
|
set beams [follow $beams]
|
2023-12-16 06:02:16 +00:00
|
|
|
}
|
2023-12-19 04:57:53 +00:00
|
|
|
puts [dict size $visit]
|
|
|
|
lappend l [dict size $visit]
|
2023-12-16 06:02:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
puts [lmax $l]
|
|
|
|
}
|
|
|
|
|
2023-12-17 06:24:26 +00:00
|
|
|
read-input stdin
|
2023-12-16 05:43:57 +00:00
|
|
|
puts [array get grid]
|
2023-12-17 06:24:26 +00:00
|
|
|
puts [follow {0 0 e}]
|
2023-12-19 04:57:53 +00:00
|
|
|
puts [dict get $visit]
|
2023-12-16 05:43:57 +00:00
|
|
|
|
|
|
|
solve
|
2023-12-17 06:24:26 +00:00
|
|
|
solve2
|