This commit is contained in:
Max
2022-12-13 09:37:09 +01:00
parent fd3a9a2938
commit 4efef42bc9
3 changed files with 593 additions and 2 deletions

View File

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