Day 13 part 1

Omg I had the answer ages ago but was counting them instead of adding indexes loooool kill me
This commit is contained in:
Daniel Flanagan 2022-12-15 14:33:35 -06:00
parent ca848fe338
commit 1c4d83196a
Signed by: lytedev
GPG Key ID: 5B2020A0F9921EF4
1 changed files with 201 additions and 0 deletions

201
2022/rust/src/day13.rs Normal file
View File

@ -0,0 +1,201 @@
use std::cmp::Ordering;
use std::str::FromStr;
mod common;
#[derive(Debug, Eq)]
enum Packet {
Num(i32),
List(Box<Vec<Packet>>),
}
#[derive(Debug)]
enum ParsePacketError {
EndOfList,
EndOfString,
}
impl FromStr for Packet {
type Err = ParsePacketError;
fn from_str(orig: &str) -> Result<Self, Self::Err> {
println!("orig: {}", orig);
match orig.chars().next() {
Some('[') => {
let contents = &orig[1..orig.len() - 1];
let mut chunks = vec![];
let mut chunk_start = 0;
// this is dumb. I should be able to recurse this crap but my brain must be fried
let mut nest_level = 0;
for (i, c) in contents.char_indices() {
match c {
'[' => nest_level += 1,
']' => nest_level -= 1,
',' => {
if nest_level == 0 {
chunks.push(&contents[chunk_start..i]);
chunk_start = i + 1;
}
}
_ => {}
}
}
if chunk_start < contents.len() {
chunks.push(&contents[chunk_start..]);
}
println!("{:?}", chunks);
Ok(Self::List(Box::new(
chunks
.iter()
.map(|s| s.parse::<Packet>().unwrap())
.collect(),
)))
}
Some(_) => Ok(Self::Num(orig.parse::<i32>().unwrap())),
None => Err(ParsePacketError::EndOfString),
}
}
}
impl Ord for Packet {
fn cmp(&self, other: &Self) -> Ordering {
println!("comparing {:?} with {:?}", self, other);
match (self, other) {
(Self::Num(l), Self::Num(r)) => l.cmp(r),
(Self::List(l), Self::List(r)) => {
for (l, r) in std::iter::zip(l.iter(), r.iter()) {
match l.cmp(r) {
Ordering::Equal => continue,
v => {
println!("done: {:?}", v);
return v;
}
}
}
l.len().cmp(&r.len())
}
(Self::Num(l), r) => Self::List(Box::new(vec![Self::Num(*l)])).cmp(r),
(l, Self::Num(r)) => l.cmp(&Self::List(Box::new(vec![Self::Num(*r)]))),
}
}
}
impl PartialOrd for Packet {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl PartialEq for Packet {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(Self::Num(l), Self::Num(r)) => l == r,
(Self::List(l), Self::List(r)) => {
l.len() == r.len() && l.iter().zip(r.iter()).all(|(l, r)| l == r)
}
(Self::Num(_), Self::List(_)) => false,
(Self::List(_), Self::Num(_)) => false,
}
}
}
#[derive(Debug)]
struct PacketPair {
left: Packet,
right: Packet,
}
type Input = Vec<PacketPair>;
type Answer = usize;
fn processed_input(input: &str) -> Input {
input
.split("\n\n")
.map(|c| {
let mut l = c.lines();
let result = PacketPair {
left: l.next().unwrap().parse::<Packet>().unwrap(),
right: l.next().unwrap().parse::<Packet>().unwrap(),
};
println!("{:?}", result);
return result;
})
.collect::<Vec<PacketPair>>()
}
fn part1(input: &Input) -> Answer {
let mut sum = 0;
let mut i = 1;
for pair in input {
if pair.left < pair.right {
sum += i
}
i += 1
}
sum
}
fn part2(input: &Input) -> Answer {
0
}
fn main() {
let input_text = common::day_input(13);
eprintln!("{}\n\nAbove is your input file.\n\n", input_text);
let input = processed_input(&input_text);
common::show_answers(&part1(&input), &part2(&input))
// common::show_both_answers(&both_parts(&input))
}
// fn both_parts(input: &Input) -> (Answer, Answer) {
// (0, 0)
// }
#[cfg(test)]
mod tests {
use super::*;
const TEST_INPUT: &str = "[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]";
#[test]
fn test() {
let mut v = vec![Packet::Num(1), Packet::Num(0)];
v.sort();
assert_eq!(v, vec![Packet::Num(0), Packet::Num(1)]);
assert!("[1,1,3,1]".parse::<Packet>().unwrap() < "[1,1,5,1]".parse::<Packet>().unwrap());
assert_eq!(
"[[8,7,6]]".parse::<Packet>().unwrap(),
Packet::List(Box::new(vec![Packet::List(Box::new(vec![
Packet::Num(8),
Packet::Num(7),
Packet::Num(6)
]))]))
);
let input = processed_input(TEST_INPUT);
assert_eq!(part1(&input), 13);
assert_eq!(part2(&input), 0);
// assert_eq!(both_parts(&input), (0, 0));
}
}