Skip to content

Commit 1f873d8

Browse files
committed
Year 2015 Day 19
1 parent 237cff5 commit 1f873d8

File tree

4 files changed

+125
-0
lines changed

4 files changed

+125
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -228,3 +228,4 @@ The minimal SBT project provides:
228228
| 16 | [Aunt Sue](https://adventofcode.com/2015/day/16) | [Source](src/main/scala/AdventOfCode2015/Day16.scala) |
229229
| 17 | [No Such Thing as Too Much](https://adventofcode.com/2015/day/17) | [Source](src/main/scala/AdventOfCode2015/Day17.scala) |
230230
| 18 | [Like a GIF For Your Yard](https://adventofcode.com/2015/day/18) | [Source](src/main/scala/AdventOfCode2015/Day18.scala) |
231+
| 19 | [Medicine for Rudolph](https://adventofcode.com/2015/day/19) | [Source](src/main/scala/AdventOfCode2015/Day19.scala) |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
Al => ThF
2+
Al => ThRnFAr
3+
B => BCa
4+
B => TiB
5+
B => TiRnFAr
6+
Ca => CaCa
7+
Ca => PB
8+
Ca => PRnFAr
9+
Ca => SiRnFYFAr
10+
Ca => SiRnMgAr
11+
Ca => SiTh
12+
F => CaF
13+
F => PMg
14+
F => SiAl
15+
H => CRnAlAr
16+
H => CRnFYFYFAr
17+
H => CRnFYMgAr
18+
H => CRnMgYFAr
19+
H => HCa
20+
H => NRnFYFAr
21+
H => NRnMgAr
22+
H => NTh
23+
H => OB
24+
H => ORnFAr
25+
Mg => BF
26+
Mg => TiMg
27+
N => CRnFAr
28+
N => HSi
29+
O => CRnFYFAr
30+
O => CRnMgAr
31+
O => HP
32+
O => NRnFAr
33+
O => OTi
34+
P => CaP
35+
P => PTi
36+
P => SiRnFAr
37+
Si => CaSi
38+
Th => ThCa
39+
Ti => BP
40+
Ti => TiTi
41+
e => HF
42+
e => NAl
43+
e => OMg
44+
45+
ORnPBPMgArCaCaCaSiThCaCaSiThCaCaPBSiRnFArRnFArCaCaSiThCaCaSiThCaCaCaCaCaCaSiRnFYFArSiRnMgArCaSiRnPTiTiBFYPBFArSiRnCaSiRnTiRnFArSiAlArPTiBPTiRnCaSiAlArCaPTiTiBPMgYFArPTiRnFArSiRnCaCaFArRnCaFArCaSiRnSiRnMgArFYCaSiRnMgArCaCaSiThPRnFArPBCaSiRnMgArCaCaSiThCaSiRnTiMgArFArSiThSiThCaCaSiRnMgArCaCaSiRnFArTiBPTiRnCaSiAlArCaPTiRnFArPBPBCaCaSiThCaPBSiThPRnFArSiThCaSiThCaSiThCaPTiBSiRnFYFArCaCaPRnFArPBCaCaPBSiRnTiRnFArCaPRnFArSiRnCaCaCaSiThCaRnCaFArYCaSiRnFArBCaCaCaSiThFArPBFArCaSiRnFArRnCaCaCaFArSiRnFArTiRnPMgArF
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package AdventOfCode2015
2+
3+
object Day19:
4+
type Rules = Set[(scala.util.matching.Regex, Seq[String])]
5+
6+
def parse(input: Seq[String]): (Seq[(String, String)], String) =
7+
val index = input.indexOf("")
8+
val pairs = input.take(index).map(_.split(" => ")).map(a => a(0) -> a(1))
9+
(pairs, input(index + 1))
10+
11+
def makeRules(pairs: Seq[(String, String)]): Rules =
12+
pairs.map((k,v) => (k.r, v)).groupMap(_._1)(_._2).toSet
13+
14+
def candidates(rules: Rules, input: String): Set[String] = rules.flatMap { case (key, values) =>
15+
key.findAllMatchIn(input).flatMap(mat => values.map(input.patch(mat.start, _, mat.end - mat.start)))
16+
}
17+
18+
def aStar(rules: Rules, start: String): Int =
19+
val cost = collection.mutable.Map(start -> 0)
20+
val todo = collection.mutable.PriorityQueue(start -> 0)(Ordering.by(-_._2))
21+
22+
while todo.nonEmpty do
23+
val (current, _) = todo.dequeue()
24+
if current == "e" then return cost(current)
25+
val nextCost = cost(current) + 1
26+
27+
candidates(rules, current).foreach { next =>
28+
if !cost.contains(next) || nextCost < cost(next) then
29+
cost(next) = nextCost
30+
val priority = nextCost + next.size
31+
todo.enqueue(next -> priority)
32+
}
33+
end while
34+
35+
-1
36+
end aStar
37+
38+
def part1(input: Seq[String]): Int =
39+
val (pairs, start) = parse(input)
40+
val rules = makeRules(pairs)
41+
candidates(rules, start).size
42+
43+
def part2(input: Seq[String]): Int =
44+
val (pairs, start) = parse(input)
45+
val rules = makeRules(pairs.map(_.swap))
46+
aStar(rules, start)
47+
48+
def main(args: Array[String]): Unit =
49+
val data = io.Source.fromResource("AdventOfCode2015/Day19.txt").getLines().toSeq
50+
println(part1(data))
51+
println(part2(data))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package AdventOfCode2015
2+
3+
import org.scalatest.funsuite.AnyFunSuite
4+
5+
class Day19Suite extends AnyFunSuite:
6+
val sample1 = Seq(
7+
"H => HO",
8+
"H => OH",
9+
"O => HH",
10+
"",
11+
"HOH")
12+
13+
test("Part 1 should handle sample input correctly") {
14+
assert(Day19.part1(sample1) == 4)
15+
}
16+
17+
val sample2 = Seq(
18+
"e => H",
19+
"e => O",
20+
"H => HO",
21+
"H => OH",
22+
"O => HH",
23+
"",
24+
"HOHOHO")
25+
26+
test("Part 2 should handle sample input correctly") {
27+
assert(Day19.part2(sample2) == 6)
28+
}

0 commit comments

Comments
 (0)