Skip to content

Commit

Permalink
Added solution to puzzle 2015/day19
Browse files Browse the repository at this point in the history
  • Loading branch information
Pierre Gagelin committed Dec 3, 2022
1 parent 35d82c7 commit 00c0dd1
Show file tree
Hide file tree
Showing 8 changed files with 220 additions and 0 deletions.
8 changes: 8 additions & 0 deletions 2015/day19/Cargo.toml
@@ -0,0 +1,8 @@
[package]
name = "day19"
version = "0.1.0"
edition = "2021"

[[bin]]
name = "day19"
path = "day19.rs"
142 changes: 142 additions & 0 deletions 2015/day19/day19.rs
@@ -0,0 +1,142 @@
//! [Day 19: Medicine for Rudolph](https://adventofcode.com/2015/day/19)

use std::collections::HashSet;
use std::env;
use std::fs;

struct Puzzle {
medicine_molecule: String,
replacements: Vec<(String, String)>,
}

impl Puzzle {
fn new() -> Puzzle {
Puzzle {
medicine_molecule: String::new(),
replacements: Vec::new(),
}
}

fn configure(&mut self, filename: &str) {
let mut data: Vec<String> = fs::read_to_string(filename)
.expect("Failed to read input file")
.lines()
.map(ToString::to_string)
.collect();

self.medicine_molecule = data.pop().unwrap();

// Remove empty delimiter
data.pop();

for line in data {
// Get the replacement rule
let mut replacement: Vec<&str> = line.split(" => ").collect();
let to = replacement.pop().unwrap().to_string();
let from = replacement.pop().unwrap().to_string();
self.replacements.push((from, to));
}
}

fn part1(&mut self) -> usize {
let mut molecules = HashSet::new();

for (from, to) in &self.replacements {
// Split the molecule on each atom
let sub_molecules: Vec<String> = self
.medicine_molecule
.split_inclusive(from)
.map(ToString::to_string)
.collect();

// Apply the replacement rule for each atom found
for (i, sub_mol) in sub_molecules.iter().enumerate() {
let mut generated_molecule = sub_molecules.clone();
let sub_mol = sub_mol.replace(from, to);
generated_molecule[i] = sub_mol;
molecules.insert(generated_molecule.concat());
}
}
molecules.remove(&self.medicine_molecule);

molecules.len()
}

/// This resolution works but it's not truly what's asked by the puzzle. We don't know if this
/// method yields the lowest count of iterations required to produce the molecule. Finding the
/// lowest count of iterations is a way harder puzzle and was probably not meant by the author
/// of the puzzle. The puzzle input is probably designed in order for only one answer to rise.
fn part2(&mut self) -> usize {
let mut iterations = 0_usize;

// Reduce the medicine molecule to the electron is equivalent to create the medicine molecule from the electron
while self.medicine_molecule != "e" {
for (from, to) in &self.replacements {
// Reverse apply the replacement only once
if self.medicine_molecule.find(to) != None {
self.medicine_molecule = self.medicine_molecule.replacen(to, from, 1);
break;
}
}
iterations += 1;
}

iterations
}
}

/// Test from the puzzle description
#[test]
fn test1() {
let mut puzzle = Puzzle::new();
puzzle.configure("test01.txt");
assert_eq!(puzzle.part1(), 4);
}

/// Test from the puzzle description
#[test]
fn test2() {
let mut puzzle = Puzzle::new();
puzzle.configure("test02.txt");
assert_eq!(puzzle.part1(), 7);
}

/// Test from the puzzle description
#[ignore = "Heuristic made to solve the problem does not work here"]
#[test]
fn test3() {
let mut puzzle = Puzzle::new();
puzzle.configure("test03.txt");
assert_eq!(puzzle.part2(), 3);
}

/// Test from the puzzle description
#[ignore = "Heuristic made to solve the problem does not work here"]
#[test]
fn test4() {
let mut puzzle = Puzzle::new();
puzzle.configure("test04.txt");
assert_eq!(puzzle.part2(), 6);
}

/// Test from a player's input
#[test]
fn test5() {
let mut puzzle = Puzzle::new();
puzzle.configure("test05.txt");
assert_eq!(puzzle.part1(), 518);
assert_eq!(puzzle.part2(), 200);
}

fn main() {
let mut puzzle = Puzzle::new();

let args: Vec<String> = env::args().collect();
puzzle.configure(args.get(1).expect("No input file"));

let result = puzzle.part1();
println!("{}", result);

let result = puzzle.part2();
println!("{}", result);
}
5 changes: 5 additions & 0 deletions 2015/day19/test01.txt
@@ -0,0 +1,5 @@
H => HO
H => OH
O => HH

HOH
5 changes: 5 additions & 0 deletions 2015/day19/test02.txt
@@ -0,0 +1,5 @@
H => HO
H => OH
O => HH

HOHOHO
7 changes: 7 additions & 0 deletions 2015/day19/test03.txt
@@ -0,0 +1,7 @@
e => H
e => O
H => HO
H => OH
O => HH

HOH
7 changes: 7 additions & 0 deletions 2015/day19/test04.txt
@@ -0,0 +1,7 @@
e => H
e => O
H => HO
H => OH
O => HH

HOHOHO
45 changes: 45 additions & 0 deletions 2015/day19/test05.txt
@@ -0,0 +1,45 @@
Al => ThF
Al => ThRnFAr
B => BCa
B => TiB
B => TiRnFAr
Ca => CaCa
Ca => PB
Ca => PRnFAr
Ca => SiRnFYFAr
Ca => SiRnMgAr
Ca => SiTh
F => CaF
F => PMg
F => SiAl
H => CRnAlAr
H => CRnFYFYFAr
H => CRnFYMgAr
H => CRnMgYFAr
H => HCa
H => NRnFYFAr
H => NRnMgAr
H => NTh
H => OB
H => ORnFAr
Mg => BF
Mg => TiMg
N => CRnFAr
N => HSi
O => CRnFYFAr
O => CRnMgAr
O => HP
O => NRnFAr
O => OTi
P => CaP
P => PTi
P => SiRnFAr
Si => CaSi
Th => ThCa
Ti => BP
Ti => TiTi
e => HF
e => NAl
e => OMg

CRnSiRnCaPTiMgYCaPTiRnFArSiThFArCaSiThSiThPBCaCaSiRnSiRnTiTiMgArPBCaPMgYPTiRnFArFArCaSiRnBPMgArPRnCaPTiRnFArCaSiThCaCaFArPBCaCaPTiTiRnFArCaSiRnSiAlYSiThRnFArArCaSiRnBFArCaCaSiRnSiThCaCaCaFYCaPTiBCaSiThCaSiThPMgArSiRnCaPBFYCaCaFArCaCaCaCaSiThCaSiRnPRnFArPBSiThPRnFArSiRnMgArCaFYFArCaSiRnSiAlArTiTiTiTiTiTiTiRnPMgArPTiTiTiBSiRnSiAlArTiTiRnPMgArCaFYBPBPTiRnSiRnMgArSiThCaFArCaSiThFArPRnFArCaSiRnTiBSiThSiRnSiAlYCaFArPRnFArSiThCaFArCaCaSiThCaCaCaSiRnPRnCaFArFYPMgArCaPBCaPBSiRnFYPBCaFArCaSiAl
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -88,5 +88,6 @@ Puzzle
[Day 16: Aunt Sue](https://adventofcode.com/2015/day/16) | ⭐⭐ | Rust Python
[Day 17: No Such Thing as Too Much](https://adventofcode.com/2015/day/17) | ⭐⭐ | Rust
[Day 18: Like a GIF For Your Yard](https://adventofcode.com/2015/day/18) | ⭐⭐ | Rust
[Day 19: Medicine for Rudolph](https://adventofcode.com/2015/day/19) | ⭐⭐ | Rust
[Day 20: Infinite Elves and Infinite Houses](https://adventofcode.com/2015/day/20) | ⭐⭐ | Rust
[Day 25: Let It Snow](https://adventofcode.com/2015/day/25) | ⭐ | Rust

0 comments on commit 00c0dd1

Please sign in to comment.