Day 13, puzzle 1
This commit is contained in:
		
							
								
								
									
										14
									
								
								src/bin/d13p1.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/bin/d13p1.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					use aoc22::{day13, util};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn main() {
 | 
				
			||||||
 | 
					    let pairs = day13::parse_pairs(&util::parse_input());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let mut sum = 0;
 | 
				
			||||||
 | 
					    for (i, pair) in pairs.iter().enumerate() {
 | 
				
			||||||
 | 
					        if pair.0 < pair.1 {
 | 
				
			||||||
 | 
					            sum += i + 1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    println!("Sum of indices of pairs in right order: {}", sum);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										116
									
								
								src/day13.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								src/day13.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,116 @@
 | 
				
			|||||||
 | 
					use std::cmp::Ordering;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use itertools::{EitherOrBoth, Itertools};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Debug)]
 | 
				
			||||||
 | 
					pub enum Node {
 | 
				
			||||||
 | 
					    List(Vec<Node>),
 | 
				
			||||||
 | 
					    Num(usize),
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl PartialOrd for Node {
 | 
				
			||||||
 | 
					    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
 | 
				
			||||||
 | 
					        match self {
 | 
				
			||||||
 | 
					            Node::List(l1) => match other {
 | 
				
			||||||
 | 
					                Node::Num(n2) => self.partial_cmp(&Node::List(vec![Node::Num(*n2)])),
 | 
				
			||||||
 | 
					                Node::List(l2) => {
 | 
				
			||||||
 | 
					                    for pair in l1.iter().zip_longest(l2.iter()) {
 | 
				
			||||||
 | 
					                        match pair {
 | 
				
			||||||
 | 
					                            EitherOrBoth::Both(n1, n2) => {
 | 
				
			||||||
 | 
					                                if n1 < n2 {
 | 
				
			||||||
 | 
					                                    return Some(Ordering::Less);
 | 
				
			||||||
 | 
					                                } else if n2 < n1 {
 | 
				
			||||||
 | 
					                                    return Some(Ordering::Greater);
 | 
				
			||||||
 | 
					                                }
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            EitherOrBoth::Left(_) => return Some(Ordering::Greater),
 | 
				
			||||||
 | 
					                            EitherOrBoth::Right(_) => return Some(Ordering::Less),
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    Some(Ordering::Equal)
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            Node::Num(n1) => match other {
 | 
				
			||||||
 | 
					                Node::Num(n2) => n1.partial_cmp(n2),
 | 
				
			||||||
 | 
					                Node::List(_) => Node::List(vec![Node::Num(*n1)]).partial_cmp(other),
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl PartialEq for Node {
 | 
				
			||||||
 | 
					    fn eq(&self, other: &Self) -> bool {
 | 
				
			||||||
 | 
					        self.partial_cmp(other) == Some(Ordering::Equal)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn ne(&self, other: &Self) -> bool {
 | 
				
			||||||
 | 
					        !self.eq(other)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn parse_pairs(input: &String) -> Vec<(Node, Node)> {
 | 
				
			||||||
 | 
					    let mut result = Vec::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for mut p in &input.lines().chunks(3) {
 | 
				
			||||||
 | 
					        let first = parse_list(p.next().unwrap()).0;
 | 
				
			||||||
 | 
					        let second = parse_list(p.next().unwrap()).0;
 | 
				
			||||||
 | 
					        assert!(p.next().unwrap_or("").is_empty());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        result.push((first, second));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    result
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum ParseState {
 | 
				
			||||||
 | 
					    Idle,
 | 
				
			||||||
 | 
					    InNumber,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn parse_list(line: &str) -> (Node, usize) {
 | 
				
			||||||
 | 
					    assert_eq!(line.chars().next(), Some('['));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let mut state = ParseState::Idle;
 | 
				
			||||||
 | 
					    let mut i = 1;
 | 
				
			||||||
 | 
					    let mut result = Vec::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let mut num_start = 0;
 | 
				
			||||||
 | 
					    while i < line.len() {
 | 
				
			||||||
 | 
					        let c = line.chars().nth(i).unwrap();
 | 
				
			||||||
 | 
					        match state {
 | 
				
			||||||
 | 
					            ParseState::Idle => {
 | 
				
			||||||
 | 
					                if c == '[' {
 | 
				
			||||||
 | 
					                    let (n, inc) = parse_list(&line[i..]);
 | 
				
			||||||
 | 
					                    result.push(n);
 | 
				
			||||||
 | 
					                    i += inc;
 | 
				
			||||||
 | 
					                } else if c == ']' {
 | 
				
			||||||
 | 
					                    // End of list reached
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                } else if c.is_numeric() {
 | 
				
			||||||
 | 
					                    num_start = i;
 | 
				
			||||||
 | 
					                    state = ParseState::InNumber;
 | 
				
			||||||
 | 
					                } else if c != ',' {
 | 
				
			||||||
 | 
					                    panic!("Unknown char: {}", c);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            ParseState::InNumber => {
 | 
				
			||||||
 | 
					                if c == ',' {
 | 
				
			||||||
 | 
					                    let slice = &line[num_start..i];
 | 
				
			||||||
 | 
					                    result.push(Node::Num(slice.parse().unwrap()));
 | 
				
			||||||
 | 
					                    state = ParseState::Idle;
 | 
				
			||||||
 | 
					                } else if c == ']' {
 | 
				
			||||||
 | 
					                    // End of list reached
 | 
				
			||||||
 | 
					                    let slice = &line[num_start..i];
 | 
				
			||||||
 | 
					                    result.push(Node::Num(slice.parse().unwrap()));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                } else if !c.is_numeric() {
 | 
				
			||||||
 | 
					                    panic!("Unknown digit {}", c);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        i += 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    (Node::List(result), i)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -2,6 +2,7 @@ pub mod day1;
 | 
				
			|||||||
pub mod day10;
 | 
					pub mod day10;
 | 
				
			||||||
pub mod day11;
 | 
					pub mod day11;
 | 
				
			||||||
pub mod day12;
 | 
					pub mod day12;
 | 
				
			||||||
 | 
					pub mod day13;
 | 
				
			||||||
pub mod day2;
 | 
					pub mod day2;
 | 
				
			||||||
pub mod day3;
 | 
					pub mod day3;
 | 
				
			||||||
pub mod day4;
 | 
					pub mod day4;
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user