day4: optimized

This commit is contained in:
Ishan Jain 2023-12-04 13:25:47 +05:30
parent 5ffe28fab3
commit 780171280f
Signed by: ishan
GPG Key ID: 0506DB2A1CC75C27
4 changed files with 91 additions and 63 deletions

16
Cargo.lock generated
View File

@ -12,7 +12,6 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
name = "aoc2023"
version = "0.1.0"
dependencies = [
"fxhash",
"ureq",
]
@ -22,12 +21,6 @@ version = "0.21.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9"
[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "cc"
version = "1.0.83"
@ -71,15 +64,6 @@ dependencies = [
"percent-encoding",
]
[[package]]
name = "fxhash"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
dependencies = [
"byteorder",
]
[[package]]
name = "getrandom"
version = "0.2.11"

View File

@ -17,7 +17,6 @@ codegen-units = 16
rpath = false
[dependencies]
fxhash = "0.2.1"
ureq = { version = "2.9.1" }

View File

@ -1,8 +1,5 @@
#![feature(slice_split_once)]
#![feature(test)]
use fxhash::FxHashSet;
extern crate test;
const INPUTS: [&[u8]; 2] = [
@ -11,9 +8,8 @@ const INPUTS: [&[u8]; 2] = [
];
fn process(data: &[u8]) -> u64 {
let mut win_num = FxHashSet::default();
let mut total = 0;
for data in data.split(|&x| x == b'\n') {
if data.is_empty() {
continue;
@ -22,25 +18,26 @@ fn process(data: &[u8]) -> u64 {
let (_, nums) = data.split_once(|&x| x == b':').unwrap();
let (nums, wins) = nums.split_once(|&x| x == b'|').unwrap();
let nums = nums.split(|&x| x == b' ');
let wins = wins.split(|&x| x == b' ');
for win in wins {
let mut bit_map = BitMap::new();
for win in wins.split(|&x| x == b' ') {
if win.is_empty() {
continue;
}
let win = parse(win);
win_num.insert(win);
bit_map.set(win);
}
let mut val = 0;
for num in nums {
for num in nums.split(|&x| x == b' ') {
if num.is_empty() {
continue;
}
let num = parse(num);
if win_num.contains(&num) {
if bit_map.get(num) {
if val == 0 {
val = 1;
} else {
@ -50,20 +47,36 @@ fn process(data: &[u8]) -> u64 {
}
total += val;
win_num.clear();
}
total
}
struct BitMap(u128);
impl BitMap {
#[inline]
pub const fn new() -> Self {
Self(0)
}
#[inline]
pub fn set(&mut self, idx: usize) {
debug_assert!(idx < 128);
self.0 |= 1 << idx;
}
#[inline]
pub const fn get(&self, idx: usize) -> bool {
debug_assert!(idx < 128);
(self.0 >> idx) & 1 == 1
}
}
#[inline]
fn parse(b: &[u8]) -> u64 {
fn parse(b: &[u8]) -> usize {
let mut out = 0;
let mut pow = 1;
for c in b.iter().rev() {
out += (c - b'0') as u64 * pow;
out += (c - b'0') as usize * pow;
pow *= 10;
}

View File

@ -1,73 +1,105 @@
#![feature(test)]
#![feature(slice_split_once)]
use std::collections::HashSet;
extern crate test;
const INPUTS: [&str; 2] = [include_str!("./sample.txt"), include_str!("./input.txt")];
const INPUTS: [&[u8]; 2] = [
include_bytes!("./sample.txt"),
include_bytes!("./input.txt"),
];
fn process(data: &str) -> u64 {
fn process(data: &[u8]) -> usize {
let mut cards = vec![];
let mut total = 0;
for data in data.lines() {
let (x, nums) = data.split_once(':').unwrap();
for data in data.split(|&x| x == b'\n') {
if data.is_empty() {
continue;
}
let (x, nums) = data.split_once(|&x| x == b':').unwrap();
let v = x.split_at(4).1.trim();
let id = v.parse::<usize>().unwrap();
let id = parse(&x[5..]);
let (nums, wins) = nums.split_once('|').unwrap();
let nums: Vec<&str> = nums.split(' ').collect();
let wins: Vec<&str> = wins.split(' ').collect();
let (nums, wins) = nums.split_once(|&x| x == b'|').unwrap();
let nums = nums.split(|&x| x == b' ');
let wins = wins.split(|&x| x == b' ');
let mut card = vec![];
let mut win = HashSet::new();
let mut card = BitMap::new();
let mut win = BitMap::new();
for num in nums {
if num.is_empty() {
continue;
}
let num = num.parse::<u64>().unwrap();
let num = parse(num);
card.push(num);
card.set(num);
}
for w in wins {
if w.is_empty() {
continue;
}
let num = w.parse::<u64>().unwrap();
win.insert(num);
let num = parse(w);
win.set(num);
}
cards.push((id, card, win));
}
let mut stack: Vec<(usize, Vec<u64>, HashSet<u64>)> = cards.iter().rev().cloned().collect();
let mut counter = vec![1; cards.len() + 1];
counter[0] = 0;
let mut count = vec![0; cards.len() + 1];
while let Some((id, card, wins)) = stack.pop() {
for (id, card, wins) in cards.into_iter() {
let mut sum = 0;
for c in card {
if wins.contains(&c) {
for c in 0..100 {
if card.get(c) && wins.get(c) {
sum += 1;
}
}
count[id] += 1;
for i in id..id + sum {
stack.push(cards[i].clone())
let cid = counter[id];
for c in counter.iter_mut().skip(id + 1).take(sum) {
*c += cid;
}
}
for c in count.iter().skip(1) {
total += c;
counter.into_iter().sum::<usize>()
}
#[derive(Clone)]
struct BitMap(u128);
impl BitMap {
#[inline]
pub const fn new() -> Self {
Self(0)
}
#[inline]
pub fn set(&mut self, idx: usize) {
debug_assert!(idx < 128);
self.0 |= 1 << idx;
}
#[inline]
pub const fn get(&self, idx: usize) -> bool {
debug_assert!(idx < 128);
(self.0 >> idx) & 1 == 1
}
}
#[inline]
fn parse(b: &[u8]) -> usize {
let mut out = 0;
let mut pow = 1;
for c in b.iter().rev() {
if !c.is_ascii_digit() {
continue;
}
out += (c - b'0') as usize * pow;
pow *= 10;
}
println!("{:?}", count);
total
out
}
fn main() {