Skip to content

Commit

Permalink
2023-08 WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
jurisk committed Dec 8, 2023
1 parent 0e8a2be commit 18ebc21
Showing 1 changed file with 40 additions and 16 deletions.
56 changes: 40 additions & 16 deletions scala2/src/main/scala/jurisk/adventofcode/y2023/Advent08.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@ object Advent08 {
}
}

type NodeId = String
private type NodeId = Int
private type NodeName = String

final case class Mapping(
from: NodeId,
name: NodeName,
left: NodeId,
right: NodeId,
) {
Expand All @@ -36,30 +37,50 @@ object Advent08 {

final case class Input(
instructions: IndexedSeq[Instruction],
mapping: Map[NodeId, Mapping],
mappings: IndexedSeq[Mapping],
) {
def instructionAtStep(step: Long): Instruction = instructions(
(step % instructions.length).toInt
)

def findNodesByNameFilter(predicate: NodeName => Boolean): IndexedSeq[NodeId] = mappings.indices.filter(index => predicate(mapping(index).name))

def findNodeByName(name: NodeName): NodeId = {
val result = mappings.indexWhere(_.name === name)
if (result === -1) {
sys.error(s"Did not find node $name")
} else {
result
}
}

def mapping(nodeId: NodeId): Mapping = mappings(nodeId)
}

def parse(input: List[List[String]]): Input = {
val List(List(instructionLine), mappingLines) = input
val instructions = instructionLine.map(Instruction.parse)

val mappings = mappingLines
val mappingTuples: IndexedSeq[(NodeName, NodeName, NodeName)] = mappingLines
.toIndexedSeq
.map {
case s"$from = ($left, $right)" => Mapping(from, left, right)
case s"$from = ($left, $right)" => (from, left, right)
case line => line.failedToParse
}
.map { x =>
x.from -> x
}
.toMap

val mappings = mappingTuples map { case (from, left, right) =>
def idx(name: NodeName): NodeId = mappingTuples.indexWhere {case (from, _, _) => from == name }

Mapping(
name = from,
left = idx(left),
right = idx(right),
)
}

Input(
instructions = instructions,
mapping = mappings,
mappings = mappings,
)
}

Expand All @@ -78,15 +99,18 @@ object Advent08 {
}
}

def part1(game: Input): Long =
loopAt(game, "AAA", _ == "ZZZ")
def part1(game: Input): Long = {
val start = game.findNodeByName("AAA")
val finish = game.findNodeByName("ZZZ")

loopAt(game, start, _ == finish)
}

def part2(game: Input): Long = {
val startNodes = game.mapping.keys.filter(_.last == 'A')
val startNodes = game.findNodesByNameFilter(_.last === 'A')
val finishNodes = game.findNodesByNameFilter(_.last === 'Z')

val individualResults = startNodes map { node =>
loopAt(game, node, _.last == 'Z')
}
val individualResults = startNodes.map(loopAt(game, _, finishNodes.contains))

lcmMany(individualResults)
}
Expand Down

0 comments on commit 18ebc21

Please sign in to comment.