summaryrefslogblamecommitdiffstats
path: root/2024/tcl/06.tcl
blob: 39f980e5bac47ccd2dc37679c1f85b9895f15df6 (plain) (tree)
1
2
3
4
5
6
7
8
9
10


                
            


                                        


                                                        





                                       


                                                                      




                                                 
                                                                                      
 
                                                 











                                                 
                                                                         




                                                 
                                                                                  

                                                                                 
                                                                                                                 

            

                                                                                               



                                                      

                                                       

                                      

                                     

                          
                                                                                





                                                          
                                 



                                 
                                                          




                                                                  
#!/bin/env tclsh

source lib.tcl
setup 6 grid

puts {Part 1: Count unique guard coords}

set input(visits) {}
set guard(y) [lsearch $input(grid) *^*]
set guard(x) [lsearch [lindex $input(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 input
  dict set input(visits) [list $guard(y) $guard(x)] $guard(dir) 1
  lset input(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 >= $input(h) || $xnew < 0 || $xnew >= $input(w)} { return 0 }

  if {[lindex $input(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 $input(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 >= $input(h) || $xnew < 0 || $xnew >= $input(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 $input(visits) [list $ynew $xnew]]} {
    continue
  }
  if {[dict exists $input(visits) [list $guard(y) $guard(x)] [expr {($guard(dir) + 1) % 4}]]} {
#    foreach line $input(debug) {
#      puts [join $line ""]
#    }
    dict incr placed_obstructions [list $ynew $xnew] 1
    incr potential_loops
  } elseif {[lindex $input(grid) $ynew $xnew] != "#"} {
    set input_backup [array get input]
    set guard_backup [array get guard]

    lset input(grid) $ynew $xnew "#"
    lset input(debug) $ynew $xnew "#"

    while {[step_guard]} {
      if {[dict exists $input(visits) [list $guard(y) $guard(x)] $guard(dir)]} {
        dict incr placed_obstructions [list $ynew $xnew] 2
        incr potential_loops
        break
      }
    }

    array set input $input_backup
    array set guard $guard_backup
  }
}

puts "Unique coords: [llength [dict keys $input(visits)]]"

puts ""
puts {Part 2: Number of potential looping obstructions}

puts "Potential count: [llength [dict keys $placed_obstructions]]"