Solutions for 2022, as well as 2015-2018 and 2019 up to day 11

This commit is contained in:
Chris Alge 2023-03-12 15:20:02 +01:00
commit 1895197c49
722 changed files with 375457 additions and 0 deletions

View file

@ -0,0 +1,8 @@
[package]
name = "day16-permutation_promenade"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

View file

@ -0,0 +1,47 @@
\--- Day 16: Permutation Promenade ---
----------
You come upon a very unusual sight; a group of programs here appear to be [dancing](https://www.youtube.com/watch?v=lyZQPjUT5B4&t=53).
There are sixteen programs in total, named `a` through `p`. They start by standing in a line: `a` stands in position `0`, `b` stands in position `1`, and so on until `p`, which stands in position `15`.
The programs' *dance* consists of a sequence of *dance moves*:
* *Spin*, written `sX`, makes `X` programs move from the end to the front, but maintain their order otherwise. (For example, `s3` on `abcde` produces `cdeab`).
* *Exchange*, written `xA/B`, makes the programs at positions `A` and `B` swap places.
* *Partner*, written `pA/B`, makes the programs named `A` and `B` swap places.
For example, with only five programs standing in a line (`abcde`), they could do the following dance:
* `s1`, a spin of size `1`: `eabcd`.
* `x3/4`, swapping the last two programs: `eabdc`.
* `pe/b`, swapping programs `e` and `b`: `baedc`.
After finishing their dance, the programs end up in order `baedc`.
You watch the dance for a while and record their dance moves (your puzzle input). *In what order are the programs standing* after their dance?
Your puzzle answer was `cgpfhdnambekjiol`.
\--- Part Two ---
----------
Now that you're starting to get a feel for the dance moves, you turn your attention to *the dance as a whole*.
Keeping the positions they ended up in from their previous dance, the programs perform it again and again: including the first dance, a total of *one billion* (`1000000000`) times.
In the example above, their second dance would *begin* with the order `baedc`, and use the same dance moves:
* `s1`, a spin of size `1`: `cbaed`.
* `x3/4`, swapping the last two programs: `cbade`.
* `pe/b`, swapping programs `e` and `b`: `ceadb`.
*In what order are the programs standing* after their billion dances?
Your puzzle answer was `gjmiofcnaehpdlbk`.
Both parts of this puzzle are complete! They provide two gold stars: \*\*
At this point, all that is left is for you to [admire your Advent calendar](/2017).
If you still want to see it, you can [get your puzzle input](16/input).

View file

@ -0,0 +1,86 @@
#[derive(Clone, Copy)]
enum Move {
Spin(usize),
Exchange(usize, usize),
Partner(char, char),
}
impl Move {
fn parse(line: &str) -> Self {
match line.chars().next() {
Some('s') => Self::Spin(line[1..].parse().unwrap()),
Some('x') => {
let (l, r) = line[1..].split_once('/').unwrap();
Self::Exchange(l.parse().unwrap(), r.parse().unwrap())
},
Some('p') => Self::Partner(line.chars().nth(1).unwrap(), line.chars().nth(3).unwrap()),
_ => panic!("Unexpected Move: {line}"),
}
}
fn perform(self, target: &mut [char]) {
match self {
Self::Spin(by) => target.rotate_right(by),
Self::Exchange(a, b) => target.swap(a, b),
Self::Partner(a, b) => {
let pos_a = target.iter().position(|c| *c==a).unwrap();
let pos_b = target.iter().position(|c| *c==b).unwrap();
target[pos_a] = b;
target[pos_b] = a;
},
}
}
}
pub fn run(input: &str) -> (String, String) {
let initial_line = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p'];
let mut line = initial_line;
let moves: Vec<_> = input.split(',').map(Move::parse).collect();
for mov in &moves {
mov.perform(&mut line);
}
let first: String = line.iter().collect();
let mut remainder = None;
for iter in 2..=1_000_000_000 {
for mov in &moves {
mov.perform(&mut line);
}
if line == initial_line {
eprintln!("Arrangement from 0 repeated at {iter}");
remainder = Some(1_000_000_000%iter);
break;
}
}
if let Some(r) = remainder {
for _ in 0..r {
for mov in &moves {
mov.perform(&mut line);
}
}
}
let second = line.iter().collect();
(first, second)
}
#[cfg(test)]
mod tests {
use super::*;
use std::fs::read_to_string;
fn read_file(name: &str) -> String {
read_to_string(name).expect(&format!("Unable to read file: {name}")[..]).trim().to_string()
}
#[test]
fn test_sample() {
let sample_input = read_file("tests/sample_input");
assert_eq!(run(&sample_input), ("paedcbfghijklmno".to_string(), "ghidjklmnopabcef".to_string()));
}
#[test]
fn test_challenge() {
let challenge_input = read_file("tests/challenge_input");
assert_eq!(run(&challenge_input), ("cgpfhdnambekjiol".to_string(), "gjmiofcnaehpdlbk".to_string()));
}
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
s1,x3/4,pe/b