this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

solutions: clean up impl

Use macro to generate day boilerplate

+117 -62
+66
src/solutions/day.rs
··· 1 + // pub trait Day { 2 + // type Parsed; 3 + // fn parse(input: &str) -> Self::Parsed; 4 + // fn part1(data: &Self::Parsed) -> i64; 5 + // fn part2(data: &Self::Parsed) -> i64; 6 + // } 7 + 8 + // #[macro_export] 9 + // macro_rules! day { 10 + // ($name:ident, $num:literal) => { 11 + // pub struct $name; 12 + 13 + // impl $name { 14 + // pub fn run(test: bool) -> (i64, i64) { 15 + // let raw = if test { 16 + // include_str!(concat!("../../inputs/", $num, ".test")) 17 + // } else { 18 + // include_str!(concat!("../../inputs/", $num, ".txt")) 19 + // }; 20 + // let parsed = <Self as Day>::parse(raw); 21 + // (<Self as Day>::part1(&parsed), <Self as Day>::part2(&parsed)) 22 + // } 23 + // } 24 + // }; 25 + // } 26 + 27 + pub trait Day: Sized { 28 + type Parsed; 29 + fn parse(input: &'static str) -> Self::Parsed; 30 + fn part1(&self) -> i64; 31 + fn part2(&self) -> i64; 32 + } 33 + 34 + #[macro_export] 35 + macro_rules! day { 36 + ($name:ident, $num:literal, $parsed:ty) => { 37 + pub struct $name { 38 + data: $parsed, 39 + } 40 + 41 + impl $name { 42 + pub fn new(test: bool) -> Self { 43 + let raw = if test { 44 + include_str!(concat!("../../inputs/", $num, ".test")) 45 + } else { 46 + include_str!(concat!("../../inputs/", $num, ".txt")) 47 + }; 48 + Self { 49 + data: <Self as Day>::parse(raw), 50 + } 51 + } 52 + } 53 + }; 54 + } 55 + 56 + // day!(Day2, "2", Vec<(i64, i64)>); 57 + 58 + // impl Day for Day2 { 59 + // type Parsed = Vec<(i64, i64)>; 60 + // fn parse(input: &str) -> Self::Parsed { /* ... */ 61 + // } 62 + // fn part1(&self) -> i64 { /* uses self.data */ 63 + // } 64 + // fn part2(&self) -> i64 { /* uses self.data */ 65 + // } 66 + // }
+17 -18
src/solutions/day1.rs
··· 1 - use std::fs; 1 + use super::Day; 2 + use crate::day; 2 3 3 - pub struct Day1 { 4 - data: String, 5 - } 4 + day!(Day1, 1, Vec<&'static str>); 6 5 7 6 struct Result { 8 - sum: i32, 9 - times_crossed: i32, 7 + sum: i64, 8 + times_crossed: i64, 10 9 } 11 10 12 - impl Day1 { 13 - pub fn new(path: &str) -> Self { 14 - Day1 { 15 - data: fs::read_to_string(path).expect("failed to read input file"), 16 - } 11 + impl Day for Day1 { 12 + type Parsed = Vec<&'static str>; 13 + 14 + fn parse(input: &'static str) -> Self::Parsed { 15 + input.lines().collect() 17 16 } 18 17 19 - pub fn part1(&self) -> i32 { 18 + fn part1(&self) -> i64 { 20 19 self.data 21 - .lines() 20 + .iter() 22 21 .fold( 23 22 Result { 24 23 sum: 50, 25 24 times_crossed: 0, 26 25 }, 27 26 |mut acc, line| { 28 - let n: i32 = line[1..].parse().unwrap(); 27 + let n = line[1..].parse::<i64>().unwrap(); 29 28 acc.sum += if &line[..1] == "L" { -n } else { n }; 30 29 acc.sum = acc.sum.rem_euclid(100); 31 30 acc.times_crossed += if acc.sum == 0 { 1 } else { 0 }; ··· 35 34 .times_crossed 36 35 } 37 36 38 - pub fn part2(&self) -> i32 { 37 + fn part2(&self) -> i64 { 39 38 self.data 40 - .lines() 39 + .iter() 41 40 .fold( 42 41 Result { 43 42 sum: 50, 44 43 times_crossed: 0, 45 44 }, 46 45 |mut acc, line| { 47 - let n: i32 = line[1..].parse().unwrap(); 46 + let n = line[1..].parse::<i64>().unwrap(); 48 47 let old = acc.sum; 49 48 acc.sum += if &line[..1] == "L" { -n } else { n }; 50 - acc.times_crossed += (old > 0 && acc.sum < 0) as i32; 49 + acc.times_crossed += (old > 0 && acc.sum < 0) as i64; 51 50 acc.times_crossed += if acc.sum == 0 { 52 51 1 53 52 } else {
+32 -44
src/solutions/day2.rs
··· 1 - use std::fs; 1 + use super::Day; 2 + use crate::day; 2 3 3 - pub struct Day2 { 4 - data: String, 4 + fn invalid_id(n: &i64) -> bool { 5 + let s = n.to_string(); 6 + s.len() % 2 == 0 && s[..s.len() / 2] == s[s.len() / 2..] 5 7 } 6 8 7 - fn divisors_desc(n: usize) -> impl Iterator<Item = usize> { 8 - (1..n).rev().filter(move |&i| n % i == 0) 9 + fn new_invalid_id(n: &i64) -> bool { 10 + let s = n.to_string(); 11 + let b = s.as_bytes(); 12 + (1..s.len()) 13 + .rev() 14 + .filter(|&d| s.len() % d == 0) 15 + .any(|d| b.chunks(d).all(|c| c == &b[..d])) 9 16 } 10 17 11 - fn invalid_id(id: &i64) -> bool { 12 - let str_id = id.to_string(); 13 - if str_id.len() % 2 != 0 { 14 - return false; 15 - } 16 - let (left, right) = str_id.split_at(str_id.len() / 2); 17 - left == right 18 - } 18 + day!(Day2, 2, Vec<(i64, i64)>); 19 19 20 - fn new_invalid_id(id: &i64) -> bool { 21 - let str_id = id.to_string(); 22 - for div in divisors_desc(str_id.len()) { 23 - let chars = str_id.chars().collect::<Vec<char>>(); 24 - let seqs = chars.chunks(div).collect::<Vec<_>>(); 25 - if seqs.iter().all(|&seq| seq == seqs[0]) { 26 - return true; 27 - } 28 - } 29 - false 30 - } 20 + impl Day for Day2 { 21 + type Parsed = Vec<(i64, i64)>; 31 22 32 - impl Day2 { 33 - pub fn new(path: &str) -> Self { 34 - Self { 35 - data: fs::read_to_string(path).expect("failed to read input file"), 36 - } 23 + fn parse(input: &'static str) -> Self::Parsed { 24 + input 25 + .split(',') 26 + .map(|range| { 27 + let (n1, n2) = range.split_once('-').unwrap(); 28 + let (n1, n2) = (n1.parse::<i64>().unwrap(), n2.parse::<i64>().unwrap()); 29 + (n1, n2) 30 + }) 31 + .collect() 37 32 } 38 - 39 - pub fn part1(&self) -> i64 { 40 - self.data.split(',').fold(0, |acc, range| { 41 - let (n1, n2) = range.split_once('-').unwrap(); 42 - println!("Range: {}-{}", n1, n2); 43 - let (n1, n2) = (n1.parse::<i64>().unwrap(), n2.parse::<i64>().unwrap()); 44 - println!("Range: {}-{}", n1, n2); 45 - (n1..=n2).filter(|x| invalid_id(x)).sum::<i64>() + acc 33 + // 19386344315 34 + fn part1(&self) -> i64 { 35 + self.data.iter().fold(0, |acc, (n1, n2)| { 36 + (*n1..=*n2).filter(|x| invalid_id(x)).sum::<i64>() + acc 46 37 }) 47 38 } 48 39 49 - pub fn part2(&self) -> i64 { 50 - self.data.split(',').fold(0, |acc, range| { 51 - let (n1, n2) = range.split_once('-').unwrap(); 52 - println!("Range: {}-{}", n1, n2); 53 - let (n1, n2) = (n1.parse::<i64>().unwrap(), n2.parse::<i64>().unwrap()); 54 - println!("Range: {}-{}", n1, n2); 55 - (n1..=n2).filter(|x| new_invalid_id(x)).sum::<i64>() + acc 40 + // 34421651192 41 + fn part2(&self) -> i64 { 42 + self.data.iter().fold(0, |acc, (n1, n2)| { 43 + (*n1..=*n2).filter(|x| new_invalid_id(x)).sum::<i64>() + acc 56 44 }) 57 45 } 58 46 }
+2
src/solutions/mod.rs
··· 1 + pub mod day; 1 2 pub mod day1; 2 3 pub mod day2; 4 + pub use day::Day; 3 5 pub use day1::Day1; 4 6 pub use day2::Day2;