day 2

kokirigla.de fe2df250 60434029

verified
Changed files
+104
src
+98
src/day2.rs
···
···
+
use anyhow::Context;
+
const INPUT: &str = include_str!("input/2/actual.txt");
+
const IS_PART_2: bool = true;
+
+
pub fn main() -> anyhow::Result<()> {
+
let ranges = parse(INPUT).context("parsing input")?;
+
+
let mut sum: u128 = 0;
+
+
for range in &ranges {
+
let range_sum = range
+
.sum_of_invalid_ids()
+
.context("summing invalid IDs for range")?;
+
sum += range_sum;
+
}
+
+
println!("TOTAL SUM OF INVALID NUMBERS IS {}", sum);
+
+
Ok(())
+
}
+
+
struct Range(u128, u128);
+
+
impl Range {
+
pub fn sum_of_invalid_ids(&self) -> anyhow::Result<u128> {
+
let mut sum: u128 = 0;
+
for n in self.0..=self.1 {
+
if (if IS_PART_2 {
+
is_invalid_pt_2(n)
+
} else {
+
is_invalid(n)
+
})
+
.context("checking invalidity")?
+
{
+
// println!("{} is invalid", n);
+
sum += n
+
} else {
+
// println!("{} is valid", n);
+
}
+
}
+
Ok(sum)
+
}
+
}
+
+
fn parse(input: &str) -> anyhow::Result<Vec<Range>> {
+
let input = input.trim();
+
let mut ranges = Vec::new();
+
input
+
.split(',')
+
.try_for_each(|raw_range| -> anyhow::Result<()> {
+
let split_raw = raw_range.split('-').collect::<Vec<&str>>();
+
let first = split_raw
+
.get(0)
+
.context("getting first")?
+
.parse::<u128>()
+
.context("parsing first")?;
+
let second = split_raw
+
.get(1)
+
.context("getting second")?
+
.parse::<u128>()
+
.context("parsing second")?;
+
ranges.push(Range(first, second));
+
Ok(())
+
})
+
.context("running loop")?;
+
Ok(ranges)
+
}
+
+
fn is_invalid_pt_2(num: u128) -> anyhow::Result<bool> {
+
let as_string = num.to_string();
+
let length = as_string.len();
+
+
for i in 1..=length / 2 {
+
if length % i != 0 {
+
continue;
+
}
+
+
let pattern = &as_string[0..i];
+
let repetitions = length / i;
+
+
if pattern.repeat(repetitions) == as_string {
+
return Ok(true);
+
}
+
}
+
+
Ok(false)
+
}
+
+
fn is_invalid(num: u128) -> anyhow::Result<bool> {
+
let as_string = num.to_string();
+
let middle = as_string.len() / 2;
+
+
let split = as_string.split_at(middle);
+
+
let (left, right) = (split.0.to_string(), split.1.to_string());
+
+
Ok(left == right)
+
}
+1
src/input/2/actual.txt
···
···
+
92916254-92945956,5454498003-5454580069,28-45,4615-7998,4747396917-4747534264,272993-389376,36290651-36423050,177-310,3246326-3418616,48-93,894714-949755,952007-1003147,3-16,632-1029,420-581,585519115-585673174,1041-1698,27443-39304,71589003-71823870,97-142,2790995-2837912,579556301-579617006,653443-674678,1515120817-1515176202,13504-20701,1896-3566,8359-13220,51924-98061,505196-638209,67070129-67263432,694648-751703,8892865662-8892912125
+1
src/input/2/example.txt
···
···
+
11-22,95-115,998-1012,1188511880-1188511890,222220-222224,1698522-1698528,446443-446449,38593856-38593862,565653-565659,824824821-824824827,2121212118-2121212124
+4
src/main.rs
···
use anyhow::Context;
mod day1;
fn main() -> anyhow::Result<()> {
println!("day 1...");
day1::main().context("running day 1")?;
Ok(())
}
···
use anyhow::Context;
mod day1;
+
mod day2;
fn main() -> anyhow::Result<()> {
println!("day 1...");
day1::main().context("running day 1")?;
+
+
println!("day 2...");
+
day2::main().context("running day2")?;
Ok(())
}