advent-of-code

advent of code attempts
git clone git://bvnf.space/advent-of-code.git
Log | Files | Refs

a.tcl (1745B)


      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