Skip to content

Commit 819c69c

Browse files
committed
feat(day18): part 1
1 parent d4db302 commit 819c69c

File tree

3 files changed

+181
-1
lines changed

3 files changed

+181
-1
lines changed

build.sbt

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ version := "1.0"
2525
// Want to use a published library in your project?
2626
// You can define other libraries as dependencies in your build like this:
2727

28-
libraryDependencies += "org.scala-lang.modules" %% "scala-parser-combinators" % "1.1.2"
28+
libraryDependencies += "com.lihaoyi" %% "fastparse" % "2.3.3"
2929

3030
// Here, `libraryDependencies` is a set of dependencies, and by using `+=`,
3131
// we're adding the scala-parser-combinators dependency to the set of dependencies

day18.sc

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import common.loadPackets
2+
import fastparse.SingleLineWhitespace._
3+
import fastparse._
4+
5+
import scala.annotation.tailrec
6+
import scala.util.matching.Regex
7+
8+
val input = loadPackets(List("day18.txt"))
9+
10+
@tailrec
11+
def findExplodeIndex(string: String, depth: Int = 0, index: Int = 0): Option[Int] =
12+
string.headOption match {
13+
case None => None
14+
case Some('[') if depth == 4 => Some(index)
15+
case Some('[') => findExplodeIndex(string.tail, depth + 1, index + 1)
16+
case Some(']') => findExplodeIndex(string.tail, depth - 1, index + 1)
17+
case _ => findExplodeIndex(string.tail, depth, index + 1)
18+
}
19+
20+
val pairRegex = """\[(\d+),(\d+)]""".r
21+
def parsePair(pair: String): (Int, Int) = pair match {
22+
case pairRegex(left, right) => (left.toInt, right.toInt)
23+
}
24+
25+
val digitsRegex = """\d+""".r
26+
27+
def addToMatchIfPresent(string: String, toAdd: Int, m: Option[Regex.Match]): String =
28+
m.map(m =>
29+
List(string.substring(0, m.start),
30+
m.toString.toInt + toAdd,
31+
string.substring(m.end)).mkString)
32+
.getOrElse(string)
33+
34+
def addLeftIfPresent(string: String, toAdd: Int): String =
35+
addToMatchIfPresent(string, toAdd, digitsRegex.findAllMatchIn(string).toList.lastOption)
36+
37+
def addRightIfPresent(string: String, toAdd: Int): String =
38+
addToMatchIfPresent(string, toAdd, digitsRegex.findFirstMatchIn(string))
39+
40+
def explode(string: String): Option[String] =
41+
findExplodeIndex(string).map(from => {
42+
val to = string.indexOf(']', from) + 1
43+
val (left, right) = parsePair(string.substring(from, to))
44+
val before = string.substring(0, from)
45+
val after = string.substring(to)
46+
List(addLeftIfPresent(before, left), "0", addRightIfPresent(after, right)).mkString
47+
})
48+
49+
val splitRegex = """\d{2,}""".r
50+
def split(string: String): Option[String] =
51+
splitRegex.findFirstMatchIn(string).map(m => {
52+
val value = m.toString.toInt
53+
val left = value / 2
54+
val right = value - left
55+
List(string.substring(0, m.start), s"[${left},${right}]", string.substring(m.end)).mkString
56+
})
57+
58+
@tailrec
59+
def reduce(string: String): String = {
60+
explode(string).orElse(split(string)) match {
61+
case Some(reduction) => reduce(reduction)
62+
case None => string
63+
}
64+
}
65+
66+
def add(left: String, right: String): String =
67+
reduce(s"[${left},${right}]")
68+
69+
val reduced = input.reduce(add)
70+
71+
object Parser {
72+
def number[_: P]: P[Int] = CharIn("0-9").rep(1).!.map(_.toInt)
73+
def expression[_: P]: P[Int] = P("[" ~ (number | expression) ~ "," ~ (number|expression) ~ "]").map{
74+
case(left, right) => 3 * left + 2 * right
75+
}
76+
def magnitude(string: String): Parsed[Int] = parse(string, expression(_))
77+
}
78+
79+
val part1 = Parser.magnitude(reduced)
80+

src/main/resources/day18.txt

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
[[[5,[4,8]],0],[[[2,2],5],[7,9]]]
2+
[[[[4,2],0],[4,[9,9]]],[[[7,0],[9,8]],5]]
3+
[[[[3,2],2],4],0]
4+
[[8,7],[[9,4],[8,[5,5]]]]
5+
[[[1,7],[[8,2],[3,5]]],[6,8]]
6+
[[[[7,1],[4,2]],[[6,0],[3,8]]],[[[5,2],8],[7,[4,7]]]]
7+
[[6,[5,8]],[[4,[3,0]],5]]
8+
[[[[1,2],[1,5]],[[7,1],6]],[2,[4,7]]]
9+
[[9,[[5,3],3]],9]
10+
[6,[[[6,1],2],[6,[5,6]]]]
11+
[[[9,8],[[5,6],7]],[[4,[9,9]],[8,1]]]
12+
[[4,7],[[[3,1],[1,5]],[5,8]]]
13+
[[[9,7],[5,[6,0]]],[[9,[3,5]],7]]
14+
[[[[1,2],[1,4]],4],0]
15+
[[[[0,0],[1,2]],[[0,2],[1,6]]],[0,[[6,2],[5,1]]]]
16+
[[[1,2],[[0,2],4]],[[5,[7,3]],2]]
17+
[[5,[1,[6,3]]],[5,[2,[5,3]]]]
18+
[[[9,[7,7]],7],[[8,1],[[9,1],7]]]
19+
[[[[6,5],6],[6,5]],[7,[9,[3,9]]]]
20+
[[6,[9,3]],6]
21+
[[5,[[2,3],[9,1]]],[0,[[5,8],4]]]
22+
[[[[4,9],[2,3]],7],6]
23+
[[[2,6],6],[[[9,0],9],[4,[6,1]]]]
24+
[[[9,[9,1]],[4,4]],[0,[6,8]]]
25+
[8,[2,[[0,4],[5,4]]]]
26+
[[3,[9,4]],[[0,[6,9]],2]]
27+
[[[1,1],[[0,1],[1,9]]],[[5,4],[6,9]]]
28+
[4,[2,[[6,9],0]]]
29+
[[[6,[3,7]],[3,7]],[1,[2,[4,7]]]]
30+
[[[[6,4],[0,0]],[[8,2],5]],[[8,[2,4]],[4,[9,1]]]]
31+
[[[[8,1],[8,0]],[5,[7,6]]],[2,[[0,2],[9,2]]]]
32+
[[6,7],[[9,[1,1]],[[9,2],9]]]
33+
[[[[7,2],[8,8]],0],4]
34+
[[[2,1],[[3,1],9]],9]
35+
[[[[5,5],9],[[7,8],[6,0]]],[[[4,0],[0,6]],[6,2]]]
36+
[[6,[3,[9,4]]],[[[5,5],5],2]]
37+
[[[4,3],[9,[8,4]]],4]
38+
[[[0,[5,9]],[[9,6],8]],[7,[3,[8,9]]]]
39+
[[6,[[8,2],[0,2]]],[[8,8],[[7,9],2]]]
40+
[[[0,[8,0]],7],[[[7,2],[6,6]],[[5,5],5]]]
41+
[5,[[1,[3,6]],[[0,7],6]]]
42+
[0,[[[5,7],[6,2]],8]]
43+
[[[4,[5,4]],[[2,9],[5,3]]],[7,[2,4]]]
44+
[[6,[[8,4],6]],9]
45+
[[[7,[7,7]],[2,9]],[8,[5,[6,4]]]]
46+
[[[[7,9],[9,9]],[[6,1],[5,5]]],[[[4,3],[7,3]],[6,[0,3]]]]
47+
[[2,[2,0]],6]
48+
[[[[2,3],2],1],[0,2]]
49+
[[[[8,6],[5,6]],3],1]
50+
[[[[4,9],[2,4]],2],[2,[[6,3],[3,4]]]]
51+
[0,[[[1,0],[4,0]],8]]
52+
[[4,[6,[2,1]]],[[[5,8],4],[[8,0],4]]]
53+
[[[0,0],[[3,4],1]],[9,[1,[7,0]]]]
54+
[[0,0],[[[9,3],8],[[1,7],[4,6]]]]
55+
[[[4,3],3],[[[3,3],9],9]]
56+
[[[[2,0],[0,1]],[[1,2],[1,0]]],[[[6,6],1],[7,1]]]
57+
[[1,[[2,7],9]],[[[9,1],6],[[7,0],0]]]
58+
[[7,[[5,4],0]],8]
59+
[[6,9],[[[8,1],6],[5,[1,2]]]]
60+
[[7,6],[[[1,9],2],[0,3]]]
61+
[[[9,7],[9,[5,2]]],[[[0,0],2],[0,8]]]
62+
[[9,[6,2]],[5,8]]
63+
[[[6,[0,3]],[[5,1],[4,4]]],[6,[5,[1,9]]]]
64+
[[8,8],[[[3,1],7],[[8,3],3]]]
65+
[[[[1,1],[9,5]],9],[[[2,8],[6,4]],[[1,2],[4,5]]]]
66+
[[[1,7],8],[[5,[0,6]],[9,[3,3]]]]
67+
[[7,3],[[[8,2],3],4]]
68+
[[9,3],[[1,[7,0]],5]]
69+
[[[9,[2,2]],[7,5]],[[7,[1,7]],[[0,5],7]]]
70+
[[1,[[0,3],3]],1]
71+
[[9,[[3,0],[9,0]]],1]
72+
[[2,[[3,9],7]],[[[8,1],[7,2]],[9,[6,3]]]]
73+
[4,[[0,[0,4]],[0,1]]]
74+
[[[[2,8],6],[[6,6],[5,8]]],[[1,[7,5]],[[2,2],[6,0]]]]
75+
[[[6,7],8],[[[1,5],[9,3]],[0,2]]]
76+
[[[[6,6],[6,2]],[0,6]],[[[1,5],2],[[0,3],[3,9]]]]
77+
[[5,[8,2]],[3,8]]
78+
[[8,7],[[0,5],[3,[6,8]]]]
79+
[[6,[[2,3],5]],[[9,[0,8]],[[2,4],[1,8]]]]
80+
[[[[5,7],[4,3]],[[5,4],5]],[0,[[6,5],2]]]
81+
[2,[[5,[0,7]],[3,[4,0]]]]
82+
[1,9]
83+
[[[[1,4],1],[0,[1,2]]],2]
84+
[[4,3],[5,[6,4]]]
85+
[[[4,4],[[8,0],[6,5]]],[[4,[9,1]],[[1,1],[2,2]]]]
86+
[[4,3],[[[1,1],1],[[4,6],[5,7]]]]
87+
[[[[6,1],[5,3]],2],[[[0,6],[7,3]],8]]
88+
[[[2,8],5],[1,[3,[8,7]]]]
89+
[[7,[5,[9,0]]],[[[9,1],2],[2,[9,6]]]]
90+
[[[[7,3],1],[[4,6],[5,1]]],[[[4,7],4],[[5,2],[3,7]]]]
91+
[[[[2,3],8],[7,8]],[[[5,5],[2,5]],[[6,8],1]]]
92+
[[[2,1],[[8,9],[4,3]]],[[8,[9,0]],7]]
93+
[[[[8,2],5],0],[[8,[9,6]],[[6,1],1]]]
94+
[[[3,[4,9]],[[5,4],[2,2]]],4]
95+
[[[[9,8],4],[[7,4],9]],[[0,7],6]]
96+
[[7,[[6,1],8]],[[2,0],[2,5]]]
97+
[[[[3,2],6],5],6]
98+
[6,[3,5]]
99+
[[[[7,1],7],4],[[[4,6],5],[1,[7,9]]]]
100+
[[[[7,0],7],[8,9]],[5,[[2,5],6]]]

0 commit comments

Comments
 (0)