1
0
Fork 0
mirror of https://github.com/Findus23/AdventOfCode2019.git synced 2024-08-27 19:52:12 +02:00

add day 3

This commit is contained in:
Lukas Winkler 2019-12-05 14:57:19 +01:00
parent 38f37f755c
commit 62bc48fd96
Signed by: lukas
GPG key ID: 54DE4D798D244853
6 changed files with 227 additions and 0 deletions

View file

@ -8,6 +8,7 @@ jobs:
- cd python
script:
- pytest
- mypy 1 2 3
- language: rust
rust: stable

View file

@ -49,6 +49,8 @@ def part2() -> int:
if cl[0] == 19690720:
return 100 * noun + verb
return -1
if __name__ == '__main__':
print(part1())

80
python/3/day3.py Normal file
View file

@ -0,0 +1,80 @@
from typing import Tuple, List
def parse_path(path: str):
commands = path.split(",")
return [(c[0], int(c[1:])) for c in commands]
def record_path(path) -> List[Tuple[int, int]]:
pos = [0, 0]
poslist = []
for direction, length in path:
while length > 0:
if direction == "U":
pos[1] += 1
elif direction == "D":
pos[1] -= 1
elif direction == "R":
pos[0] += 1
elif direction == "L":
pos[0] -= 1
else:
raise ValueError(f"invalid direction: {direction}")
poslist.append((pos[0], pos[1]))
length -= 1
return poslist
def manhatten_distance(point: Tuple[int, int]) -> int:
return abs(point[0]) + abs(point[1])
def closest_crossing(first_path, second_path) -> int:
p1 = record_path(first_path)
p2 = record_path(second_path)
commons = set(p1).intersection(set(p2))
min_dist = 100000
for crossing in commons:
dist = manhatten_distance(crossing)
if dist < min_dist:
min_dist = dist
return min_dist
def shortest_signal(first_path, second_path) -> int:
p1 = record_path(first_path)
p2 = record_path(second_path)
commons = set(p1).intersection(set(p2))
shortest = 10000000
for crossing in commons:
total = 0
for path in [p1, p2]:
i = 0
for segment in path:
i += 1
if segment == crossing:
total += i
break
if total < shortest:
shortest = total
return shortest
def part1() -> int:
with open("3/input.txt") as f:
w1, w2 = f.readlines()
return closest_crossing(parse_path(w1), parse_path(w2))
def part2() -> int:
with open("3/input.txt") as f:
w1, w2 = f.readlines()
return shortest_signal(parse_path(w1), parse_path(w2))
if __name__ == '__main__':
print(part1())
print(part2())

2
python/3/input.txt Normal file
View file

@ -0,0 +1,2 @@
R990,U796,R784,U604,R6,U437,L96,U285,L361,U285,L339,D512,L389,D840,L425,U444,L485,D528,L262,U178,L80,U2,R952,U459,L361,D985,R56,U135,R953,D913,L361,U120,L329,U965,L294,U890,L126,U214,R232,D444,L714,U791,R888,U923,R378,U233,L654,D703,R902,D715,R469,D60,R990,U238,R755,U413,L409,D601,R452,U504,R472,D874,L766,D594,R696,U398,R593,D889,R609,D405,L962,U176,L237,U642,L393,D91,L463,U936,R199,D136,R601,D8,R359,D863,L410,U598,L444,D34,R664,D323,R72,D98,L565,D476,L197,D132,R510,U665,R936,U3,R385,U144,L284,D713,L605,U106,R543,D112,R528,D117,R762,U330,R722,U459,L229,U375,L870,D81,R623,U95,L148,D530,L622,D62,R644,D365,L214,U847,R31,D832,L648,D293,R79,D748,L270,U159,L8,U83,R195,U912,L409,D649,L750,D286,L623,D956,R81,U775,R44,D437,L199,U698,L42,U419,L883,U636,L323,U89,L246,D269,L992,U739,R62,U47,R63,U17,L234,U135,R126,D208,L69,U550,L123,D66,R463,U992,R411,D276,L851,U520,R805,D300,L894,U171,L922,D901,R637,U907,R328,U433,L316,D644,L398,U10,L648,D190,R884,U474,R397,D718,L925,D578,R249,U959,L697,D836,R231,U806,R982,U827,R579,U830,L135,D666,R818,D502,L898,D585,R91,D190,L255,U535,R56,U390,R619,D815,L300,D81,R432,D70,L940,D587,L259,D196,R241,U4,R440,U678,R185,U451,R733,D984,R464,D298,L738,U600,R353,D44,L458,U559,L726,D786,L307,D333,L226,D463,R138,D142,L521,D201,R51,D202,L204,U130,L333,U597,R298,U42,L951,U66,R312,U707,L555,D225,L360,D12,L956,D361,L989,D625,L944,D398,L171,D982,L377,U114,L339,U164,R39,D793,R992,U834,R675,U958,R334,D697,L734,D40,L149,U394,R976
L1005,D52,L125,U787,L761,U262,L466,D966,R895,U789,R6,U2,R870,U971,R238,D946,L752,D240,R721,U349,L679,D518,L104,U417,L462,U544,L519,U797,R873,U70,R298,U45,L779,D921,R468,D421,R803,U108,L812,D498,R226,D309,R766,U724,L961,U472,R940,U944,R418,D682,R328,U55,R737,U961,L343,U397,R112,D292,L155,U162,R398,U445,L524,U256,R323,D587,L862,D726,R624,D230,R460,U539,R723,U93,L507,U608,L150,U159,R35,U458,R208,U546,L495,D835,L636,U960,L322,U408,L78,D250,L994,U818,R107,U978,R401,D147,R574,D549,R983,U698,L99,D63,L772,U409,R975,U990,L893,U467,L860,D721,R504,U102,R678,D672,L406,D933,R743,D788,R142,D44,R208,D424,R28,D674,R331,D968,L154,U206,R222,D354,R687,D331,L539,D390,L373,D514,L622,U673,R345,U943,L508,D337,R265,D785,L189,U429,R344,D719,R622,U199,L765,U350,R833,U309,R95,U911,R548,U746,R107,D867,L648,D680,R28,U596,L891,U168,R933,U571,R365,U267,R916,D130,L149,D898,L513,D167,R587,U799,R134,D328,R562,D929,L399,U568,R565,U241,L395,U822,L624,D145,L995,U516,R474,D609,R153,U52,R561,D15,R283,U321,L850,U218,L225,D635,L630,U102,L84,D672,L128,D885,L506,U911,R355,D132,R155,D120,L110,U368,R149,D343,L708,U378,R591,D585,L381,D517,R852,U432,R342,U273,R893,D277,L548,U859,L891,U311,L901,U255,R421,U90,L72,D474,L654,U12,L146,D867,L485,D663,R123,D82,L21,U408,L38,D864,L114,D645,R936,U765,L832,D668,L482,U79,L594,U276,L559,D469,R314,D162,R621,U230,L688,U82,R605,U191,L381,D327,L91,D217,R714,D942,R851,U358,R22,U952,R279,D897,R485,D867,L940,U891,L223,D264,L634,D560,R645,D705,L289,U584,R97,U920,R41

33
python/3/test_day3.py Normal file
View file

@ -0,0 +1,33 @@
from day3 import parse_path, manhatten_distance, closest_crossing, part1, shortest_signal, part2
def test_parse_path():
assert parse_path("R8,U5,L5,D3") == [('R', 8), ('U', 5), ('L', 5), ('D', 3)]
def test_manhatten_distance():
assert manhatten_distance((1, 4)) == 5
def test_closest_crossing():
assert closest_crossing(parse_path("R8,U5,L5,D3"), parse_path("U7,R6,D4,L4")) == 6
assert closest_crossing(parse_path("R75,D30,R83,U83,L12,D49,R71,U7,L72"),
parse_path("U62,R66,U55,R34,D71,R55,D58,R83")) == 159
assert closest_crossing(parse_path("R98,U47,R26,D63,R33,U87,L62,D20,R33,U53,R51"),
parse_path("U98,R91,D20,R16,D67,R40,U7,R15,U6,R7")) == 135
def test_shortest_signal():
assert shortest_signal(parse_path("R8,U5,L5,D3"), parse_path("U7,R6,D4,L4")) == 30
assert shortest_signal(parse_path("R75,D30,R83,U83,L12,D49,R71,U7,L72"),
parse_path("U62,R66,U55,R34,D71,R55,D58,R83")) == 610
assert shortest_signal(parse_path("R98,U47,R26,D63,R33,U87,L62,D20,R33,U53,R51"),
parse_path("U98,R91,D20,R16,D67,R40,U7,R15,U6,R7")) == 410
def test_part1():
assert part1() == 316
def test_part2():
assert part2() == 16368

109
rust/src/day2.rs Normal file
View file

@ -0,0 +1,109 @@
use std::fs;
type IntCode = Vec<i32>;
fn parse_intcode(codestr: &str) -> IntCode {
let split: IntCode = codestr
.split(",")
.map(|codestr| codestr.parse::<i32>().expect("can't parse intcode"))
.collect();
return split;
}
fn run_intcode(mut cl: IntCode) -> IntCode {
let mut p = 0; // pointer,
loop {
let code = cl[p];
if code == 99 {
break;
}
let from1 = cl[p + 1] as usize;
let from2 = cl[p + 2] as usize;
let to = cl[p + 3] as usize;
cl[to] = match code {
1 => cl[from1] + cl[from2],
2 => cl[from1] * cl[from2],
_ => panic!("invalid intcode: {}", code),
};
p += 4
}
return cl;
}
pub fn part1() -> i32 {
let mut data = fs::read_to_string("../python/2/input.txt").expect("Unable to read file");
data.pop();
let mut cl = parse_intcode(data.as_str());
cl[1] = 12;
cl[2] = 2;
cl = run_intcode(cl);
return cl[0];
}
pub fn part2() -> i32 {
let mut data = fs::read_to_string("../python/2/input.txt").expect("Unable to read file");
data.pop();
let inital_cl = parse_intcode(data.as_str());
let mut cl: IntCode;
for noun in 0..99 {
for verb in 0..99 {
cl = inital_cl.clone();
cl[1] = noun;
cl[2] = verb;
cl = run_intcode(cl);
if cl[0] == 19690720 {
return 100 * noun + verb;
}
}
}
return -1;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_intcode() {
assert_eq!(parse_intcode("2,2,3,45,5"), [2, 2, 3, 45, 5])
}
#[test]
#[should_panic(expected = "invalid intcode: 123")]
fn test_opcode_panics() {
let cl = vec![123, 123, 123, 123];
run_intcode(cl);
}
#[test]
fn test_run_intcode1() {
let mut cl: IntCode = vec![1, 0, 0, 0, 99];
cl = run_intcode(cl);
assert_eq!(cl, vec![2, 0, 0, 0, 99])
}
#[test]
fn test_run_intcode2() {
let mut cl: IntCode = vec![2, 3, 0, 3, 99];
cl = run_intcode(cl);
assert_eq!(cl, vec![2, 3, 0, 6, 99])
}
#[test]
fn test_run_intcode3() {
let mut cl: IntCode = vec![2, 4, 4, 5, 99, 0];
cl = run_intcode(cl);
assert_eq!(cl, vec![2, 4, 4, 5, 99, 9801])
}
#[test]
fn test_run_intcode4() {
let mut cl: IntCode = vec![1, 1, 1, 4, 99, 5, 6, 0, 99];
cl = run_intcode(cl);
assert_eq!(cl, vec![30, 1, 1, 4, 2, 5, 6, 0, 99])
}
#[test]
fn test_part1() {
assert_eq!(part1(), 4714701)
}
#[test]
fn test_part2() {
assert_eq!(part2(), 5121)
}
}