summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/day13.rs115
-rw-r--r--src/main.rs2
2 files changed, 117 insertions, 0 deletions
diff --git a/src/day13.rs b/src/day13.rs
new file mode 100644
index 0000000..d2bd050
--- /dev/null
+++ b/src/day13.rs
@@ -0,0 +1,115 @@
+use std::cmp::Ordering;
+
+#[derive(Debug,Clone,PartialEq)]
+enum Packet {
+ Num(i32),
+ Lst(Vec<Packet>)
+}
+
+impl Packet {
+ fn parse<T: Iterator<Item = char>>(chrs: &mut T) -> Packet {
+ let mut numchrs = String::new();
+ let mut children: Vec<Packet> = Vec::new();
+ loop {
+ match chrs.next() {
+ Some('[') => {
+ children.push(Packet::parse(chrs));
+ },
+ Some(']') | None => break,
+ Some(',') => {
+ if !numchrs.is_empty() {
+ children.push(Packet::Num(numchrs.parse().expect("chars wasn't a number!")));
+ }
+ numchrs.clear();
+ },
+ Some(x) => {
+ numchrs.push(x);
+ },
+ }
+ }
+ if !numchrs.is_empty() {
+ children.push(Packet::Num(numchrs.parse().expect("chars wasn't a number!")));
+ }
+ Packet::Lst(children)
+ }
+ fn coerce_to_lst(&self) -> Packet {
+ match self {
+ Self::Lst(x) => Packet::Lst(x.to_vec()),
+ Self::Num(x) => Packet::Lst(vec![Packet::Num(*x)])
+ }
+ }
+ fn rightorder(left: &Packet, right: &Self) -> Ordering {
+ if let (Packet::Num(x), Packet::Num(y)) = (left, right) {
+ if x < y {
+ Ordering::Less
+ } else if x == y {
+ Ordering::Equal
+ } else {
+ Ordering::Greater
+ }
+ } else if let (Packet::Lst(x), Packet::Lst(y)) = (left, right) {
+ for ix in 0..(x.len().max(y.len())) {
+ let maybe_xx = x.get(ix);
+ if maybe_xx.is_none() {
+ return Ordering::Less;
+ }
+ let maybe_yy = y.get(ix);
+ if maybe_yy.is_none() {
+ return Ordering::Greater;
+ }
+ let rr = Packet::rightorder(maybe_xx.unwrap(), maybe_yy.unwrap());
+ match rr {
+ Ordering::Less | Ordering::Greater => return rr,
+ Ordering::Equal => {},
+ }
+ }
+ Ordering::Equal
+ } else {
+ Packet::rightorder(&left.coerce_to_lst(), &right.coerce_to_lst())
+ }
+ }
+}
+
+pub fn run(input: String) {
+ // let x: i32 = input.lines().collect::<Vec<&str>>().split(|x| {x.is_empty()})
+ // .enumerate()
+ // .map(|(ix, ps)| {
+ // if ps.len() != 2 {
+ // panic!("Expected pairs of packets, got {:?}", ps);
+ // }
+ // let ps1 = ps[0];
+ // let ps2 = ps[1];
+ // let p1 = Packet::parse(&mut ps1.chars().into_iter());
+ // let p2 = Packet::parse(&mut ps2.chars().into_iter());
+ // //println!("ps1 {} ps2 {} p1 {:?} p2 {:?}", ps1, ps2, p1, p2);
+ // match Packet::rightorder(&p1, &p2) {
+ // Ordering::Less => (ix+1) as i32,
+ // Ordering::Greater => 0 as i32,
+ // Ordering::Equal => panic!("2 identical packets????")
+ // }
+ // })
+ // .sum();
+
+ // println!("Day 13: {}", x);
+ let mut zinput = String::from("
+[[2]]
+[[6]]
+");
+ zinput.push_str(&input);
+ let mut packets = zinput.lines()
+ .filter(|x| {!x.is_empty()})
+ .map(|x| {Packet::parse(&mut x.chars().into_iter())})
+ .enumerate()
+ .collect::<Vec<(usize, Packet)>>();
+ packets.sort_by(|(_, p1), (_, p2)| { Packet::rightorder(p1, p2)});
+ let mut dp1: usize = 0;
+ let mut dp2: usize = 0;
+ for (nix, (oix, _)) in packets.into_iter().enumerate() {
+ if oix == 0 {
+ dp1 = nix+1;
+ } else if oix == 1 {
+ dp2 = nix+1;
+ }
+ }
+ println!("Day 13: {}", dp1*dp2);
+} \ No newline at end of file
diff --git a/src/main.rs b/src/main.rs
index 885a516..0b427f1 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -14,6 +14,7 @@ mod day9;
mod day10;
mod day11;
mod day12;
+mod day13;
fn main() {
day1::run(fs::read_to_string("input/day1.txt").expect("Failed to read input file!"));
@@ -28,4 +29,5 @@ fn main() {
day10::run(fs::read_to_string("input/day10.txt").expect("Failed to read input file!"));
day11::run(fs::read_to_string("input/day11.txt").expect("Failed to read input file!"));
day12::run(fs::read_to_string("input/day12.txt").expect("Failed to read input file!"));
+ day13::run(fs::read_to_string("input/day13.txt").expect("Failed to read input file!"));
}