Day 1, day 2, day 3
This commit is contained in:
parent
1b1e13b523
commit
8117741f48
20 changed files with 1349 additions and 1 deletions
16
README.md
16
README.md
|
@ -1,3 +1,17 @@
|
|||
# AoC-2019
|
||||
|
||||
Advent Of Code 2019
|
||||
[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/
|
||||
|
|
6
day1/1/day1.py
Normal file
6
day1/1/day1.py
Normal file
|
@ -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}")
|
100
day1/1/input
Normal file
100
day1/1/input
Normal file
|
@ -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
|
13
day1/2/day2.py
Normal file
13
day1/2/day2.py
Normal file
|
@ -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}")
|
100
day1/2/input
Normal file
100
day1/2/input
Normal file
|
@ -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
|
153
day2/1/input
Normal file
153
day2/1/input
Normal file
|
@ -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
|
9
day2/1/intcode/Cargo.toml
Normal file
9
day2/1/intcode/Cargo.toml
Normal file
|
@ -0,0 +1,9 @@
|
|||
[package]
|
||||
name = "intcode"
|
||||
version = "0.1.0"
|
||||
authors = ["Armin Friedl <dev@friedl.net>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
153
day2/1/intcode/input
Normal file
153
day2/1/intcode/input
Normal file
|
@ -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
|
148
day2/1/intcode/src/main.rs
Normal file
148
day2/1/intcode/src/main.rs
Normal file
|
@ -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<u32>,
|
||||
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<u32> {
|
||||
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<dyn Error>>{
|
||||
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>) -> 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}
|
||||
}
|
||||
}
|
9
day2/2/Cargo.toml
Normal file
9
day2/2/Cargo.toml
Normal file
|
@ -0,0 +1,9 @@
|
|||
[package]
|
||||
name = "intcode"
|
||||
version = "0.1.0"
|
||||
authors = ["Armin Friedl <dev@friedl.net>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
153
day2/2/input
Normal file
153
day2/2/input
Normal file
|
@ -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
|
119
day2/2/src/main.rs
Normal file
119
day2/2/src/main.rs
Normal file
|
@ -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<u32>,
|
||||
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<u32> {
|
||||
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<dyn Error>>{
|
||||
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(())
|
||||
}
|
9
day3/1/crossed_wires/Cargo.toml
Normal file
9
day3/1/crossed_wires/Cargo.toml
Normal file
|
@ -0,0 +1,9 @@
|
|||
[package]
|
||||
name = "crossed_wires"
|
||||
version = "0.1.0"
|
||||
authors = ["Armin Friedl <dev@friedl.net>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
2
day3/1/crossed_wires/input
Normal file
2
day3/1/crossed_wires/input
Normal file
|
@ -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
|
2
day3/1/crossed_wires/src/input
Normal file
2
day3/1/crossed_wires/src/input
Normal file
|
@ -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
|
161
day3/1/crossed_wires/src/main.rs
Normal file
161
day3/1/crossed_wires/src/main.rs
Normal file
|
@ -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<Point>,
|
||||
path: LinkedList<Point>,
|
||||
}
|
||||
|
||||
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<Point> {
|
||||
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)}
|
||||
}
|
||||
}
|
9
day3/2/crossed_wires/Cargo.toml
Normal file
9
day3/2/crossed_wires/Cargo.toml
Normal file
|
@ -0,0 +1,9 @@
|
|||
[package]
|
||||
name = "crossed_wires"
|
||||
version = "0.1.0"
|
||||
authors = ["Armin Friedl <dev@friedl.net>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
2
day3/2/crossed_wires/input
Normal file
2
day3/2/crossed_wires/input
Normal file
|
@ -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
|
2
day3/2/crossed_wires/src/input
Normal file
2
day3/2/crossed_wires/src/input
Normal file
|
@ -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
|
184
day3/2/crossed_wires/src/main.rs
Normal file
184
day3/2/crossed_wires/src/main.rs
Normal file
|
@ -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<Point>,
|
||||
path: LinkedList<Point>,
|
||||
}
|
||||
|
||||
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<Point> {
|
||||
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}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue