Started with aoc 2015, unable to make d4 part2 faster. Multi-threaded actually slower
This commit is contained in:
parent
ae00eb4f80
commit
8370d27bea
9
Cargo.lock
generated
9
Cargo.lock
generated
@ -2,9 +2,18 @@
|
|||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 4
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "md5"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "y2015"
|
name = "y2015"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"md5",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "y2016"
|
name = "y2016"
|
||||||
|
@ -4,3 +4,4 @@ version = "0.1.0"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
md5 = "0.7.0"
|
||||||
|
1
y2015/resources/1_input.txt
Normal file
1
y2015/resources/1_input.txt
Normal file
File diff suppressed because one or more lines are too long
1000
y2015/resources/2_input.txt
Normal file
1000
y2015/resources/2_input.txt
Normal file
File diff suppressed because it is too large
Load Diff
1
y2015/resources/3_input.txt
Normal file
1
y2015/resources/3_input.txt
Normal file
File diff suppressed because one or more lines are too long
20
y2015/src/bin/d1.rs
Normal file
20
y2015/src/bin/d1.rs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
use std::fs;
|
||||||
|
|
||||||
|
use y2015::days::d1;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
part1();
|
||||||
|
part2();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part1() {
|
||||||
|
let root = env!("CARGO_MANIFEST_DIR");
|
||||||
|
let content = fs::read_to_string(format!("{root}/resources/1_input.txt")).unwrap();
|
||||||
|
println!("{}", d1::process_part1(&content));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part2() {
|
||||||
|
let root = env!("CARGO_MANIFEST_DIR");
|
||||||
|
let content = fs::read_to_string(format!("{root}/resources/1_input.txt")).unwrap();
|
||||||
|
println!("{}", d1::process_part2(&content));
|
||||||
|
}
|
20
y2015/src/bin/d2.rs
Normal file
20
y2015/src/bin/d2.rs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
use std::fs;
|
||||||
|
|
||||||
|
use y2015::days::d2;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
part1();
|
||||||
|
part2();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part1() {
|
||||||
|
let root = env!("CARGO_MANIFEST_DIR");
|
||||||
|
let content = fs::read_to_string(format!("{root}/resources/2_input.txt")).unwrap();
|
||||||
|
println!("{}", d2::process_part1(&content));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part2() {
|
||||||
|
let root = env!("CARGO_MANIFEST_DIR");
|
||||||
|
let content = fs::read_to_string(format!("{root}/resources/2_input.txt")).unwrap();
|
||||||
|
println!("{}", d2::process_part2(&content));
|
||||||
|
}
|
20
y2015/src/bin/d3.rs
Normal file
20
y2015/src/bin/d3.rs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
use std::fs;
|
||||||
|
|
||||||
|
use y2015::days::d3;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
part1();
|
||||||
|
part2();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part1() {
|
||||||
|
let root = env!("CARGO_MANIFEST_DIR");
|
||||||
|
let content = fs::read_to_string(format!("{root}/resources/3_input.txt")).unwrap();
|
||||||
|
println!("{}", d3::process_part1(&content));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part2() {
|
||||||
|
let root = env!("CARGO_MANIFEST_DIR");
|
||||||
|
let content = fs::read_to_string(format!("{root}/resources/3_input.txt")).unwrap();
|
||||||
|
println!("{}", d3::process_part2(&content));
|
||||||
|
}
|
20
y2015/src/bin/d4.rs
Normal file
20
y2015/src/bin/d4.rs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
use std::time::Instant;
|
||||||
|
|
||||||
|
use y2015::days::d4;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
part1();
|
||||||
|
part2();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part1() {
|
||||||
|
let now = Instant::now();
|
||||||
|
println!("{}", d4::process_part1("bgvyzdsv"));
|
||||||
|
println!("{}µs", now.elapsed().as_micros());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part2() {
|
||||||
|
let now = Instant::now();
|
||||||
|
println!("{}", d4::process_part2("bgvyzdsv"));
|
||||||
|
println!("{}µs", now.elapsed().as_micros());
|
||||||
|
}
|
74
y2015/src/days/d1.rs
Normal file
74
y2015/src/days/d1.rs
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
use core::panic;
|
||||||
|
|
||||||
|
pub fn process_part1(input: &str) -> i32 {
|
||||||
|
input
|
||||||
|
.chars()
|
||||||
|
.map(|char| {
|
||||||
|
if char == '(' {
|
||||||
|
1
|
||||||
|
} else if char == ')' {
|
||||||
|
-1
|
||||||
|
} else if char == '\n' {
|
||||||
|
0
|
||||||
|
} else {
|
||||||
|
panic!("Expected '(' or ')'")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.sum()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn process_part2(input: &str) -> i32 {
|
||||||
|
let mut floor = 0;
|
||||||
|
let mut pos = 0;
|
||||||
|
for char in input.chars() {
|
||||||
|
pos += 1;
|
||||||
|
if char == '(' {
|
||||||
|
floor += 1;
|
||||||
|
} else if char == ')' {
|
||||||
|
floor += -1;
|
||||||
|
} else if char == '\n' {
|
||||||
|
floor += 0;
|
||||||
|
} else {
|
||||||
|
panic!("Expected '(' or ')'")
|
||||||
|
}
|
||||||
|
if floor == -1 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pos
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests_1 {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn it_works() {
|
||||||
|
let result = process_part1("(())");
|
||||||
|
assert_eq!(result, 0);
|
||||||
|
let result = process_part1("(())");
|
||||||
|
assert_eq!(result, 0);
|
||||||
|
let result = process_part1("(((");
|
||||||
|
assert_eq!(result, 3);
|
||||||
|
let result = process_part1("(()(()(");
|
||||||
|
assert_eq!(result, 3);
|
||||||
|
let result = process_part1("))(((((");
|
||||||
|
assert_eq!(result, 3);
|
||||||
|
let result = process_part1("())");
|
||||||
|
assert_eq!(result, -1);
|
||||||
|
let result = process_part1("))(");
|
||||||
|
assert_eq!(result, -1);
|
||||||
|
let result = process_part1(")))");
|
||||||
|
assert_eq!(result, -3);
|
||||||
|
let result = process_part1(")())())");
|
||||||
|
assert_eq!(result, -3);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part2() {
|
||||||
|
let result = process_part2(")(())))(");
|
||||||
|
assert_eq!(result, 1);
|
||||||
|
let result = process_part2("()()))))");
|
||||||
|
assert_eq!(result, 5);
|
||||||
|
}
|
||||||
|
}
|
57
y2015/src/days/d2.rs
Normal file
57
y2015/src/days/d2.rs
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
pub fn process_part1(input: &str) -> i64 {
|
||||||
|
input
|
||||||
|
.lines()
|
||||||
|
.map(|line| {
|
||||||
|
line.split("x")
|
||||||
|
.map(|dimension| dimension.parse::<i64>().unwrap())
|
||||||
|
.collect::<Vec<i64>>()
|
||||||
|
})
|
||||||
|
.map(|dimension| {
|
||||||
|
let squares = (
|
||||||
|
dimension[0] * dimension[1],
|
||||||
|
dimension[0] * dimension[2],
|
||||||
|
dimension[1] * dimension[2],
|
||||||
|
);
|
||||||
|
squares.0.min(squares.1).min(squares.2) + squares.0 * 2 + squares.1 * 2 + squares.2 * 2
|
||||||
|
})
|
||||||
|
.sum()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn process_part2(input: &str) -> i64 {
|
||||||
|
input
|
||||||
|
.lines()
|
||||||
|
.map(|line| {
|
||||||
|
line.split("x")
|
||||||
|
.map(|dimension| dimension.parse::<i64>().unwrap())
|
||||||
|
.collect::<Vec<i64>>()
|
||||||
|
})
|
||||||
|
.map(|dimension| {
|
||||||
|
let bow = dimension[0] * dimension[1] * dimension[2];
|
||||||
|
let ribbon = {
|
||||||
|
let largest = dimension[0].max(dimension[1]).max(dimension[2]);
|
||||||
|
dimension[0] * 2 + dimension[1] * 2 + dimension[2] * 2 - largest * 2
|
||||||
|
};
|
||||||
|
bow + ribbon
|
||||||
|
})
|
||||||
|
.sum()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests_2 {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
const INPUT: &str = "2x3x4
|
||||||
|
1x1x10";
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn it_works() {
|
||||||
|
let result = process_part1(INPUT);
|
||||||
|
assert_eq!(result, 101);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part2() {
|
||||||
|
let result = process_part2(INPUT);
|
||||||
|
assert_eq!(result, 48);
|
||||||
|
}
|
||||||
|
}
|
111
y2015/src/days/d3.rs
Normal file
111
y2015/src/days/d3.rs
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
use core::panic;
|
||||||
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
pub fn process_part1(input: &str) -> i64 {
|
||||||
|
let mut visited_coords = HashSet::new();
|
||||||
|
let mut last_coord = (0, 0);
|
||||||
|
visited_coords.insert(last_coord);
|
||||||
|
input.chars().for_each(|char| {
|
||||||
|
if char == '^' {
|
||||||
|
last_coord.1 += 1;
|
||||||
|
visited_coords.insert(last_coord);
|
||||||
|
} else if char == '>' {
|
||||||
|
last_coord.0 += 1;
|
||||||
|
visited_coords.insert(last_coord);
|
||||||
|
} else if char == '<' {
|
||||||
|
last_coord.0 -= 1;
|
||||||
|
visited_coords.insert(last_coord);
|
||||||
|
} else if char == 'v' {
|
||||||
|
last_coord.1 -= 1;
|
||||||
|
visited_coords.insert(last_coord);
|
||||||
|
} else if char == '\n' {
|
||||||
|
println!("The end");
|
||||||
|
} else {
|
||||||
|
panic!("Could not parse direction");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
visited_coords.len() as i64
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn process_part2(input: &str) -> i64 {
|
||||||
|
let mut visited_coords = HashSet::new();
|
||||||
|
let mut last_coord = (0, 0);
|
||||||
|
let mut is_robot = false;
|
||||||
|
let mut last_robo_coord = (0, 0);
|
||||||
|
visited_coords.insert(last_coord);
|
||||||
|
input.chars().for_each(|char| {
|
||||||
|
if is_robot {
|
||||||
|
if char == '^' {
|
||||||
|
last_robo_coord.1 += 1;
|
||||||
|
visited_coords.insert(last_robo_coord);
|
||||||
|
} else if char == '>' {
|
||||||
|
last_robo_coord.0 += 1;
|
||||||
|
visited_coords.insert(last_robo_coord);
|
||||||
|
} else if char == '<' {
|
||||||
|
last_robo_coord.0 -= 1;
|
||||||
|
visited_coords.insert(last_robo_coord);
|
||||||
|
} else if char == 'v' {
|
||||||
|
last_robo_coord.1 -= 1;
|
||||||
|
visited_coords.insert(last_robo_coord);
|
||||||
|
} else if char == '\n' {
|
||||||
|
println!("The end");
|
||||||
|
} else {
|
||||||
|
panic!("Could not parse direction");
|
||||||
|
}
|
||||||
|
} else if char == '^' {
|
||||||
|
last_coord.1 += 1;
|
||||||
|
visited_coords.insert(last_coord);
|
||||||
|
} else if char == '>' {
|
||||||
|
last_coord.0 += 1;
|
||||||
|
visited_coords.insert(last_coord);
|
||||||
|
} else if char == '<' {
|
||||||
|
last_coord.0 -= 1;
|
||||||
|
visited_coords.insert(last_coord);
|
||||||
|
} else if char == 'v' {
|
||||||
|
last_coord.1 -= 1;
|
||||||
|
visited_coords.insert(last_coord);
|
||||||
|
} else if char == '\n' {
|
||||||
|
println!("The end");
|
||||||
|
} else {
|
||||||
|
panic!("Could not parse direction");
|
||||||
|
}
|
||||||
|
is_robot = !is_robot;
|
||||||
|
});
|
||||||
|
visited_coords.len() as i64
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests_3 {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
const INPUT: &str = ">
|
||||||
|
^v
|
||||||
|
^>v<
|
||||||
|
^v^v^v^v^v";
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn it_works() {
|
||||||
|
let mut lines = INPUT.lines();
|
||||||
|
let result = process_part1(lines.next().unwrap());
|
||||||
|
assert_eq!(result, 2);
|
||||||
|
let result = process_part1(lines.next().unwrap());
|
||||||
|
assert_eq!(result, 2);
|
||||||
|
let result = process_part1(lines.next().unwrap());
|
||||||
|
assert_eq!(result, 4);
|
||||||
|
let result = process_part1(lines.next().unwrap());
|
||||||
|
assert_eq!(result, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part2() {
|
||||||
|
let mut lines = INPUT.lines();
|
||||||
|
let result = process_part2(lines.next().unwrap());
|
||||||
|
assert_eq!(result, 2);
|
||||||
|
let result = process_part2(lines.next().unwrap());
|
||||||
|
assert_eq!(result, 3);
|
||||||
|
let result = process_part2(lines.next().unwrap());
|
||||||
|
assert_eq!(result, 3);
|
||||||
|
let result = process_part2(lines.next().unwrap());
|
||||||
|
assert_eq!(result, 11);
|
||||||
|
}
|
||||||
|
}
|
72
y2015/src/days/d4.rs
Normal file
72
y2015/src/days/d4.rs
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
use std::{
|
||||||
|
sync::{mpsc, Arc, Mutex},
|
||||||
|
thread,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn process_part1(input: &str) -> i64 {
|
||||||
|
let mut n = 1;
|
||||||
|
loop {
|
||||||
|
let hash = md5::compute(format!("{input}{n}"));
|
||||||
|
let hash = format!("{hash:x}");
|
||||||
|
if hash.split_at(5).0 == "00000" {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
n += 1;
|
||||||
|
}
|
||||||
|
n
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn process_part2(input: &str) -> i64 {
|
||||||
|
let threads = thread::available_parallelism().unwrap().get();
|
||||||
|
|
||||||
|
let found = Arc::new(Mutex::new(false));
|
||||||
|
|
||||||
|
let (tx, rx) = mpsc::channel();
|
||||||
|
thread::scope(|s| {
|
||||||
|
for thread in 0..threads {
|
||||||
|
let tx_clone = tx.clone();
|
||||||
|
let found_clone = found.clone();
|
||||||
|
s.spawn(move || {
|
||||||
|
let mut n = thread + 1;
|
||||||
|
loop {
|
||||||
|
{
|
||||||
|
if *found_clone.lock().unwrap() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let hash = md5::compute(format!("{input}{n}"));
|
||||||
|
let hash = format!("{hash:x}");
|
||||||
|
if hash.split_at(6).0 == "000000" {
|
||||||
|
let _ = tx_clone.send(n);
|
||||||
|
let mut found_guard = found_clone.lock().unwrap();
|
||||||
|
*found_guard = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
n += 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
drop(tx);
|
||||||
|
let mut res = vec![];
|
||||||
|
while let Ok(n) = rx.recv() {
|
||||||
|
res.push(n);
|
||||||
|
}
|
||||||
|
*res.iter().min().unwrap() as i64
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests_4 {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
const INPUT1: &str = "abcdef";
|
||||||
|
const INPUT2: &str = "pqrstuv";
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn it_works() {
|
||||||
|
let result = process_part1(INPUT1);
|
||||||
|
assert_eq!(result, 609043);
|
||||||
|
let result = process_part1(INPUT2);
|
||||||
|
assert_eq!(result, 1048970);
|
||||||
|
}
|
||||||
|
}
|
4
y2015/src/days/mod.rs
Normal file
4
y2015/src/days/mod.rs
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
pub mod d1;
|
||||||
|
pub mod d2;
|
||||||
|
pub mod d3;
|
||||||
|
pub mod d4;
|
@ -0,0 +1 @@
|
|||||||
|
pub mod days;
|
Loading…
Reference in New Issue
Block a user