Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit fdc4611

Browse files
committedDec 28, 2021
Year 2019 Day 11
1 parent 375c76b commit fdc4611

File tree

4 files changed

+105
-0
lines changed

4 files changed

+105
-0
lines changed
 

‎README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,4 @@ Entries for the annual [Advent of Code](https://adventofcode.com/) challenge, wr
7878
| 8 | [Space Image Format](https://adventofcode.com/2019/day/8) | [Source](src/main/scala/AdventOfCode2019/Day08.scala) |
7979
| 9 | [Sensor Boost](https://adventofcode.com/2019/day/9) | [Source](src/main/scala/AdventOfCode2019/Day09.scala) |
8080
| 10 | [Monitoring Station](https://adventofcode.com/2019/day/10) | [Source](src/main/scala/AdventOfCode2019/Day10.scala) |
81+
| 11 | [Space Police](https://adventofcode.com/2019/day/11) | [Source](src/main/scala/AdventOfCode2019/Day11.scala) |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3,8,1005,8,324,1106,0,11,0,0,0,104,1,104,0,3,8,1002,8,-1,10,1001,10,1,10,4,10,1008,8,0,10,4,10,1001,8,0,29,3,8,1002,8,-1,10,101,1,10,10,4,10,108,0,8,10,4,10,101,0,8,50,1,1106,9,10,1,102,15,10,2,1003,3,10,1,3,19,10,3,8,102,-1,8,10,101,1,10,10,4,10,1008,8,0,10,4,10,1001,8,0,89,1,1105,9,10,2,1103,1,10,3,8,102,-1,8,10,101,1,10,10,4,10,1008,8,1,10,4,10,1001,8,0,119,1006,0,26,1,109,7,10,3,8,1002,8,-1,10,1001,10,1,10,4,10,108,1,8,10,4,10,1002,8,1,147,1006,0,75,1,1005,17,10,3,8,102,-1,8,10,101,1,10,10,4,10,108,0,8,10,4,10,102,1,8,176,3,8,102,-1,8,10,1001,10,1,10,4,10,1008,8,1,10,4,10,102,1,8,199,3,8,102,-1,8,10,1001,10,1,10,4,10,108,1,8,10,4,10,102,1,8,220,2,103,10,10,1,1,0,10,1,102,17,10,3,8,1002,8,-1,10,101,1,10,10,4,10,108,1,8,10,4,10,101,0,8,254,2,1001,10,10,1006,0,12,1,3,6,10,3,8,102,-1,8,10,101,1,10,10,4,10,1008,8,0,10,4,10,102,1,8,288,2,1106,9,10,2,1009,6,10,2,1101,18,10,2,103,8,10,101,1,9,9,1007,9,1045,10,1005,10,15,99,109,646,104,0,104,1,21101,838211318676,0,1,21102,341,1,0,1106,0,445,21101,0,838211051932,1,21101,0,352,0,1106,0,445,3,10,104,0,104,1,3,10,104,0,104,0,3,10,104,0,104,1,3,10,104,0,104,1,3,10,104,0,104,0,3,10,104,0,104,1,21101,0,21704576195,1,21101,0,399,0,1106,0,445,21101,0,179356830951,1,21101,410,0,0,1105,1,445,3,10,104,0,104,0,3,10,104,0,104,0,21102,837897052948,1,1,21102,1,433,0,1106,0,445,21102,709052085092,1,1,21102,1,444,0,1105,1,445,99,109,2,21201,-1,0,1,21101,0,40,2,21102,476,1,3,21102,466,1,0,1105,1,509,109,-2,2105,1,0,0,1,0,0,1,109,2,3,10,204,-1,1001,471,472,487,4,0,1001,471,1,471,108,4,471,10,1006,10,503,1102,1,0,471,109,-2,2106,0,0,0,109,4,2102,1,-1,508,1207,-3,0,10,1006,10,526,21101,0,0,-3,21201,-3,0,1,21201,-2,0,2,21101,0,1,3,21101,545,0,0,1105,1,550,109,-4,2105,1,0,109,5,1207,-3,1,10,1006,10,573,2207,-4,-2,10,1006,10,573,21201,-4,0,-4,1105,1,641,22102,1,-4,1,21201,-3,-1,2,21202,-2,2,3,21101,592,0,0,1105,1,550,21201,1,0,-4,21102,1,1,-1,2207,-4,-2,10,1006,10,611,21101,0,0,-1,22202,-2,-1,-2,2107,0,-3,10,1006,10,633,21202,-1,1,1,21101,633,0,0,106,0,508,21202,-2,-1,-2,22201,-4,-2,-4,109,-5,2105,1,0
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
package AdventOfCode2019
2+
3+
object Day11:
4+
object IntCode:
5+
val powers = Map(1 -> 100, 2 -> 1000, 3 -> 10000)
6+
7+
sealed trait State
8+
case object Initial extends State
9+
case object Running extends State
10+
case object Halted extends State
11+
case class Output(value: Long) extends State
12+
13+
def apply(input: Seq[Long]): IntCode =
14+
val memory = input.zipWithIndex.map((value, index) => index.toLong -> value)
15+
IntCode(0, 0, memory.toMap.withDefaultValue(0), Seq(), Initial)
16+
end IntCode
17+
18+
case class IntCode(ip: Long, relativeBase: Long, memory: Map[Long, Long], input: Seq[Long], result: IntCode.State):
19+
import IntCode._
20+
21+
private def next: IntCode = memory(ip) % 100 match
22+
case 1 => copy(ip = ip + 4, memory = write(3, read(1) + read(2)), result = Running) // Add
23+
case 2 => copy(ip = ip + 4, memory = write(3, read(1) * read(2)), result = Running) // Multiply
24+
case 3 => copy(ip = ip + 2, memory = write(1, input.head), input = input.tail, result = Running) // Read
25+
case 4 => copy(ip = ip + 2, result = Output(read(1))) // Write
26+
case 5 => copy(ip = if read(1) != 0 then read(2) else ip + 3, result = Running) // Jump if true
27+
case 6 => copy(ip = if read(1) == 0 then read(2) else ip + 3, result = Running) // Jump if false
28+
case 7 => copy(ip = ip + 4, memory = write(3, if read(1) < read(2) then 1 else 0), result = Running) // Less than
29+
case 8 => copy(ip = ip + 4, memory = write(3, if read(1) == read(2) then 1 else 0), result = Running) // Equals
30+
case 9 => copy(ip = ip + 2, relativeBase = relativeBase + read(1), result = Running) // Relative base
31+
case 99 => copy(result = Halted) // Halt
32+
33+
private def read(offset: Int): Long = (memory(ip) / powers(offset)) % 10 match
34+
case 0 => memory(memory(ip + offset))
35+
case 1 => memory(ip + offset)
36+
case 2 => memory(relativeBase + memory(ip + offset))
37+
38+
private def write(offset: Int, value: Long): Map[Long, Long] = (memory(ip) / powers(offset)) % 10 match
39+
case 0 => memory.updated(memory(ip + offset), value)
40+
case 2 => memory.updated(relativeBase + memory(ip + offset), value)
41+
42+
def withInput(next: Long*): IntCode = copy(input = input.appendedAll(next))
43+
44+
def nextOutput: IntCode = Iterator.iterate(next)(_.next).dropWhile(_.result == Running).next()
45+
46+
def lastOutput: Long =
47+
val output = Iterator.iterate(this)(_.nextOutput).takeWhile(_.result != Halted)
48+
output.toSeq.map(_.result).collect { case Output(value) => value }.last
49+
end IntCode
50+
51+
enum Direction:
52+
case Up, Down, Left, Right
53+
54+
case class Point(x: Int, y: Int):
55+
def updated(dx: Int, dy: Int): Point = Point(x + dx, y + dy)
56+
57+
import IntCode._
58+
import Direction._
59+
60+
val clockwise = Map(Up -> Right, Right -> Down, Down -> Left, Left -> Up)
61+
val antiClockwise = Map(Up -> Left, Left -> Down, Down -> Right, Right -> Up)
62+
val deltas = Map(Up -> (0, -1), Down -> (0, 1), Left -> (-1, 0), Right -> (1, 0))
63+
64+
def paint(intCode: IntCode, direction: Direction, position: Point, panels: Map[Point, Long]): Map[Point, Long] =
65+
val first = intCode.withInput(panels(position)).nextOutput
66+
first.result match
67+
case Halted => panels
68+
case Output(color) =>
69+
val second = first.nextOutput
70+
val Output(turn) = second.result
71+
72+
val nextDirection = if turn == 1 then clockwise(direction) else antiClockwise(direction)
73+
val nextPosition = position.updated.tupled(deltas(nextDirection))
74+
val nextPanels = panels.updated(position, color)
75+
76+
paint(second, nextDirection, nextPosition, nextPanels)
77+
end paint
78+
79+
def part1(memory: Seq[Long]): Long = paint(IntCode(memory), Up, Point(0, 0), Map().withDefaultValue(0L)).size
80+
81+
def part2(memory: Seq[Long]): Map[Point, Long] = paint(IntCode(memory), Up, Point(0, 0), Map(Point(0, 0) -> 1L).withDefaultValue(0L))
82+
83+
def main(args: Array[String]): Unit =
84+
val data = io.Source.fromResource("AdventOfCode2019/Day11.txt").mkString.trim.split(",").map(_.toLong).toSeq
85+
println(part1(data))
86+
87+
val panels = part2(data)
88+
val minX = panels.keys.map(_.x).min
89+
val maxX = panels.keys.map(_.x).max
90+
val minY = panels.keys.map(_.y).min
91+
val maxY = panels.keys.map(_.y).max
92+
93+
for y <- minY to maxY do
94+
println()
95+
for x <- minX to maxX do
96+
print(if panels(Point(x, y)) == 1 then '#' else ' ')
97+
end main
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package AdventOfCode2019
2+
3+
import org.scalatest.funsuite.AnyFunSuite
4+
5+
class Day11Suite extends AnyFunSuite
6+
// No unit tests possible

0 commit comments

Comments
 (0)
Please sign in to comment.