aoc day2
This commit is contained in:
parent
77e9d3eb96
commit
7daf5a0294
4 changed files with 1130 additions and 13 deletions
|
@ -7,8 +7,14 @@ edition = "2018"
|
|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
alloc_counter = "0.0.4"
|
||||
anyhow = "1.0"
|
||||
itertools = "0.9"
|
||||
|
||||
[[bin]]
|
||||
name = "day01"
|
||||
path = "src/day01/main.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "day02"
|
||||
path = "src/day02/main.rs"
|
||||
|
|
|
@ -1,33 +1,29 @@
|
|||
use anyhow::Result;
|
||||
use std::io::prelude::*;
|
||||
use std::io::stdin;
|
||||
|
||||
static INPUT: &str = include_str!("../../input01");
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let nums: Vec<i64> = stdin()
|
||||
.lock()
|
||||
let nums: Vec<i64> = INPUT
|
||||
.lines()
|
||||
.map(|line| {
|
||||
line.expect("unable to read input")
|
||||
.parse::<i64>()
|
||||
.expect("input is not a number")
|
||||
})
|
||||
.map(|line| line.parse::<i64>().expect("input is not a number"))
|
||||
.collect();
|
||||
'outer: for a in nums.iter() {
|
||||
|
||||
'outer2: for a in nums.iter() {
|
||||
for b in nums.iter() {
|
||||
if a + b == 2020 {
|
||||
println!("{} + {} = 2020", 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 c in nums.iter() {
|
||||
if a + b + c == 2020 {
|
||||
println!("{} + {} + {} = 2020", a, b, c);
|
||||
println!("product: {}", a * b * c);
|
||||
break 'outer;
|
||||
break 'outer3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
115
src/day02/main.rs
Normal file
115
src/day02/main.rs
Normal 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,
|
||||
};
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue