summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--day5/.vscode/launch.json43
-rw-r--r--day5/Cargo.lock4
-rw-r--r--day5/Cargo.toml6
-rw-r--r--day5/src/main.rs114
4 files changed, 167 insertions, 0 deletions
diff --git a/day5/.vscode/launch.json b/day5/.vscode/launch.json
new file mode 100644
index 0000000..ee5a08f
--- /dev/null
+++ b/day5/.vscode/launch.json
@@ -0,0 +1,43 @@
+{
+ // 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 'day5'",
+ "cargo": {
+ "args": [
+ "build",
+ "--bin=day5",
+ "--package=day5"
+ ],
+ "filter": {
+ "kind": "bin"
+ }
+ },
+ "args": ["input.txt"],
+ "cwd": "${workspaceFolder}"
+ },
+ {
+ "type": "lldb",
+ "request": "launch",
+ "name": "Debug unit tests in executable 'day5'",
+ "cargo": {
+ "args": [
+ "test",
+ "--no-run",
+ "--bin=day5",
+ "--package=day5"
+ ],
+ "filter": {
+ "kind": "bin"
+ }
+ },
+ "args": [],
+ "cwd": "${workspaceFolder}"
+ }
+ ]
+} \ No newline at end of file
diff --git a/day5/Cargo.lock b/day5/Cargo.lock
new file mode 100644
index 0000000..9b1783a
--- /dev/null
+++ b/day5/Cargo.lock
@@ -0,0 +1,4 @@
+[[package]]
+name = "day5"
+version = "0.1.0"
+
diff --git a/day5/Cargo.toml b/day5/Cargo.toml
new file mode 100644
index 0000000..122a7cb
--- /dev/null
+++ b/day5/Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "day5"
+version = "0.1.0"
+authors = ["Jan Tuomi <jan.tuomi@eficode.com>"]
+
+[dependencies]
diff --git a/day5/src/main.rs b/day5/src/main.rs
new file mode 100644
index 0000000..4b2b0bc
--- /dev/null
+++ b/day5/src/main.rs
@@ -0,0 +1,114 @@
+use std::env;
+use std::io::BufReader;
+use std::io::BufRead;
+use std::fs::File;
+use std::process;
+
+static ASCII_LOWER: [char; 26] = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
+ 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
+ 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
+
+fn same_unit(a: &char, b: &char) -> bool {
+ a.to_lowercase().to_string() == b.to_lowercase().to_string()
+}
+
+fn same_polarity(a: &char, b: &char) -> bool {
+ (a.is_lowercase() && b.is_lowercase()) || (a.is_uppercase() && b.is_uppercase())
+}
+
+fn find_removable_indices(chars: &Vec<char>) -> Option<(usize, usize)> {
+ let mut res: Option<(usize, usize)> = None;
+ for (i, cur) in chars.iter().enumerate() {
+ if i == chars.len() - 1 { // last element
+ break;
+ }
+
+ let next = chars[i + 1];
+ if same_unit(&cur, &next) && !same_polarity(&cur, &next) {
+ res = Some((i, i + 1));
+ break;
+ }
+ }
+
+ res
+}
+
+fn react_polymer(line: &String) -> String {
+ let mut string: Vec<char> = line.trim().chars().collect();
+ loop {
+ let indices = find_removable_indices(&string);
+ let (rem_i1, rem_i2): (usize, usize);
+ match indices {
+ Some((i1, i2)) => {
+ rem_i1 = i1;
+ rem_i2 = i2;
+
+ let s = &mut string;
+ s.remove(rem_i2);
+ s.remove(rem_i1);
+
+ continue;
+ }
+ None => {
+ break;
+ }
+ };
+ }
+
+ string.into_iter().collect()
+}
+
+fn react_polymer_without_char(line: &String, ch: &char) -> String {
+ let line_ref: &str = line.as_ref();
+ let a = *ch;
+ let b_str = a.to_uppercase().to_string();
+ let b: &str = b_str.as_ref();
+ let replaced_line = line_ref.replace(*ch, "").replace(a, "").replace(b, "");
+ let res = react_polymer(&replaced_line);
+ res
+}
+
+fn main() {
+ let args: Vec<String> = env::args().collect();
+ if args.len() != 2 {
+ println!("Wrong number of arguments. Provide just a file name.");
+ process::exit(1);
+ }
+ let filename = &args[1];
+ println!("Using file {} as input.", filename);
+ let f = match File::open(filename) {
+ Ok(file) => file,
+ Err(e) => {
+ println!("Failed to open file {}. {:?}", filename, e);
+ process::exit(1);
+ }
+ };
+ let file = BufReader::new(&f);
+ let mut lines: Vec<String> = file.lines()
+ .map(|line| line.expect("Could not parse line."))
+ .collect();
+ &lines.sort();
+ assert_eq!(lines.len(), 1);
+ let line = &lines[0];
+
+ // exercise 1
+ println!("Solving 1...");
+ let result = react_polymer(&line);
+
+ // println!("1. Result: {}", result);
+ println!("1. Length: {}", result.len());
+
+ // exercise 2
+ println!("Solving 2...");
+ let mut best = line.len();
+ for ch in &ASCII_LOWER {
+ let result = react_polymer_without_char(&line, ch);
+ let len = result.len();
+ println!("Debug: ch: {}, len: {}", &ch, &len);
+ if len < best {
+ best = len;
+ println!("Debug: new best: {}", &len);
+ }
+ }
+ println!("2. Length: {}", best);
+} \ No newline at end of file