Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • main
1 result

Target

Select target project
No results found
Select Git revision
  • main
1 result
Show changes

Commits on Source 5

10 files
+ 492
2
Compare changes
  • Side-by-side
  • Inline

Files

.vscode/launch.json

0 → 100644
+45 −0
Original line number Diff line number Diff line
{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "type": "lldb",
            "request": "launch",
            "name": "Debug executable 'advent-of-code-23'",
            "cargo": {
                "args": [
                    "build",
                    "--bin=advent-of-code-23",
                    "--package=advent-of-code-23"
                ],
                "filter": {
                    "name": "advent-of-code-23",
                    "kind": "bin"
                }
            },
            "args": [],
            "cwd": "${workspaceFolder}"
        },
        {
            "type": "lldb",
            "request": "launch",
            "name": "Debug unit tests in executable 'advent-of-code-23'",
            "cargo": {
                "args": [
                    "test",
                    "--no-run",
                    "--bin=advent-of-code-23",
                    "--package=advent-of-code-23"
                ],
                "filter": {
                    "name": "advent-of-code-23",
                    "kind": "bin"
                }
            },
            "args": [],
            "cwd": "${workspaceFolder}"
        }
    ]
}
 No newline at end of file

src/day_12_1/mod.rs

0 → 100644
+72 −0
Original line number Diff line number Diff line
use std::collections::VecDeque;

pub fn solve_from_str(input: &str) -> u32 {
    input.lines().map(|line| possibilities_from_str(line)).sum()
}

fn possibilities_from_str(input: &str) -> u32 {
    let mut data = input.split(" ");
    let springs: Vec<char> = data.next().unwrap().chars().collect();
    let arrangement: VecDeque<u32> = data
        .next()
        .unwrap()
        .split(",")
        .map(|value| str::parse(value).unwrap())
        .collect();

    possibilities(&springs, &arrangement)
}

fn possibilities(springs: &Vec<char>, arrangement: &VecDeque<u32>) -> u32 {
    let mut arrangement_clone = arrangement.clone();

    let mut cluster_size = None;
    let mut space_required = false;

    for i in 0..springs.len() {
        if springs[i] == '.' {
            if cluster_size.is_none() {
                space_required = false;
            } else {
                return 0;
            }
        } else if springs[i] == '#' {
            if space_required {
                return 0;
            }

            if let Some(current) = cluster_size {
                cluster_size = Some(current - 1);
            } else {
                if let Some(next) = arrangement_clone.pop_front() {
                    cluster_size = Some(next - 1);
                } else {
                    return 0;
                }
            }

            if cluster_size == Some(0) {
                cluster_size = None;
                space_required = true;
            }
        } else if springs[i] == '?' {
            let mut possibility_0 = springs.clone();
            possibility_0[i] = '.';
            let amount_0 = possibilities(&possibility_0, arrangement);

            let mut possibility_1 = springs.clone();
            possibility_1[i] = '#';
            let amount_1 = possibilities(&possibility_1, arrangement);

            return amount_0 + amount_1;
        } else {
            panic!();
        }
    }

    if cluster_size.is_some() || !arrangement_clone.is_empty() {
        0
    } else {        
        1
    }
}

src/day_12_2/mod.rs

0 → 100644
+121 −0
Original line number Diff line number Diff line
use std::collections::VecDeque;

use rayon::iter::ParallelIterator;
use rayon::str::ParallelString;

pub fn solve_from_str(input: &str) -> u64 {
    input
        .par_lines()
        .map(|line| possibilities_from_str(line))
        .sum()
}

fn possibilities_from_str(input: &str) -> u64 {
    let mut data = input.split(" ");
    let springs_folded: Vec<char> = data.next().unwrap().chars().collect();
    let arrangement_folded: Vec<u32> = data
        .next()
        .unwrap()
        .split(",")
        .map(|value| str::parse(value).unwrap())
        .collect();

    let mut springs = springs_folded.clone();
    for _ in 0..4 {
        springs.push('?');
        springs.append(&mut springs_folded.clone());
    }

    let mut arrangement = arrangement_folded.clone();
    for _ in 0..4 {
        arrangement.append(&mut arrangement_folded.clone());
    }

    let result = possibilities(
        &springs,
        &arrangement,
        0,
        None,
        0,
        false,
        false,
    );

    println!("{} - {}", input, result);

    result
}

fn possibilities(
    springs: &Vec<char>,
    arrangement: &Vec<u32>,
    start_index: usize,
    cluster_size: Option<u32>,
    arrangement_index: usize,
    mut force_spring: bool,
    mut force_broken: bool,
) -> u64 {
    let mut cluster_size = cluster_size;

    let mut arrangement_index = arrangement_index;

    for i in start_index..springs.len() {
        if springs[i] == '.' || force_spring {
            if cluster_size.is_some() {
                if cluster_size == Some(0) {
                    cluster_size = None;
                } else {
                    return 0;
                }
            }
        } else if springs[i] == '#' || force_broken {
            if cluster_size == Some(0) {
                return 0;
            }

            if let Some(current) = cluster_size {
                cluster_size = Some(current - 1);
            } else {
                if arrangement_index < arrangement.len() {
                    cluster_size = Some(arrangement[arrangement_index] - 1);
                    arrangement_index += 1;
                } else {
                    return 0;
                }
            }
        } else if springs[i] == '?' {
            let amount_0 = possibilities(
                springs,
                arrangement,
                i,
                cluster_size,
                arrangement_index,
                true,
                false,
            );

            let amount_1 = possibilities(
                springs,
                arrangement,
                i,
                cluster_size,
                arrangement_index,
                false,
                true,
            );

            return amount_0 + amount_1;
        } else {
            panic!();
        }

        force_spring = false;
        force_broken = false;
    }

    if cluster_size.unwrap_or(0) != 0 || arrangement_index != arrangement.len() {
        0
    } else {
        1
    }
}

src/day_13_1/mod.rs

0 → 100644
+54 −0
Original line number Diff line number Diff line
use crate::util::to_grid_flipped_axis;

pub fn solve_from_str(input: &str) -> usize {
    input
        .split("\n\n")
        .map(|pattern| pattern_to_value(&to_grid_flipped_axis(pattern)))
        .sum()
}

fn pattern_to_value(grid: &Vec<Vec<char>>) -> usize {
    let width = grid[0].len();
    let height = grid.len();

    for n_left in 1..width {
        let mut valid = true;
        
        for i in 0..usize::min(n_left, width - n_left) {
            if grid.iter().any(|line| line[n_left - 1 - i] != line[n_left + i]) {
                valid = false;
                break;
            }
        }

        if valid {
            return n_left;
        }
    }

    for n_top in 1..height {
        let mut valid = true;

        for i in 0..usize::min(n_top, height - n_top) {
            for column in 0..width {
                if grid[n_top - 1 - i][column] != grid[n_top + i][column] {
                    valid = false;
                    break;
                }
            }
        }

        if valid {
            return n_top * 100;
        }
    }

    for line in grid {
        for char in line {
            print!("{}", char);
        }
        println!();
    }

    panic!();
}

src/day_13_2/mod.rs

0 → 100644
+60 −0
Original line number Diff line number Diff line
use crate::util::to_grid_flipped_axis;

pub fn solve_from_str(input: &str) -> usize {
    input
        .split("\n\n")
        .map(|pattern| pattern_to_value(&to_grid_flipped_axis(pattern)))
        .sum()
}

fn pattern_to_value(grid: &Vec<Vec<char>>) -> usize {
    let width = grid[0].len();
    let height = grid.len();

    for n_left in 1..width {
        let mut defects = 0;
        
        for i in 0..usize::min(n_left, width - n_left) {
            for row in 0..height {
                if grid[row][n_left - 1 - i] != grid[row][n_left + i] {
                    defects += 1;
                    if defects > 1 {
                        break;
                    }
                }
            }
        }

        if defects == 1 {
            return n_left;
        }
    }

    for n_top in 1..height {
        let mut defects = 0;

        for i in 0..usize::min(n_top, height - n_top) {
            for column in 0..width {
                if grid[n_top - 1 - i][column] != grid[n_top + i][column] {
                    defects += 1;
                    if defects > 1 {
                        break;
                    }
                }
            }
        }

        if defects == 1 {
            return n_top * 100;
        }
    }

    for line in grid {
        for char in line {
            print!("{}", char);
        }
        println!();
    }

    panic!();
}

src/day_14_1/mod.rs

0 → 100644
+46 −0
Original line number Diff line number Diff line
use crate::util::*;

pub fn solve_from_str(input: &str) -> usize {
    let mut grid = to_grid_flipped_axis(input);

    let height = grid.len();

    tilt_up(&mut grid);

    grid.iter()
        .enumerate()
        .map(|(i, line)| get_line_value(height - i, line))
        .sum()
}

fn tilt_up(grid: &mut Vec<Vec<char>>) {
    let width = grid[0].len();
    let height = grid.len();

    for y in 0..height {
        for x in 0..width {
            if grid[y][x] == 'O' {
                let mut y_valid = y;

                for y_new in (0..y).rev() {
                    dbg!(y_new);

                    if grid[y_new][x] == '.' {
                        y_valid = y_new;
                    } else {
                        break;
                    }
                }

                grid[y][x] = '.';
                grid[y_valid][x] = 'O';
            }
        }
    }
}

fn get_line_value(multiplier: usize, line: &Vec<char>) -> usize {
    line.iter()
        .map(|char| if *char == 'O' { multiplier } else { 0 })
        .sum()
}

src/day_15_1/mod.rs

0 → 100644
+10 −0
Original line number Diff line number Diff line
pub fn solve_from_str(input: &str) -> u32 {
    input
        .split(",")
        .map(|string| {
            string
                .chars()
                .fold(0, |acc, char| (acc + char as u32) * 17 % 256)
        })
        .sum()
}

src/day_15_2/mod.rs

0 → 100644
+67 −0
Original line number Diff line number Diff line
pub fn solve_from_str(input: &str) -> usize {
    let mut hashmap: Vec<Vec<(&str, usize)>> = Vec::new();

    for i in 0..256 {
        hashmap.push(Vec::new());
    }

    for instruction in input.split(",") {
        if instruction.contains("=") {
            let mut data = instruction.split("=");
            let label = data.next().unwrap();
            let focal_length = str::parse(data.next().unwrap()).unwrap();

            let lensbox = &mut hashmap[hash(label)];

            let index = lensbox.iter().enumerate().find_map(|(index, lens)| {
                if lens.0.eq(label) {
                    Some(index)
                } else {
                    None
                }
            });
            if let Some(index) = index {
                lensbox[index] = (label, focal_length);
            } else {
                lensbox.push((label, focal_length));
            }
        } else if instruction.contains("-") {
            let mut data = instruction.split("-");
            let label = data.next().unwrap();

            let lensbox = &mut hashmap[hash(label)];

            let index = lensbox.iter().enumerate().find_map(|(index, lens)| {
                if lens.0.eq(label) {
                    Some(index)
                } else {
                    None
                }
            });

            if let Some(index) = index {
                lensbox.remove(index);
            }
        } else {
            panic!();
        }
    }

    hashmap
        .iter()
        .enumerate()
        .map(|(boxindex, lensbox)| {
            lensbox
                .iter()
                .enumerate()
                .map(|(lensindex, lens)| (boxindex + 1) * (lensindex + 1) * lens.1)
                .sum::<usize>()
        })
        .sum()
}

fn hash(input: &str) -> usize {
    input
        .chars()
        .fold(0, |acc, char| (acc + char as usize) * 17 % 256)
}
+8 −1
Original line number Diff line number Diff line
@@ -2,6 +2,13 @@ mod day_10_1;
mod day_10_2;
mod day_11_1;
mod day_11_2;
mod day_12_1;
mod day_12_2;
mod day_13_1;
mod day_13_2;
mod day_14_1;
mod day_15_1;
mod day_15_2;
mod day_1_1;
mod day_1_2;
mod day_2_1;
@@ -28,7 +35,7 @@ use std::fs;
fn main() {
    let input = fs::read_to_string("input").expect("Could not read input!");

    let solution = day_10_2::solve_from_str(input.trim_end());
    let solution = day_12_2::solve_from_str(input.trim_end());

    println!("Solution: {}", solution);
}
+9 −1
Original line number Diff line number Diff line
use std::println;

use rayon::collections::binary_heap::Iter;
use regex::Regex;

pub fn regex_positive_number(input: &str) -> u32 {
@@ -37,6 +36,15 @@ pub fn to_grid_flipped_axis(input: &str) -> Vec<Vec<char>> {
    input.lines().map(|line| line.chars().collect()).collect()
}

pub fn print_grid_flipped_axis(input: &Vec<Vec<char>>) {
    for line in input {
        for char in line {
            print!("{}", char);
        }
        println!();
    }
}

pub fn to_grid(input: &str) -> Vec<Vec<char>> {
    let width = input.lines().next().unwrap().chars().count();
    let height = input.lines().count();