Jake Fenton 1 рік тому
батько
коміт
1fc10cdd1f
2 змінених файлів з 172 додано та 0 видалено
  1. 149 0
      src/bin/13.rs
  2. 23 0
      src/examples/13.txt

+ 149 - 0
src/bin/13.rs

@@ -0,0 +1,149 @@
+
+#[derive(Clone, Debug)]
+pub enum PacketVal {
+    scalar(u32),
+    list(Vec<PacketVal>)
+}
+
+pub enum Cmp {
+    good,
+    bad,
+    idk
+}
+
+impl PacketVal {
+    pub fn append(&mut self, val: PacketVal) {
+        match self {
+            PacketVal::list(l) => l.push(val),
+            _ => panic!("Cannot append to a scalar!")
+        }
+    }
+
+    fn lst_to_lst(left: &Vec<PacketVal>, other: &Vec<PacketVal>, skip_check: bool) -> Cmp {
+        for (l, r) in left.iter().zip(other.iter()) {
+            match l.lt(r) {
+                Cmp::good => return Cmp::good,
+                Cmp::bad => return Cmp::bad,
+                Cmp::idk => continue,
+            };
+        } 
+
+        if left.len() < other.len() {
+            return Cmp::good
+        } else if left.len() == other.len() {
+            // println!("moo");
+            return Cmp::idk
+        } else {
+            return Cmp::bad
+        }
+    }
+
+    fn list_cmp(left: &Vec<PacketVal>, other: &PacketVal) -> Cmp {
+        match other {
+            PacketVal::list(l) => PacketVal::lst_to_lst(left, l, false),
+            PacketVal::scalar(s) => PacketVal::lst_to_lst(left, &[PacketVal::scalar(*s)].to_vec(), true)
+        }
+    }
+
+    fn scalar_cmp(s: u32, other: &PacketVal) -> Cmp {
+        match other {
+            PacketVal::scalar(r) => if s < *r { Cmp::good } else if s == *r { Cmp::idk } else { Cmp::bad },
+            PacketVal::list(l) => PacketVal::lst_to_lst(&[PacketVal::scalar(s)].to_vec(), l, true),
+        }
+    }
+
+    fn lt(&self, other: &PacketVal) -> Cmp { 
+        match &self {
+            &PacketVal::scalar(s) => PacketVal::scalar_cmp(*s, other),
+            &PacketVal::list(l) => PacketVal::list_cmp(l, other),
+        } 
+    }
+}
+
+
+pub fn parse_line(line: &str) -> PacketVal {
+    let mut pack_stack: Vec<PacketVal> = Vec::new();
+    let mut char = line.chars().peekable();
+
+    while let Some(curr_char) = char.next() {
+        if curr_char == '[' {
+            pack_stack.push(PacketVal::list(Vec::new()));
+        } else if curr_char == ']' {
+            let popped = pack_stack.pop().unwrap();
+            if pack_stack.len() == 0 {
+                return popped;
+            }
+            pack_stack.last_mut().unwrap().append(popped);
+        } else if curr_char.is_digit(10) {
+            if char.peek().unwrap() == &'0' {
+                pack_stack.last_mut().unwrap().append(PacketVal::scalar(10));
+                char.next();
+            } else {
+                let digi = curr_char.to_digit(10).unwrap();
+                let pv = PacketVal::scalar(digi);
+                let mut thing = pack_stack.pop().unwrap();
+                thing.append(pv);
+                pack_stack.push(thing);
+            }
+        } else if curr_char == ',' {
+            continue;
+        }
+    }
+    unreachable!()
+}
+
+pub fn part_one(input: &str) -> Option<u32> {
+    let mut lines = input.lines();
+    let mut count = 0;
+    let mut idx = 1;
+    
+    loop {
+        let left_line = lines.next().unwrap();
+        let left = parse_line(left_line);
+        // println!("l: {:?}", left);
+        let right_line = lines.next().unwrap();
+        let right = parse_line(right_line);
+        // println!("r: {:?}", right);
+
+        match left.lt(&right) {
+            Cmp::good => count += idx,
+            Cmp::bad => {},
+            Cmp::idk => println!("yo idx {} is weird", idx)
+        }
+
+        idx += 1;
+        match lines.next() {
+            Some(_) => continue,
+            _ => break
+        }
+    }
+    
+    Some(count)
+}
+
+pub fn part_two(input: &str) -> Option<u32> {
+    None
+}
+
+fn main() {
+    let input = &advent_of_code::read_file("inputs", 13);
+    advent_of_code::solve!(1, part_one, input);
+    advent_of_code::solve!(2, part_two, input);
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_part_one() {
+        let input = advent_of_code::read_file("examples", 13);
+        assert_eq!(part_one(&input), Some(13));
+    }
+
+    #[test]
+    fn test_part_two() {
+        let input = advent_of_code::read_file("examples", 13);
+        assert_eq!(part_two(&input), None);
+    }
+}

+ 23 - 0
src/examples/13.txt

@@ -0,0 +1,23 @@
+[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]