Compare commits
4 Commits
76367959ae
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1d9dc696a8 | ||
|
|
9654c59bfd | ||
|
|
65b220007e | ||
|
|
3515ad8d11 |
@@ -4,8 +4,8 @@ language: "scala"
|
||||
dockerfile: "Dockerfile"
|
||||
code: "/code"
|
||||
workdir: "/code"
|
||||
runonce: "./mill aoc.assembly"
|
||||
cmd: "java -jar ./out/aoc/assembly.dest/out.jar %day% %input%"
|
||||
runonce: "./mill aoc.nativeImage"
|
||||
cmd: "./out/aoc/nativeImage.dest/aoc %day% %input%"
|
||||
environment:
|
||||
- AOC_BENCH=1
|
||||
daypath: "aoc/src/dev/ctsk/aoc/days/Day%dayzero%.scala"
|
||||
|
||||
12
Dockerfile
12
Dockerfile
@@ -1,9 +1,15 @@
|
||||
FROM eclipse-temurin:23-jdk-alpine
|
||||
FROM eclipse-temurin:23-jdk
|
||||
|
||||
RUN apk add curl
|
||||
RUN apt-get update && apt-get install -y curl gzip build-essential libz-dev
|
||||
RUN curl -fL "https://github.com/coursier/launchers/raw/master/cs-x86_64-pc-linux.gz" | gzip -d > cs
|
||||
RUN chmod +x cs
|
||||
RUN cp cs /usr/local/bin
|
||||
RUN ./cs setup --yes
|
||||
|
||||
COPY . /build
|
||||
|
||||
WORKDIR /build
|
||||
|
||||
RUN ./mill aoc.assembly
|
||||
RUN ./mill aoc.assembly
|
||||
|
||||
RUN ./mill aoc.nativeImage
|
||||
@@ -3,6 +3,8 @@ package dev.ctsk.aoc.days
|
||||
import dev.ctsk.aoc.{Direction, *}
|
||||
|
||||
import scala.collection.mutable
|
||||
import scala.util.boundary
|
||||
import scala.util.boundary.break
|
||||
|
||||
object Day16 extends Solver(16):
|
||||
override def run(input_ : os.ReadablePath): (Timings, Solution) =
|
||||
@@ -14,28 +16,40 @@ object Day16 extends Solver(16):
|
||||
val end = grid.findFirst(_ == 'E').get
|
||||
|
||||
case class State(distance: Int, pose: Pose)
|
||||
implicit def ord: Ordering[State] = Ordering.by(-1 * _.distance)
|
||||
|
||||
Direction.Up.ordinal
|
||||
|
||||
def search(start: Pose): (Map[Pose, Int], Map[Pose, List[Pose]]) =
|
||||
val distance = mutable.Map(start -> 0)
|
||||
val ancestor = mutable.Map.empty[Pose, List[Pose]]
|
||||
val heap = mutable.PriorityQueue(State(0, start))
|
||||
var near = mutable.Stack(State(0, start))
|
||||
var far = mutable.Stack.empty[State]
|
||||
|
||||
inline def relax(u: Pose, v: Pose, vDist: Int): Unit =
|
||||
inline def relax(u: Pose, v: Pose, vDist: Int, isFar: Boolean): Unit =
|
||||
val oldDist = distance.getOrElse(v, 1_000_000)
|
||||
if vDist == oldDist then ancestor(v) +:= u
|
||||
if vDist < oldDist then
|
||||
ancestor(v) = List(u)
|
||||
distance(v) = vDist
|
||||
heap.enqueue(State(vDist, v))
|
||||
if isFar
|
||||
then far.push(State(vDist, v))
|
||||
else near.push(State(vDist, v))
|
||||
|
||||
while heap.nonEmpty do
|
||||
val State(uDist, u) = heap.dequeue()
|
||||
if uDist == distance(u) then
|
||||
if !grid(u.step.pos).contains('#') then relax(u, u.step, uDist + 1)
|
||||
for (v <- Seq(u.turnLeft, u.turnRight)) do relax(u, v, uDist + 1000)
|
||||
boundary:
|
||||
while near.nonEmpty do
|
||||
var atEnd = false;
|
||||
while near.nonEmpty do
|
||||
val State(uDist, u) = near.pop()
|
||||
atEnd |= u.pos == end
|
||||
if uDist == distance(u) then
|
||||
if !grid(u.step.pos).contains('#') then
|
||||
relax(u, u.step, uDist + 1, false)
|
||||
for (v <- Seq(u.turnLeft, u.turnRight)) do
|
||||
relax(u, v, uDist + 1000, true)
|
||||
|
||||
if atEnd then break()
|
||||
|
||||
val tmp = near
|
||||
near = far
|
||||
far = tmp
|
||||
|
||||
(distance.toMap, ancestor.toMap)
|
||||
|
||||
@@ -43,7 +57,7 @@ object Day16 extends Solver(16):
|
||||
search(Pose(start, Direction.Right))
|
||||
}
|
||||
|
||||
val endPose = DIRS.map(Pose(end, _)).minBy(distance(_))
|
||||
val endPose = DIRS.map(Pose(end, _)).minBy(distance.getOrElse(_, 1_000_000))
|
||||
|
||||
val p1 = distance(endPose)
|
||||
|
||||
|
||||
@@ -59,7 +59,6 @@ object Day24 extends Solver(24):
|
||||
var carry = ins(Gate.of(Op.AND, x(0), y(0)))
|
||||
for i <- 1 to 44
|
||||
do
|
||||
println((i, carry))
|
||||
val x_ = x(i)
|
||||
val y_ = y(i)
|
||||
val x_y_xor = lookup(Gate.of(Op.XOR, x_, y_)).get
|
||||
@@ -79,169 +78,4 @@ object Day24 extends Solver(24):
|
||||
(
|
||||
Timings(0, p1._1, p2._1),
|
||||
Solution(Long.box(p1._2), p2._2)
|
||||
)
|
||||
|
||||
// def construct_(id: String, f: String => Node): Node =
|
||||
// wires.get(id) match
|
||||
// case Some(l, r, op) => Node.Inner(id, Op.valueOf(op), f(l), f(r))
|
||||
// case None => Node.Leaf(id)
|
||||
// val construct = Memo.Y(construct_)
|
||||
|
||||
// val ends = wires.keySet.map(construct)
|
||||
// val nodes = ends ++
|
||||
// ends.collect { case Node.Inner(_, _, l, r) => Set(l, r) }.flatten
|
||||
|
||||
// def downstream_(node: Node): Set[Node] =
|
||||
// nodes.collect {
|
||||
// case inner: Node.Inner if inner.lhs.id == node.id => inner
|
||||
// case inner: Node.Inner if inner.rhs.id == node.id => inner
|
||||
// }
|
||||
// val downstream = Memo(downstream_)
|
||||
|
||||
// def tag(t: Char)(i: Int): String = f"$t$i%02d"
|
||||
|
||||
// val x = tag('x');
|
||||
// val y = tag('y');
|
||||
// val z = tag('z');
|
||||
// var lastCarry = ends.find(op(Op.AND, leaf(x(0)), leaf(y(0)))).get
|
||||
|
||||
// for i <- 1 to 44 do
|
||||
// val out = op(Op.XOR, op(Op.XOR, leaf(x(i)), leaf(y(i))), _ => true)
|
||||
// val mkCarry = op(
|
||||
// Op.OR,
|
||||
// op(Op.AND, leaf(x(i)), leaf(y(i))),
|
||||
// op(
|
||||
// Op.AND,
|
||||
// op(Op.XOR, leaf(x(i)), leaf(y(i))),
|
||||
// {
|
||||
// case Node.Inner(id, _, _, _) => id == lastCarry.id
|
||||
// case _ => false
|
||||
// }
|
||||
// )
|
||||
// )
|
||||
//
|
||||
// ends
|
||||
// .find(out) match
|
||||
// case Some(node) => ()
|
||||
// case None =>
|
||||
// println(
|
||||
// (
|
||||
// z(i),
|
||||
// wires(z(i)),
|
||||
// ends.find(end =>
|
||||
// op(Op.XOR, leaf(x(i)), leaf(y(i)))(construct(end))
|
||||
// )
|
||||
// )
|
||||
// )
|
||||
//
|
||||
// def dependencies_(id: String, f: String => Set[String]): Set[String] =
|
||||
// wires.get(id) match
|
||||
// case Some(in1, in2, op) => f(in1) ++ f(in2)
|
||||
// case None => Set(id)
|
||||
// val dependencies = Memo.Y(dependencies_)
|
||||
//
|
||||
// val allDeps = wires.keySet.groupBy(dependencies)
|
||||
|
||||
// val carries = wires.filter((k, v) => v._3 == "OR").keySet
|
||||
|
||||
// val xs = (0 to 44).map(x).toSet
|
||||
// val ys = (0 to 44).map(y).toSet
|
||||
// val zs = (0 to 45).map(z).toSet
|
||||
|
||||
// (zs - "z45")
|
||||
// def tag(i: Int): (String, String) =
|
||||
// if i == 0
|
||||
// then
|
||||
// val candidates = revDependencies(Set("x00", "y00"))
|
||||
// val output = candidates.find(wires(_)._3 == "XOR")
|
||||
// val carry = candidates.find(wires(_)._3 == "AND")
|
||||
// (output, carry)
|
||||
// else
|
||||
// val candidates = revDependencies(Set("x00", "y00"))
|
||||
// val (pOutput, pCarry) = tag(i - 1)
|
||||
|
||||
// dependencies()
|
||||
//
|
||||
// def resolve_(id: String, f: String => Int): Int =
|
||||
// wires.get(id) match
|
||||
// case Some(in1, in2, "XOR") => f(in1) ^ f(in2)
|
||||
// case Some(in1, in2, "OR") => f(in1) | f(in2)
|
||||
// case Some(in1, in2, "AND") => f(in1) & f(in2)
|
||||
// case _ => inits(id)
|
||||
// val resolve = Memo.Y(resolve_)
|
||||
//
|
||||
// val p1 = timed { (0 to 45).reverse.map(z).map(resolve).mkString.binLong }
|
||||
//
|
||||
// val clear =
|
||||
// (for
|
||||
// i <- 0 to 44
|
||||
// v <- Seq("x", "y")
|
||||
// yield f"$v${i}%02d" -> 0).toMap
|
||||
|
||||
// for i <- 0 to 44 do
|
||||
// for
|
||||
// y <- 0 to 1
|
||||
// x <- 0 to 1
|
||||
// do
|
||||
// val z = resolve(
|
||||
// clear ++
|
||||
// Seq(
|
||||
// f"y${i}%02d" -> y,
|
||||
// f"x${i}%02d" -> x
|
||||
// ).toMap,
|
||||
// f"z${i}%02d"
|
||||
// )
|
||||
// val carry = resolve(
|
||||
// clear ++ Seq(
|
||||
// f"y${i}%02d" -> y,
|
||||
// f"x${i}%02d" -> x
|
||||
// ).toMap,
|
||||
// f"z${i + 1}%02d"
|
||||
// )
|
||||
//
|
||||
// if z != (x ^ y) then println(f"z$i")
|
||||
// if carry != (x & y) then println(f"carry$i")
|
||||
// assert(z == (x ^ y))
|
||||
// assert(carry == (x & y))
|
||||
|
||||
// val outs = wires.keySet
|
||||
// .filter(_(0) == 'z')
|
||||
// .map(out => (out, resolve(out)))
|
||||
// .toArray
|
||||
// .sorted
|
||||
// .map(_._2)
|
||||
|
||||
//
|
||||
// wires.foreach {
|
||||
// case (id, (in1, in2, op)) =>
|
||||
// val col = op match
|
||||
// case "XOR" => "[color=\"red\"]"
|
||||
// case "OR" => "[color=\"blue\"]"
|
||||
// case "AND" => "[color=\"green\"]"
|
||||
// println(f"$in1 -> $id $col")
|
||||
// println(f"$in2 -> $id $col")
|
||||
// }
|
||||
|
||||
// println(
|
||||
// outs.mkString.reverse.foldLeft(0L)((acc, c) => (acc << 1) + c.asDigit)
|
||||
// )
|
||||
|
||||
// enum Op { case AND, OR, XOR }
|
||||
//
|
||||
// enum Node:
|
||||
// case Inner(op: Op, lhs: Node, rhs: Node)
|
||||
// case Leaf(id: String)
|
||||
// def id: String = this match
|
||||
// case inner: Inner => inner.id
|
||||
// case leaf: Leaf => leaf.id
|
||||
//
|
||||
// def op(op: Op, l: Node => Boolean, r: Node => Boolean)(node: Node): Boolean =
|
||||
// node match
|
||||
// case Node.Inner(_, inner, lhs, rhs) =>
|
||||
// op == inner && (l(lhs) && r(rhs) || l(rhs) && r(lhs))
|
||||
// case Node.Leaf(_) => false
|
||||
//
|
||||
// def leaf(id: String)(node: Node): Boolean =
|
||||
// node match
|
||||
// case Node.Leaf(leaf) => leaf == id
|
||||
// case _ => false
|
||||
)
|
||||
Reference in New Issue
Block a user