commit ef3482d10654fca6868840aaa425b9ca1a02e1b5
parent ddaa88f98f745cf6df86ceca1ccc03511b5856f5
Author: Martin Ashby <martin@ashbysoft.com>
Date: Sat, 14 Dec 2024 09:30:08 +0000
Day6 pt2
Diffstat:
2 files changed, 24 insertions(+), 36 deletions(-)
diff --git a/src/main/scala/Day6.scala b/src/main/scala/Day6.scala
@@ -3,15 +3,16 @@ def day6_pt1(input: Iterator[String]): Int =
val lst = input.toList
val pos = lst.zipWithIndex.find((s, y) => s.contains("^")).map((s, y) => (s.indexOf('^'), y)).get
val grid = updated(lst, pos, '.')
- do_follow(grid, pos, '^')
+ val grid2 = do_follow(grid, pos, '^')
+ grid2.map(line => line.count(ch => ch == 'X')).sum
@tailrec()
-def do_follow(grid: List[String], pos: (Int,Int), dir: Char): Int =
+def do_follow(grid: List[String], pos: (Int,Int), dir: Char): List[String] =
val grid2 = updated(grid, pos, 'X')
val pos2 = next_pos(pos, dir)
val (x2, y2) = pos2
if (oob(grid2, pos2)) {
- return grid2.map(line => line.count(ch => ch == 'X')).sum
+ return grid2
}
if (grid_at(grid2, pos2) == '#') {
val dir2 = next_dir(dir)
@@ -24,44 +25,31 @@ def day6_pt2(input: Iterator[String]): Int =
val lst = input.toList
val pos = lst.zipWithIndex.find((s, y) => s.contains("^")).map((s, y) => (s.indexOf('^'), y)).get
val grid = updated(lst, pos, '.')
- do_follow2(grid, pos, '^', List(), Set())
+ val grid2 = do_follow(grid, pos, '^')
+ List.range(0, grid.size).flatMap(y => List.range(0, grid(0).size).map(x => (x, y)))
+ .filter(block => block != pos) // Can't add a block where the guard currenly is...
+ .filter(block => grid_at(grid2, block) == 'X') // only bother testing locations the guard actually visited; otherwise it's an ineffective block
+ .filter(block => {
+ val res = do_follow3(updated(grid, block, '#'), pos, '^', Set())
+ println(s"Testing new block at $block: $res")
+ res
+ })
+ .size
@tailrec()
-def do_follow2(grid: List[String], pos: (Int,Int), dir: Char, hist: List[((Int,Int), Char)], cand: Set[(Int,Int)]): Int =
- val hist2 = hist.appended((pos, dir))
+def do_follow3(grid: List[String], pos: (Int,Int), dir: Char, hist: Set[((Int,Int), Char)]): Boolean =
+ if (hist.contains(pos, dir)) {
+ return true
+ }
val pos2 = next_pos(pos, dir)
if (oob(grid, pos2)) {
- println(cand)
- return cand.size
+ return false
}
- if (grid_at(grid, pos2) == '#') {
- do_follow2(grid, pos, next_dir(dir), hist2, cand)
- } else {
- // Test if there _was_ a block at pos2; would it result in a cycle?
- val dir_spec = next_dir(dir)
- val pos_spec = next_pos(pos2, dir_spec)
- val cand2 = if (!oob(grid, pos_spec) && grid_at(grid, pos_spec) != '#' && do_follow3(grid, pos_spec, dir_spec, hist2)) {
- cand + pos2
- } else {
- cand
- }
- do_follow2(grid, pos2, dir, hist2, cand2)
- }
-@tailrec()
-def do_follow3(grid: List[String], pos: (Int,Int), dir: Char, hist: List[((Int,Int), Char)]): Boolean =
- val pos2 = next_pos(pos, dir)
- if (oob(grid, pos2)) {
- false
- } else if (hist.contains(pos2, dir)) {
- true
+ if (grid_at(grid, pos2) == '#') {
+ do_follow3(grid, pos, next_dir(dir), hist + ((pos, dir)))
} else {
- val hist2 = hist.appended((pos2, dir))
- if (grid_at(grid, pos2) == '#') {
- do_follow3(grid, pos, next_dir(dir), hist2)
- } else {
- do_follow3(grid, pos2, dir, hist2)
- }
+ do_follow3(grid, pos2, dir, hist + ((pos, dir)))
}
// def print(grid: List[String]): Unit =
diff --git a/src/main/scala/Main.scala b/src/main/scala/Main.scala
@@ -1,2 +1,2 @@
@main def run(): Unit =
- println(day6_pt2(scala.io.Source.fromFile("day6.txt").getLines()))
-\ No newline at end of file
+ println(day6_pt1(scala.io.Source.fromFile("day6.txt").getLines()))
+\ No newline at end of file