1
0
Fork 0

Added Day 3 Part 1

This commit is contained in:
Ishan Jain 2021-12-03 11:08:45 +05:30
parent f11678a866
commit 53583df5e9
3 changed files with 1076 additions and 49 deletions

13
inputs/day3.sample.txt Normal file
View File

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

1003
inputs/day3.txt Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,75 +1,86 @@
#![feature(test)] #![feature(test)]
extern crate test; extern crate test;
const INPUT: &'static str = include_str!("../inputs/day2.txt"); const INPUTS: [&'static str; 2] = [
include_str!("../inputs/day3.sample.txt"),
include_str!("../inputs/day3.txt"),
];
enum Moves { fn cmds(input: &'static str) -> Vec<u64> {
Forward(i32), input
Down(i32), .lines()
Up(i32), .filter(|&x| !x.is_empty())
.map(|x| u64::from_str_radix(x, 2).unwrap())
.collect()
} }
fn cmds() -> impl Iterator<Item = Moves> { fn solution<const MAX_LINE_LENGTH: usize>(levels: &[u64]) -> i64 {
INPUT.lines().filter(|&x| !x.is_empty()).map(|x| { let dominant_mask = count_bits::<MAX_LINE_LENGTH>(&levels, true);
let mut x = x.split_ascii_whitespace();
let cmd = x.next(); let mut gamma = 0;
let val = x.next().map(|x| x.parse::<i32>()).unwrap().unwrap(); for i in (0..MAX_LINE_LENGTH).rev() {
let v = dominant_mask & (1 << i);
gamma <<= 1;
match cmd { if v > 0 {
Some("forward") => Moves::Forward(val), gamma |= 1;
Some("down") => Moves::Down(val), } else {
Some("up") => Moves::Up(val), gamma |= 0
_ => unreachable!(),
} }
}) }
let epsilon = !gamma & ((1 << MAX_LINE_LENGTH as i64) - 1);
gamma * epsilon
} }
struct Ship { fn count_bits<const LINE_LENGTH: usize>(levels: &[u64], dominant: bool) -> u64 {
aim: i32, let n = levels.len();
vert_pos: i32, let mut count = [0; LINE_LENGTH];
hor_pos: i32,
}
fn solution(moves: impl Iterator<Item = Moves>) -> i32 { for &level in levels.iter() {
let mut ship = Ship { for i in 0..LINE_LENGTH {
aim: 0, let c = level & (1 << i);
hor_pos: 0,
vert_pos: 0,
};
for mmove in moves { if c != 0 {
match mmove { count[i as usize] += 1;
Moves::Forward(v) => {
ship.hor_pos += v;
ship.vert_pos += ship.aim * v;
} }
Moves::Down(v) => ship.aim += v,
Moves::Up(v) => ship.aim -= v,
} }
} }
ship.hor_pos * ship.vert_pos let mut mask = 0;
for (i, c) in count.into_iter().enumerate() {
if c >= n - c {
mask |= 1 << i;
}
}
if dominant {
mask
} else {
!mask
}
} }
fn main() { fn main() {
let moves = cmds(); let moves = cmds(INPUTS[0]);
let count = solution(moves); let count = solution::<5>(&moves);
println!("increased {} times", count); println!("Result {}", count);
let moves = cmds(INPUTS[1]);
let count = solution::<12>(&moves);
println!("Result {}", count);
} }
#[bench] #[bench]
fn solution_bench(b: &mut test::Bencher) { fn solution_bench(b: &mut test::Bencher) {
let moves = cmds(INPUTS[1]);
b.iter(|| { b.iter(|| {
// Not ideal since we want to benchmark the function let v = solution::<12>(&moves);
// _excluding_ the time it takes to go through the input
let moves = cmds();
let v = solution(moves);
test::black_box(v); test::black_box(v);
}) })
} }
#[test] #[test]
fn solution_test() { fn solution_test() {
assert_eq!(solution(cmds()), 1463827010); assert_eq!(solution::<5>(&cmds(INPUTS[0])), 198);
assert_eq!(solution::<12>(&cmds(INPUTS[1])), 3687446);
} }