Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions 2015/src/main/scala/aoc2015/Day07.scala
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,12 @@ object Day07 extends AoC:
def solve(rules: Vector[Rule], wire: Wire, setWireB: Option[Int] = None): Int =
@tailrec
def fold(rules: Seq[Rule], env: Env = Map.empty): Int =
env.get(wire) match
env.get(wire).runtimeChecked match
case Some(v) => v
case None => rules match
case rule +: rest => rule.call(env) match
case Some(v) => fold(rest, env.updated(rule.ret, v))
case None => fold(rest :+ rule, env)
case _ => sys.error(s"undefined wire=$wire")

val puzzleInput: Vector[Rule] = setWireB.map(v => Val(v, "b") +: rules.filterNot(_.ret == "b")).getOrElse(rules)
fold(puzzleInput)
Expand Down
3 changes: 1 addition & 2 deletions 2015/src/main/scala/aoc2015/Day13.scala
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,8 @@ object Day13 extends AoC:
val n1 = List(setting.init.last, setting.last, setting.head)
val n2 = List(setting.last, setting.head, setting.tail.head)
(n1 :: n2 :: setting.sliding(3).toList)
.map:
.collect:
case List(nl, name, nr) => name -> List(nl, nr)
case _ => sys.error("expected a list of size 3")
.toMap

def happiness(name: String): Int =
Expand Down
6 changes: 2 additions & 4 deletions 2016/src/main/scala/aoc2016/Day01.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ object Day01 extends AoC:
x.abs + y.abs

infix def process(cmd: Cmd): Vector[Ikke] =
(dir, cmd.turn) match
(dir, cmd.turn).runtimeChecked match
case (N, 'L') => (1 to cmd.dist).map(dist => copy(x = x - dist, dir = W)).toVector
case (E, 'L') => (1 to cmd.dist).map(dist => copy(y = y + dist, dir = N)).toVector
case (S, 'L') => (1 to cmd.dist).map(dist => copy(x = x + dist, dir = E)).toVector
Expand All @@ -29,7 +29,6 @@ object Day01 extends AoC:
case (E, 'R') => (1 to cmd.dist).map(dist => copy(y = y - dist, dir = S)).toVector
case (S, 'R') => (1 to cmd.dist).map(dist => copy(x = x - dist, dir = W)).toVector
case (W, 'R') => (1 to cmd.dist).map(dist => copy(y = y + dist, dir = N)).toVector
case _ => sys.error("boom!")

object Ikke:

Expand All @@ -43,11 +42,10 @@ object Day01 extends AoC:

@tailrec
def twice(test: Vector[Ikke], visited: Vector[Ikke]): Option[Ikke] =
test match
test.runtimeChecked match
case Vector() => None
case h +: t if visited.exists(ikke => ikke.x == h.x && ikke.y == h.y) => Some(h)
case _ +: t => twice(t, visited)
case _ => sys.error("boom!")

val next = path.last.process(commands.head)
if twice(next, path).nonEmpty then twice(next, path).get else solve(commands.tail :+ commands.head, path :++ next)
Expand Down
3 changes: 1 addition & 2 deletions 2016/src/main/scala/aoc2016/Day04.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@ object Day04 extends AoC:
underlying.filter(_.isDigit).toInt

def checksum: String =
underlying match
underlying.runtimeChecked match
case s"$nameAndId[$checksum]" => checksum
case _ => sys.error(s"no checksum: $underlying")

def isValid: Boolean =

Expand Down
9 changes: 3 additions & 6 deletions 2016/src/main/scala/aoc2016/Day21.scala
Original file line number Diff line number Diff line change
Expand Up @@ -42,40 +42,37 @@ object Day21 extends AoC:
s.patch(x, "", 1).patch(y, s.charAt(x).toString, 0)

infix def scramble(s: String): String =
this match
this.runtimeChecked match
case SwapPosition(x, y) => s.swapPosition(x, y)
case SwapLetter(a, b) => s.swapLetter(a, b)
case Rotate("left", n) => s.rotateLeft(n)
case Rotate("right", n) => s.rotateRight(n)
case RotateByPosition(a) => s.rotateByPositionRight(a)
case ReverseByPosition(x, y) => s.reverseByPosition(x, y)
case Move(x, y) => s.move(x, y)
case _ => sys.error("boom!")

infix def unscramble(s: String): String =
this match
this.runtimeChecked match
case SwapPosition(x, y) => s.swapPosition(x, y)
case SwapLetter(a, b) => s.swapLetter(a, b)
case Rotate("left", n) => s.rotateRight(n)
case Rotate("right", n) => s.rotateLeft(n)
case RotateByPosition(a) => s.rotateByPositionLeft(a)
case ReverseByPosition(x, y) => s.reverseByPosition(x, y)
case Move(x, y) => s.move(y, x)
case _ => sys.error("boom!")

import Operation.*


val operations: Vector[Operation] =
lines
.map:
.collect:
case s"swap position $x with position $y" => SwapPosition(x.toInt, y.toInt)
case s"swap letter $a with letter $b" => SwapLetter(a.head, b.head)
case s"rotate based on position of letter $a" => RotateByPosition(a.head)
case s"rotate $d $n $plural" => Rotate(d, n.toInt)
case s"reverse positions $x through $y" => ReverseByPosition(x.toInt, y.toInt)
case s"move position $x to position $y" => Move(x.toInt, y.toInt)
case s: String => sys.error(s"match error: '$s'")


override lazy val answer1: String = operations.foldLeft("abcdefgh")((s, o) => o.scramble(s))
Expand Down
14 changes: 6 additions & 8 deletions 2016/src/main/scala/aoc2016/Day23.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ object Day23 extends AoC:
case r: Register => registers.getOrElse(r, 0)
case v: Value => v

def update(register: Operand, operand: Operand, f: Value => Value = identity): Registers =
if register.isRegister then
val value = (f compose registers.valueOf)(operand)
registers.updated(register.toRegister, value)
def update(target: Operand, source: Operand, f: Value => Value = identity): Registers =
if target.isRegister then
val value = (f compose registers.valueOf)(source)
registers.updated(target.toRegister, value)
else
registers

Expand Down Expand Up @@ -74,16 +74,14 @@ object Day23 extends AoC:
def toggle(offset: Operand): Vector[Option[Instruction]] =
val index = pc + registers.valueOf(offset)
if instructions.indices.contains(index) then
instructions.updated(index, instructions(index) match
val update = instructions(index).runtimeChecked match
case None => None
case Some(CPY(o, r)) => Some(JNZ(o, r))
case Some(INC(r)) => Some(DEC(r))
case Some(DEC(r)) => Some(INC(r))
case Some(JNZ(o, v)) => Some(CPY(o, v))
case Some(TGL(x)) => Some(INC(x))
//Part 2
case _ => sys.error("boom!")
)
instructions.updated(index, update)
else
instructions

Expand Down
3 changes: 1 addition & 2 deletions 2017/src/main/scala/aoc2017/Day22.scala
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,9 @@ object Day22 extends AoC:
.flatMap: (row,y) =>
row
.zipWithIndex
.map:
.collect:
case ('#',x) => Pos.of(x,y) -> Infected
case ('.',x) => Pos.of(x,y) -> Clean
case ( c ,_) => sys.error(s"unexpected char=$c")
.toMap
.withDefaultValue(Clean)

Expand Down
3 changes: 1 addition & 2 deletions 2018/src/main/scala/aoc2018/Day06.scala
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,9 @@ object Day06 extends AoC:
val closest: Vector[(Pos,Pos)] =
positions.flatMap: p =>
coordinates.map(c => (c, c.manhattanDistance(p)))
.sortBy(_.distance).take(2) match
.sortBy(_.distance).take(2).runtimeChecked match
case a +: b +: _ if a.distance == b.distance => None
case a +: _ => Some(p,a.coordinate)
case _ => sys.error(s"no distance found for position: $p")

val areas: Map[Pos,Int] =
closest.groupMapReduce((_,c) => c)((_,_) => 1)(_+_)
Expand Down
3 changes: 1 addition & 2 deletions 2018/src/main/scala/aoc2018/Day07.scala
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,8 @@ object Day07 extends AoC:

val steps: Vector[(Char,Char)] =
def parser(s: String): (Char,Char) =
s match
s.runtimeChecked match
case s"Step $first must be finished before step $second can begin." => (first.head, second.head)
case _ => sys.error("boom!")
lines.map(parser)

override lazy val answer1: String = solve(steps, timer = _ => 1, parallelization = 1).right.mkString("")
Expand Down
6 changes: 2 additions & 4 deletions 2018/src/main/scala/aoc2018/Day13.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ object Day13 extends AoC:
extension (d: Dir)

infix def follow(c: Char): Dir =
(d, c) match
(d, c).runtimeChecked match
case (_, '|') | (_, '-') => d
case (N, '/') => E
case (E, '/') => N
Expand All @@ -20,7 +20,6 @@ object Day13 extends AoC:
case (E, '\\') => S
case (S, '\\') => E
case (W, '\\') => N
case _ => sys.error(s"unable to follow dir=$d, char=$c")

infix def turn(turn: Turn): Dir =
(d, turn) match
Expand Down Expand Up @@ -56,11 +55,10 @@ object Day13 extends AoC:

def move(grid: Grid): Cart =
val c = grid.charAt(pos step dir)
c match
c.runtimeChecked match
case Some('|') | Some('-') => copy(pos = pos step dir)
case Some('/') | Some('\\') => copy(pos = pos step dir, dir = dir follow c.get)
case Some('+') => copy(pos = pos step dir, dir = dir turn atIntersection, atIntersection = atIntersection.next)
case _ => sys.error(s"unexpected char at pos=$pos, char=$c")

val (grid: Grid, carts: Vector[Cart]) =
val matrix = lines.map(_.toVector)
Expand Down
3 changes: 1 addition & 2 deletions 2019/src/main/scala/aoc2019/Day06.scala
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,9 @@ object Day06 extends AoC:

@tailrec
def path(l: Vector[Name], r: Vector[Name]): Vector[Name] =
(l,r) match
(l,r).runtimeChecked match
case (l1 +: l2 +: _ , r1 +: r2 +: _) if l1 == r1 && l2 == r2 => path(l.tail, r.tail)
case (l1 +: _ , r1 +: _ ) if l1 == r1 => l.reverse ++ r.tail
case _ => sys.error(s"unmatched l=$l, r=$r")

override lazy val answer1: Int = planets.map(orbits).map(_.length).sum
override lazy val answer2: Int = path(pathToCom("YOU"), pathToCom("SAN")).length
3 changes: 1 addition & 2 deletions 2019/src/main/scala/aoc2019/Day08.scala
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,10 @@ object Day08 extends AoC:
extension (dig: Dig)

def digitToPix: Pix =
dig match
dig.runtimeChecked match
case 0 => Black
case 1 => White
case 2 => Trans
case _ => sys.error("boom")

def stack(top: Layer[Pix], bot: Layer[Pix]): Layer[Pix] =
top.zip(bot).map((t,b) => b.stack(t))
Expand Down
4 changes: 2 additions & 2 deletions 2019/src/main/scala/aoc2019/Day13.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ object Day13 extends AoC:
extension (outputs: LazyList[Value])
def render: Map[Location,Tile] =
outputs.grouped(3).foldLeft(Map.empty[Location,Tile]):
case (result, LazyList(x,y,id)) => result + (Location(x,y) -> Tile.fromId(id))
case output => sys.error(s"invalid output: $output")
case (result, LazyList(x, y, id)) => result + (Location(x, y) -> Tile.fromId(id))
case output => sys.error(s"invalid output: $output")

val program: Mem = Mem.parse(input)

Expand Down
3 changes: 1 addition & 2 deletions 2019/src/main/scala/aoc2019/Day23.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ object Day23 extends AoC:

val nextInput = if cpu.stdin.nonEmpty then in else Seq.empty

run match
case None => sys.error(s"unexpected halt")
run.runtimeChecked match
case Some(cpu, None) => State(cpu, nextInput, out)
case Some(cpu, Some(value)) => State(cpu, nextInput, out :+ value)

Expand Down
12 changes: 6 additions & 6 deletions 2019/src/main/scala/aoc2019/Day24.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ object Day24 extends AoC:
case Area(5, y, amount) => Set(Area(3, 2, amount - 1))
case Area(x, -1, amount) => Set(Area(2, 1, amount - 1))
case Area(x, 5, amount) => Set(Area(2, 3, amount - 1))
case Area(2, 2, amount) => area match
case Area(2, 1, amount) => Set.tabulate(5)(x => Area(x, 0, amount + 1))
case Area(2, 3, amount) => Set.tabulate(5)(x => Area(x, 4, amount + 1))
case Area(1, 2, amount) => Set.tabulate(5)(y => Area(0, y, amount + 1))
case Area(3, 2, amount) => Set.tabulate(5)(y => Area(4, y, amount + 1))
case _ => sys.error(s"illegal area: $area")
case Area(2, 2, amount) =>
area.runtimeChecked match
case Area(2, 1, amount) => Set.tabulate(5)(x => Area(x, 0, amount + 1))
case Area(2, 3, amount) => Set.tabulate(5)(x => Area(x, 4, amount + 1))
case Area(1, 2, amount) => Set.tabulate(5)(y => Area(0, y, amount + 1))
case Area(3, 2, amount) => Set.tabulate(5)(y => Area(4, y, amount + 1))
case other => Set(other)

def step(grid: Set[Area], neighbours: Area => Seq[Area]): Set[Area] =
Expand Down
9 changes: 3 additions & 6 deletions 2019/src/main/scala/aoc2019/cpu/CPU.scala
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,15 @@ case class CPU(mem: Mem, stdin: LazyList[Value] = LazyList.empty, ip: Pointer =
def paramMode(offset: Int): Int = ((value(0) / math.pow(10, 2 + offset).toInt) % 10).toInt

def read(offset: Int): Value =
paramMode(offset) match
paramMode(offset).runtimeChecked match
case 0 => mem(param(offset).toInt)
case 1 => param(offset)
case 2 => mem((base + param(offset)).toInt)
case _ => sys.error(s"illegal parameter read mode ${paramMode(offset)}")

def write(offset: Int, value: Value): Mem =
paramMode(offset) match
paramMode(offset).runtimeChecked match
case 0 => mem.set(param(offset).toInt, value)
case 2 => mem.set((base + param(offset)).toInt, value)
case _ => sys.error(s"illegal parameter write mode ${paramMode(offset)}")

def withInput(input: Value*): CPU =
copy(stdin = input.to(LazyList))
Expand All @@ -54,7 +52,7 @@ case class CPU(mem: Mem, stdin: LazyList[Value] = LazyList.empty, ip: Pointer =
copy(stdin = input)

def executeOne: Option[State] =
opcode match
opcode.runtimeChecked match
case 1 => Some((copy(mem = write(2, read(0) + read(1)), ip = ip + 4), None))
case 2 => Some((copy(mem = write(2, read(0) * read(1)), ip = ip + 4), None))
case 3 => Option.when(stdin.nonEmpty)(copy(mem = write(0, stdin.head), ip = ip + 2, stdin = stdin.tail), None)
Expand All @@ -65,7 +63,6 @@ case class CPU(mem: Mem, stdin: LazyList[Value] = LazyList.empty, ip: Pointer =
case 8 => Some((copy(mem = write(2, if (read(0) == read(1)) 1 else 0), ip = ip + 4), None))
case 9 => Some((copy(ip = ip + 2, base = base + read(0).toInt), None))
case 99 => None
case _ => sys.error(s"unknown opcode $opcode")

def outputs: LazyList[Value] =
LazyList.unfold(this)(_.executeOne.map(_.swap)).flatten
Expand Down
3 changes: 1 addition & 2 deletions 2020/src/main/scala/aoc2020/Day03.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,10 @@ object Day03 extends AoC:
def walk(dx: Int, dy: Int): Long =
@tailrec
def step(x: Int, y: Int, acc: Long = 0): Long =
sample(x, y) match
sample(x, y).runtimeChecked match
case None => acc
case Some('.') => step(x + dx, y + dy, acc)
case Some('#') => step(x + dx, y + dy, acc + 1)
case _ => sys.error(s"boom: x=$x,y=$y,dx=$dx,dy=$dy")
step(dx,dy)

val forest: Forest = Forest(lines.map(_.toVector))
Expand Down
14 changes: 7 additions & 7 deletions 2020/src/main/scala/aoc2020/Day04.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,23 @@ import scala.io.*

object Day04 extends AoC:

type Passport = Map[String,String]
type Passport = Map[String, String]

object Passport:
val empty: Passport =
Map.empty[String,String]
Map.empty[String, String]

val passports: Vector[Passport] =
lines.foldLeft(Vector(Passport.empty)): (acc,line) =>
lines.foldLeft(Vector(Passport.empty)): (result, line) =>
line.split(' ') match
case Array("") =>
Passport.empty +: acc
Passport.empty +: result
case line: Array[String] =>
val update = line.map(_.split(':')).map(kv => kv(0) -> kv(1)).toMap
(update ++ acc.head) +: acc.tail
(update ++ result.head) +: result.tail

def valYear(key: String, min: Int, max: Int)(passport: Passport): Boolean =
passport.get(key).exists(year => year.toInt >= min && year.toInt <= max)
def valYear(key: String, min: Int, max: Int)(p: Passport): Boolean =
p.get(key).exists(year => year.toInt >= min && year.toInt <= max)

def valHgt(p: Passport): Boolean =
p.get("hgt").exists: height =>
Expand Down
5 changes: 2 additions & 3 deletions 2020/src/main/scala/aoc2020/Day06.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@ package aoc2020
import nmcb.*

object Day06 extends AoC:



val answers: Vector[Vector[String]] =
lines.foldLeft(Vector(Vector.empty[String])):
case (result, line) if line.nonEmpty => (line +: result.head) +: result.tail
case (result, _) => Vector.empty[String] +: result

def chars(list: Vector[String]): String =
list.fold("")(_+_).distinct
list.mkString("").distinct

override lazy val answer1: Int = answers.map(chars).map(_.length).sum
override lazy val answer2: Int = answers.map(grp => grp.fold(chars(grp))(_ intersect _).length).sum
3 changes: 1 addition & 2 deletions 2020/src/main/scala/aoc2020/Day07.scala
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,9 @@ object Day07 extends AoC:
bags.filter(b => b.from == from && b.to.isDefined).map(b => b.to.get -> b.count)

def solve2(inner: Vector[(Color,Int)], result: Int = 0): Int =
inner match
inner.runtimeChecked match
case Vector() => result
case (child,count) +: cs => solve2(cs, result + count + count * solve2(childrenOf(child)))
case _ => sys.error("boom!")


override lazy val answer1: Int = bags.solve1(bags.parentsOf("shinygold")).distinct.size
Expand Down
3 changes: 1 addition & 2 deletions 2020/src/main/scala/aoc2020/Day08.scala
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,9 @@ object Day08 extends AoC:
def patch(program: Program): Program =

def patchLine(line: Int): Program =
program(line) match
program(line).runtimeChecked match
case Instruction("nop", arg) => program.updated(line, Instruction("jmp", arg))
case Instruction("jmp", arg) => program.updated(line, Instruction("nop", arg))
case Instruction(op, arg) => sys.error(s"invalid op=$op, arg=$arg")

VM(program).run(debug = true)
.trace
Expand Down
Loading