summaryrefslogtreecommitdiff
path: root/d09/src
diff options
context:
space:
mode:
authorPrefetch2023-02-25 11:41:27 +0100
committerPrefetch2023-02-25 11:41:27 +0100
commit3b877bf4cc667eb8bcc787d145203600a4dba2d2 (patch)
treec1d247def29fcb58ae28e4ae4e4d73d1b4e1b27f /d09/src
Initial commit
Diffstat (limited to 'd09/src')
-rw-r--r--d09/src/main.rs123
1 files changed, 123 insertions, 0 deletions
diff --git a/d09/src/main.rs b/d09/src/main.rs
new file mode 100644
index 0000000..7b24487
--- /dev/null
+++ b/d09/src/main.rs
@@ -0,0 +1,123 @@
+use std::fs;
+
+fn decompress(input: &str, recurse: bool) -> String {
+ let mut output = String::new();
+
+ let mut i = 0;
+ let chars: Vec<char> = input.chars().collect();
+
+ while i < chars.len() {
+ // If we find a compression marker "(LENGTHxREPETITIONS)"
+ if chars[i] == '(' {
+ i += 1;
+ let mut marker = String::new();
+ while chars[i] != ')' {
+ marker.push(chars[i]);
+ i += 1;
+ }
+ i += 1; // i -> first char after ')'
+
+ // Read info from the compression marker...
+ let parsed: Vec<&str> = marker.split('x').collect();
+ let len: usize = parsed[0].parse().unwrap();
+ let rep: usize = parsed[1].parse().unwrap();
+
+ // ... and decompress the next `len' characters accordingly
+ let replacement = if recurse {
+ // Part 2: markers within decompressed data are also handled
+ decompress(&input[i..i + len], true)
+ } else {
+ // Part 1: markers within decompressed data are ignored
+ String::from(&input[i..i + len])
+ };
+ for _n in 0..rep {
+ output.push_str(&replacement);
+ }
+
+ i += len;
+ } else {
+ // This part isn't compressed, copy it verbatim
+ output.push(chars[i]);
+ i += 1;
+ }
+ }
+
+ output
+}
+
+fn main() {
+ // Read my initial data from input text file
+ let input = fs::read_to_string("input.txt").unwrap();
+ let compr = input.trim_end();
+
+ // Part 1 gives 110346 for me
+ println!("Part 1 solution: {}", decompress(compr, false).len());
+
+ // Part 2 gives 10774309173 for me. Watch that RAM!
+ println!("Part 2 solution: {}", decompress(compr, true).len());
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn part1_example1() {
+ let input = "ADVENT";
+ assert_eq!(decompress(input, false).len(), 6);
+ }
+
+ #[test]
+ fn part1_example2() {
+ let input = "A(1x5)BC";
+ assert_eq!(decompress(input, false).len(), 7);
+ }
+
+ #[test]
+ fn part1_example3() {
+ let input = "(3x3)XYZ";
+ assert_eq!(decompress(input, false).len(), 9);
+ }
+
+ #[test]
+ fn part1_example4() {
+ let input = "A(2x2)BCD(2x2)EFG";
+ assert_eq!(decompress(input, false).len(), 11);
+ }
+
+ #[test]
+ fn part1_example5() {
+ let input = "(6x1)(1x3)A";
+ assert_eq!(decompress(input, false).len(), 6);
+ }
+
+ #[test]
+ fn part1_example6() {
+ let input = "X(8x2)(3x3)ABCY";
+ assert_eq!(decompress(input, false).len(), 18);
+ }
+
+ #[test]
+ fn part2_example1() {
+ let input = "(3x3)XYZ";
+ assert_eq!(decompress(input, true).len(), 9);
+ }
+
+ #[test]
+ fn part2_example2() {
+ let input = "X(8x2)(3x3)ABCY";
+ assert_eq!(decompress(input, true).len(), 20);
+ }
+
+ #[test]
+ fn part2_example3() {
+ let input = "(27x12)(20x12)(13x14)(7x10)(1x12)A";
+ assert_eq!(decompress(input, true).len(), 241920);
+ }
+
+ #[test]
+ fn part2_example4() {
+ let input = "(25x3)(3x3)ABC(2x3)XY(5x2)PQRSTX(18x9)(3x2)TWO(5x7)SEVEN";
+ assert_eq!(decompress(input, true).len(), 445);
+ }
+}