@@ -3,20 +3,25 @@ import cats.syntax.all.*
33
44object Day04 :
55
6- // val s: Store[Int, Option[Char]] = Store(f = _ => Some('a'), s = 0)
7- // val x: Option[Char] = s.peeks(identity)
8- // val y : List[Option[Char]] = s.experiment[List](n => List.range(start = n, end = n + 3) )
6+ case class Word ( s : String ) :
7+ val length : Int = s.length
8+ val toOptionChars : List [Option [Char ]] = s.toList.map( Some .apply )
99
1010 case class Pos (row : Int , col : Int )
1111
1212 object Pos :
1313 val zero = Pos (row = 0 , col = 0 )
1414
15+ type StoreGrid = Store [Pos , Option [Char ]]
16+
17+ enum WordCheckResult :
18+ case Found , NotFound
19+
1520 case class Grid (rows : List [List [Char ]]):
1621
17- private val toVectors : Vector [Vector [Char ]] = rows.map(_.toVector).toVector
22+ val toVectors : Vector [Vector [Char ]] = rows.map(_.toVector).toVector
1823
19- def toStore : Store [ Pos , Option [ Char ]] = Store (
24+ def toStore : StoreGrid = Store (
2025 p => toVectors.get(p.row).flatMap(_.get(p.col)),
2126 s = Pos .zero
2227 )
@@ -25,4 +30,41 @@ object Day04:
2530 rows.zipWithIndex.flatMap((row, rowIndex) => row.zipWithIndex.map((_, colIndex) => Pos (rowIndex, colIndex)))
2631
2732 object Grid :
33+
2834 def parse (rows : List [String ]): Option [Grid ] = Grid (rows = rows.map(_.toList)).some
35+
36+ /*
37+ XMAS
38+ ....
39+ ....
40+ ....
41+ */
42+ def topLeftPositions (w : Word )(p : Pos ): List [Pos ] =
43+ List .range(start = p.col, end = p.col + w.length).map(col => Pos (p.row, col))
44+
45+ def wordCheckTopLeft (w : Word , store : StoreGrid ): WordCheckResult = wordCheck(topLeftPositions, w, store)
46+
47+ /*
48+ ...S
49+ ..A.
50+ .M..
51+ X...
52+ */
53+ def ascDiagonalPositions (w : Word )(p : Pos ): List [Pos ] =
54+ List .range(start = 0 , end = w.length).reverse.map(i => Pos (row = i + p.row, col = w.length - i - 1 + p.col))
55+
56+ def wordCheckAscDiagonal (w : Word , store : StoreGrid ): WordCheckResult = wordCheck(ascDiagonalPositions, w, store)
57+
58+ /*
59+ X...
60+ .M..
61+ ..A.
62+ ...S
63+ */
64+ def descDiagonalPositions (w : Word )(p : Pos ): List [Pos ] =
65+ List .range(start = 0 , end = w.length).map(i => Pos (row = i + p.row, col = i + p.col))
66+
67+ def wordCheckDescDiagonal (w : Word , store : StoreGrid ): WordCheckResult = wordCheck(descDiagonalPositions, w, store)
68+
69+ def wordCheck (positions : Word => Pos => List [Pos ], w : Word , store : StoreGrid ): WordCheckResult =
70+ if w.toOptionChars == store.experiment(positions(w)) then WordCheckResult .Found else WordCheckResult .NotFound
0 commit comments