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.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "md5"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771"
|
||||
|
||||
[[package]]
|
||||
name = "y2015"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"md5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "y2016"
|
||||
|
@ -4,3 +4,4 @@ version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[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