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
|
set txt [read -nonewline stdin]
set lines [split $txt "\n"]
proc look_for_num {arr y x} {
while {[incr x -1] >= 0 && [string is digit [lindex $arr $y $x]]} {}
incr x
# get end of string
set tmp [lindex $arr $y]
set tmp [lrange $tmp $x end]
set tmp [join $tmp {}]
if {[string is digit -failindex i $tmp]} { set i end } else { set i [expr {$x+$i-1}]}
return [list $x $i]
}
set 2d {}
foreach line $lines {
lappend 2d [split $line {}]
}
set height [llength $2d]
set width [llength [lindex $2d 0]]
set found {}
set part2 0
for {set y 0} {$y < $height} {incr y} {
for {set x 0} {$x < $width} {incr x} {
switch -glob [lindex $2d $y $x] {
[0-9] {
# part of a number
}
. {
# nothing
}
default {
# treat everything else as a "symbol"
# look around for numbers
set localfound {}
foreach dx {-1 0 1} {
foreach dy {-1 0 1} {
set xx [expr {$x + $dx}]
set yy [expr {$y + $dy}]
if {$xx < 0 || $xx >= $width || $yy < 0 || $yy >= $height || (($dx==0)&&($dy==0))} {
continue
}
if {[string is digit [lindex $2d $yy $xx]]} {
set bounds [look_for_num $2d $yy $xx]
set num [join [lrange [lindex $2d $yy] {*}$bounds] {}]
# add to dictionary of found numbers:
# key is y,x of start of number
# val is numbervalue
dict set localfound "${yy},[lindex $bounds 0]" $num
# check if already set?
}
}
}
# Part 2
if {[lindex $2d $y $x] == "*"} {
set tmp [dict values $localfound]
if {[llength $tmp] == 2} {
incr part2 [expr [join $tmp "*"]]
}
}
set found [dict merge $localfound $found]
}
}
}
}
set tot 0
dict map {k v} $found {
incr tot $v
}
puts $tot
puts $part2
|