Adding day 18 p1 and 19 p1 + creating folder 2018

This commit is contained in:
Xavier Morel
2019-01-17 16:40:36 +01:00
parent 5fb50b11af
commit 5723d21ecb
32 changed files with 121 additions and 0 deletions

53
2018/day18/part1.scala Normal file
View File

@@ -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))
}

68
2018/day19/part1.scala Normal file
View File

@@ -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))