This commit is contained in:
Stefan Schwarz 2020-12-02 13:07:28 +01:00
parent 77e9d3eb96
commit 7daf5a0294
4 changed files with 1130 additions and 13 deletions

View file

@ -7,8 +7,14 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
alloc_counter = "0.0.4"
anyhow = "1.0" anyhow = "1.0"
itertools = "0.9"
[[bin]] [[bin]]
name = "day01" name = "day01"
path = "src/day01/main.rs" path = "src/day01/main.rs"
[[bin]]
name = "day02"
path = "src/day02/main.rs"

1000
input02 Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,33 +1,29 @@
use anyhow::Result; use anyhow::Result;
use std::io::prelude::*;
use std::io::stdin; static INPUT: &str = include_str!("../../input01");
fn main() -> Result<()> { fn main() -> Result<()> {
let nums: Vec<i64> = stdin() let nums: Vec<i64> = INPUT
.lock()
.lines() .lines()
.map(|line| { .map(|line| line.parse::<i64>().expect("input is not a number"))
line.expect("unable to read input")
.parse::<i64>()
.expect("input is not a number")
})
.collect(); .collect();
'outer: for a in nums.iter() {
'outer2: for a in nums.iter() {
for b in nums.iter() { for b in nums.iter() {
if a + b == 2020 { if a + b == 2020 {
println!("{} + {} = 2020", a, b); println!("{} + {} = 2020", a, b);
println!("product: {}", a * b); println!("product: {}", a * b);
break 'outer; break 'outer2;
} }
} }
} }
'outer: for a in nums.iter() { 'outer3: for a in nums.iter() {
for b in nums.iter() { for b in nums.iter() {
for c in nums.iter() { for c in nums.iter() {
if a + b + c == 2020 { if a + b + c == 2020 {
println!("{} + {} + {} = 2020", a, b, c); println!("{} + {} + {} = 2020", a, b, c);
println!("product: {}", a * b * c); println!("product: {}", a * b * c);
break 'outer; break 'outer3;
} }
} }
} }

115
src/day02/main.rs Normal file
View file

@ -0,0 +1,115 @@
use alloc_counter::{count_alloc, AllocCounterSystem};
use anyhow::Result;
#[global_allocator]
static A: AllocCounterSystem = AllocCounterSystem;
static INPUT: &str = include_str!("../../input02");
fn main() -> Result<()> {
println!("validating...");
let (cnt, _) = count_alloc(|| {
let cnt = INPUT.lines().filter_map(validate_1).count();
println!("part1: {} results are valid", cnt);
let cnt = INPUT.lines().filter_map(validate_2).count();
println!("part2: {} results are valid", cnt);
});
println!("{:?} allocations", cnt);
Ok(())
}
fn validate_1(input: &str) -> Option<()> {
let mut input = Splitter::from(input);
let min = input
.get_before('-')?
.parse::<usize>()
.expect("invalid input");
input.skip();
let max = input
.get_before(' ')?
.parse::<usize>()
.expect("invalid input");
input.skip();
let c = input.get_before(':')?.chars().next()?;
input.skip();
input.skip();
let input = &*input;
let count = input.chars().filter(|&iter_c| iter_c == c).count();
if count >= min && count <= max {
return Some(());
}
None
}
fn validate_2(input: &str) -> Option<()> {
let mut splitter = Splitter::from(input);
let correct = splitter
.get_before('-')
.expect("invalid input")
.parse::<usize>()
.expect("invalid input");
splitter.skip();
let incorrect = splitter
.get_before(' ')
.expect("invalid input")
.parse::<usize>()
.expect("invalid input");
splitter.skip();
let c = splitter
.get_before(':')
.expect("invalid input")
.chars()
.next()
.expect("invalid input");
splitter.skip();
splitter.skip();
let splitter = &*splitter;
let a = splitter.chars().nth(correct - 1).expect("invalid input") == c;
let b = splitter.chars().nth(incorrect - 1).expect("invalid input") == c;
if a as usize + b as usize == 1 {
return Some(());
}
None
}
struct Splitter<'a> {
inner: Option<&'a str>,
}
impl<'a> From<&'a str> for Splitter<'a> {
fn from(inner: &'a str) -> Self {
Splitter { inner: Some(inner) }
}
}
impl<'a> std::ops::Deref for Splitter<'a> {
type Target = str;
fn deref(&self) -> &Self::Target {
match self.inner {
Some(inner) => inner,
None => "",
}
}
}
impl<'a> Splitter<'a> {
fn get_before(&mut self, r: char) -> Option<&'a str> {
let inner = self.inner?;
if let Some(pos) = inner.find(r) {
let (before, after) = inner.split_at(pos);
self.inner = Some(after);
Some(before)
} else {
self.inner = None;
Some(inner)
}
}
fn skip(&mut self) {
self.inner = match self.inner {
Some(inner) => Some(&inner[1..]),
None => None,
};
}
}