day 8 part 1 but very optimized blazingy type of thing

This commit is contained in:
nora 2024-12-08 12:07:08 +01:00
parent c6f3193aa7
commit d246992de0
8 changed files with 442 additions and 7 deletions

16
2024/Cargo.lock generated
View file

@ -179,6 +179,16 @@ dependencies = [
"nom",
]
[[package]]
name = "day08"
version = "0.1.0"
dependencies = [
"divan",
"helper",
"nom",
"smallvec",
]
[[package]]
name = "divan"
version = "0.1.16"
@ -306,6 +316,12 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "smallvec"
version = "1.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
[[package]]
name = "strsim"
version = "0.11.1"

16
2024/day08/Cargo.toml Normal file
View file

@ -0,0 +1,16 @@
[package]
name = "day08"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
nom.workspace = true
helper.workspace = true
divan.workspace = true
smallvec = "1.13.2"
[[bench]]
name = "benches"
harness = false

View file

@ -0,0 +1,3 @@
fn main() {
day08::bench();
}

50
2024/day08/input.txt Normal file
View file

@ -0,0 +1,50 @@
...............................6.B..........P.....
n..............M..................................
....n.....sM7.............................6.....p.
......................Mr......................P...
.......n.......................................p.E
.......................6...................p......
r..............................C........B....P....
.....................d........6......B4....P......
.........................7....................4...
.n......................R..............4..........
.....N........S.................K.C..........4....
...........N..r.....................B....K........
..................................................
......N.......x.............7.......K.....2....E..
...................r..H........R..................
.....................s....p........C...........2..
....3.......................M.....................
........k....................H....5...............
.....x....N................d.5..y................J
m.....................d7...................J......
.......exk........................................
.......x.............5.......R....................
..........eY......................................
...S.3..............................O.E...J.......
.......8...H....k...............J.................
......S.e.........C.H.....................X.....y.
................j..........y.........2............
...........e.........k............................
......YS...3..............5..........K...XR.......
...m..............j.s..........c..................
.........................j........................
...............j..................................
.....m................................2...........
.........Y......................................b.
..................................................
.......................h...........b..............
............m......D..............d...............
........o......D..................................
...................................O..............
..................................................
......8...........................................
........D.Y..o...................1................
.....................................b..9.........
........................h..0......................
.....o......................h..0........b1........
.........8.............X..........................
..........o..........c..........1...........O.....
....8....................y0...c...................
..............D.......c..................9..0.....
............................1..........O..9.......

View file

@ -0,0 +1,12 @@
............
........0...
.....0......
.......0....
....0.......
......A.....
............
............
........A...
.........A..
............
............

330
2024/day08/src/lib.rs Normal file
View file

@ -0,0 +1,330 @@
use helper::{Day, Variants};
pub fn main() {
helper::main::<Day08>(include_str!("../input.txt"));
}
struct Day08;
helper::define_variants! {
day => crate::Day08;
part1 {
basic => crate::part1;
asciicheck => crate::part1_asciicheck;
parsing => crate::part1_parsing;
vec_opts => crate::part1_vec_opts;
arrayvec => crate::part1_arrayvec;
}
part2 {
basic => crate::part2;
}
}
impl Day for Day08 {
fn part1() -> Variants {
part1_variants!(construct_variants)
}
fn part2() -> Variants {
part2_variants!(construct_variants)
}
}
fn part1(input: &str) -> u64 {
let mut all_antennas = vec![vec![]; 128];
let mut height = 0;
let mut width = 0;
for (row, line) in input.lines().enumerate() {
for (col, cell) in line.bytes().enumerate() {
if cell.is_ascii_alphanumeric() {
all_antennas[cell as usize].push((col, row));
}
}
width = line.len();
height += 1;
}
let mut is_antinode = vec![false; width * height];
for antennas in all_antennas {
for &a in &antennas {
for &b in &antennas {
if a == b {
continue;
}
let diff = (a.0 as i64 - b.0 as i64, a.1 as i64 - b.1 as i64);
let antinode = (a.0 as i64 + diff.0, a.1 as i64 + diff.1);
if !(0..(width as i64)).contains(&antinode.0) {
continue;
}
if !(0..(height as i64)).contains(&antinode.1) {
continue;
}
is_antinode[(antinode.0 as usize * width) + antinode.1 as usize] = true;
}
}
}
is_antinode
.iter()
.filter(|is_antinode| **is_antinode)
.count() as u64
}
fn part1_asciicheck(input: &str) -> u64 {
let mut all_antennas = vec![vec![]; 128];
let mut height = 0;
let mut width = 0;
for (row, line) in input.lines().enumerate() {
for (col, cell) in line.bytes().enumerate() {
if cell != b'.' {
all_antennas[cell as usize].push((col, row));
}
}
width = line.len();
height += 1;
}
let mut is_antinode = vec![false; width * height];
for antennas in all_antennas {
for &a in &antennas {
for &b in &antennas {
if a == b {
continue;
}
let diff = (a.0 as i64 - b.0 as i64, a.1 as i64 - b.1 as i64);
let antinode = (a.0 as i64 + diff.0, a.1 as i64 + diff.1);
if !(0..(width as i64)).contains(&antinode.0) {
continue;
}
if !(0..(height as i64)).contains(&antinode.1) {
continue;
}
is_antinode[(antinode.0 as usize * width) + antinode.1 as usize] = true;
}
}
}
is_antinode
.iter()
.filter(|is_antinode| **is_antinode)
.count() as u64
}
fn part1_parsing(input: &str) -> u64 {
let mut all_antennas = vec![vec![]; 128];
let mut width = 0;
let mut row = 0;
let mut col = 0;
for cell in input.bytes() {
if cell == b'\n' {
row += 1;
width = col;
col = 0;
} else if cell != b'.' {
all_antennas[cell as usize].push((col, row));
col += 1;
} else {
col += 1;
}
}
let height = row;
let mut is_antinode = vec![false; width * height];
for antennas in all_antennas {
for &a in &antennas {
for &b in &antennas {
if a == b {
continue;
}
let diff = (a.0 as i64 - b.0 as i64, a.1 as i64 - b.1 as i64);
let antinode = (a.0 as i64 + diff.0, a.1 as i64 + diff.1);
if !(0..(width as i64)).contains(&antinode.0) {
continue;
}
if !(0..(height as i64)).contains(&antinode.1) {
continue;
}
is_antinode[(antinode.0 as usize * width) + antinode.1 as usize] = true;
}
}
}
is_antinode
.iter()
.filter(|is_antinode| **is_antinode)
.count() as u64
}
fn part1_vec_opts(input: &str) -> u64 {
let mut all_antennas = [const { vec![] }; 256];
let mut width = 0;
let mut row = 0;
let mut col = 0;
for cell in input.bytes() {
if cell == b'\n' {
row += 1;
width = col;
col = 0;
} else if cell != b'.' {
all_antennas[cell as usize].push((col, row));
col += 1;
} else {
col += 1;
}
}
let height = row;
let mut is_antinode = vec![false; width * height];
let all_antennas = &all_antennas[b'0' as usize..b'z' as usize];
for antennas in all_antennas {
for &a in antennas {
for &b in antennas {
if a == b {
continue;
}
let diff = (a.0 as i64 - b.0 as i64, a.1 as i64 - b.1 as i64);
let antinode = (a.0 as i64 + diff.0, a.1 as i64 + diff.1);
if !(0..(width as i64)).contains(&antinode.0) {
continue;
}
if !(0..(height as i64)).contains(&antinode.1) {
continue;
}
unsafe {
*is_antinode
.get_unchecked_mut((antinode.0 as usize * width) + antinode.1 as usize) =
true;
}
}
}
}
is_antinode
.iter()
.filter(|is_antinode| **is_antinode)
.count() as u64
}
fn part1_arrayvec(input: &str) -> u64 {
type Coods = (usize, usize);
struct Arrayvec {
elems: [Coods; 8],
len: usize,
}
impl Arrayvec {
fn push(&mut self, elem: Coods) {
self.elems[self.len] = elem;
self.len += 1;
}
}
impl<'a> IntoIterator for &'a Arrayvec {
type IntoIter = std::slice::Iter<'a,Coods>;
type Item = &'a Coods;
fn into_iter(self) -> Self::IntoIter {
unsafe { self.elems.get_unchecked(0..self.len).iter() }
}
}
let mut all_antennas = [const {
Arrayvec {
elems: [(0, 0); 8],
len: 0,
}
}; 256];
let mut width = 0;
let mut row = 0;
let mut col = 0;
for cell in input.bytes() {
if cell == b'\n' {
row += 1;
width = col;
col = 0;
} else if cell != b'.' {
all_antennas[cell as usize].push((col, row));
col += 1;
} else {
col += 1;
}
}
let height = row;
let mut is_antinode = vec![false; width * height];
let all_antennas = &all_antennas[b'0' as usize..b'z' as usize];
for antennas in all_antennas {
for &a in antennas {
for &b in antennas {
if a == b {
continue;
}
let diff = (a.0 as i64 - b.0 as i64, a.1 as i64 - b.1 as i64);
let antinode = (a.0 as i64 + diff.0, a.1 as i64 + diff.1);
if !(0..(width as i64)).contains(&antinode.0) {
continue;
}
if !(0..(height as i64)).contains(&antinode.1) {
continue;
}
unsafe {
*is_antinode
.get_unchecked_mut((antinode.0 as usize * width) + antinode.1 as usize) =
true;
}
}
}
}
is_antinode
.iter()
.filter(|is_antinode| **is_antinode)
.count() as u64
}
fn part2(_input: &str) -> u64 {
0
}
helper::tests! {
day08 Day08;
part1 {
small => 14;
default => 269;
}
part2 {
small => 34;
default => 0;
}
}
helper::benchmarks! {}

3
2024/day08/src/main.rs Normal file
View file

@ -0,0 +1,3 @@
fn main() {
day08::main();
}

View file

@ -40,6 +40,11 @@ pub fn main<D: Day>(default_input: &str) -> ! {
}
fn create_variant_subcommands(mut part: Command, variants: &[Variant]) -> Command {
let iter_arg = Arg::new("iter")
.long("iter")
.value_parser(value_parser!(usize))
.default_value("1");
if variants.len() > 1 {
part = part.subcommand_required(true);
@ -49,13 +54,13 @@ fn create_variant_subcommands(mut part: Command, variants: &[Variant]) -> Comman
Command::new(v.name)
.about(format!("Run the {} variant", v.name))
.arg(Arg::new("input").short('i').long("input"))
.arg(Arg::new("iter").long("iter").value_parser(value_parser!(usize)))
.arg(iter_arg.clone())
})
.for_each(|cmd| part = part.clone().subcommand(cmd));
} else {
part = part
.arg(Arg::new("input").short('i').long("input"))
.arg(Arg::new("iter").long("iter").value_parser(value_parser!(usize)));
.arg(iter_arg);
}
part
@ -66,14 +71,14 @@ fn dispatch_root_subcommand<D: Day>(
variants: &[Variant],
matches: &ArgMatches,
) -> ! {
let iter = matches.get_one::<usize>("iter").unwrap_or(&1);
if variants.len() > 1 {
let subcommand = matches.subcommand().unwrap();
let variant = variants.iter().find(|v| v.name == subcommand.0).unwrap();
let input = get_input(subcommand.1, default_input);
let (subcommand, matches) = matches.subcommand().unwrap();
let iter = matches.get_one::<usize>("iter").unwrap();
let variant = variants.iter().find(|v| v.name == subcommand).unwrap();
let input = get_input(matches, default_input);
execute::<D>(variant, &input, *iter);
} else {
let iter = matches.get_one::<usize>("iter").unwrap();
let input = get_input(matches, default_input);
execute::<D>(&variants[0], &input, *iter);
}