Skip to content

Commit 6ff9cea

Browse files
authored
Merge pull request scalacenter#254 from scalacenter/add-day-11-code
add code for 2022 day 11
2 parents 03b4f43 + c9bca94 commit 6ff9cea

File tree

2 files changed

+152
-0
lines changed

2 files changed

+152
-0
lines changed

2022/input/day11

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
Monkey 0:
2+
Starting items: 57, 58
3+
Operation: new = old * 19
4+
Test: divisible by 7
5+
If true: throw to monkey 2
6+
If false: throw to monkey 3
7+
8+
Monkey 1:
9+
Starting items: 66, 52, 59, 79, 94, 73
10+
Operation: new = old + 1
11+
Test: divisible by 19
12+
If true: throw to monkey 4
13+
If false: throw to monkey 6
14+
15+
Monkey 2:
16+
Starting items: 80
17+
Operation: new = old + 6
18+
Test: divisible by 5
19+
If true: throw to monkey 7
20+
If false: throw to monkey 5
21+
22+
Monkey 3:
23+
Starting items: 82, 81, 68, 66, 71, 83, 75, 97
24+
Operation: new = old + 5
25+
Test: divisible by 11
26+
If true: throw to monkey 5
27+
If false: throw to monkey 2
28+
29+
Monkey 4:
30+
Starting items: 55, 52, 67, 70, 69, 94, 90
31+
Operation: new = old * old
32+
Test: divisible by 17
33+
If true: throw to monkey 0
34+
If false: throw to monkey 3
35+
36+
Monkey 5:
37+
Starting items: 69, 85, 89, 91
38+
Operation: new = old + 7
39+
Test: divisible by 13
40+
If true: throw to monkey 1
41+
If false: throw to monkey 7
42+
43+
Monkey 6:
44+
Starting items: 75, 53, 73, 52, 75
45+
Operation: new = old * 7
46+
Test: divisible by 2
47+
If true: throw to monkey 0
48+
If false: throw to monkey 4
49+
50+
Monkey 7:
51+
Starting items: 94, 60, 79
52+
Operation: new = old + 2
53+
Test: divisible by 3
54+
If true: throw to monkey 1
55+
If false: throw to monkey 6

2022/src/day11.scala

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
package day11
2+
3+
import locations.Directory.currentDir
4+
import inputs.Input.loadFileSync
5+
6+
import scala.collection.immutable.Queue
7+
8+
@main def part1: Unit =
9+
println(s"The solution is ${part1(loadInput())}")
10+
11+
@main def part2: Unit =
12+
println(s"The solution is ${part2(loadInput())}")
13+
14+
def loadInput(): String = loadFileSync(s"$currentDir/../input/day11")
15+
16+
def part1(input: String): Long =
17+
run(initial = parseInput(input), times = 20, adjust = _ / 3)
18+
19+
def part2(input: String): Long =
20+
run(initial = parseInput(input), times = 10_000, adjust = identity)
21+
22+
type Worry = Long
23+
type Op = Worry => Worry
24+
type Monkeys = IndexedSeq[Monkey]
25+
26+
case class Monkey(
27+
items: Queue[Worry],
28+
divisibleBy: Int,
29+
ifTrue: Int,
30+
ifFalse: Int,
31+
op: Op,
32+
inspected: Int
33+
)
34+
35+
def iterate[Z](times: Int)(op: Z => Z)(z: Z): Z =
36+
(0 until times).foldLeft(z) { (z, _) => op(z) }
37+
38+
def run(initial: Monkeys, times: Int, adjust: Op): Long =
39+
val lcm = initial.map(_.divisibleBy.toLong).product
40+
val monkeys = iterate(times)(round(adjust, lcm))(initial)
41+
monkeys.map(_.inspected.toLong).sorted.reverseIterator.take(2).product
42+
43+
def round(adjust: Op, lcm: Worry)(monkeys: Monkeys): Monkeys =
44+
monkeys.indices.foldLeft(monkeys) { (monkeys, index) =>
45+
turn(index, monkeys, adjust, lcm)
46+
}
47+
48+
def turn(index: Int, monkeys: Monkeys, adjust: Op, lcm: Worry): Monkeys =
49+
val monkey = monkeys(index)
50+
val Monkey(items, divisibleBy, ifTrue, ifFalse, op, inspected) = monkey
51+
52+
val monkeys1 = items.foldLeft(monkeys) { (monkeys, item) =>
53+
val inspected = op(item)
54+
val nextWorry = adjust(inspected) % lcm
55+
val thrownTo =
56+
if nextWorry % divisibleBy == 0 then ifTrue
57+
else ifFalse
58+
val thrownToMonkey =
59+
val m = monkeys(thrownTo)
60+
m.copy(items = m.items :+ nextWorry)
61+
monkeys.updated(thrownTo, thrownToMonkey)
62+
}
63+
val monkey1 = monkey.copy(
64+
items = Queue.empty,
65+
inspected = inspected + items.size
66+
)
67+
monkeys1.updated(index, monkey1)
68+
end turn
69+
70+
def parseInput(input: String): Monkeys =
71+
72+
def eval(by: String): Op =
73+
if by == "old" then identity
74+
else Function.const(by.toInt)
75+
76+
def parseOperator(op: String, left: Op, right: Op): Op =
77+
op match
78+
case "+" => old => left(old) + right(old)
79+
case "*" => old => left(old) * right(old)
80+
81+
IArray.from(
82+
for
83+
case Seq(
84+
s"Monkey $n:",
85+
s" Starting items: $items",
86+
s" Operation: new = $left $operator $right",
87+
s" Test: divisible by $div",
88+
s" If true: throw to monkey $ifTrue",
89+
s" If false: throw to monkey $ifFalse",
90+
_*
91+
) <- input.linesIterator.grouped(7)
92+
yield
93+
val op = parseOperator(operator, eval(left), eval(right))
94+
val itemsQueue = items.split(", ").map(_.toLong).to(Queue)
95+
Monkey(itemsQueue, div.toInt, ifTrue.toInt, ifFalse.toInt, op, inspected = 0)
96+
)
97+
end parseInput

0 commit comments

Comments
 (0)