blob: fa480618f44ae86d4bb68ab1b7f75bfaabeeda67 (
plain) (
tree)
|
|
#!/bin/env tclsh
source lib.tcl
setup 6
puts {Part 1: Count unique guard coords}
set map(grid) {}
foreach line $input {
lappend map(grid) [split $line ""]
}
set map(h) [llength $map(grid)]
set map(w) [llength [lindex $map(grid) 0]]
set map(visits) {}
set map(debug) $map(grid)
set guard(y) [lsearch $map(grid) *^*]
set guard(x) [lsearch [lindex $map(grid) $guard(y)] ^]
set guard(dir) 0
set placed_obstructions {}
set rot_map {{-1 0} {0 1} {1 0} {0 -1}}
proc step_guard {} {
global guard rot_map map
dict set map(visits) [list $guard(y) $guard(x)] $guard(dir) 1
lset map(debug) $guard(y) $guard(x) [lindex {^ > v <} $guard(dir)]
lassign [lindex $rot_map $guard(dir)] ydir xdir
set ynew [expr {$guard(y) + $ydir}]
set xnew [expr {$guard(x) + $xdir}]
if {$ynew < 0 || $ynew >= $map(h) || $xnew < 0 || $xnew >= $map(w)} { return 0 }
if {[lindex $map(grid) $ynew $xnew] == "#"} {
set guard(dir) [expr {($guard(dir) + 1) % 4}]
return 1
}
set guard(y) $ynew
set guard(x) $xnew
return 1
}
# sigh
set potential_loops 0
while {[step_guard]} {
puts -nonewline "Unique coords: [llength [dict keys $map(visits)]]\r"
flush stdout
lassign [lindex $rot_map $guard(dir)] ydir xdir
set ynew [expr {$guard(y) + $ydir}]
set xnew [expr {$guard(x) + $xdir}]
if {$ynew < 0 || $ynew >= $map(h) || $xnew < 0 || $xnew >= $map(w)} continue
# it took me. 2 hours. to realize i needed the clause after the ||. god dammit.
if {[dict exists $placed_obstructions [list $ynew $xnew]] || [dict exists $map(visits) [list $ynew $xnew]]} {
continue
}
if {[dict exists $map(visits) [list $guard(y) $guard(x)] [expr {($guard(dir) + 1) % 4}]]} {
# foreach line $map(debug) {
# puts [join $line ""]
# }
dict incr placed_obstructions [list $ynew $xnew] 1
incr potential_loops
} elseif {[lindex $map(grid) $ynew $xnew] != "#"} {
set map_backup [array get map]
set guard_backup [array get guard]
lset map(grid) $ynew $xnew "#"
lset map(debug) $ynew $xnew "#"
while {[step_guard]} {
if {[dict exists $map(visits) [list $guard(y) $guard(x)] $guard(dir)]} {
dict incr placed_obstructions [list $ynew $xnew] 2
incr potential_loops
break
}
}
array set map $map_backup
array set guard $guard_backup
}
}
puts "Unique coords: [llength [dict keys $map(visits)]]"
puts ""
puts {Part 2: Number of potential looping obstructions}
puts "Potential count: [llength [dict keys $placed_obstructions]]"
|