Compare commits
10 commits
2a7d50eb22
...
a903132905
Author | SHA1 | Date | |
---|---|---|---|
dece | a903132905 | ||
dece | 7f9920447a | ||
dece | 6ad8e84551 | ||
dece | 351fc11bed | ||
dece | 56ec1d2ec7 | ||
dece | 1310c4314e | ||
dece | 2a07c6458c | ||
dece | 595db92c73 | ||
dece | b8cc585455 | ||
dece | 7c6bfc0ac1 |
1
2015/.gitignore
vendored
Normal file
1
2015/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
target/
|
14
2015/Cargo.lock
generated
Normal file
14
2015/Cargo.lock
generated
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
[[package]]
|
||||||
|
name = "aoc2015"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"md5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "md5"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771"
|
11
2015/Cargo.toml
Normal file
11
2015/Cargo.toml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
[package]
|
||||||
|
name = "aoc2015"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["dece <shgck@pistache.land>"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
name = "aoc"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
md5 = "0.7.0"
|
31
2015/src/bin/day1.rs
Normal file
31
2015/src/bin/day1.rs
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
use aoc::input;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let lines = input::read_lines();
|
||||||
|
let line = lines[0].to_owned();
|
||||||
|
|
||||||
|
// Part 1
|
||||||
|
let mut floor = 0;
|
||||||
|
for c in line.chars() {
|
||||||
|
match c {
|
||||||
|
'(' => floor += 1,
|
||||||
|
')' => floor -= 1,
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println!("Floor: {}", floor);
|
||||||
|
|
||||||
|
// Part 2
|
||||||
|
floor = 0;
|
||||||
|
for (i, c) in line.chars().enumerate() {
|
||||||
|
match c {
|
||||||
|
'(' => floor += 1,
|
||||||
|
')' => floor -= 1,
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
if floor == -1 {
|
||||||
|
println!("Entered -1 at {}.", i + 1);
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
28
2015/src/bin/day2.rs
Normal file
28
2015/src/bin/day2.rs
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
use aoc::input;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let lines = input::read_lines();
|
||||||
|
let dimensions: Vec<Vec<u32>> = lines.iter().map(|line| {
|
||||||
|
line.split('x').map(|dim| dim.parse::<u32>().unwrap()).collect()
|
||||||
|
}).collect();
|
||||||
|
|
||||||
|
// Part 1
|
||||||
|
let total: u32 = dimensions.iter().map(|dim| {
|
||||||
|
let (l, w, h) = (dim[0], dim[1], dim[2]);
|
||||||
|
let areas = vec!(l * w, w * h, h * l);
|
||||||
|
let slack = areas.iter().min().unwrap();
|
||||||
|
areas.iter().map(|a| 2 * a).sum::<u32>() + slack
|
||||||
|
}).sum();
|
||||||
|
println!("Needed paper: {}.", total);
|
||||||
|
|
||||||
|
// Part 2
|
||||||
|
let total: u32 = dimensions.iter().map(|dim| {
|
||||||
|
let mut sdim = dim.clone();
|
||||||
|
sdim.sort();
|
||||||
|
let (d1, d2, d3) = (sdim[0], sdim[1], sdim[2]);
|
||||||
|
let wrap = 2 * d1 + 2 * d2;
|
||||||
|
let bow = d1 * d2 * d3;
|
||||||
|
wrap + bow
|
||||||
|
}).sum();
|
||||||
|
println!("Needed ribbon: {}.", total);
|
||||||
|
}
|
45
2015/src/bin/day3.rs
Normal file
45
2015/src/bin/day3.rs
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use aoc::input;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let chars = input::read_chars();
|
||||||
|
|
||||||
|
// Part 1
|
||||||
|
let mut houses = HashMap::<(i32, i32), u32>::new();
|
||||||
|
let (mut x, mut y) = (0, 0);
|
||||||
|
houses.insert((0, 0), 1);
|
||||||
|
for c in chars.chars() {
|
||||||
|
match c {
|
||||||
|
'>' => x += 1,
|
||||||
|
'<' => x -= 1,
|
||||||
|
'v' => y += 1,
|
||||||
|
'^' => y -= 1,
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
let presents = houses.entry((x, y)).or_insert(0);
|
||||||
|
*presents += 1;
|
||||||
|
}
|
||||||
|
let num_houses = houses.values().filter(|v| **v > 0).count();
|
||||||
|
println!("Houses delivered: {}.", num_houses);
|
||||||
|
|
||||||
|
// Part 2
|
||||||
|
let mut houses = HashMap::<(i32, i32), u32>::new();
|
||||||
|
let (mut x, mut y, mut rx, mut ry) = (0, 0, 0, 0);
|
||||||
|
houses.insert((0, 0), 1);
|
||||||
|
let mut is_robot_turn = false;
|
||||||
|
for c in chars.chars() {
|
||||||
|
match c {
|
||||||
|
'>' => if is_robot_turn { rx += 1 } else { x += 1 },
|
||||||
|
'<' => if is_robot_turn { rx -= 1 } else { x -= 1 },
|
||||||
|
'v' => if is_robot_turn { ry += 1 } else { y += 1 },
|
||||||
|
'^' => if is_robot_turn { ry -= 1 } else { y -= 1 },
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
let presents = houses.entry(if is_robot_turn { (rx, ry) } else { (x, y) }).or_insert(0);
|
||||||
|
*presents += 1;
|
||||||
|
is_robot_turn = !is_robot_turn;
|
||||||
|
}
|
||||||
|
let num_houses = houses.values().filter(|v| **v > 0).count();
|
||||||
|
println!("Houses delivered: {}.", num_houses);
|
||||||
|
}
|
30
2015/src/bin/day4.rs
Normal file
30
2015/src/bin/day4.rs
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
use aoc::input;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let lines = input::read_lines();
|
||||||
|
let mut key = lines[0].to_string();
|
||||||
|
let key_len = key.len();
|
||||||
|
|
||||||
|
// Part 1
|
||||||
|
let mut n = 0;
|
||||||
|
loop {
|
||||||
|
key.replace_range(key_len.., &n.to_string());
|
||||||
|
let hash = md5::compute(key.as_bytes());
|
||||||
|
if &hash[..2] == [0, 0] && hash[2] < 0x10 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
n += 1
|
||||||
|
}
|
||||||
|
println!("Found coin with n {}.", n);
|
||||||
|
|
||||||
|
// Part 2
|
||||||
|
loop {
|
||||||
|
key.replace_range(key_len.., &n.to_string());
|
||||||
|
let hash = md5::compute(key.as_bytes());
|
||||||
|
if &hash[..3] == [0, 0, 0] {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
n += 1
|
||||||
|
}
|
||||||
|
println!("Found coin with n {}.", n);
|
||||||
|
}
|
21
2015/src/input.rs
Normal file
21
2015/src/input.rs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
use std::io;
|
||||||
|
|
||||||
|
pub fn read_lines() -> Vec<String> {
|
||||||
|
let mut lines = vec!();
|
||||||
|
loop {
|
||||||
|
let mut text = String::new();
|
||||||
|
let read_count = io::stdin().read_line(&mut text).unwrap();
|
||||||
|
if read_count == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if let Some(stripped) = text.strip_suffix("\n") {
|
||||||
|
text = stripped.to_string()
|
||||||
|
}
|
||||||
|
lines.push(text);
|
||||||
|
}
|
||||||
|
lines
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read_chars() -> String {
|
||||||
|
read_lines()[0].to_owned()
|
||||||
|
}
|
1
2015/src/lib.rs
Normal file
1
2015/src/lib.rs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
pub mod input;
|
|
@ -1,7 +0,0 @@
|
||||||
def main():
|
|
||||||
with open("", "rt") as f:
|
|
||||||
lines = [line.rstrip() for line in f.readlines()]
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
|
@ -3,7 +3,7 @@ from collections import defaultdict
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
nl = list(map(lambda s: int(s), sys.stdin.read().rstrip().split(",")))
|
nl = list(map(int, sys.stdin.read().rstrip().split(",")))
|
||||||
|
|
||||||
# Part 1
|
# Part 1
|
||||||
print("Part 1:", get_nth(2020, nl))
|
print("Part 1:", get_nth(2020, nl))
|
||||||
|
|
133
2020/day20.py
Normal file
133
2020/day20.py
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
import math
|
||||||
|
import sys
|
||||||
|
|
||||||
|
DIM = 10
|
||||||
|
|
||||||
|
def main():
|
||||||
|
groups = sys.stdin.read().rstrip().split("\n\n")
|
||||||
|
tiles = {}
|
||||||
|
for group in groups:
|
||||||
|
lines = [line.rstrip() for line in group.splitlines()]
|
||||||
|
tile_id = int(lines[0][5:].rstrip(":"))
|
||||||
|
tiles[tile_id] = list(map(list, lines[1:]))
|
||||||
|
idim = int(math.sqrt(len(tiles)))
|
||||||
|
|
||||||
|
# Part 1
|
||||||
|
# instructions are not very clean, but looks like we only have to check 3
|
||||||
|
# rotations + optionally horizontal flip. vertical flip is not needed on
|
||||||
|
# example, and a vflip is actually rot180 + hflip.
|
||||||
|
perms = {}
|
||||||
|
for tile_id, tile in tiles.items():
|
||||||
|
perms[tile_id] = permutations(tile)
|
||||||
|
image = search({}, 0, 0, [], perms, idim)
|
||||||
|
tl = image[(0, 0)]
|
||||||
|
tr = image[(0, idim - 1)]
|
||||||
|
bl = image[(idim - 1, 0)]
|
||||||
|
br = image[(idim - 1, idim - 1)]
|
||||||
|
print("Multiplied corners:", tl[0] * tr[0] * bl[0] * br[0])
|
||||||
|
|
||||||
|
# Part 2
|
||||||
|
pattern = [
|
||||||
|
(0, 0), (1, 1),
|
||||||
|
(4, 1), (5, 0), (6, 0), (7, 1),
|
||||||
|
(10, 1), (11, 0), (12, 0), (13, 1),
|
||||||
|
(16, 1), (17, 0), (18, 0), (18, -1), (19, 0)
|
||||||
|
]
|
||||||
|
merged = merge_tiles(image, perms, idim)
|
||||||
|
global DIM
|
||||||
|
DIM = len(merged)
|
||||||
|
perms = permutations(merged)
|
||||||
|
max_monsters = max(find_monsters(perm, pattern) for perm in perms)
|
||||||
|
num_dashes = sum(c == "#" for row in merged for c in row)
|
||||||
|
monster_dashes = max_monsters * len(pattern)
|
||||||
|
print("Roughness:", num_dashes - monster_dashes)
|
||||||
|
|
||||||
|
def permutations(tile):
|
||||||
|
return [
|
||||||
|
tile,
|
||||||
|
hflip(tile),
|
||||||
|
rot90(tile),
|
||||||
|
rot90(hflip(tile)),
|
||||||
|
rot90(rot90(tile)),
|
||||||
|
rot90(rot90(hflip(tile))),
|
||||||
|
rot90(rot90(rot90(tile))),
|
||||||
|
rot90(rot90(rot90(hflip(tile)))),
|
||||||
|
]
|
||||||
|
|
||||||
|
def rot90(tile):
|
||||||
|
rtile = [[None for _ in range(DIM)] for _ in range(DIM)]
|
||||||
|
for x in range(DIM):
|
||||||
|
for y in range(DIM):
|
||||||
|
rtile[x][y] = tile[DIM - y - 1][x]
|
||||||
|
return rtile
|
||||||
|
|
||||||
|
def hflip(tile):
|
||||||
|
return [row[::] for row in tile[::-1]]
|
||||||
|
|
||||||
|
def search(image, x, y, placed, perms, idim):
|
||||||
|
fitting = find_fitting(image, x, y, placed, perms)
|
||||||
|
if (x, y) == (idim - 1, idim - 1) and len(fitting) == 1:
|
||||||
|
image[(idim - 1, idim - 1)] = fitting[0]
|
||||||
|
return image
|
||||||
|
for fit in fitting:
|
||||||
|
nimage = image.copy()
|
||||||
|
nimage[(x, y)] = fit
|
||||||
|
nx = (x + 1) % idim
|
||||||
|
ny = y if nx > 0 else y + 1
|
||||||
|
nplaced = placed + [fit[0]]
|
||||||
|
if (complete_image := search(nimage, nx, ny, nplaced, perms, idim)):
|
||||||
|
return complete_image
|
||||||
|
|
||||||
|
def find_fitting(image, x, y, placed, perms):
|
||||||
|
up_perm = image.get((x, y - 1))
|
||||||
|
up = perms[up_perm[0]][up_perm[1]] if up_perm else None
|
||||||
|
left_perm = image.get((x - 1, y))
|
||||||
|
left = perms[left_perm[0]][left_perm[1]] if left_perm else None
|
||||||
|
down_perm = image.get((x, y + 1))
|
||||||
|
down = perms[down_perm[0]][down_perm[1]] if down_perm else None
|
||||||
|
right_perm = image.get((x + 1, y))
|
||||||
|
right = perms[right_perm[0]][right_perm[1]] if right_perm else None
|
||||||
|
return [
|
||||||
|
(tile_id, tile_perm_id)
|
||||||
|
for tile_id, tile_perms in perms.items()
|
||||||
|
if tile_id not in placed
|
||||||
|
for tile_perm_id, tile_perm in enumerate(tile_perms)
|
||||||
|
if fits(tile_perm, up, left, down, right)
|
||||||
|
]
|
||||||
|
|
||||||
|
def fits(tile, up, left, down, right):
|
||||||
|
return all((
|
||||||
|
not up or tile[0] == up[-1],
|
||||||
|
not down or tile[-1] == down[0],
|
||||||
|
not left or [r[0] for r in tile] == [r[-1] for r in left],
|
||||||
|
not right or [r[-1] for r in tile] == [r[0] for r in right],
|
||||||
|
))
|
||||||
|
|
||||||
|
def merge_tiles(image, perms, idim):
|
||||||
|
tdim = DIM - 2
|
||||||
|
merged = [[] for _ in range(idim * tdim)]
|
||||||
|
for ix in range(idim):
|
||||||
|
for iy in range(idim):
|
||||||
|
i_tile_id, i_perm_id = image[(ix, iy)]
|
||||||
|
tile = perms[i_tile_id][i_perm_id]
|
||||||
|
for y, row in enumerate(tile[1:-1]):
|
||||||
|
merged[iy * tdim + y] += row[1:-1]
|
||||||
|
return merged
|
||||||
|
|
||||||
|
def find_monsters(image, pattern):
|
||||||
|
w, h = len(image[0]), len(image)
|
||||||
|
num_monsters = 0
|
||||||
|
for x in range(w):
|
||||||
|
for y in range(h):
|
||||||
|
for px, py in pattern:
|
||||||
|
ix, iy = x + px, y + py
|
||||||
|
if not 0 <= ix < w or not 0 <= iy < h:
|
||||||
|
break
|
||||||
|
if image[iy][ix] != "#":
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
num_monsters += 1
|
||||||
|
return num_monsters
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
51
2020/day23.py
Normal file
51
2020/day23.py
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def main():
|
||||||
|
lines = [line.rstrip() for line in sys.stdin]
|
||||||
|
|
||||||
|
# Part 1
|
||||||
|
cups = list(map(int, lines[0]))
|
||||||
|
for _ in range(100):
|
||||||
|
move(cups)
|
||||||
|
while cups[0] != 1:
|
||||||
|
cups.append(cups.pop(0))
|
||||||
|
print("Part 1:", "".join(map(str, cups))[1:])
|
||||||
|
|
||||||
|
# Part 2
|
||||||
|
# No spare 256TB of RAM nor repetitions it seems! Use another structure.
|
||||||
|
cups_list = list(map(int, lines[0]))
|
||||||
|
cups_list += list(range(10, 1000001))
|
||||||
|
cups = {
|
||||||
|
cups_list[i]: cups_list[(i + 1) % 1000000]
|
||||||
|
for i in range(len(cups_list))
|
||||||
|
}
|
||||||
|
cc = cups_list[0]
|
||||||
|
for _ in range(10000000):
|
||||||
|
zyoooom(cups, cc)
|
||||||
|
cc = cups[cc]
|
||||||
|
print("Part 2:", cups[1] * cups[cups[1]])
|
||||||
|
|
||||||
|
def move(cups):
|
||||||
|
cc = cups[0]
|
||||||
|
pick = cups[1:4]
|
||||||
|
d = cc - 1 or 9
|
||||||
|
while d in pick:
|
||||||
|
d = d - 1 if d > 1 else 9
|
||||||
|
del cups[1:4]
|
||||||
|
di = cups.index(d) + 1
|
||||||
|
cups[di:di] = pick
|
||||||
|
cups.append(cups.pop(0))
|
||||||
|
|
||||||
|
def zyoooom(cups, c):
|
||||||
|
pick = cups[c], cups[cups[c]], cups[cups[cups[c]]]
|
||||||
|
after_pick = cups[pick[2]]
|
||||||
|
dest = c - 1 or 1000000
|
||||||
|
while dest in pick:
|
||||||
|
dest = dest - 1 if dest > 1 else 1000000
|
||||||
|
after_dest = cups[dest]
|
||||||
|
cups[c] = after_pick
|
||||||
|
cups[dest] = pick[0]
|
||||||
|
cups[pick[2]] = after_dest
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
65
2020/day24.py
Normal file
65
2020/day24.py
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from grid import Grid
|
||||||
|
|
||||||
|
def main():
|
||||||
|
lines = [line.rstrip() for line in sys.stdin]
|
||||||
|
g = Grid(value_factory=int)
|
||||||
|
|
||||||
|
# Part 1
|
||||||
|
for line in lines:
|
||||||
|
x, y = 0, 0
|
||||||
|
while line:
|
||||||
|
if line[0] in ("e", "w"):
|
||||||
|
x, y = move(x, y, line[0])
|
||||||
|
line = line[1:]
|
||||||
|
else:
|
||||||
|
x, y = move(x, y, line[:2])
|
||||||
|
line = line[2:]
|
||||||
|
g.setv(x, y, abs(g.getv(x, y) - 1))
|
||||||
|
print("Black tiles:", sum(v for _, _, v in g.values_gen()))
|
||||||
|
|
||||||
|
# Part 2 aka stop using this grid class it's horrible
|
||||||
|
for _ in range(100):
|
||||||
|
expand(g)
|
||||||
|
yagol(g)
|
||||||
|
print("Black tiles p2:", sum(v for _, _, v in g.values_gen()))
|
||||||
|
|
||||||
|
def move(x, y, d):
|
||||||
|
if d in ("e", "w"):
|
||||||
|
x += 1 if d == "e" else -1
|
||||||
|
else:
|
||||||
|
dy, dx = d[0], d[1]
|
||||||
|
if y % 2 == 0 and dx == "w":
|
||||||
|
x -= 1
|
||||||
|
elif y % 2 == 1 and dx == "e":
|
||||||
|
x += 1
|
||||||
|
y += 1 if dy == "s" else -1
|
||||||
|
return x, y
|
||||||
|
|
||||||
|
D = ["e", "se", "sw", "w", "nw", "ne"]
|
||||||
|
|
||||||
|
def expand(g):
|
||||||
|
for x, y, _ in list(g.values_gen()):
|
||||||
|
for d in D:
|
||||||
|
dx, dy = move(x, y, d)
|
||||||
|
if not g.hasv(dx, dy):
|
||||||
|
g.setv(dx, dy, 0)
|
||||||
|
|
||||||
|
def yagol(g):
|
||||||
|
c = {}
|
||||||
|
for x, y, v in g.values_gen():
|
||||||
|
bn = 0
|
||||||
|
for d in D:
|
||||||
|
nx, ny = move(x, y, d)
|
||||||
|
if g.hasv(nx, ny):
|
||||||
|
bn += g.getv(nx, ny)
|
||||||
|
if v == 1 and (bn == 0 or bn > 2):
|
||||||
|
c[(x, y)] = 0
|
||||||
|
elif v == 0 and bn == 2:
|
||||||
|
c[(x, y)] = 1
|
||||||
|
for (x, y), v in c.items():
|
||||||
|
g.setv(x, y, v)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
29
2020/day25.py
Normal file
29
2020/day25.py
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def main():
|
||||||
|
lines = [line.rstrip() for line in sys.stdin]
|
||||||
|
cpk, dpk = int(lines[0]), int(lines[1])
|
||||||
|
|
||||||
|
dls = crack(dpk, 7) # cracking door's key is much quicker
|
||||||
|
k = gen_key(cpk, dls)
|
||||||
|
print(k)
|
||||||
|
|
||||||
|
def step(v, sn):
|
||||||
|
return (v * sn) % 20201227
|
||||||
|
|
||||||
|
def crack(pk, sn):
|
||||||
|
i = 0
|
||||||
|
v = 1
|
||||||
|
while v != pk:
|
||||||
|
v = step(v, sn)
|
||||||
|
i += 1
|
||||||
|
return i
|
||||||
|
|
||||||
|
def gen_key(sn, ls):
|
||||||
|
v = 1
|
||||||
|
for _ in range(ls):
|
||||||
|
v = step(v, sn)
|
||||||
|
return v
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
19
2020/new.py
19
2020/new.py
|
@ -1,19 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
import os
|
|
||||||
from datetime import date
|
|
||||||
|
|
||||||
TEMPLATE = """\
|
|
||||||
import sys
|
|
||||||
|
|
||||||
def main():
|
|
||||||
lines = [line.rstrip() for line in sys.stdin]
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
"""
|
|
||||||
|
|
||||||
day = date.today().day
|
|
||||||
with open(f"day{day}.py", "wt") as f:
|
|
||||||
f.write(TEMPLATE)
|
|
||||||
os.system(f"python ../fetch.py {day}")
|
|
19
fetch.py
19
fetch.py
|
@ -1,19 +0,0 @@
|
||||||
from datetime import datetime
|
|
||||||
import os
|
|
||||||
import requests
|
|
||||||
import sys
|
|
||||||
|
|
||||||
if len(sys.argv) < 2:
|
|
||||||
print("Usage: <fetch> day")
|
|
||||||
sys.exit()
|
|
||||||
day = sys.argv[1]
|
|
||||||
year = sys.argv[2] if len(sys.argv) > 2 else str(datetime.now().year)
|
|
||||||
|
|
||||||
URL = "https://adventofcode.com/{}/day/{}/input"
|
|
||||||
SESSION_ID = os.environ["AOC_SESSION"]
|
|
||||||
|
|
||||||
response = requests.get(URL.format(year, day), cookies={"session": SESSION_ID})
|
|
||||||
response.raise_for_status()
|
|
||||||
|
|
||||||
with open("day{}.txt".format(day), "wt") as output_file:
|
|
||||||
output_file.write(response.text)
|
|
59
prepare.py
Normal file
59
prepare.py
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import webbrowser
|
||||||
|
from datetime import datetime
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import requests
|
||||||
|
|
||||||
|
|
||||||
|
URL = "https://adventofcode.com/{}/day/{}"
|
||||||
|
SESSION_ID = os.environ["AOC_SESSION"]
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
now = datetime.now()
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument("day", type=int, default=now.day)
|
||||||
|
parser.add_argument("year", type=int, default=now.year)
|
||||||
|
parser.add_argument("--lang", default="py")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
day_url = get_url(args.day, args.year)
|
||||||
|
input_url = day_url + "/input"
|
||||||
|
input_text = fetch(input_url)
|
||||||
|
create_files(input_text, args.day, args.year, args.lang)
|
||||||
|
webbrowser.open_new_tab(day_url)
|
||||||
|
webbrowser.open_new_tab(input_url)
|
||||||
|
|
||||||
|
def fetch(input_url):
|
||||||
|
response = requests.get(input_url, cookies={"session": SESSION_ID})
|
||||||
|
response.raise_for_status()
|
||||||
|
return response.text
|
||||||
|
|
||||||
|
def get_url(day, year):
|
||||||
|
return URL.format(year, day)
|
||||||
|
|
||||||
|
def create_files(text, day, year, lang):
|
||||||
|
root_dir = Path(__file__).parent.resolve()
|
||||||
|
year_dir = root_dir / str(year)
|
||||||
|
year_dir.mkdir(exist_ok=True)
|
||||||
|
input_path = year_dir / f"day{day}.txt"
|
||||||
|
with open(input_path, "wt") as output_file:
|
||||||
|
output_file.write(text)
|
||||||
|
template_path = root_dir / f"template.{lang}"
|
||||||
|
if template_path.exists():
|
||||||
|
if lang == "rs":
|
||||||
|
bin_path = year_dir / "src" / "bin"
|
||||||
|
bin_path.mkdir(exist_ok=True)
|
||||||
|
script_path = bin_path / f"day{day}.{lang}"
|
||||||
|
else:
|
||||||
|
script_path = year_dir / f"day{day}.{lang}"
|
||||||
|
shutil.copyfile(template_path, script_path)
|
||||||
|
else:
|
||||||
|
print(f"No template for {lang}.")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
7
template.py
Normal file
7
template.py
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def main():
|
||||||
|
lines = [line.rstrip() for line in sys.stdin]
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
5
template.rs
Normal file
5
template.rs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
use aoc::input;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue