Skip to content

Commit

Permalink
Day3 part 1
Browse files Browse the repository at this point in the history
  • Loading branch information
benoitpas committed Dec 3, 2023
1 parent c9d5ece commit 24b3f5e
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 1 deletion.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,14 @@ Also without the hint on reddit I think it would have taken me a long time to fi

## Day2
Part 1 is mostly about parsing the input, I went for a quick and dirty 'split' based solution. No to be used in prod, that would be very fragile !

Part 2 was straightforward, we didn't even need to worry about interger overflows.

## Day 3
The most straightforward solution is probably to iterate over the grid, down to bottom and left to right to find the number and determines which ones are close to symbols.

Out of curiosity I'm going to try a solution where I zip the current line with the lines below and above (to find the nearby symbols) and then 'split' the line to find the symbols.

Initially I thought it would be a lot more complex than the iterative approach but it turns out to be quite short.

It may be interesting to try to implement the iterative solution with a state monad.
1 change: 0 additions & 1 deletion src/main/scala/day2.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import zio._
import zio.Console._
import scala.io.BufferedSource

object Day2 extends ZIOAppDefault {

Expand Down
53 changes: 53 additions & 0 deletions src/main/scala/day3.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import zio._
import zio.Console._

object Day3 extends ZIOAppDefault {

def padSchematics(schematics: List[String]) =
val s2 = schematics.map("." + _ + ".")
val pad = "." * s2(0).length
pad :: s2.appended(pad)

def horizontalZip(pSchematics: List[String]): List[List[(Char, Char, Char)]] =
val n = pSchematics.length - 2
val psr1 = pSchematics.take(n)
val psr2 = pSchematics.tail.take(n)
val psr3 = pSchematics.tail.tail
((psr1 zip psr2) zip psr3) map ((a, b) =>
val bt = List(a._1, a._2, b)
bt.transpose.map { case c1 :: c2 :: c3 :: _ =>
(c1, c2, c3)
}
)

def isDigit(c: Char) = '0' <= c && c <= '9'

def isPart(c: Char): Boolean = !(isDigit(c) || c == '.')

def isPart(col: (Char, Char, Char)): Boolean = isPart(col._1) || isPart(col._2) || isPart(col._3)

def findPartsNumber(zSchematics: List[(Char, Char, Char)]): List[Int] =
zSchematics
.foldLeft((List[Int](), "", false)) {
case ((l, digits, isPartNumber), col) if isDigit(col._2) =>
(l, digits.appended(col._2), isPartNumber || isPart(col))
case ((l, digits, isPartNumber), col) =>
(
if (isPartNumber || isPart(col)) && digits != "" then l.appended(digits.toInt)
else l,
"",
isPart(col)
)
}
._1

def part1(schematics: List[String]) =
val zs = horizontalZip(padSchematics(schematics))
zs.flatMap(findPartsNumber).sum

def run =
for {
v <- Day1.readFile("day3_input.txt")
_ <- printLine(s"part1=${part1(v)}")
} yield ()
}
34 changes: 34 additions & 0 deletions src/test/scala/day3_test.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import org.junit.Test
import org.junit.Assert._

class Day3Test {

val schematics = List(
"467..114..",
"...*......",
"..35..633.",
"......#...",
"617*......",
".....+.58.",
"..592.....",
"......755.",
"...$.*....",
".664.598.."
)

@Test def testPadSchematics(): Unit =
assertEquals(List("...", ".#.", "..."), Day3.padSchematics(List("#")))

@Test def testHorizontalZip(): Unit =
assertEquals(
List(List(('1', '3', '5'), ('2', '4', '6')), List(('3', '5', '7'), ('4', '6', '8'))),
Day3.horizontalZip(List("12", "34", "56", "78"))
)

@Test def testFindPartsNumber(): Unit =
val hz = Day3.horizontalZip(List(schematics(5), schematics(6), schematics(7)))(0)
assertEquals(List(592), Day3.findPartsNumber(hz))

@Test def testPart1(): Unit =
assertEquals(4361, Day3.part1(schematics));
}

0 comments on commit 24b3f5e

Please sign in to comment.