blob: 39f980e5bac47ccd2dc37679c1f85b9895f15df6 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
#!/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]]"
|