Complete day 3

This commit is contained in:
Tyler Hallada 2021-12-03 01:04:07 -05:00
parent 51251ea83e
commit 87fdd366ca
5 changed files with 1138 additions and 0 deletions

8
Cargo.lock generated
View File

@ -27,3 +27,11 @@ dependencies = [
"anyhow",
"common",
]
[[package]]
name = "day03"
version = "0.1.0"
dependencies = [
"anyhow",
"common",
]

10
crates/day03/Cargo.toml Normal file
View File

@ -0,0 +1,10 @@
[package]
name = "day03"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
anyhow = "1.0"
common = { path = "../common" }

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,12 @@
00100
11110
10110
10111
10101
01111
00111
11100
10000
11001
00010
01010

108
crates/day03/src/main.rs Normal file
View File

@ -0,0 +1,108 @@
use anyhow::{anyhow, Result};
use common::instrument;
const INPUT: &str = include_str!("input/input.txt");
fn get_most_common(lines: &[&str]) -> Vec<usize> {
let mut most_common = vec![0; lines[0].len()];
for line in lines.iter() {
let chars = line.chars();
for (i, c) in chars.enumerate() {
if c == '1' {
most_common[i] += 1;
}
}
}
return most_common;
}
fn solve_part1(input: &str) -> Result<i32> {
let lines: Vec<&str> = input.trim().lines().collect();
let most_common = get_most_common(&lines);
let mut gamma = 0;
let mut epsilon = 0;
for (i, c) in most_common.into_iter().enumerate() {
if i > 0 {
gamma <<= 1;
epsilon <<= 1;
}
if c > (lines.len() / 2) {
gamma |= 1;
} else {
epsilon |= 1;
}
}
Ok(gamma * epsilon)
}
fn solve_part2(input: &str) -> Result<i32> {
let lines: Vec<&str> = input.trim().lines().collect();
let mut oxygen = lines.clone();
let mut co2 = lines.clone();
for i in 0..lines[0].len() {
let oxygen_most_common = get_most_common(&oxygen);
let co2_most_common = get_most_common(&co2);
if oxygen.len() > 1 {
if oxygen_most_common[i] as f32 >= (oxygen.len() as f32 / 2.0) {
oxygen = oxygen
.into_iter()
.filter(|l| l.chars().nth(i).unwrap() == '1')
.collect();
} else {
oxygen = oxygen
.into_iter()
.filter(|l| l.chars().nth(i).unwrap() == '0')
.collect();
}
}
if co2.len() > 1 {
if co2_most_common[i] as f32 >= (co2.len() as f32 / 2.0) {
co2 = co2
.into_iter()
.filter(|l| l.chars().nth(i).unwrap() == '0')
.collect();
} else {
co2 = co2
.into_iter()
.filter(|l| l.chars().nth(i).unwrap() == '1')
.collect();
}
}
if oxygen.len() == 1 && co2.len() == 1 {
return Ok(i32::from_str_radix(oxygen[0], 2)? * i32::from_str_radix(co2[0], 2)?);
}
}
Err(anyhow!("No ratings found"))
}
fn main() {
instrument!(solve_part1(INPUT).unwrap(), solve_part2(INPUT).unwrap());
}
#[cfg(test)]
mod tests {
use super::*;
const TEST_INPUT: &str = include_str!("input/test.txt");
#[test]
fn solves_part1() {
assert_eq!(solve_part1(TEST_INPUT).unwrap(), 198);
}
#[test]
fn solves_part2() {
assert_eq!(solve_part2(TEST_INPUT).unwrap(), 230);
}
}