Skip to content

Commit

Permalink
add day14
Browse files Browse the repository at this point in the history
  • Loading branch information
mirsella committed Dec 14, 2023
1 parent 8a8c5d3 commit 4eeede2
Show file tree
Hide file tree
Showing 5 changed files with 162 additions and 1 deletion.
2 changes: 1 addition & 1 deletion 2023/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ members = [
"day11",
"day12",
"day13",
# "day14",
"day14",
# "day15",
# "day16",
# "day17",
Expand Down
19 changes: 19 additions & 0 deletions 2023/day14/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
input.txt
flamegraph.svg
perf.data*
### Rust
# Generated by Cargo
# will have compiled files and executables
debug/
target/

# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock

# These are backup files generated by rustfmt
**/*.rs.bk

# MSVC Windows builds of rustc generate these, which store debugging information
*.pdb

11 changes: 11 additions & 0 deletions 2023/day14/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "day14"
authors = ["mirsella <[email protected]>"]
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]

grid = { git = "https://github.com/mirsella/grid" }
28 changes: 28 additions & 0 deletions 2023/day14/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
use std::fs::File;
use std::io::{self, Read};
use std::path::PathBuf;
use std::{env, fs};

fn replace_in_file(file_path: &PathBuf, old: &str, new: &str) -> io::Result<()> {
let mut contents = String::new();
File::open(file_path)?.read_to_string(&mut contents)?;
let new_contents = contents.replace(old, new);
if contents != new_contents {
println!("Updating {}", file_path.display());
fs::write(file_path, new_contents)?;
}
Ok(())
}

fn main() -> io::Result<()> {
let pkg_name = env::var("CARGO_PKG_NAME").unwrap();
replace_in_file(
&"../Cargo.toml".into(),
&format!("# \"{pkg_name}\""),
&format!("\"{pkg_name}\""),
)?;

replace_in_file(&"./Cargo.toml".into(), "\n[workspace]", "")?;

Ok(())
}
103 changes: 103 additions & 0 deletions 2023/day14/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
use std::collections::HashMap;

use grid::Grid;

fn slide_up(col: &mut [&mut char]) {
let mut hard: isize = -1;
let mut last: isize = 0;
for i in 0..col.len() {
match col[i] {
'#' => {
hard = i as isize;
last = 0;
}
'O' => {
*col[i] = '.';
*col[(hard + last + 1) as usize] = 'O';
last += 1;
}
_ => (),
}
}
}

fn calculate_weight<'a>(col: impl Iterator<Item = &'a char>, row_len: usize) -> usize {
col.enumerate().fold(
0,
|acc, (i, &c)| {
if c == 'O' {
acc + (row_len - i)
} else {
acc
}
},
)
}

fn part1(input: &str) -> usize {
let vec = input.chars().filter(|&c| c != '\n').collect::<Vec<_>>();
let mut grid = Grid::from_vec(vec, input.find('\n').unwrap());
(0..grid.cols())
.map(|i| {
let mut col = grid.iter_col_mut(i).collect::<Vec<_>>();
slide_up(col.as_mut_slice());
calculate_weight(grid.iter_col(i), grid.cols())
})
.sum()
}
fn part2(input: &str, cycle: usize) -> usize {
let vec = input.chars().filter(|&c| c != '\n').collect::<Vec<_>>();
let mut grid = Grid::from_vec(vec, input.find('\n').unwrap());
let mut map = HashMap::with_capacity(1000);
let mut count = 0;
let (spins, cycle_len) = loop {
count += 1;
for _ in 0..4 {
// FIX: 99% performance loss on this loop
(0..grid.cols())
.for_each(|i| slide_up(grid.iter_col_mut(i).collect::<Vec<_>>().as_mut_slice()));
grid.rotate_right();
}
if let Some(dup) = map.insert(grid.iter().copied().collect::<Vec<_>>(), count) {
break (count, count - dup);
}
};
let spins_left = (cycle - spins) % cycle_len;
for _ in 0..spins_left {
for _ in 0..4 {
(0..grid.cols())
.for_each(|i| slide_up(grid.iter_col_mut(i).collect::<Vec<_>>().as_mut_slice()));
grid.rotate_right();
}
}
(0..grid.cols())
.map(|i| calculate_weight(grid.iter_col(i), grid.cols()))
.sum()
}
fn main() {
let input = include_str!("../input.txt");
println!("Part 1: {}", part1(input));
println!("Part 2: {}", part2(input, 1000000000));
}

#[cfg(test)]
mod tests {
const INPUT: &str = "O....#....
O.OO#....#
.....##...
OO.#O....O
.O.....O#.
O.#..O.#.#
..O..#O..O
.......O..
#....###..
#OO..#....";
#[test]
fn part1() {
assert_eq!(super::part1(INPUT), 136);
}
#[test]
fn part2() {
assert_eq!(super::part2(INPUT, 1000000000), 64);
}
}

0 comments on commit 4eeede2

Please sign in to comment.