Day 13
This commit is contained in:
@ -1,3 +1,138 @@
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
use std::{cmp::Ordering, fs::read_to_string, str::Lines};
|
||||
|
||||
#[derive(Debug, Clone, Eq)]
|
||||
enum Node {
|
||||
Number(i32),
|
||||
List(Vec<Node>),
|
||||
}
|
||||
|
||||
impl PartialEq for Node {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.partial_cmp(other) == Some(Ordering::Equal)
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for Node {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
self.partial_cmp(other).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for Node {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
match (self, other) {
|
||||
(Self::Number(n1), Self::Number(n2)) => n1.partial_cmp(n2),
|
||||
(Self::Number(n), Self::List(_)) => {
|
||||
Self::List(vec![Self::Number(*n)]).partial_cmp(other)
|
||||
}
|
||||
(Self::List(_), Self::Number(n)) => {
|
||||
self.partial_cmp(&Self::List(vec![Self::Number(*n)]))
|
||||
}
|
||||
(Self::List(l1), Self::List(l2)) => {
|
||||
for i in 0..l1.len().min(l2.len()) {
|
||||
let n1 = &l1[i];
|
||||
let n2 = &l2[i];
|
||||
match n1.partial_cmp(&n2) {
|
||||
None | Some(Ordering::Equal) => (),
|
||||
ord => return ord,
|
||||
}
|
||||
}
|
||||
Some(l1.len().cmp(&l2.len()))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for Node {
|
||||
fn from(line: &str) -> Self {
|
||||
match line.split_once('[') {
|
||||
None => Self::Number(line.parse().unwrap()),
|
||||
Some(("", "]")) => Self::List(vec![]),
|
||||
Some(("", r)) => match r.rsplit_once(']') {
|
||||
Some((r, "")) => {
|
||||
let mut indentation = 0;
|
||||
Self::List(
|
||||
r.split(|c| match c {
|
||||
'[' => {
|
||||
indentation += 1;
|
||||
false
|
||||
}
|
||||
']' => {
|
||||
indentation -= 1;
|
||||
false
|
||||
}
|
||||
',' if indentation == 0 => true,
|
||||
_ => false,
|
||||
})
|
||||
.map(Into::into)
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
_ => panic!("missing closing parenthesis"),
|
||||
},
|
||||
_ => panic!("invalid input"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_pair(lines: &mut Lines) -> Option<(Node, Node)> {
|
||||
let [first, second] = &lines
|
||||
.take_while(|line| !line.is_empty())
|
||||
.map(Node::from)
|
||||
.collect::<Vec<_>>()[..] else {return None;};
|
||||
Some((first.clone(), second.clone()))
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let input = "[1,1,3,1,1]
|
||||
[1,1,5,1,1]
|
||||
|
||||
[[1],[2,3,4]]
|
||||
[[1],4]
|
||||
|
||||
[9]
|
||||
[[8,7,6]]
|
||||
|
||||
[[4,4],4,4]
|
||||
[[4,4],4,4,4]
|
||||
|
||||
[7,7,7,7]
|
||||
[7,7,7]
|
||||
|
||||
[]
|
||||
[3]
|
||||
|
||||
[[[]]]
|
||||
[[]]
|
||||
|
||||
[1,[2,[3,[4,[5,6,7]]]],8,9]
|
||||
[1,[2,[3,[4,[5,6,0]]]],8,9]"
|
||||
.to_owned();
|
||||
let input = read_to_string("input.txt").unwrap_or(input);
|
||||
let mut input = input.lines();
|
||||
let mut pairs = vec![];
|
||||
while let Some(pair) = parse_pair(&mut input) {
|
||||
pairs.push(pair);
|
||||
}
|
||||
let correct: usize = pairs
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter_map(|(i, pair)| if pair.0 < pair.1 { Some(i + 1) } else { None })
|
||||
.sum();
|
||||
println!("{correct}");
|
||||
let mut packets: Vec<_> = pairs.into_iter().flat_map(|p| [p.0, p.1]).collect();
|
||||
packets.push("[[2]]".into());
|
||||
packets.push("[[6]]".into());
|
||||
packets.sort();
|
||||
let decoder_key = (packets
|
||||
.iter()
|
||||
.position(|e| *e == Node::from("[[2]]"))
|
||||
.unwrap()
|
||||
+ 1)
|
||||
* (packets
|
||||
.iter()
|
||||
.position(|e| *e == Node::from("[[6]]"))
|
||||
.unwrap()
|
||||
+ 1);
|
||||
println!("{decoder_key}");
|
||||
}
|
||||
|
Reference in New Issue
Block a user