day 8 part 1
This commit is contained in:
parent
8f6aa7fcc7
commit
5cc33ed979
2 changed files with 772 additions and 0 deletions
104
src/bin/day8.rs
Normal file
104
src/bin/day8.rs
Normal file
|
@ -0,0 +1,104 @@
|
|||
#![forbid(elided_lifetimes_in_paths, unsafe_code)]
|
||||
|
||||
use aoc23::read;
|
||||
use chumsky::prelude::*;
|
||||
use std::collections::HashMap;
|
||||
|
||||
enum Instruction {
|
||||
Left,
|
||||
Right
|
||||
}
|
||||
|
||||
impl Instruction {
|
||||
fn parser() -> impl Parser<char, Self, Error = Simple<char>> {
|
||||
choice((
|
||||
just('L').map(|_| Self::Left),
|
||||
just('R').map(|_| Self::Right)
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Node {
|
||||
left: String,
|
||||
right: String
|
||||
}
|
||||
|
||||
fn parse_node_name() -> impl Parser<char, String, Error = Simple<char>> {
|
||||
none_of([',', ')', ' '])
|
||||
.repeated()
|
||||
.at_least(1)
|
||||
.map(|chars| chars.into_iter().collect())
|
||||
}
|
||||
|
||||
impl Node {
|
||||
fn parser() -> impl Parser<char, Self, Error = Simple<char>> {
|
||||
just("(")
|
||||
.ignore_then(parse_node_name())
|
||||
.then_ignore(just(", "))
|
||||
.then(parse_node_name())
|
||||
.then_ignore(just(")"))
|
||||
.map(|(left, right)| Self { left, right })
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Network {
|
||||
nodes: HashMap<String, Node>
|
||||
}
|
||||
|
||||
impl Network {
|
||||
fn parser() -> impl Parser<char, Self, Error = Simple<char>> {
|
||||
parse_node_name()
|
||||
.then_ignore(just(" = "))
|
||||
.then(Node::parser())
|
||||
.then_ignore(just("\n"))
|
||||
.repeated()
|
||||
.map(|nodes| Self {
|
||||
nodes: nodes.into_iter().collect()
|
||||
})
|
||||
}
|
||||
|
||||
fn node(&self, node: &str) -> &Node {
|
||||
self.nodes
|
||||
.get(node)
|
||||
.unwrap_or_else(|| panic!("Failed to get node {node:?}"))
|
||||
}
|
||||
|
||||
fn left(&self, node: &str) -> &str {
|
||||
&self.node(node).left
|
||||
}
|
||||
|
||||
fn right(&self, node: &str) -> &str {
|
||||
&self.node(node).right
|
||||
}
|
||||
}
|
||||
|
||||
fn parser() -> impl Parser<char, (Vec<Instruction>, Network), Error = Simple<char>> {
|
||||
Instruction::parser()
|
||||
.repeated()
|
||||
.at_least(1)
|
||||
.then_ignore(just("\n\n"))
|
||||
.then(Network::parser())
|
||||
.then_ignore(end())
|
||||
}
|
||||
|
||||
fn main() -> anyhow::Result<()> {
|
||||
let (instructions, network) = read("inputs/day8.txt", parser())?;
|
||||
// eprintln!("{network:?}");
|
||||
|
||||
let mut curr_node = "AAA";
|
||||
let mut i = 0;
|
||||
let mut steps = 0;
|
||||
while curr_node != "ZZZ" {
|
||||
curr_node = match instructions[i] {
|
||||
Instruction::Left => network.left(curr_node),
|
||||
Instruction::Right => network.right(curr_node)
|
||||
};
|
||||
i = (i + 1) % instructions.len();
|
||||
steps += 1;
|
||||
}
|
||||
println!("{steps}");
|
||||
|
||||
Ok(())
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue