diff options
Diffstat (limited to '2024/tcl/06.tcl')
-rwxr-xr-x | 2024/tcl/06.tcl | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/2024/tcl/06.tcl b/2024/tcl/06.tcl new file mode 100755 index 0000000..fa48061 --- /dev/null +++ b/2024/tcl/06.tcl @@ -0,0 +1,90 @@ +#!/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]]" |