adventofcode2023/day12/sol2.tcl

94 lines
2.6 KiB
Tcl
Raw Normal View History

2023-12-12 09:15:32 +00:00
#!/usr/bin/env tclsh
source ../prelude.tcl
set input stdin
2023-12-12 09:40:29 +00:00
proc count-memo {row nums i left} {
global memo
if {$i == 0} {
array unset memo
}
2023-12-12 09:15:32 +00:00
set key "$i,$left,[llength $nums]"
2023-12-12 09:40:29 +00:00
if {[info exists memo($key)]} {
2023-12-12 09:15:32 +00:00
#puts "$key exists"
2023-12-12 09:40:29 +00:00
return $memo($key)
2023-12-12 09:15:32 +00:00
}
set n [count $row $nums $i $left]
2023-12-12 09:40:29 +00:00
set memo($key) $n
2023-12-12 09:15:32 +00:00
return $n
}
proc count {row nums i left} {
2023-12-12 09:40:29 +00:00
#puts [list count $row $nums $i $left]
2023-12-12 09:15:32 +00:00
if {$i >= [string length $row]} {
2023-12-12 09:40:29 +00:00
return [expr {($left > 1 || [llength $nums] > 0) ? 0 : 1}]
2023-12-12 09:15:32 +00:00
}
if {[llength $nums] <= 0 && $left <= 0} {
return [expr {[string first "#" $row $i] >= 0 ? 0 : 1}]
}
set c [string index $row $i]
incr i
if {$c eq "."} {
if {$left > 1} {
2023-12-12 09:40:29 +00:00
# contradiction: expecting a "#"
2023-12-12 09:15:32 +00:00
return 0
} elseif {$left == 1} {
2023-12-12 09:40:29 +00:00
# left counts the number of "#" left in the current group,
# plus the "." at the end. if left==1 then we've seen all
# the "#" and now we need to see a "."
2023-12-12 09:15:32 +00:00
set left 0
} else {
# nothing
}
2023-12-12 09:40:29 +00:00
return [count-memo $row $nums $i $left]
2023-12-12 09:15:32 +00:00
}
if {$c eq "#"} {
if {$left > 1} {
incr left -1
} elseif {$left == 1} {
2023-12-12 09:40:29 +00:00
# contradiction: expecting a "."
2023-12-12 09:15:32 +00:00
return 0
} else {
set nums [lassign $nums left] ;# shift nums
}
2023-12-12 09:40:29 +00:00
return [count-memo $row $nums $i $left]
2023-12-12 09:15:32 +00:00
}
if {$c eq "?"} {
if {$left > 1} {
# must be "#"
incr left -1
#set row [string replace $row $i-1 $i-1 "#"]
2023-12-12 09:40:29 +00:00
return [count-memo $row $nums $i $left]
2023-12-12 09:15:32 +00:00
} elseif {$left == 1} {
# must be "."
set left 0
#set row [string replace $row $i-1 $i-1 "."]
2023-12-12 09:40:29 +00:00
return [count-memo $row $nums $i $left]
2023-12-12 09:15:32 +00:00
} else {
# bifurcate
2023-12-12 09:40:29 +00:00
# "."
2023-12-12 09:15:32 +00:00
#set row [string replace $row $i-1 $i-1 "."]
2023-12-12 09:40:29 +00:00
set a [count-memo $row $nums $i $left]
2023-12-12 09:15:32 +00:00
set nums [lassign $nums left]
2023-12-12 09:40:29 +00:00
# "#"
2023-12-12 09:15:32 +00:00
#set row [string replace $row $i-1 $i-1 "#"]
2023-12-12 09:40:29 +00:00
set b [count-memo $row $nums $i $left]
2023-12-12 09:15:32 +00:00
return [expr {$a + $b}]
}
}
error "invalid character '$c' at position $i"
}
2023-12-12 09:40:29 +00:00
set part1 0
2023-12-12 09:15:32 +00:00
set part2 0
while {[gets $input line] >= 0} {
lassign $line row nums
set row "$row?$row?$row?$row?$row"
2023-12-12 09:40:29 +00:00
#set row [string trim $row "."]
2023-12-12 09:15:32 +00:00
set nums [split $nums ","]
set nums [concat $nums $nums $nums $nums $nums]
2023-12-12 09:40:29 +00:00
set n [count-memo $row $nums 0 0]
2023-12-12 09:15:32 +00:00
puts "$n | $row $nums"
incr part2 $n
}
puts $part2