diff options
| author | omagdy7 <omar.professional8777@gmail.com> | 2023-04-14 00:25:59 +0200 |
|---|---|---|
| committer | omagdy7 <omar.professional8777@gmail.com> | 2023-04-14 00:25:59 +0200 |
| commit | 0a507d6986d220b56c8e55c55b71fa7c4d560993 (patch) | |
| tree | 8f1b9e8a3305db220a172258028c80d3a1db5557 /2022/Rust/src | |
| parent | 9d0923ac49cc92eb1e75a07dcb6a8a274d144360 (diff) | |
| download | aoc-0a507d6986d220b56c8e55c55b71fa7c4d560993.tar.xz aoc-0a507d6986d220b56c8e55c55b71fa7c4d560993.zip | |
Day13 done in rust
Diffstat (limited to '2022/Rust/src')
| -rw-r--r-- | 2022/Rust/src/day13.rs | 153 | ||||
| -rwxr-xr-x | 2022/Rust/src/day3.rs | 2 | ||||
| -rwxr-xr-x | 2022/Rust/src/day4.rs | 4 | ||||
| -rwxr-xr-x | 2022/Rust/src/day5.rs | 4 |
4 files changed, 158 insertions, 5 deletions
diff --git a/2022/Rust/src/day13.rs b/2022/Rust/src/day13.rs new file mode 100644 index 0000000..b07e515 --- /dev/null +++ b/2022/Rust/src/day13.rs @@ -0,0 +1,153 @@ +use std::{cmp::Ordering, fmt, str::FromStr}; + +#[derive(PartialEq, Eq, Clone)] +enum ListItem { + List(Vec<ListItem>), + Number(usize), +} + +impl fmt::Debug for ListItem { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + ListItem::List(arr) => f.debug_list().entries(arr.iter()).finish(), + ListItem::Number(num) => write!(f, "{}", num), + } + } +} + +impl ListItem { + fn with_slice<T>(&self, f: impl FnOnce(&[ListItem]) -> T) -> T { + match self { + Self::List(n) => f(&n[..]), + Self::Number(n) => f(&[Self::Number(*n)]), + } + } +} + +impl std::cmp::Ord for ListItem { + fn cmp(&self, other: &Self) -> Ordering { + self.partial_cmp(other).unwrap() + } +} + +impl PartialOrd for ListItem { + fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { + match (self, other) { + (ListItem::Number(a), ListItem::Number(b)) => a.partial_cmp(b), + (l, r) => l.with_slice(|l| r.with_slice(|r| l.partial_cmp(r))), + } + } +} + +impl FromStr for ListItem { + type Err = String; + + fn from_str(input: &str) -> Result<Self, Self::Err> { + // Remove whitespace from input + let input = input.trim(); + + // Check if input is empty + if input.is_empty() { + return Ok(ListItem::List(vec![])); + } + + // Check if input is a number + if let Ok(num) = input.parse::<usize>() { + return Ok(ListItem::Number(num)); + } + + // Check if input is a list + if input.starts_with('[') && input.ends_with(']') { + // Remove brackets from input + let input = &input[1..input.len() - 1]; + + // Split input by commas + let mut items = Vec::new(); + let mut start = 0; + let mut level = 0; + for (i, c) in input.char_indices() { + match c { + '[' => level += 1, + ']' => level -= 1, + ',' if level == 0 => { + // Parse a list item + let item = ListItem::from_str(&input[start..i])?; + items.push(item); + start = i + 1; + } + _ => {} + } + } + // Parse the last list item + let item = ListItem::from_str(&input[start..])?; + items.push(item); + + return Ok(ListItem::List(items)); + } + + // Invalid input + Err("Invalid input".to_string()) + } +} + +type Packet = ListItem; + +#[derive(Debug)] +struct PacketPair { + left: Packet, + right: Packet, +} + +// [[1],[2,3,4]] +fn solve_part_one(data: &str) -> usize { + let packets_pairs: Vec<&str> = data.split("\n\n").collect(); + let mut packets: Vec<PacketPair> = vec![]; + for pair in packets_pairs { + let (first, last) = pair + .split_once("\n") + .expect("Should be splittable by newline"); + let first = ListItem::from_str(first).unwrap(); + let last = ListItem::from_str(last).unwrap(); + packets.push(PacketPair { + left: first, + right: last, + }); + } + let mut ans = 0; + for (i, pair) in packets.iter().enumerate() { + if pair.left < pair.right { + ans += i + 1; + } + } + ans +} + +fn solve_part_two(data: &str) -> usize { + let dividers = vec![ + Packet::List(vec![Packet::Number(2)]), + Packet::List(vec![Packet::Number(6)]), + ]; + + let mut packets = data + .lines() + .filter(|s| !s.is_empty()) + .map(|line| Packet::from_str(line).unwrap()) + .chain(dividers.iter().cloned()) + .collect::<Vec<_>>(); + + packets.sort(); + + dividers + .iter() + .map(|d| packets.binary_search(d).unwrap() + 1) + .product::<usize>() +} + +fn main() { + let test = include_str!("../input/day13.test"); + let prod = include_str!("../input/day13.prod"); + println!("Part1_test : {}", solve_part_one(test)); + println!("Part1_prod : {}", solve_part_one(prod)); + println!("{}", solve_part_two(test)); + println!("{}", solve_part_two(prod)); +} diff --git a/2022/Rust/src/day3.rs b/2022/Rust/src/day3.rs index 8a6c289..1b0d258 100755 --- a/2022/Rust/src/day3.rs +++ b/2022/Rust/src/day3.rs @@ -45,7 +45,7 @@ fn solve_part_two(data: &str) -> u32 { } fn main() { - let data = include_str!("../data/day3.prod"); + let data = include_str!("../input/day3.prod"); println!("{}", solve_part_one(data)); println!("{}", solve_part_two(data)); } diff --git a/2022/Rust/src/day4.rs b/2022/Rust/src/day4.rs index ca50935..0dbc3dc 100755 --- a/2022/Rust/src/day4.rs +++ b/2022/Rust/src/day4.rs @@ -59,8 +59,8 @@ fn solve_part_two(data: &str) -> u32 { } fn main() { - let data_test = include_str!("../data/day4.test"); - let data_prod = include_str!("../data/day4.prod"); + let data_test = include_str!("../input/day4.test"); + let data_prod = include_str!("../input/day4.prod"); println!("{}", solve_part_one(data_test)); println!("{}", solve_part_two(data_test)); println!("{}", solve_part_one(data_prod)); diff --git a/2022/Rust/src/day5.rs b/2022/Rust/src/day5.rs index d344ddd..b9fe68f 100755 --- a/2022/Rust/src/day5.rs +++ b/2022/Rust/src/day5.rs @@ -183,8 +183,8 @@ fn solve_part_two(data: &str) -> String { } fn main() { - let data_test = include_str!("../data/day5.test"); - let data_prod = include_str!("../data/day5.prod"); + let data_test = include_str!("../input/day5.test"); + let data_prod = include_str!("../input/day5.prod"); println!("part one test: {}", solve_part_one(data_test)); println!("part one prod: {}", solve_part_one(data_prod)); |
