1
0

Refactoring, Added day9

This commit is contained in:
Ishan Jain 2022-12-12 01:17:01 +05:30
parent 28a57f0ff7
commit 5f243befac
Signed by: ishan
GPG Key ID: 0506DB2A1CC75C27
5 changed files with 2217 additions and 0 deletions

94
src/day9/1.rs Normal file
View File

@ -0,0 +1,94 @@
#![feature(byte_slice_trim_ascii)]
#![feature(test)]
use std::collections::HashSet;
extern crate test;
const INPUTS: [&[u8]; 2] = [
include_bytes!("./sample1.txt"),
include_bytes!("./input.txt"),
];
#[derive(Debug)]
enum Move {
R(usize),
L(usize),
U(usize),
D(usize),
}
fn parse(input: &[u8]) -> impl Iterator<Item = Move> + '_ {
input.trim_ascii().split(|&c| c == b'\n').map(|line| {
let (a, b) = line.split_at(1);
let b = b
.iter()
.skip(1)
.fold(0, |a, x| (a * 10) + (x - b'0') as usize);
match &a {
[b'R'] => Move::R(b),
[b'L'] => Move::L(b),
[b'U'] => Move::U(b),
[b'D'] => Move::D(b),
_ => unreachable!(),
}
})
}
fn main() {
for input in INPUTS.iter() {
let output = parse(input);
let score = solution(output);
println!("{}", score);
}
}
fn solution(input: impl Iterator<Item = Move>) -> usize {
let (mut sxh, mut syh) = (0, 0);
let (mut sxt, mut syt) = (0, 0);
let mut set = HashSet::with_capacity(5000);
for mmove in input {
let (steps, (dsxh, dsyh)): (usize, (i32, i32)) = match mmove {
Move::R(v) => (v, (1, 0)),
Move::L(v) => (v, (-1, 0)),
Move::U(v) => (v, (0, -1)),
Move::D(v) => (v, (0, 1)),
};
for _ in 0..steps {
sxh += dsxh;
syh += dsyh;
(sxt, syt) = move_tail((sxh, syh), (sxt, syt));
set.insert((sxt, syt));
}
}
set.len()
}
#[inline]
const fn move_tail((sxh, syh): (i32, i32), (sxt, syt): (i32, i32)) -> (i32, i32) {
let dx = sxh - sxt;
let dy = syh - syt;
if dx.abs() == 2 || dy.abs() == 2 {
(sxt + dx.signum(), syt + dy.signum())
} else {
(sxt, syt)
}
}
#[bench]
fn solution_bench(b: &mut test::Bencher) {
b.iter(|| {
let input = parse(INPUTS[1]);
let result = solution(input);
test::black_box(result);
})
}

107
src/day9/2.rs Normal file
View File

@ -0,0 +1,107 @@
#![feature(byte_slice_trim_ascii)]
#![feature(test)]
extern crate test;
use std::collections::HashSet;
const INPUTS: [&[u8]; 2] = [
include_bytes!("./sample.txt"),
include_bytes!("./input.txt"),
];
#[derive(Debug)]
enum Move {
R(u8),
L(u8),
U(u8),
D(u8),
}
fn parse(input: &[u8]) -> Vec<Move> {
input
.trim_ascii()
.split(|&c| c == b'\n')
.map(|line| {
let (a, b) = line.split_at(1);
let b = b.iter().skip(1).fold(0, |a, x| (a * 10) + (x - b'0'));
match &a {
[b'R'] => Move::R(b),
[b'L'] => Move::L(b),
[b'U'] => Move::U(b),
[b'D'] => Move::D(b),
_ => unreachable!(),
}
})
.collect()
}
fn main() {
for input in INPUTS.iter() {
let output = parse(input);
let score = solution(output);
println!("{}", score);
}
}
fn solution(input: Vec<Move>) -> usize {
let mut locs = [(0, 0); 10];
let mut set: HashSet<(i32, i32)> = HashSet::with_capacity_and_hasher(3000, Default::default());
set.insert((0, 0));
for mmove in input {
let (steps, (dsxh, dsyh)) = match mmove {
Move::R(v) => (v, (1, 0)),
Move::L(v) => (v, (-1, 0)),
Move::U(v) => (v, (0, -1)),
Move::D(v) => (v, (0, 1)),
};
let locs9 = locs[9];
for _ in 0..steps {
// Update Head position
locs[0].0 += dsxh;
locs[0].1 += dsyh;
// One by one, Updated position of each knot
for i in 1..10 {
let loci = move_tail(locs[i - 1], locs[i]);
if loci == locs[i] {
break;
}
locs[i] = loci;
}
if locs9 != locs[9] {
set.insert(locs[9]);
}
}
}
set.len()
}
#[inline]
const fn move_tail((sxh, syh): (i32, i32), (sxt, syt): (i32, i32)) -> (i32, i32) {
let dx = sxh - sxt;
let dy = syh - syt;
if dx.abs() == 2 || dy.abs() == 2 {
// signum gets you 1 or -1 depending on the sign of number
(sxt + dx.signum(), syt + dy.signum())
} else {
(sxt, syt)
}
}
#[bench]
fn solution_bench(b: &mut test::Bencher) {
b.iter(|| {
let input = parse(INPUTS[1]);
let result = solution(input);
test::black_box(result);
})
}

2000
src/day9/input.txt Normal file

File diff suppressed because it is too large Load Diff

8
src/day9/sample.txt Normal file
View File

@ -0,0 +1,8 @@
R 5
U 8
L 8
D 3
R 17
D 10
L 25
U 20

8
src/day9/sample1.txt Normal file
View File

@ -0,0 +1,8 @@
R 4
U 4
L 3
D 1
R 4
D 1
L 5
R 2