From 8117741f48878bb427d76b55a4f6974d725e15eb Mon Sep 17 00:00:00 2001 From: Armin Friedl Date: Wed, 4 Dec 2019 20:18:15 +0100 Subject: [PATCH] Day 1, day 2, day 3 --- README.md | 16 ++- day1/1/day1.py | 6 + day1/1/input | 100 +++++++++++++++++ day1/2/day2.py | 13 +++ day1/2/input | 100 +++++++++++++++++ day2/1/input | 153 +++++++++++++++++++++++++ day2/1/intcode/Cargo.toml | 9 ++ day2/1/intcode/input | 153 +++++++++++++++++++++++++ day2/1/intcode/src/main.rs | 148 +++++++++++++++++++++++++ day2/2/Cargo.toml | 9 ++ day2/2/input | 153 +++++++++++++++++++++++++ day2/2/src/main.rs | 119 ++++++++++++++++++++ day3/1/crossed_wires/Cargo.toml | 9 ++ day3/1/crossed_wires/input | 2 + day3/1/crossed_wires/src/input | 2 + day3/1/crossed_wires/src/main.rs | 161 +++++++++++++++++++++++++++ day3/2/crossed_wires/Cargo.toml | 9 ++ day3/2/crossed_wires/input | 2 + day3/2/crossed_wires/src/input | 2 + day3/2/crossed_wires/src/main.rs | 184 +++++++++++++++++++++++++++++++ 20 files changed, 1349 insertions(+), 1 deletion(-) create mode 100644 day1/1/day1.py create mode 100644 day1/1/input create mode 100644 day1/2/day2.py create mode 100644 day1/2/input create mode 100644 day2/1/input create mode 100644 day2/1/intcode/Cargo.toml create mode 100644 day2/1/intcode/input create mode 100644 day2/1/intcode/src/main.rs create mode 100644 day2/2/Cargo.toml create mode 100644 day2/2/input create mode 100644 day2/2/src/main.rs create mode 100644 day3/1/crossed_wires/Cargo.toml create mode 100644 day3/1/crossed_wires/input create mode 100644 day3/1/crossed_wires/src/input create mode 100644 day3/1/crossed_wires/src/main.rs create mode 100644 day3/2/crossed_wires/Cargo.toml create mode 100644 day3/2/crossed_wires/input create mode 100644 day3/2/crossed_wires/src/input create mode 100644 day3/2/crossed_wires/src/main.rs diff --git a/README.md b/README.md index 378dca0..1a41bf7 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,17 @@ # AoC-2019 -Advent Of Code 2019 \ No newline at end of file +[Advent Of Code 2019][1] + +## Days + +## License + +I don't expect this to be used in any relevant capacity. Hence, this code is +under the most serious copyleft license I could find - the [EPL 2.0][2]. This is +a rather fun license for people who really mean it. It virtually checks _all_ +the boxes on (choosealicense.com)[https://choosealicense.com/appendix/]. + +Beware when cloning! I might take ownership of your favorite pet :) + +[1]: https://adventofcode.com/2019/ +[2]: https://eupl.eu/1.2/en/ diff --git a/day1/1/day1.py b/day1/1/day1.py new file mode 100644 index 0000000..512d18e --- /dev/null +++ b/day1/1/day1.py @@ -0,0 +1,6 @@ +from functools import reduce +from operator import add + +with open('input', 'r') as f: + result = reduce(add, [(int(line)//3)-2 for line in f]) + print(f"{result}") diff --git a/day1/1/input b/day1/1/input new file mode 100644 index 0000000..b43b112 --- /dev/null +++ b/day1/1/input @@ -0,0 +1,100 @@ +119341 +141179 +104964 +90174 +106547 +78708 +128438 +84980 +66768 +106894 +82394 +95489 +52669 +95631 +66849 +135461 +88795 +77228 +123981 +72391 +103823 +63982 +64997 +145184 +69311 +117874 +106314 +101353 +114745 +88889 +83875 +85051 +101949 +118449 +65252 +135144 +68497 +132390 +105856 +121098 +144838 +87829 +141579 +140516 +126377 +55911 +89261 +76610 +135578 +110154 +147648 +106639 +143854 +91637 +84297 +117449 +75041 +58141 +132983 +114681 +75817 +116453 +56544 +65230 +90622 +133929 +92089 +134197 +104271 +127204 +149761 +128253 +132253 +109273 +88734 +136243 +122128 +119246 +121118 +128448 +137797 +66767 +67488 +90616 +97823 +51642 +98789 +94130 +128350 +101600 +85570 +145174 +127257 +141772 +144415 +82959 +58548 +129474 +125838 +68864 \ No newline at end of file diff --git a/day1/2/day2.py b/day1/2/day2.py new file mode 100644 index 0000000..bdb93dc --- /dev/null +++ b/day1/2/day2.py @@ -0,0 +1,13 @@ +from functools import reduce +from operator import add + +def converge(fuel): + ff = (fuel//3)-2 + if ff <= 0: + return 0 + else: + return ff + converge(ff) + +with open('input', 'r') as f: + result = reduce(add, [converge(int(line)) for line in f]) + print(f"{result}") diff --git a/day1/2/input b/day1/2/input new file mode 100644 index 0000000..b43b112 --- /dev/null +++ b/day1/2/input @@ -0,0 +1,100 @@ +119341 +141179 +104964 +90174 +106547 +78708 +128438 +84980 +66768 +106894 +82394 +95489 +52669 +95631 +66849 +135461 +88795 +77228 +123981 +72391 +103823 +63982 +64997 +145184 +69311 +117874 +106314 +101353 +114745 +88889 +83875 +85051 +101949 +118449 +65252 +135144 +68497 +132390 +105856 +121098 +144838 +87829 +141579 +140516 +126377 +55911 +89261 +76610 +135578 +110154 +147648 +106639 +143854 +91637 +84297 +117449 +75041 +58141 +132983 +114681 +75817 +116453 +56544 +65230 +90622 +133929 +92089 +134197 +104271 +127204 +149761 +128253 +132253 +109273 +88734 +136243 +122128 +119246 +121118 +128448 +137797 +66767 +67488 +90616 +97823 +51642 +98789 +94130 +128350 +101600 +85570 +145174 +127257 +141772 +144415 +82959 +58548 +129474 +125838 +68864 \ No newline at end of file diff --git a/day2/1/input b/day2/1/input new file mode 100644 index 0000000..0ea6fa9 --- /dev/null +++ b/day2/1/input @@ -0,0 +1,153 @@ +1 +0 +0 +3 +1 +1 +2 +3 +1 +3 +4 +3 +1 +5 +0 +3 +2 +9 +1 +19 +1 +19 +5 +23 +1 +9 +23 +27 +2 +27 +6 +31 +1 +5 +31 +35 +2 +9 +35 +39 +2 +6 +39 +43 +2 +43 +13 +47 +2 +13 +47 +51 +1 +10 +51 +55 +1 +9 +55 +59 +1 +6 +59 +63 +2 +63 +9 +67 +1 +67 +6 +71 +1 +71 +13 +75 +1 +6 +75 +79 +1 +9 +79 +83 +2 +9 +83 +87 +1 +87 +6 +91 +1 +91 +13 +95 +2 +6 +95 +99 +1 +10 +99 +103 +2 +103 +9 +107 +1 +6 +107 +111 +1 +10 +111 +115 +2 +6 +115 +119 +1 +5 +119 +123 +1 +123 +13 +127 +1 +127 +5 +131 +1 +6 +131 +135 +2 +135 +13 +139 +1 +139 +2 +143 +1 +143 +10 +0 +99 +2 +0 +14 +0 \ No newline at end of file diff --git a/day2/1/intcode/Cargo.toml b/day2/1/intcode/Cargo.toml new file mode 100644 index 0000000..650d691 --- /dev/null +++ b/day2/1/intcode/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "intcode" +version = "0.1.0" +authors = ["Armin Friedl "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/day2/1/intcode/input b/day2/1/intcode/input new file mode 100644 index 0000000..0ea6fa9 --- /dev/null +++ b/day2/1/intcode/input @@ -0,0 +1,153 @@ +1 +0 +0 +3 +1 +1 +2 +3 +1 +3 +4 +3 +1 +5 +0 +3 +2 +9 +1 +19 +1 +19 +5 +23 +1 +9 +23 +27 +2 +27 +6 +31 +1 +5 +31 +35 +2 +9 +35 +39 +2 +6 +39 +43 +2 +43 +13 +47 +2 +13 +47 +51 +1 +10 +51 +55 +1 +9 +55 +59 +1 +6 +59 +63 +2 +63 +9 +67 +1 +67 +6 +71 +1 +71 +13 +75 +1 +6 +75 +79 +1 +9 +79 +83 +2 +9 +83 +87 +1 +87 +6 +91 +1 +91 +13 +95 +2 +6 +95 +99 +1 +10 +99 +103 +2 +103 +9 +107 +1 +6 +107 +111 +1 +10 +111 +115 +2 +6 +115 +119 +1 +5 +119 +123 +1 +123 +13 +127 +1 +127 +5 +131 +1 +6 +131 +135 +2 +135 +13 +139 +1 +139 +2 +143 +1 +143 +10 +0 +99 +2 +0 +14 +0 \ No newline at end of file diff --git a/day2/1/intcode/src/main.rs b/day2/1/intcode/src/main.rs new file mode 100644 index 0000000..75cbd7a --- /dev/null +++ b/day2/1/intcode/src/main.rs @@ -0,0 +1,148 @@ +use std::fs::File; +use std::io::{BufReader, BufRead}; +use std::error::Error; +use std::result::Result; + +struct Computer { + mem: Vec, + intp: *mut u32, // here will be dragons +} + +impl Computer { + fn new() -> Self { + let mut mem = vec![0]; + let intp = &mut mem[0] as *mut u32; + + Computer {mem, intp} + } + + fn push(&mut self, val: u32) { + if self.mem[0] == 0 { // we are in init state + self.mem[0] = val + } else { + self.mem.push(val); + } + } + + fn set(&mut self, pos: usize, val: u32) { + self.mem[pos] = val; + } + + fn get(&self, pos: usize) -> u32 { + self.mem[pos] + } + + fn compute(mut self) -> u32 { + // first reset the pointer just to be sure + self.intp = &mut self.mem[0] as *mut u32; + + loop { + match self._next() { + Some(1) => self._add(), + Some(2) => self._mul(), + Some(99) => break, + Some(x) => panic!{"Invalid opcode {}", x}, + None => panic!{"No halt"} + } + } + + self.mem[0] + } + + fn _add(&mut self) { + let op1 = self._expect_next() as usize; + let op2 = self._expect_next() as usize; + let pos = self._expect_next() as usize; + + println!{"Summing {} and {} to {}", self.mem[op1], self.mem[op2], pos} + + self.mem[pos] = self.mem[op1]+self.mem[op2]; + } + + fn _mul(&mut self) { + let op1 = self._expect_next() as usize; + let op2 = self._expect_next() as usize; + let pos = self._expect_next() as usize; + + println!{"Mulling {} and {} to {}", self.mem[op1], self.mem[op2], pos} + + self.mem[pos] = self.mem[op1]*self.mem[op2]; + } + + fn _next(&mut self) -> Option { + unsafe{ // Dragons + + // overflow check, smart cpu + let lstp = self.mem.last_mut().unwrap() as *mut u32; + if self.intp == lstp.offset(1) { + return None; + } + + let op = *self.intp; + println!{"Intp at {}", *self.intp} + + self.intp = self.intp.offset(1); + + Some(op) + } + } + + fn _expect_next(&mut self) -> u32 { + self._next().expect("Exhausted") + } +} + +fn main() -> Result<(), Box>{ + let input = File::open("input")?; + let reader = BufReader::new(input); + + let mut computer = Computer::new(); + + reader.lines() + .filter_map(Result::ok) // transform into Option and filter + .filter_map(|l| l.parse().ok()) // parse String to i32 transform to Option and filter + .for_each(|i| computer.push(i)); // push instruction to computer + + computer.set(1, 12); + computer.set(2, 2); + + let res = computer.compute(); + + println!{"Result: {}", res} + + Ok(()) +} + +#[cfg(test)] +mod tests { + use super::*; + + fn compute(inst: Vec) -> u32 { + let mut computer = Computer::new(); + inst.iter().for_each(|i| computer.push(*i)); + computer.compute() + } + + #[test] + fn tc0() { + let inst = vec!{1,9,10,3,2,3,11,0,99,30,40,50}; + println!{"Fixture {:?}", inst} + assert_eq!{compute(inst), 3500} + } + + #[test] + fn tc1() { + let inst = vec!{1,0,0,0,99}; + println!{"Fixture {:?}", inst} + + assert_eq!{compute(inst), 2} + } + + #[test] + fn tc4() { + let inst = vec!{1,1,1,4,99,5,6,0,99}; + println!{"Fixture {:?}", inst} + + assert_eq!{compute(inst), 30} + } +} diff --git a/day2/2/Cargo.toml b/day2/2/Cargo.toml new file mode 100644 index 0000000..650d691 --- /dev/null +++ b/day2/2/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "intcode" +version = "0.1.0" +authors = ["Armin Friedl "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/day2/2/input b/day2/2/input new file mode 100644 index 0000000..0ea6fa9 --- /dev/null +++ b/day2/2/input @@ -0,0 +1,153 @@ +1 +0 +0 +3 +1 +1 +2 +3 +1 +3 +4 +3 +1 +5 +0 +3 +2 +9 +1 +19 +1 +19 +5 +23 +1 +9 +23 +27 +2 +27 +6 +31 +1 +5 +31 +35 +2 +9 +35 +39 +2 +6 +39 +43 +2 +43 +13 +47 +2 +13 +47 +51 +1 +10 +51 +55 +1 +9 +55 +59 +1 +6 +59 +63 +2 +63 +9 +67 +1 +67 +6 +71 +1 +71 +13 +75 +1 +6 +75 +79 +1 +9 +79 +83 +2 +9 +83 +87 +1 +87 +6 +91 +1 +91 +13 +95 +2 +6 +95 +99 +1 +10 +99 +103 +2 +103 +9 +107 +1 +6 +107 +111 +1 +10 +111 +115 +2 +6 +115 +119 +1 +5 +119 +123 +1 +123 +13 +127 +1 +127 +5 +131 +1 +6 +131 +135 +2 +135 +13 +139 +1 +139 +2 +143 +1 +143 +10 +0 +99 +2 +0 +14 +0 \ No newline at end of file diff --git a/day2/2/src/main.rs b/day2/2/src/main.rs new file mode 100644 index 0000000..51929ec --- /dev/null +++ b/day2/2/src/main.rs @@ -0,0 +1,119 @@ +use std::fs::File; +use std::io::{BufReader, BufRead}; +use std::error::Error; +use std::result::Result; + +#[derive(Debug)] +struct Computer { + mem: Vec, + intp: *mut u32, // here will be dragons +} + +impl Computer { + fn new() -> Self { + let mut mem = vec![0]; + let intp = &mut mem[0] as *mut u32; + + Computer {mem, intp} + } + + fn push(&mut self, val: u32) { + if self.mem[0] == 0 { // we are in init state + self.mem[0] = val + } else { + self.mem.push(val); + } + } + + fn set(&mut self, pos: usize, val: u32) { + self.mem[pos] = val; + } + + fn compute(&mut self) -> u32 { + // first reset the pointer just to be sure + self.intp = &mut self.mem[0] as *mut u32; + + loop { + match self._next() { + Some(1) => self._add(), + Some(2) => self._mul(), + Some(99) => break, + Some(x) => panic!{"Invalid opcode {}", x}, + None => panic!{"No halt"} + } + } + + self.mem[0] + } + + fn _add(&mut self) { + let op1 = self._expect_next() as usize; + let op2 = self._expect_next() as usize; + let pos = self._expect_next() as usize; + + self.mem[pos] = self.mem[op1]+self.mem[op2]; + } + + fn _mul(&mut self) { + let op1 = self._expect_next() as usize; + let op2 = self._expect_next() as usize; + let pos = self._expect_next() as usize; + + self.mem[pos] = self.mem[op1]*self.mem[op2]; + } + + fn _next(&mut self) -> Option { + unsafe{ // Dragons + + // overflow check, smart cpu + let lstp = self.mem.last_mut().unwrap() as *mut u32; + if self.intp == lstp.offset(1) { + return None; + } + + let op = *self.intp; + self.intp = self.intp.offset(1); + + Some(op) + } + } + + fn _expect_next(&mut self) -> u32 { + self._next().expect("Exhausted") + } +} + +impl Clone for Computer { + fn clone(&self) -> Self { + let mut mem = self.mem.clone(); + let intp = &mut mem[0] as *mut u32; + + Computer { mem, intp } + } +} + +fn main() -> Result<(), Box>{ + let input = File::open("input")?; + let reader = BufReader::new(input); + + let mut computer = Computer::new(); + + reader.lines() + .filter_map(Result::ok) // transform into Option and filter + .filter_map(|l| l.parse().ok()) // parse String to i32 transform to Option and filter + .for_each(|i| computer.push(i)); // push instruction to computer + + for i in 0..100 { + for j in 0..100 { + let mut ncomp = computer.clone(); + ncomp.set(1, i); + ncomp.set(2, j); + + if 19690720 == ncomp.compute() { + println!{"Result: a={}, b={}", i, j} + } + } + } + + Ok(()) +} diff --git a/day3/1/crossed_wires/Cargo.toml b/day3/1/crossed_wires/Cargo.toml new file mode 100644 index 0000000..e6f27a2 --- /dev/null +++ b/day3/1/crossed_wires/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "crossed_wires" +version = "0.1.0" +authors = ["Armin Friedl "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/day3/1/crossed_wires/input b/day3/1/crossed_wires/input new file mode 100644 index 0000000..d2ce91a --- /dev/null +++ b/day3/1/crossed_wires/input @@ -0,0 +1,2 @@ +R1003,U756,L776,U308,R718,D577,R902,D776,R760,U638,R289,D70,L885,U161,R807,D842,R175,D955,R643,U380,R329,U573,L944,D2,L807,D886,L549,U592,R152,D884,L761,D915,L726,D677,L417,D651,L108,D377,L699,D938,R555,D222,L689,D196,L454,U309,L470,D234,R198,U689,L996,U117,R208,D310,R572,D562,L207,U244,L769,U186,R153,D756,R97,D625,R686,U244,R348,U586,L385,D466,R483,U718,L892,D39,R692,U756,L724,U148,R70,U224,L837,D370,L309,U235,R382,D579,R404,D146,R6,U584,L840,D863,R942,U646,R146,D618,L12,U210,R126,U163,R931,D661,L710,D883,L686,D688,L148,D19,R703,U530,R889,U186,R779,D503,R417,U272,R541,U21,L562,D10,L349,U998,R69,D65,R560,D585,L949,D372,L110,D865,R212,U56,L936,U957,L88,U612,R927,U642,R416,U348,L541,D416,L808,D759,R449,D6,L517,D4,R494,D143,L536,U341,R394,U179,L22,D680,L138,U249,L285,U879,L717,U756,L313,U222,R823,D208,L134,U984,R282,U635,R207,D63,L416,U511,L179,D582,L651,U932,R646,U378,R263,U138,L920,U523,L859,D556,L277,D518,R489,U561,L457,D297,R72,U920,L583,U23,L395,D844,R776,D552,L55,D500,R111,U409,R685,D427,R275,U739,R181,U333,L215,U808,R341,D537,R336,U230,R247,U748,R846,U404,R850,D493,R891,U176,L744,U585,L987,D849,R271,D848,L555,U801,R316,U753,L390,U97,L128,U45,R706,U35,L928,U913,R537,D512,R152,D410,R76,D209,R183,U941,R289,U632,L923,D190,R488,D934,R442,D303,R178,D250,R204,U247,R707,U77,R428,D701,R386,U110,R641,U925,R703,D387,L946,U415,R461,D123,L214,U236,L959,U517,R957,D524,R812,D668,R369,U340,L606,D503,R755,U390,R142,D921,L976,D36,L965,D450,L722,D224,L303,U705,L584 +L993,U810,L931,D139,R114,D77,L75,U715,R540,D994,L866,U461,R340,D179,R314,D423,R629,D8,L692,U446,L88,D132,L128,U934,L465,D58,L696,D883,L955,D565,R424,U286,R403,U57,L627,D930,R887,D941,L306,D951,R918,U587,R939,U821,L65,D18,L987,D707,L360,D54,L932,U366,R625,U609,R173,D637,R661,U888,L68,U962,R270,U369,R780,U845,L813,U481,R66,D182,R420,U605,R880,D276,L6,D529,R883,U189,R380,D472,R30,U35,L510,D844,L146,U875,R152,U545,R274,U920,R432,U814,R583,D559,L820,U135,L353,U975,L103,U615,R401,U692,L676,D781,R551,D985,L317,U836,R115,D216,L967,U286,R681,U144,L354,U678,L893,D487,R664,D185,R787,D909,L582,D283,L519,D893,L56,U768,L345,D992,L248,U439,R573,D98,L390,D43,L470,D435,R176,U468,R688,U388,L377,U800,R187,U641,L268,U857,L716,D179,R212,U196,L342,U731,R261,D92,R183,D623,L589,D215,L966,U878,L784,U740,R823,D99,L167,D992,R414,U22,L27,U390,R286,D744,L360,U554,L756,U715,R939,D806,R279,U292,L960,U633,L428,U949,R90,D321,R749,U395,L392,U348,L33,D757,R289,D367,L562,D668,L79,D193,L991,D705,L562,U25,R146,D34,R325,U203,R403,D714,R607,U72,L444,D76,R267,U924,R289,U962,L159,U726,L57,D540,R299,U343,R936,U90,L311,U243,L415,D426,L936,D570,L539,D731,R367,D374,L56,D251,L265,U65,L14,D882,L956,U88,R688,D34,R866,U777,R342,D270,L344,D953,L438,D855,L587,U320,L953,D945,L473,U559,L487,D602,R255,U871,L854,U45,R705,D247,R955,U885,R657,D664,L360,D764,L549,D676,R85,U189,L951,D922,R511,D429,R37,U11,R821,U984,R825,U874,R753,D524,L537,U618,L919,D597,L364,D231,L258,U818,R406,D208,R214,U530,R261 diff --git a/day3/1/crossed_wires/src/input b/day3/1/crossed_wires/src/input new file mode 100644 index 0000000..d2ce91a --- /dev/null +++ b/day3/1/crossed_wires/src/input @@ -0,0 +1,2 @@ +R1003,U756,L776,U308,R718,D577,R902,D776,R760,U638,R289,D70,L885,U161,R807,D842,R175,D955,R643,U380,R329,U573,L944,D2,L807,D886,L549,U592,R152,D884,L761,D915,L726,D677,L417,D651,L108,D377,L699,D938,R555,D222,L689,D196,L454,U309,L470,D234,R198,U689,L996,U117,R208,D310,R572,D562,L207,U244,L769,U186,R153,D756,R97,D625,R686,U244,R348,U586,L385,D466,R483,U718,L892,D39,R692,U756,L724,U148,R70,U224,L837,D370,L309,U235,R382,D579,R404,D146,R6,U584,L840,D863,R942,U646,R146,D618,L12,U210,R126,U163,R931,D661,L710,D883,L686,D688,L148,D19,R703,U530,R889,U186,R779,D503,R417,U272,R541,U21,L562,D10,L349,U998,R69,D65,R560,D585,L949,D372,L110,D865,R212,U56,L936,U957,L88,U612,R927,U642,R416,U348,L541,D416,L808,D759,R449,D6,L517,D4,R494,D143,L536,U341,R394,U179,L22,D680,L138,U249,L285,U879,L717,U756,L313,U222,R823,D208,L134,U984,R282,U635,R207,D63,L416,U511,L179,D582,L651,U932,R646,U378,R263,U138,L920,U523,L859,D556,L277,D518,R489,U561,L457,D297,R72,U920,L583,U23,L395,D844,R776,D552,L55,D500,R111,U409,R685,D427,R275,U739,R181,U333,L215,U808,R341,D537,R336,U230,R247,U748,R846,U404,R850,D493,R891,U176,L744,U585,L987,D849,R271,D848,L555,U801,R316,U753,L390,U97,L128,U45,R706,U35,L928,U913,R537,D512,R152,D410,R76,D209,R183,U941,R289,U632,L923,D190,R488,D934,R442,D303,R178,D250,R204,U247,R707,U77,R428,D701,R386,U110,R641,U925,R703,D387,L946,U415,R461,D123,L214,U236,L959,U517,R957,D524,R812,D668,R369,U340,L606,D503,R755,U390,R142,D921,L976,D36,L965,D450,L722,D224,L303,U705,L584 +L993,U810,L931,D139,R114,D77,L75,U715,R540,D994,L866,U461,R340,D179,R314,D423,R629,D8,L692,U446,L88,D132,L128,U934,L465,D58,L696,D883,L955,D565,R424,U286,R403,U57,L627,D930,R887,D941,L306,D951,R918,U587,R939,U821,L65,D18,L987,D707,L360,D54,L932,U366,R625,U609,R173,D637,R661,U888,L68,U962,R270,U369,R780,U845,L813,U481,R66,D182,R420,U605,R880,D276,L6,D529,R883,U189,R380,D472,R30,U35,L510,D844,L146,U875,R152,U545,R274,U920,R432,U814,R583,D559,L820,U135,L353,U975,L103,U615,R401,U692,L676,D781,R551,D985,L317,U836,R115,D216,L967,U286,R681,U144,L354,U678,L893,D487,R664,D185,R787,D909,L582,D283,L519,D893,L56,U768,L345,D992,L248,U439,R573,D98,L390,D43,L470,D435,R176,U468,R688,U388,L377,U800,R187,U641,L268,U857,L716,D179,R212,U196,L342,U731,R261,D92,R183,D623,L589,D215,L966,U878,L784,U740,R823,D99,L167,D992,R414,U22,L27,U390,R286,D744,L360,U554,L756,U715,R939,D806,R279,U292,L960,U633,L428,U949,R90,D321,R749,U395,L392,U348,L33,D757,R289,D367,L562,D668,L79,D193,L991,D705,L562,U25,R146,D34,R325,U203,R403,D714,R607,U72,L444,D76,R267,U924,R289,U962,L159,U726,L57,D540,R299,U343,R936,U90,L311,U243,L415,D426,L936,D570,L539,D731,R367,D374,L56,D251,L265,U65,L14,D882,L956,U88,R688,D34,R866,U777,R342,D270,L344,D953,L438,D855,L587,U320,L953,D945,L473,U559,L487,D602,R255,U871,L854,U45,R705,D247,R955,U885,R657,D664,L360,D764,L549,D676,R85,U189,L951,D922,R511,D429,R37,U11,R821,U984,R825,U874,R753,D524,L537,U618,L919,D597,L364,D231,L258,U818,R406,D208,R214,U530,R261 diff --git a/day3/1/crossed_wires/src/main.rs b/day3/1/crossed_wires/src/main.rs new file mode 100644 index 0000000..02d9cc5 --- /dev/null +++ b/day3/1/crossed_wires/src/main.rs @@ -0,0 +1,161 @@ +use std::io::BufRead; +use std::collections::HashSet; +use std::collections::LinkedList; + +#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)] +struct Point(i32, i32); + +#[derive(Copy, Clone)] +enum Direction { + Up, + Down, + Left, + Right +} + +#[derive(Debug)] +struct Cable { + points: HashSet, + path: LinkedList, +} + +impl Cable { + fn new(origin: Point) -> Cable { + let mut cable = Cable { + points: HashSet::new(), + path: LinkedList::new() + }; + + cable.add_point(origin); + + cable + } + + fn add_point(&mut self, point: Point) { + self.path.push_back(point); + self.points.insert(point); + } + + fn step(&mut self, direction: Direction) { + let curp = self.path.back().unwrap().clone(); + match direction { + Direction::Up => self.add_point(Point (curp.0, curp.1+1)), + Direction::Down => self.add_point(Point (curp.0, curp.1-1)), + Direction::Left => self.add_point(Point (curp.0-1, curp.1)), + Direction::Right => self.add_point(Point (curp.0+1, curp.1)) + } + } + + fn walk(&mut self, direction: Direction, steps: u32) { + for _i in 0..steps { + self.step(direction); + } + } + + fn intersections(&self, other: &Self) -> Vec { + let mut v = vec!{}; + + let s = if self.path.len() > other.path.len() {self} else {other}; + let o = if self.path.len() > other.path.len() {other} else {self}; + + for p in s.points.iter() { + if o.points.contains(p) { + v.push(*p); + } + } + + v + } +} + +fn parse(line: &str) -> Cable { + let mut cable = Cable::new(Point(0,0)); + + line.split(',').for_each(|s| { + let ss = s.split_at(1); + match ss.0 { + "R" => cable.walk(Direction::Right, ss.1.parse().unwrap()), + "L" => cable.walk(Direction::Left, ss.1.parse().unwrap()), + "U" => cable.walk(Direction::Up, ss.1.parse().unwrap()), + "D" => cable.walk(Direction::Down, ss.1.parse().unwrap()), + _ => panic! {"Unknown direction"} + }}); + + cable +} + +fn nearest_point(origin: Point, points: &[Point]) -> Point { + let mut min: Point = Point(std::i32::MAX/2-1, std::i32::MAX/2-1); + + let dist = |p: Point| {(origin.0 - p.0).abs() + (origin.1 - p.1).abs()}; + + for p in points { + if dist(*p) < dist(min) { + min = p.clone(); + } + } + + min +} + +fn distance(origin: Point, point: Point) -> i32 { + (origin.0 - point.0).abs() + (origin.1 - point.1).abs() +} + +fn main() { + let f = std::fs::File::open("input").unwrap(); + let r = std::io::BufReader::new(f); + + let mut l = r.lines(); + + let c1line = l.next().unwrap().unwrap(); + let cable1 = parse(&c1line); + + let c2line = l.next().unwrap().unwrap(); + let cable2 = parse(&c2line); + + println!{"Intersecting"} + let mut inter = cable1.intersections(&cable2); + println!{"Intersections: {:?}", inter} + + let origin = inter.iter().position(|x| *x == Point(0,0)).unwrap(); + inter.remove(origin); + + let np = nearest_point(Point(0,0), &inter); + println!("Min point: {:?}", np); + let np_dist = distance(Point(0,0), np); + println!("Distance: {}", np_dist) +} + +#[cfg(test)] +mod test { + use super::*; + + fn run_with(l1: &str, l2: &str) -> i32 { + let cable1 = parse(&l1); + let cable2 = parse(&l2); + + println!{"hi"}; + let mut inter = cable1.intersections(&cable2); + let origin = inter.iter().position(|x| *x == Point(0,0)).unwrap(); + inter.remove(origin); + let np = nearest_point(Point(0,0), &inter); + println!("Min point: {:?}", np); + + distance(Point(0,0), np) + } + + #[test] + fn tc1 () { + let l1 = "R75,D30,R83,U83,L12,D49,R71,U7,L72"; + let l2 = "U62,R66,U55,R34,D71,R55,D58,R83"; + assert_eq!{159, run_with(l1,l2)} + } + + #[test] + fn tc2 () { + let l1 = "R98,U47,R26,D63,R33,U87,L62,D20,R33,U53,R51"; + let l2 = "U98,R91,D20,R16,D67,R40,U7,R15,U6,R7"; + assert_eq!{135, run_with(l1,l2)} + } +} diff --git a/day3/2/crossed_wires/Cargo.toml b/day3/2/crossed_wires/Cargo.toml new file mode 100644 index 0000000..e6f27a2 --- /dev/null +++ b/day3/2/crossed_wires/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "crossed_wires" +version = "0.1.0" +authors = ["Armin Friedl "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/day3/2/crossed_wires/input b/day3/2/crossed_wires/input new file mode 100644 index 0000000..d2ce91a --- /dev/null +++ b/day3/2/crossed_wires/input @@ -0,0 +1,2 @@ +R1003,U756,L776,U308,R718,D577,R902,D776,R760,U638,R289,D70,L885,U161,R807,D842,R175,D955,R643,U380,R329,U573,L944,D2,L807,D886,L549,U592,R152,D884,L761,D915,L726,D677,L417,D651,L108,D377,L699,D938,R555,D222,L689,D196,L454,U309,L470,D234,R198,U689,L996,U117,R208,D310,R572,D562,L207,U244,L769,U186,R153,D756,R97,D625,R686,U244,R348,U586,L385,D466,R483,U718,L892,D39,R692,U756,L724,U148,R70,U224,L837,D370,L309,U235,R382,D579,R404,D146,R6,U584,L840,D863,R942,U646,R146,D618,L12,U210,R126,U163,R931,D661,L710,D883,L686,D688,L148,D19,R703,U530,R889,U186,R779,D503,R417,U272,R541,U21,L562,D10,L349,U998,R69,D65,R560,D585,L949,D372,L110,D865,R212,U56,L936,U957,L88,U612,R927,U642,R416,U348,L541,D416,L808,D759,R449,D6,L517,D4,R494,D143,L536,U341,R394,U179,L22,D680,L138,U249,L285,U879,L717,U756,L313,U222,R823,D208,L134,U984,R282,U635,R207,D63,L416,U511,L179,D582,L651,U932,R646,U378,R263,U138,L920,U523,L859,D556,L277,D518,R489,U561,L457,D297,R72,U920,L583,U23,L395,D844,R776,D552,L55,D500,R111,U409,R685,D427,R275,U739,R181,U333,L215,U808,R341,D537,R336,U230,R247,U748,R846,U404,R850,D493,R891,U176,L744,U585,L987,D849,R271,D848,L555,U801,R316,U753,L390,U97,L128,U45,R706,U35,L928,U913,R537,D512,R152,D410,R76,D209,R183,U941,R289,U632,L923,D190,R488,D934,R442,D303,R178,D250,R204,U247,R707,U77,R428,D701,R386,U110,R641,U925,R703,D387,L946,U415,R461,D123,L214,U236,L959,U517,R957,D524,R812,D668,R369,U340,L606,D503,R755,U390,R142,D921,L976,D36,L965,D450,L722,D224,L303,U705,L584 +L993,U810,L931,D139,R114,D77,L75,U715,R540,D994,L866,U461,R340,D179,R314,D423,R629,D8,L692,U446,L88,D132,L128,U934,L465,D58,L696,D883,L955,D565,R424,U286,R403,U57,L627,D930,R887,D941,L306,D951,R918,U587,R939,U821,L65,D18,L987,D707,L360,D54,L932,U366,R625,U609,R173,D637,R661,U888,L68,U962,R270,U369,R780,U845,L813,U481,R66,D182,R420,U605,R880,D276,L6,D529,R883,U189,R380,D472,R30,U35,L510,D844,L146,U875,R152,U545,R274,U920,R432,U814,R583,D559,L820,U135,L353,U975,L103,U615,R401,U692,L676,D781,R551,D985,L317,U836,R115,D216,L967,U286,R681,U144,L354,U678,L893,D487,R664,D185,R787,D909,L582,D283,L519,D893,L56,U768,L345,D992,L248,U439,R573,D98,L390,D43,L470,D435,R176,U468,R688,U388,L377,U800,R187,U641,L268,U857,L716,D179,R212,U196,L342,U731,R261,D92,R183,D623,L589,D215,L966,U878,L784,U740,R823,D99,L167,D992,R414,U22,L27,U390,R286,D744,L360,U554,L756,U715,R939,D806,R279,U292,L960,U633,L428,U949,R90,D321,R749,U395,L392,U348,L33,D757,R289,D367,L562,D668,L79,D193,L991,D705,L562,U25,R146,D34,R325,U203,R403,D714,R607,U72,L444,D76,R267,U924,R289,U962,L159,U726,L57,D540,R299,U343,R936,U90,L311,U243,L415,D426,L936,D570,L539,D731,R367,D374,L56,D251,L265,U65,L14,D882,L956,U88,R688,D34,R866,U777,R342,D270,L344,D953,L438,D855,L587,U320,L953,D945,L473,U559,L487,D602,R255,U871,L854,U45,R705,D247,R955,U885,R657,D664,L360,D764,L549,D676,R85,U189,L951,D922,R511,D429,R37,U11,R821,U984,R825,U874,R753,D524,L537,U618,L919,D597,L364,D231,L258,U818,R406,D208,R214,U530,R261 diff --git a/day3/2/crossed_wires/src/input b/day3/2/crossed_wires/src/input new file mode 100644 index 0000000..d2ce91a --- /dev/null +++ b/day3/2/crossed_wires/src/input @@ -0,0 +1,2 @@ +R1003,U756,L776,U308,R718,D577,R902,D776,R760,U638,R289,D70,L885,U161,R807,D842,R175,D955,R643,U380,R329,U573,L944,D2,L807,D886,L549,U592,R152,D884,L761,D915,L726,D677,L417,D651,L108,D377,L699,D938,R555,D222,L689,D196,L454,U309,L470,D234,R198,U689,L996,U117,R208,D310,R572,D562,L207,U244,L769,U186,R153,D756,R97,D625,R686,U244,R348,U586,L385,D466,R483,U718,L892,D39,R692,U756,L724,U148,R70,U224,L837,D370,L309,U235,R382,D579,R404,D146,R6,U584,L840,D863,R942,U646,R146,D618,L12,U210,R126,U163,R931,D661,L710,D883,L686,D688,L148,D19,R703,U530,R889,U186,R779,D503,R417,U272,R541,U21,L562,D10,L349,U998,R69,D65,R560,D585,L949,D372,L110,D865,R212,U56,L936,U957,L88,U612,R927,U642,R416,U348,L541,D416,L808,D759,R449,D6,L517,D4,R494,D143,L536,U341,R394,U179,L22,D680,L138,U249,L285,U879,L717,U756,L313,U222,R823,D208,L134,U984,R282,U635,R207,D63,L416,U511,L179,D582,L651,U932,R646,U378,R263,U138,L920,U523,L859,D556,L277,D518,R489,U561,L457,D297,R72,U920,L583,U23,L395,D844,R776,D552,L55,D500,R111,U409,R685,D427,R275,U739,R181,U333,L215,U808,R341,D537,R336,U230,R247,U748,R846,U404,R850,D493,R891,U176,L744,U585,L987,D849,R271,D848,L555,U801,R316,U753,L390,U97,L128,U45,R706,U35,L928,U913,R537,D512,R152,D410,R76,D209,R183,U941,R289,U632,L923,D190,R488,D934,R442,D303,R178,D250,R204,U247,R707,U77,R428,D701,R386,U110,R641,U925,R703,D387,L946,U415,R461,D123,L214,U236,L959,U517,R957,D524,R812,D668,R369,U340,L606,D503,R755,U390,R142,D921,L976,D36,L965,D450,L722,D224,L303,U705,L584 +L993,U810,L931,D139,R114,D77,L75,U715,R540,D994,L866,U461,R340,D179,R314,D423,R629,D8,L692,U446,L88,D132,L128,U934,L465,D58,L696,D883,L955,D565,R424,U286,R403,U57,L627,D930,R887,D941,L306,D951,R918,U587,R939,U821,L65,D18,L987,D707,L360,D54,L932,U366,R625,U609,R173,D637,R661,U888,L68,U962,R270,U369,R780,U845,L813,U481,R66,D182,R420,U605,R880,D276,L6,D529,R883,U189,R380,D472,R30,U35,L510,D844,L146,U875,R152,U545,R274,U920,R432,U814,R583,D559,L820,U135,L353,U975,L103,U615,R401,U692,L676,D781,R551,D985,L317,U836,R115,D216,L967,U286,R681,U144,L354,U678,L893,D487,R664,D185,R787,D909,L582,D283,L519,D893,L56,U768,L345,D992,L248,U439,R573,D98,L390,D43,L470,D435,R176,U468,R688,U388,L377,U800,R187,U641,L268,U857,L716,D179,R212,U196,L342,U731,R261,D92,R183,D623,L589,D215,L966,U878,L784,U740,R823,D99,L167,D992,R414,U22,L27,U390,R286,D744,L360,U554,L756,U715,R939,D806,R279,U292,L960,U633,L428,U949,R90,D321,R749,U395,L392,U348,L33,D757,R289,D367,L562,D668,L79,D193,L991,D705,L562,U25,R146,D34,R325,U203,R403,D714,R607,U72,L444,D76,R267,U924,R289,U962,L159,U726,L57,D540,R299,U343,R936,U90,L311,U243,L415,D426,L936,D570,L539,D731,R367,D374,L56,D251,L265,U65,L14,D882,L956,U88,R688,D34,R866,U777,R342,D270,L344,D953,L438,D855,L587,U320,L953,D945,L473,U559,L487,D602,R255,U871,L854,U45,R705,D247,R955,U885,R657,D664,L360,D764,L549,D676,R85,U189,L951,D922,R511,D429,R37,U11,R821,U984,R825,U874,R753,D524,L537,U618,L919,D597,L364,D231,L258,U818,R406,D208,R214,U530,R261 diff --git a/day3/2/crossed_wires/src/main.rs b/day3/2/crossed_wires/src/main.rs new file mode 100644 index 0000000..69dacb9 --- /dev/null +++ b/day3/2/crossed_wires/src/main.rs @@ -0,0 +1,184 @@ +use std::io::BufRead; +use std::collections::HashSet; +use std::collections::LinkedList; + +#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)] +struct Point(i32, i32); + +#[derive(Copy, Clone)] +enum Direction { + Up, + Down, + Left, + Right +} + +#[derive(Debug)] +struct Cable { + points: HashSet, + path: LinkedList, +} + +impl Cable { + fn new(origin: Point) -> Cable { + let mut cable = Cable { + points: HashSet::new(), + path: LinkedList::new() + }; + + cable.add_point(origin); + + cable + } + + fn add_point(&mut self, point: Point) { + self.path.push_back(point); + self.points.insert(point); + } + + fn step(&mut self, direction: Direction) { + let curp = self.path.back().unwrap().clone(); + match direction { + Direction::Up => self.add_point(Point (curp.0, curp.1+1)), + Direction::Down => self.add_point(Point (curp.0, curp.1-1)), + Direction::Left => self.add_point(Point (curp.0-1, curp.1)), + Direction::Right => self.add_point(Point (curp.0+1, curp.1)) + } + } + + fn walk(&mut self, direction: Direction, steps: u32) { + for _i in 0..steps { + self.step(direction); + } + } + + fn min_steps_to(&self, point: &Point) -> u32 { + let mut steps = 0; + + for &p in self.path.iter() { + if p == *point { + return steps; + } + steps+=1; + } + + std::u32::MAX/2 + } + + fn intersections(&self, other: &Self) -> Vec { + let mut v = vec!{}; + + let s = if self.path.len() > other.path.len() {self} else {other}; + let o = if self.path.len() > other.path.len() {other} else {self}; + + for p in s.points.iter() { + if o.points.contains(p) { + v.push(*p); + } + } + + v + } +} + +fn parse(line: &str) -> Cable { + let mut cable = Cable::new(Point(0,0)); + + line.split(',').for_each(|s| { + let ss = s.split_at(1); + match ss.0 { + "R" => cable.walk(Direction::Right, ss.1.parse().unwrap()), + "L" => cable.walk(Direction::Left, ss.1.parse().unwrap()), + "U" => cable.walk(Direction::Up, ss.1.parse().unwrap()), + "D" => cable.walk(Direction::Down, ss.1.parse().unwrap()), + _ => panic! {"Unknown direction"} + }}); + + cable +} + +fn nearest_point(origin: Point, points: &[Point]) -> Point { + let mut min: Point = Point(std::i32::MAX/2-1, std::i32::MAX/2-1); + + let dist = |p: Point| {(origin.0 - p.0).abs() + (origin.1 - p.1).abs()}; + + for p in points { + if dist(*p) < dist(min) { + min = p.clone(); + } + } + + min +} + +fn nearest_point_by_steps(cable1: &Cable, cable2: &Cable, points: &[Point]) -> (Point,u32) { + let mut min: Point = Point(std::i32::MAX/2-1, std::i32::MAX/2-1); + + let combined_steps = |p: &Point| {cable1.min_steps_to(p) + cable2.min_steps_to(p)}; + + for p in points { + if combined_steps(p) < combined_steps(&min) { + min = p.clone(); + } + } + + (min, combined_steps(&min)) +} + +fn main() { + let f = std::fs::File::open("input").unwrap(); + let r = std::io::BufReader::new(f); + + let mut l = r.lines(); + + let c1line = l.next().unwrap().unwrap(); + let cable1 = parse(&c1line); + + let c2line = l.next().unwrap().unwrap(); + let cable2 = parse(&c2line); + + println!{"Intersecting"} + let mut inter = cable1.intersections(&cable2); + println!{"Intersections: {:?}", inter} + + let origin = inter.iter().position(|x| *x == Point(0,0)).unwrap(); + inter.remove(origin); + + let (np,stps) = nearest_point_by_steps(&cable1, &cable2, &inter); + println!("Min point: {:?}", np); + println!("Steps: {}", stps); +} + +#[cfg(test)] +mod test { + use super::*; + + fn run_with(l1: &str, l2: &str) -> (Point, u32) { + let cable1 = parse(&l1); + let cable2 = parse(&l2); + + println!{"hi"}; + let mut inter = cable1.intersections(&cable2); + let origin = inter.iter().position(|x| *x == Point(0,0)).unwrap(); + inter.remove(origin); + let (np,stps) = nearest_point_by_steps(&cable1, &cable2, &inter); + println!("Min point: {:?}", np); + println!("Steps: {:?}", stps); + + (np,stps) + } + + #[test] + fn tc1 () { + let l1 = "R75,D30,R83,U83,L12,D49,R71,U7,L72"; + let l2 = "U62,R66,U55,R34,D71,R55,D58,R83"; + assert_eq!{610, run_with(l1,l2).1} + } + + #[test] + fn tc2 () { + let l1 = "R98,U47,R26,D63,R33,U87,L62,D20,R33,U53,R51"; + let l2 = "U98,R91,D20,R16,D67,R40,U7,R15,U6,R7"; + assert_eq!{410, run_with(l1,l2).1} + } +}