diff --git a/day1/part1.scala b/2018/day1/part1.scala similarity index 100% rename from day1/part1.scala rename to 2018/day1/part1.scala diff --git a/day1/part2.scala b/2018/day1/part2.scala similarity index 100% rename from day1/part2.scala rename to 2018/day1/part2.scala diff --git a/day10/bothparts.scala b/2018/day10/bothparts.scala similarity index 100% rename from day10/bothparts.scala rename to 2018/day10/bothparts.scala diff --git a/day11/part1.scala b/2018/day11/part1.scala similarity index 100% rename from day11/part1.scala rename to 2018/day11/part1.scala diff --git a/day11/part2.scala b/2018/day11/part2.scala similarity index 100% rename from day11/part2.scala rename to 2018/day11/part2.scala diff --git a/day12/part1.scala b/2018/day12/part1.scala similarity index 100% rename from day12/part1.scala rename to 2018/day12/part1.scala diff --git a/day12/part2.scala b/2018/day12/part2.scala similarity index 100% rename from day12/part2.scala rename to 2018/day12/part2.scala diff --git a/day13/part1.scala b/2018/day13/part1.scala similarity index 100% rename from day13/part1.scala rename to 2018/day13/part1.scala diff --git a/day14/part1.scala b/2018/day14/part1.scala similarity index 100% rename from day14/part1.scala rename to 2018/day14/part1.scala diff --git a/day15/part1.scala b/2018/day15/part1.scala similarity index 100% rename from day15/part1.scala rename to 2018/day15/part1.scala diff --git a/day15/part2.scala b/2018/day15/part2.scala similarity index 100% rename from day15/part2.scala rename to 2018/day15/part2.scala diff --git a/day16/part1.scala b/2018/day16/part1.scala similarity index 100% rename from day16/part1.scala rename to 2018/day16/part1.scala diff --git a/day16/part2.scala b/2018/day16/part2.scala similarity index 100% rename from day16/part2.scala rename to 2018/day16/part2.scala diff --git a/2018/day18/part1.scala b/2018/day18/part1.scala new file mode 100644 index 0000000..1dd39c6 --- /dev/null +++ b/2018/day18/part1.scala @@ -0,0 +1,53 @@ +import scala.io.StdIn.readLine + +val OPEN = '.' +val TREE = '|' +val LMBR = '#' + +case class Pos(x: Int, y: Int) { + lazy val adjacent = List( + Pos(x - 1, y - 1), + Pos(x - 1, y), + Pos(x - 1, y + 1), + Pos(x, y - 1), + Pos(x, y + 1), + Pos(x + 1, y - 1), + Pos(x + 1, y), + Pos(x + 1, y + 1) + ).filter { case Pos(xx, yy) => xx >= 0 && xx < 50 && yy >= 0 && yy < 50 } + + def adjacentChars(forest: Map[Pos, Char]): List[Char] = adjacent.map(forest) +} + +val forest = Iterator.continually(readLine) + .takeWhile(_ != null) + .map(_.zipWithIndex) + .zipWithIndex + .flatMap { case (line, y) => + line.map { case (char, x) => Pos(x, y) -> char } + }.toMap + +val forestEvolution = Iterator.from(1).scanLeft((0, forest)) { + case ((_, forest), turn) => (turn, forest.map { + case (p, OPEN) if p.adjacentChars(forest).count(_ == TREE) >= 3 => p -> TREE + case (p, OPEN) => p -> OPEN + case (p, TREE) if p.adjacentChars(forest).count(_ == LMBR) >= 3 => p -> LMBR + case (p, TREE) => p -> TREE + case (p, LMBR) if p.adjacentChars(forest).count(_ == LMBR) >= 1 && p.adjacentChars(forest).count(_ == TREE) >= 1 => p -> LMBR + case (p, LMBR) => p -> OPEN + }) +} + +def forestToString(forest: Map[Pos, Char]): String = + (0 to 49).map(y => (0 to 49).map(x => forest(Pos(x, y))).mkString("")).mkString("\n") + +val turns = forestEvolution + .take(11) + .toList + .foreach { case (turn, map) => + println(s"Turn $turn") + val charCounts = map.groupBy(_._2).mapValues(_.size) + charCounts.foreach { case (c, cnt) => println(s"$c count: $cnt") } + println(s"Score: ${charCounts(TREE) * charCounts(LMBR)}") + println(forestToString(map)) + } diff --git a/2018/day19/part1.scala b/2018/day19/part1.scala new file mode 100644 index 0000000..96e0bd1 --- /dev/null +++ b/2018/day19/part1.scala @@ -0,0 +1,68 @@ +import scala.io.StdIn.readLine + +def ifb(A: Int, B: Int, f: (Int, Int) => Boolean): Int = if (f(A, B)) { + 1 +} else { + 0 +} + +val OP_CODES: Map[String, ((Int, Int, Int, Registers) => Registers)] = Map( + "addr" -> ((A: Int, B: Int, C: Int, regs: List[Int]) => regs.patch(C, List(regs(A) + regs(B)), 1)), + "addi" -> ((A: Int, B: Int, C: Int, regs: List[Int]) => regs.patch(C, List(regs(A) + B), 1)), + + "mulr" -> ((A: Int, B: Int, C: Int, regs: List[Int]) => regs.patch(C, List(regs(A) * regs(B)), 1)), + "muli" -> ((A: Int, B: Int, C: Int, regs: List[Int]) => regs.patch(C, List(regs(A) * B), 1)), + + "banr" -> ((A: Int, B: Int, C: Int, regs: List[Int]) => regs.patch(C, List(regs(A) & regs(B)), 1)), + "bani" -> ((A: Int, B: Int, C: Int, regs: List[Int]) => regs.patch(C, List(regs(A) & B), 1)), + + "borr" -> ((A: Int, B: Int, C: Int, regs: List[Int]) => regs.patch(C, List(regs(A) | regs(B)), 1)), + "bori" -> ((A: Int, B: Int, C: Int, regs: List[Int]) => regs.patch(C, List(regs(A) | B), 1)), + + "setr" -> ((A: Int, B: Int, C: Int, regs: List[Int]) => regs.patch(C, List(regs(A)), 1)), + "seti" -> ((A: Int, B: Int, C: Int, regs: List[Int]) => regs.patch(C, List(A), 1)), + + "gtir" -> ((A: Int, B: Int, C: Int, regs: List[Int]) => regs.patch(C, List(ifb(A, regs(B), _ > _)), 1)), + "gtri" -> ((A: Int, B: Int, C: Int, regs: List[Int]) => regs.patch(C, List(ifb(regs(A), B, _ > _)), 1)), + "gtrr" -> ((A: Int, B: Int, C: Int, regs: List[Int]) => regs.patch(C, List(ifb(regs(A), regs(B), _ > _)), 1)), + + "eqir" -> ((A: Int, B: Int, C: Int, regs: List[Int]) => regs.patch(C, List(ifb(A, regs(B), _ == _)), 1)), + "eqri" -> ((A: Int, B: Int, C: Int, regs: List[Int]) => regs.patch(C, List(ifb(regs(A), B, _ == _)), 1)), + "eqrr" -> ((A: Int, B: Int, C: Int, regs: List[Int]) => regs.patch(C, List(ifb(regs(A), regs(B), _ == _)), 1)) +) + +type Registers = List[Int] + +case class Instruction(opcode: String, A: Int, B: Int, C: Int) { + override def toString: String = s"$opcode $A $B $C" +} + +object Instruction { + def apply(str: String): Instruction = str.split(" ").toList match { + case op :: a :: b :: c :: Nil => Instruction(op, a.toInt, b.toInt, c.toInt) + case _ => throw new RuntimeException("Invalid input") + } +} + +val (Some(ptr), programLines) = Iterator + .continually(readLine) + .takeWhile(_ != null) + .foldLeft( + (None : Option[Int], List.empty[Instruction]) + ) { + case ((None, _), line) => (Some(line.split(" ")(1).toInt), List()) + case ((ptr, lines), line) => (ptr, lines ++ List(Instruction(line))) +} + +def executeProgram(ptr: Int, instructions: List[Instruction], regs: Registers): Registers = regs(ptr) match { + case p if instructions.isDefinedAt(p) => + val inst = instructions(p) + val outputRegs = OP_CODES(inst.opcode)(inst.A, inst.B, inst.C, regs) + val incrPtrInRegs = outputRegs.patch(ptr, List(outputRegs(ptr) + 1), 1) + // println(s"ip=$ptr ${regs.mkString("[", ", ", "]")} $inst ${incrPtrInRegs.mkString("[", ", ", "]")}") + executeProgram(ptr, instructions, incrPtrInRegs) + case _ => regs +} + +val endRegs = executeProgram(ptr, programLines, List.fill(6)(0)) +println(s"End value in reg 0: " + endRegs(0)) diff --git a/day2/part1.scala b/2018/day2/part1.scala similarity index 100% rename from day2/part1.scala rename to 2018/day2/part1.scala diff --git a/day2/part2.scala b/2018/day2/part2.scala similarity index 100% rename from day2/part2.scala rename to 2018/day2/part2.scala diff --git a/day20/part1.scala b/2018/day20/part1.scala similarity index 100% rename from day20/part1.scala rename to 2018/day20/part1.scala diff --git a/day3/part1.scala b/2018/day3/part1.scala similarity index 100% rename from day3/part1.scala rename to 2018/day3/part1.scala diff --git a/day3/part2.scala b/2018/day3/part2.scala similarity index 100% rename from day3/part2.scala rename to 2018/day3/part2.scala diff --git a/day4/part1.scala b/2018/day4/part1.scala similarity index 100% rename from day4/part1.scala rename to 2018/day4/part1.scala diff --git a/day4/part2.scala b/2018/day4/part2.scala similarity index 100% rename from day4/part2.scala rename to 2018/day4/part2.scala diff --git a/day5/part1.scala b/2018/day5/part1.scala similarity index 100% rename from day5/part1.scala rename to 2018/day5/part1.scala diff --git a/day5/part2.scala b/2018/day5/part2.scala similarity index 100% rename from day5/part2.scala rename to 2018/day5/part2.scala diff --git a/day6/part1.scala b/2018/day6/part1.scala similarity index 100% rename from day6/part1.scala rename to 2018/day6/part1.scala diff --git a/day6/part2.scala b/2018/day6/part2.scala similarity index 100% rename from day6/part2.scala rename to 2018/day6/part2.scala diff --git a/day7/part1.scala b/2018/day7/part1.scala similarity index 100% rename from day7/part1.scala rename to 2018/day7/part1.scala diff --git a/day7/part2.scala b/2018/day7/part2.scala similarity index 100% rename from day7/part2.scala rename to 2018/day7/part2.scala diff --git a/day8/part1.scala b/2018/day8/part1.scala similarity index 100% rename from day8/part1.scala rename to 2018/day8/part1.scala diff --git a/day8/part2.scala b/2018/day8/part2.scala similarity index 100% rename from day8/part2.scala rename to 2018/day8/part2.scala diff --git a/day9/part1.scala b/2018/day9/part1.scala similarity index 100% rename from day9/part1.scala rename to 2018/day9/part1.scala diff --git a/day9/part2.scala b/2018/day9/part2.scala similarity index 100% rename from day9/part2.scala rename to 2018/day9/part2.scala