From 5723d21ecb7a4cc72bcba26bf15c9f34228e928b Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Thu, 17 Jan 2019 16:40:36 +0100 Subject: [PATCH] Adding day 18 p1 and 19 p1 + creating folder 2018 --- {day1 => 2018/day1}/part1.scala | 0 {day1 => 2018/day1}/part2.scala | 0 {day10 => 2018/day10}/bothparts.scala | 0 {day11 => 2018/day11}/part1.scala | 0 {day11 => 2018/day11}/part2.scala | 0 {day12 => 2018/day12}/part1.scala | 0 {day12 => 2018/day12}/part2.scala | 0 {day13 => 2018/day13}/part1.scala | 0 {day14 => 2018/day14}/part1.scala | 0 {day15 => 2018/day15}/part1.scala | 0 {day15 => 2018/day15}/part2.scala | 0 {day16 => 2018/day16}/part1.scala | 0 {day16 => 2018/day16}/part2.scala | 0 2018/day18/part1.scala | 53 +++++++++++++++++++++ 2018/day19/part1.scala | 68 +++++++++++++++++++++++++++ {day2 => 2018/day2}/part1.scala | 0 {day2 => 2018/day2}/part2.scala | 0 {day20 => 2018/day20}/part1.scala | 0 {day3 => 2018/day3}/part1.scala | 0 {day3 => 2018/day3}/part2.scala | 0 {day4 => 2018/day4}/part1.scala | 0 {day4 => 2018/day4}/part2.scala | 0 {day5 => 2018/day5}/part1.scala | 0 {day5 => 2018/day5}/part2.scala | 0 {day6 => 2018/day6}/part1.scala | 0 {day6 => 2018/day6}/part2.scala | 0 {day7 => 2018/day7}/part1.scala | 0 {day7 => 2018/day7}/part2.scala | 0 {day8 => 2018/day8}/part1.scala | 0 {day8 => 2018/day8}/part2.scala | 0 {day9 => 2018/day9}/part1.scala | 0 {day9 => 2018/day9}/part2.scala | 0 32 files changed, 121 insertions(+) rename {day1 => 2018/day1}/part1.scala (100%) rename {day1 => 2018/day1}/part2.scala (100%) rename {day10 => 2018/day10}/bothparts.scala (100%) rename {day11 => 2018/day11}/part1.scala (100%) rename {day11 => 2018/day11}/part2.scala (100%) rename {day12 => 2018/day12}/part1.scala (100%) rename {day12 => 2018/day12}/part2.scala (100%) rename {day13 => 2018/day13}/part1.scala (100%) rename {day14 => 2018/day14}/part1.scala (100%) rename {day15 => 2018/day15}/part1.scala (100%) rename {day15 => 2018/day15}/part2.scala (100%) rename {day16 => 2018/day16}/part1.scala (100%) rename {day16 => 2018/day16}/part2.scala (100%) create mode 100644 2018/day18/part1.scala create mode 100644 2018/day19/part1.scala rename {day2 => 2018/day2}/part1.scala (100%) rename {day2 => 2018/day2}/part2.scala (100%) rename {day20 => 2018/day20}/part1.scala (100%) rename {day3 => 2018/day3}/part1.scala (100%) rename {day3 => 2018/day3}/part2.scala (100%) rename {day4 => 2018/day4}/part1.scala (100%) rename {day4 => 2018/day4}/part2.scala (100%) rename {day5 => 2018/day5}/part1.scala (100%) rename {day5 => 2018/day5}/part2.scala (100%) rename {day6 => 2018/day6}/part1.scala (100%) rename {day6 => 2018/day6}/part2.scala (100%) rename {day7 => 2018/day7}/part1.scala (100%) rename {day7 => 2018/day7}/part2.scala (100%) rename {day8 => 2018/day8}/part1.scala (100%) rename {day8 => 2018/day8}/part2.scala (100%) rename {day9 => 2018/day9}/part1.scala (100%) rename {day9 => 2018/day9}/part2.scala (100%) 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