├── 2015 ├── advent22 │ └── simulazione-1235.odt.ods ├── advent15 │ └── input.txt ├── advent4.go ├── backtrack.go ├── advent20 │ ├── advent.go │ └── advent_2.go ├── advent1.go ├── advent12 │ ├── advent12_test.go │ └── advent12.py ├── advent23 │ └── input.txt ├── advent25 │ └── advent.py ├── advent10.go ├── advent3.go ├── advent2b.go ├── advent14 │ ├── input.txt │ └── advent_test.go ├── advent5b.go ├── advent13 │ └── input_test.txt ├── advent9.txt ├── advent8.go ├── advent5.go ├── advent3b.go ├── advent19 │ ├── input.txt │ └── advent.go ├── advent17 │ └── advent.go ├── advent2.go ├── advent18 │ └── advent.go ├── advent11 │ ├── advent11.go │ └── advent11_test.go ├── advent6.go └── advent6b.go ├── 2016 ├── 10 │ └── 10.py ├── 12 │ ├── input │ └── 12.py ├── 13 │ └── 13.py ├── 14 │ └── 14.py ├── 15 │ ├── input │ └── 15.py ├── 16 │ └── 16.py ├── 17 │ └── 17.py ├── 18 │ ├── input │ └── 18.py ├── 19 │ └── 19.py ├── 20 │ ├── 20.py │ └── 20green.py ├── 23 │ └── input ├── 25 │ └── input ├── 06 │ └── 06.py ├── 07 │ ├── 07b.py │ └── 07.py ├── 05 │ └── 05.py ├── 09 │ └── 09.py ├── 01 │ ├── input │ └── 01.py ├── 04 │ └── 04.py ├── 03 │ └── 03.py ├── 08 │ └── 08.py └── 02 │ └── 02.py ├── 2017 ├── 10 │ └── 10.py ├── 11 │ └── 11.py ├── 12 │ └── 12.py ├── 13 │ ├── input │ └── 13.py ├── 15 │ └── 15.py ├── 16 │ └── 16.py ├── 17 │ └── 17.py ├── 18 │ └── input ├── 19 │ └── input-test ├── 20 │ └── input-test ├── 21 │ └── input-test ├── 22 │ └── input ├── 23 │ └── input ├── 24 │ ├── input-test │ ├── input │ └── 24.py ├── 04 │ └── 04.py ├── 07 │ └── input2 ├── 05 │ ├── 05.py │ └── 05.c ├── 09 │ └── 09.py ├── 06 │ └── 06.py ├── 08 │ └── 08.py └── 02 │ └── 02.py ├── 2018 ├── 12 │ ├── input.txt │ └── 12.py ├── 14 │ └── 14.py ├── 15 │ └── input.txt ├── 19 │ └── input.txt ├── 21 │ └── input.txt ├── 01 │ └── 01.py ├── 05 │ └── 05.py ├── 02 │ └── 02.py ├── 06 │ ├── input.txt │ └── 06.py ├── 08 │ └── 08.py ├── 03 │ └── 03.py └── 09 │ └── 09.py ├── 2019 ├── 10 │ └── input.txt ├── 12 │ └── input.txt ├── 16 │ └── input.txt ├── 19 │ └── input.txt ├── 24 │ └── input.txt ├── 25 │ └── map.png ├── 02 │ ├── input.txt │ └── 02.py ├── 01 │ ├── 01.py │ └── input.txt ├── 04 │ └── 04.py ├── 07 │ └── input.txt └── 08 │ └── 08.py ├── 2020 ├── 10 │ ├── input.txt │ ├── day_10.py │ └── test_10.py ├── 11 │ └── test_11.py ├── 12 │ └── test_12.py ├── 13 │ ├── input.txt │ ├── test_13.py │ └── day_13.py ├── 14 │ └── test_14.py ├── 15 │ ├── day_15.py │ └── test_15.py ├── 17 │ ├── input.txt │ └── day_17.py ├── 18 │ ├── day_18.py │ └── test_18.py ├── 21 │ └── test_21.py ├── 22 │ ├── input.txt │ ├── test_22.py │ └── day_22.py ├── 23 │ ├── test_23.py │ └── day_23.py ├── 24 │ └── test_24.py ├── 25 │ ├── input.txt │ ├── day_25.py │ └── test_25.py ├── conftest.py ├── 02 │ ├── day_02.py │ └── test_02.py ├── 01 │ ├── day_01.py │ └── test_01.py ├── 06 │ ├── day_06.py │ └── test_06.py ├── 03 │ ├── day_03.py │ └── test_03.py ├── 08 │ └── test_08.py ├── 09 │ ├── test_09.py │ └── day_09.py ├── 05 │ ├── day_05.py │ └── test_05.py └── 07 │ ├── test_07.py │ └── day_07.py ├── 2021 ├── 10 │ ├── test_10.py │ └── day_10.py ├── 11 │ ├── input.txt │ └── test_11.py ├── 12 │ ├── input.txt │ ├── day_12.py │ └── test_12.py ├── 13 │ ├── test_13.py │ └── day_13.py ├── 14 │ ├── test_14.py │ ├── input.txt │ └── 14.py ├── 15 │ ├── test_15.py │ └── day_15.py ├── 16 │ └── input.txt ├── 17 │ ├── input.txt │ ├── test_17.py │ └── day_17.py ├── 19 │ └── rotations.py ├── 20 │ └── test_20.py ├── 21 │ ├── input.txt │ └── test_21.py ├── 23 │ ├── input.txt │ └── test_23.py ├── 24 │ ├── test_24.py │ └── short_24.py ├── 25 │ ├── test_25.py │ └── day_25.py ├── 06 │ ├── input.txt │ ├── test_06.py │ └── day_06.py ├── conftest.py ├── 07 │ ├── test_07.py │ └── day_07.py ├── 01 │ ├── test_01.py │ └── day_01.py ├── 02 │ ├── test_02.py │ └── day_02.py ├── 09 │ ├── test_09.py │ └── day_09.py ├── 03 │ ├── test_03.py │ └── day_03.py ├── 05 │ ├── test_05.py │ └── day_05.py ├── 04 │ └── test_04.py └── 08 │ └── test_08.py ├── 2022 ├── 10 │ └── day_10.py ├── 11 │ ├── test_11.py │ └── input.txt ├── 12 │ └── test_12.py ├── 13 │ ├── eval.py │ ├── test_13.py │ └── day_13.py ├── 14 │ └── test_14.py ├── 15 │ ├── test_15.py │ └── day_15.py ├── 16 │ └── test_16.py ├── 17 │ └── test_17.py ├── 18 │ └── test_18.py ├── 20 │ └── test_20.py ├── 06 │ ├── day_06.py │ └── test_06.py ├── conftest.py ├── 02 │ ├── test_02.py │ └── day_02.py ├── 08 │ └── test_08.py ├── 04 │ ├── test_04.py │ └── day_04.py ├── 01 │ ├── test_01.py │ └── day_01.py ├── 03 │ ├── test_03.py │ └── day_03.py ├── 05 │ ├── test_05.py │ └── day_05.py ├── 09 │ └── test_09.py └── 07 │ ├── test_07.py │ └── day_07.py └── .gitignore /2020/25/input.txt: -------------------------------------------------------------------------------- 1 | 1614360 2 | 7734663 3 | -------------------------------------------------------------------------------- /2021/17/input.txt: -------------------------------------------------------------------------------- 1 | target area: x=111..161, y=-154..-101 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *.swp 3 | a.out 4 | .cache* 5 | __pycache__ 6 | -------------------------------------------------------------------------------- /2019/24/input.txt: -------------------------------------------------------------------------------- 1 | #.... 2 | #...# 3 | ##.## 4 | ....# 5 | #.##. 6 | -------------------------------------------------------------------------------- /2017/21/input-test: -------------------------------------------------------------------------------- 1 | ../.# => ##./#../... 2 | .#./..#/### => #..#/..../..../#..# 3 | -------------------------------------------------------------------------------- /2019/25/map.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leriomaggio/aoc-1/main/2019/25/map.png -------------------------------------------------------------------------------- /2017/24/input-test: -------------------------------------------------------------------------------- 1 | 0/2 2 | 2/2 3 | 2/3 4 | 3/4 5 | 3/5 6 | 0/1 7 | 10/1 8 | 9/10 9 | -------------------------------------------------------------------------------- /2021/21/input.txt: -------------------------------------------------------------------------------- 1 | Player 1 starting position: 1 2 | Player 2 starting position: 3 3 | -------------------------------------------------------------------------------- /2017/20/input-test: -------------------------------------------------------------------------------- 1 | p=< 3,0,0>, v=< 2,0,0>, a=<-1,0,0> 2 | p=< 4,0,0>, v=< 0,0,0>, a=<-2,0,0> 3 | -------------------------------------------------------------------------------- /2021/23/input.txt: -------------------------------------------------------------------------------- 1 | ############# 2 | #...........# 3 | ###B#C#A#D### 4 | #B#C#D#A# 5 | ######### 6 | -------------------------------------------------------------------------------- /2019/12/input.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /2016/18/input: -------------------------------------------------------------------------------- 1 | ^..^^.^^^..^^.^...^^^^^....^.^..^^^.^.^.^^...^.^.^.^.^^.....^.^^.^.^.^.^.^.^^..^^^^^...^.....^....^. 2 | -------------------------------------------------------------------------------- /2020/17/input.txt: -------------------------------------------------------------------------------- 1 | ..#....# 2 | ##.#..## 3 | .###.... 4 | #....#.# 5 | #.###### 6 | ##.#.... 7 | #....... 8 | .#...... 9 | -------------------------------------------------------------------------------- /2015/advent22/simulazione-1235.odt.ods: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leriomaggio/aoc-1/main/2015/advent22/simulazione-1235.odt.ods -------------------------------------------------------------------------------- /2017/19/input-test: -------------------------------------------------------------------------------- 1 | | 2 | | +--+ 3 | A | C 4 | F---|----E|--+ 5 | | | | D 6 | +B-+ +--+ 7 | -------------------------------------------------------------------------------- /2020/13/input.txt: -------------------------------------------------------------------------------- 1 | 1002394 2 | 13,x,x,41,x,x,x,37,x,x,x,x,x,419,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,19,x,x,x,23,x,x,x,x,x,29,x,421,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,17 3 | -------------------------------------------------------------------------------- /2021/11/input.txt: -------------------------------------------------------------------------------- 1 | 4721224663 2 | 6875415276 3 | 2742448428 4 | 4878231556 5 | 5684643743 6 | 3553681866 7 | 4788183625 8 | 4255856532 9 | 1415818775 10 | 2326886125 11 | -------------------------------------------------------------------------------- /2017/04/04.py: -------------------------------------------------------------------------------- 1 | passphrases = [l.split() for l in open("input", "r").readlines()] 2 | 3 | passphrases_ordered = [["".join(sorted(p)) for p in l] for l in passphrases] 4 | 5 | for p in (passphrases, passphrases_ordered): 6 | print(sum(1 if len(set(l)) == len(l) else 0 for l in p)) 7 | -------------------------------------------------------------------------------- /2017/07/input2: -------------------------------------------------------------------------------- 1 | pbga (66) 2 | xhth (57) 3 | ebii (61) 4 | havc (66) 5 | ktlj (57) 6 | fwft (72) -> ktlj, cntj, xhth 7 | qoyq (66) 8 | padx (45) -> pbga, havc, qoyq 9 | tknk (41) -> ugml, padx, fwft 10 | jptl (61) 11 | ugml (68) -> gyxo, ebii, jptl 12 | gyxo (61) 13 | cntj (57) 14 | -------------------------------------------------------------------------------- /2016/12/input: -------------------------------------------------------------------------------- 1 | cpy 1 a 2 | cpy 1 b 3 | cpy 26 d 4 | jnz c 2 5 | jnz 1 5 6 | cpy 7 c 7 | inc d 8 | dec c 9 | jnz c -2 10 | cpy a c 11 | inc a 12 | dec b 13 | jnz b -2 14 | cpy c b 15 | dec d 16 | jnz d -6 17 | cpy 16 c 18 | cpy 17 d 19 | inc a 20 | dec d 21 | jnz d -2 22 | dec c 23 | jnz c -5 24 | -------------------------------------------------------------------------------- /2015/advent15/input.txt: -------------------------------------------------------------------------------- 1 | Sprinkles: capacity 5, durability -1, flavor 0, texture 0, calories 5 2 | PeanutButter: capacity -1, durability 3, flavor 0, texture 0, calories 1 3 | Frosting: capacity 0, durability -1, flavor 4, texture 0, calories 6 4 | Sugar: capacity -1, durability 0, flavor 0, texture 2, calories 8 5 | -------------------------------------------------------------------------------- /2021/12/input.txt: -------------------------------------------------------------------------------- 1 | CV-mk 2 | gm-IK 3 | sk-gm 4 | ca-sk 5 | sx-mk 6 | gm-start 7 | sx-ca 8 | kt-sk 9 | ca-VS 10 | kt-ml 11 | kt-ca 12 | mk-IK 13 | end-sx 14 | end-sk 15 | gy-sx 16 | end-ca 17 | ca-ml 18 | gm-CV 19 | sx-kt 20 | start-CV 21 | IK-start 22 | CV-kt 23 | ml-mk 24 | ml-CV 25 | ml-gm 26 | ml-IK 27 | -------------------------------------------------------------------------------- /2016/23/input: -------------------------------------------------------------------------------- 1 | cpy a b 2 | dec b 3 | cpy a d 4 | cpy 0 a 5 | cpy b c 6 | inc a 7 | dec c 8 | jnz c -2 9 | dec d 10 | jnz d -5 11 | dec b 12 | cpy b c 13 | cpy c d 14 | dec d 15 | inc c 16 | jnz d -2 17 | tgl c 18 | cpy -16 c 19 | jnz 1 c 20 | cpy 94 c 21 | jnz 99 d 22 | inc a 23 | inc d 24 | jnz d -2 25 | inc c 26 | jnz c -5 27 | -------------------------------------------------------------------------------- /2018/01/01.py: -------------------------------------------------------------------------------- 1 | freqs = [int(x.strip()) for x in open("input.txt").readlines()] 2 | print(sum(freqs)) 3 | curr_freq = 0 4 | seen = set([0]) 5 | n = 0 6 | while True: 7 | curr_freq += freqs[n % len(freqs)] 8 | if curr_freq in seen: 9 | print(curr_freq) 10 | break 11 | seen.add(curr_freq) 12 | n += 1 13 | -------------------------------------------------------------------------------- /2019/02/input.txt: -------------------------------------------------------------------------------- 1 | 1,0,0,3,1,1,2,3,1,3,4,3,1,5,0,3,2,1,10,19,2,9,19,23,1,9,23,27,2,27,9,31,1,31,5,35,2,35,9,39,1,39,10,43,2,43,13,47,1,47,6,51,2,51,10,55,1,9,55,59,2,6,59,63,1,63,6,67,1,67,10,71,1,71,10,75,2,9,75,79,1,5,79,83,2,9,83,87,1,87,9,91,2,91,13,95,1,95,9,99,1,99,6,103,2,103,6,107,1,107,5,111,1,13,111,115,2,115,6,119,1,119,5,123,1,2,123,127,1,6,127,0,99,2,14,0,0 2 | -------------------------------------------------------------------------------- /2016/06/06.py: -------------------------------------------------------------------------------- 1 | from collections import Counter 2 | 3 | counts = [[] for i in range(8)] 4 | 5 | for line in open("input").readlines(): 6 | for i, c in enumerate(line.strip()): 7 | counts[i].append(c) 8 | 9 | print("".join(Counter(count).most_common()[0][0] for count in counts)) 10 | print("".join(Counter(count).most_common()[-1][0] for count in counts)) 11 | -------------------------------------------------------------------------------- /2016/15/input: -------------------------------------------------------------------------------- 1 | Disc #1 has 17 positions; at time=0, it is at position 5. 2 | Disc #2 has 19 positions; at time=0, it is at position 8. 3 | Disc #3 has 7 positions; at time=0, it is at position 1. 4 | Disc #4 has 13 positions; at time=0, it is at position 7. 5 | Disc #5 has 5 positions; at time=0, it is at position 1. 6 | Disc #6 has 3 positions; at time=0, it is at position 0. 7 | -------------------------------------------------------------------------------- /2016/25/input: -------------------------------------------------------------------------------- 1 | cpy a d 2 | cpy 4 c 3 | cpy 643 b 4 | inc d 5 | dec b 6 | jnz b -2 7 | dec c 8 | jnz c -5 9 | cpy d a 10 | jnz 0 0 11 | cpy a b 12 | cpy 0 a 13 | cpy 2 c 14 | jnz b 2 15 | jnz 1 6 16 | dec b 17 | dec c 18 | jnz c -4 19 | inc a 20 | jnz 1 -7 21 | cpy 2 b 22 | jnz c 2 23 | jnz 1 4 24 | dec b 25 | dec c 26 | jnz 1 -4 27 | jnz 0 0 28 | out b 29 | jnz a -19 30 | jnz 1 -21 31 | -------------------------------------------------------------------------------- /2020/22/input.txt: -------------------------------------------------------------------------------- 1 | Player 1: 2 | 31 3 | 33 4 | 27 5 | 43 6 | 29 7 | 25 8 | 36 9 | 11 10 | 15 11 | 5 12 | 14 13 | 34 14 | 7 15 | 18 16 | 26 17 | 41 18 | 19 19 | 45 20 | 12 21 | 1 22 | 8 23 | 35 24 | 44 25 | 30 26 | 50 27 | 28 | Player 2: 29 | 42 30 | 40 31 | 6 32 | 17 33 | 3 34 | 16 35 | 22 36 | 23 37 | 32 38 | 21 39 | 24 40 | 46 41 | 49 42 | 48 43 | 38 44 | 47 45 | 13 46 | 9 47 | 39 48 | 20 49 | 10 50 | 2 51 | 37 52 | 28 53 | 4 54 | -------------------------------------------------------------------------------- /2017/05/05.py: -------------------------------------------------------------------------------- 1 | for times in range(2): 2 | maze = [int(l.strip()) for l in open("input", "r").readlines()] 3 | l = len(maze) 4 | 5 | pos = steps = 0 6 | 7 | while pos >= 0 and pos < l: 8 | if times == 0: 9 | inc = 1 10 | else: 11 | inc = -1 if maze[pos] >= 3 else 1 12 | maze[pos] += inc 13 | pos += maze[pos] - inc 14 | steps += 1 15 | 16 | print(steps) 17 | -------------------------------------------------------------------------------- /2022/06/day_06.py: -------------------------------------------------------------------------------- 1 | def message(data, length): 2 | for x in range(length, len(data)): 3 | if len(set(data[x - length:x])) == length: 4 | return x 5 | 6 | def solve1(data): 7 | return message(data, 4) 8 | 9 | 10 | def solve2(data): 11 | return message(data, 14) 12 | 13 | 14 | if __name__ == "__main__": 15 | data = open("input.txt").read() 16 | print(solve1(data)) 17 | print(solve2(data)) 18 | -------------------------------------------------------------------------------- /2017/23/input: -------------------------------------------------------------------------------- 1 | set b 84 2 | set c b 3 | jnz a 2 4 | jnz 1 5 5 | mul b 100 6 | sub b -100000 7 | set c b 8 | sub c -17000 9 | set f 1 10 | set d 2 11 | set e 2 12 | set g d 13 | mul g e 14 | sub g b 15 | jnz g 2 16 | set f 0 17 | sub e -1 18 | set g e 19 | sub g b 20 | jnz g -8 21 | sub d -1 22 | set g d 23 | sub g b 24 | jnz g -13 25 | jnz f 2 26 | sub h -1 27 | set g b 28 | sub g c 29 | jnz g 2 30 | jnz 1 3 31 | sub b -17 32 | jnz 1 -23 33 | -------------------------------------------------------------------------------- /2015/advent4.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "crypto/md5" 5 | "fmt" 6 | "io" 7 | "strings" 8 | ) 9 | 10 | func main() { 11 | key := "ckczppom" 12 | for i := 1; ; i++ { 13 | h := md5.New() 14 | io.WriteString(h, fmt.Sprintf("%s%d", key, i)) 15 | if strings.HasPrefix(fmt.Sprintf("%x", h.Sum(nil)), "000000") { 16 | fmt.Println(i) 17 | break 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /2016/07/07b.py: -------------------------------------------------------------------------------- 1 | import re 2 | def abba(x): 3 | return any(a == d and b == c and a != b for a, b, c, d in zip(x, x[1:], x[2:], x[3:])) 4 | 5 | lines = [re.split(r'\[([^\]]+)\]', line) for line in open('input')] 6 | parts = [(' '.join(p[::2]), ' '.join(p[1::2])) for p in lines] 7 | print(sum(abba(sn) and not(abba(hn)) for sn, hn in parts)) 8 | print(sum(any(a == c and a != b and b+a+b in hn for a, b, c in zip(sn, sn[1:], sn[2:])) for sn, hn in parts)) 9 | -------------------------------------------------------------------------------- /2015/backtrack.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | var cities = []string{"A", "B", "C", "D"} 8 | 9 | func route(i, n int) { 10 | if i == n { 11 | fmt.Println(cities) 12 | } else { 13 | for j := i; j <= n; j++ { 14 | cities[i], cities[j] = cities[j], cities[i] 15 | route(i+1, n) 16 | cities[i], cities[j] = cities[j], cities[i] 17 | } 18 | } 19 | } 20 | 21 | func main() { 22 | route(0, len(cities)-1) 23 | } 24 | -------------------------------------------------------------------------------- /2016/20/20.py: -------------------------------------------------------------------------------- 1 | blocked = [[int(n) for n in l.strip().split("-")] for l in open("input").readlines()] 2 | 3 | max_last = good_ip = 0 4 | 5 | for blocked_from, blocked_to in sorted(blocked): 6 | if blocked_from > max_last + 1: 7 | if good_ip == 0: 8 | print(max_last + 1) 9 | good_ip += blocked_from - (max_last + 1) 10 | max_last = max(max_last, blocked_to) 11 | 12 | print(good_ip + max_last - min(4294967295, max_last)) 13 | -------------------------------------------------------------------------------- /2017/09/09.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | data = open("input").read().strip() 4 | 5 | data = re.sub("!.", "", data) 6 | garbage = re.findall("<[^>]*>", data) 7 | data = re.sub("<[^>]*>", "", data) 8 | data = re.sub(",", "", data) 9 | 10 | tot = 0 11 | value = 0 12 | for p in data: 13 | if p == "{": 14 | value += 1 15 | elif p == "}": 16 | tot += value 17 | value -= 1 18 | 19 | print(tot) 20 | print(sum(len(l) - 2 for l in garbage)) 21 | -------------------------------------------------------------------------------- /2015/advent20/advent.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | const MAX = 1000000 8 | 9 | func main() { 10 | var house [MAX]int 11 | found := false 12 | for elf := 1; elf < MAX && !found; elf++ { 13 | for present := elf; present < MAX; present += elf { 14 | house[present] += elf * 10 15 | if house[present] >= 36000000 { 16 | fmt.Println(present, house[present]) 17 | found = true 18 | break 19 | } 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /2017/06/06.py: -------------------------------------------------------------------------------- 1 | banks = [4, 1, 15, 12, 0, 9, 9, 5, 5, 8, 7, 3, 14, 5, 12, 3] 2 | 3 | L = len(banks) 4 | 5 | 6 | for c in range(2): 7 | step = 0 8 | seen = set() 9 | 10 | while not tuple(banks) in seen: 11 | seen.add(tuple(banks)) 12 | p = banks.index(max(banks)) 13 | m, banks[p] = banks[p], 0 14 | while m > 0: 15 | p += 1 16 | banks[p % L] += 1 17 | m -= 1 18 | step += 1 19 | 20 | print(step) 21 | -------------------------------------------------------------------------------- /2017/13/input: -------------------------------------------------------------------------------- 1 | 0: 3 2 | 1: 2 3 | 2: 4 4 | 4: 4 5 | 6: 5 6 | 8: 8 7 | 10: 6 8 | 12: 6 9 | 14: 6 10 | 16: 6 11 | 18: 8 12 | 20: 8 13 | 22: 12 14 | 24: 10 15 | 26: 9 16 | 28: 8 17 | 30: 8 18 | 32: 12 19 | 34: 12 20 | 36: 12 21 | 38: 12 22 | 40: 8 23 | 42: 12 24 | 44: 14 25 | 46: 14 26 | 48: 10 27 | 50: 12 28 | 52: 12 29 | 54: 14 30 | 56: 14 31 | 58: 14 32 | 62: 12 33 | 64: 14 34 | 66: 14 35 | 68: 14 36 | 70: 12 37 | 74: 14 38 | 76: 14 39 | 78: 14 40 | 80: 18 41 | 82: 17 42 | 84: 30 43 | 88: 14 44 | -------------------------------------------------------------------------------- /2015/advent20/advent_2.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | const MAX = 1000000 8 | 9 | func main() { 10 | var house [MAX]int 11 | found := false 12 | for elf := 1; elf < MAX && !found; elf++ { 13 | present := elf 14 | for count := 0; count < 50 && present < MAX; count++ { 15 | house[present] += elf * 11 16 | if house[present] >= 36000000 { 17 | fmt.Println(present, house[present]) 18 | found = true 19 | break 20 | } 21 | present += elf 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /2015/advent1.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | //"strings" 7 | //"strconv" 8 | ) 9 | 10 | func main() { 11 | dat, _ := ioutil.ReadFile("src/advent/advent1.txt") 12 | floor := 0 13 | first := true 14 | for i, ch := range dat { 15 | if ch == '(' { 16 | floor += 1 17 | } else if ch == ')' { 18 | floor -= 1 19 | } 20 | if floor == -1 && first { 21 | fmt.Printf("Floor -1: %d\n", i+1) 22 | first = false 23 | } 24 | } 25 | fmt.Printf("Floor: %d\n", floor) 26 | } 27 | -------------------------------------------------------------------------------- /2018/05/05.py: -------------------------------------------------------------------------------- 1 | data = open("input.txt").read().strip() 2 | 3 | 4 | def react(data): 5 | p = 0 6 | while p < len(data) - 1: 7 | if data[p].lower() == data[p + 1].lower() and data[p] != data[p + 1]: 8 | data = data[:p] + data[p + 2:] 9 | if p > 0: 10 | p -= 1 11 | else: 12 | p += 1 13 | return data 14 | 15 | 16 | print(len(react(data))) 17 | print(min(len(react(data.replace(c, "").replace(c.upper(), ""))) for c in "abcdefghijklmnopqrstuvwxyz")) 18 | -------------------------------------------------------------------------------- /2015/advent12/advent12_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "testing" 4 | 5 | var Jsons = []string{"[1,2,3]", "{\"a\":2,\"b\":4}", "[[[3]]]", "{\"a\":{\"b\":4},\"c\":-1}", "{\"a\":[-1,1]}", "[-1,{\"a\":1}]", "[]", "{}"} 6 | var Results = []int{6, 6, 3, 3, 0, 0, 0, 0} 7 | 8 | func TestJsonSum(t *testing.T) { 9 | for i := 0; i < len(Results); i++ { 10 | sum := JsonSum(Jsons[i]) 11 | if false && sum != Results[i] { 12 | t.Fatalf("Sum di %s dovrebbe essere %d e non %d", Jsons[i], Results[i], sum) 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /2018/21/input.txt: -------------------------------------------------------------------------------- 1 | #ip 2 2 | seti 123 0 3 3 | bani 3 456 3 4 | eqri 3 72 3 5 | addr 3 2 2 6 | seti 0 0 2 7 | seti 0 0 3 8 | bori 3 65536 4 9 | seti 10649702 3 3 10 | bani 4 255 5 11 | addr 3 5 3 12 | bani 3 16777215 3 13 | muli 3 65899 3 14 | bani 3 16777215 3 15 | gtir 256 4 5 16 | addr 5 2 2 17 | addi 2 1 2 18 | seti 27 7 2 19 | seti 0 6 5 20 | addi 5 1 1 21 | muli 1 256 1 22 | gtrr 1 4 1 23 | addr 1 2 2 24 | addi 2 1 2 25 | seti 25 9 2 26 | addi 5 1 5 27 | seti 17 9 2 28 | setr 5 7 4 29 | seti 7 1 2 30 | eqrr 3 0 5 31 | addr 5 2 2 32 | seti 5 4 2 33 | -------------------------------------------------------------------------------- /2017/18/input: -------------------------------------------------------------------------------- 1 | set i 31 2 | set a 1 3 | mul p 17 4 | jgz p p 5 | mul a 2 6 | add i -1 7 | jgz i -2 8 | add a -1 9 | set i 127 10 | set p 735 11 | mul p 8505 12 | mod p a 13 | mul p 129749 14 | add p 12345 15 | mod p a 16 | set b p 17 | mod b 10000 18 | snd b 19 | add i -1 20 | jgz i -9 21 | jgz a 3 22 | rcv b 23 | jgz b -1 24 | set f 0 25 | set i 126 26 | rcv a 27 | rcv b 28 | set p a 29 | mul p -1 30 | add p b 31 | jgz p 4 32 | snd a 33 | set a b 34 | jgz 1 3 35 | snd b 36 | set f 1 37 | add i -1 38 | jgz i -11 39 | snd a 40 | jgz f -16 41 | jgz a -19 42 | -------------------------------------------------------------------------------- /2015/advent23/input.txt: -------------------------------------------------------------------------------- 1 | jio a, +19 2 | inc a 3 | tpl a 4 | inc a 5 | tpl a 6 | inc a 7 | tpl a 8 | tpl a 9 | inc a 10 | inc a 11 | tpl a 12 | tpl a 13 | inc a 14 | inc a 15 | tpl a 16 | inc a 17 | inc a 18 | tpl a 19 | jmp +23 20 | tpl a 21 | tpl a 22 | inc a 23 | inc a 24 | tpl a 25 | inc a 26 | inc a 27 | tpl a 28 | inc a 29 | tpl a 30 | inc a 31 | tpl a 32 | inc a 33 | tpl a 34 | inc a 35 | inc a 36 | tpl a 37 | inc a 38 | inc a 39 | tpl a 40 | tpl a 41 | inc a 42 | jio a, +8 43 | inc b 44 | jie a, +4 45 | tpl a 46 | inc a 47 | jmp +2 48 | hlf a 49 | jmp -7 50 | -------------------------------------------------------------------------------- /2018/02/02.py: -------------------------------------------------------------------------------- 1 | from collections import Counter 2 | 3 | threes = twos = 0 4 | 5 | ids = [id.strip() for id in open("input.txt").readlines()] 6 | 7 | for id in ids: 8 | count = Counter(id.strip()) 9 | twos += 1 if 2 in count.values() else 0 10 | threes += 1 if 3 in count.values() else 0 11 | 12 | print(twos * threes) 13 | 14 | for n in range(len(ids[0])): 15 | new_ids = [id[:n] + id[n + 1:] for id in ids] 16 | most_common = Counter(new_ids).most_common()[0] 17 | if most_common[1] == 2: 18 | print(most_common[0]) 19 | break 20 | -------------------------------------------------------------------------------- /2016/15/15.py: -------------------------------------------------------------------------------- 1 | def solve(discs): 2 | wait = 0 3 | 4 | while True: 5 | second = wait + 1 6 | for disc in discs: 7 | if (disc[1] + second) % disc[0] != 0: 8 | break 9 | second += 1 10 | else: 11 | return wait 12 | break 13 | wait += 1 14 | 15 | 16 | rows = [l.strip().split() for l in open("input").readlines()] 17 | discs = [[int(parts[3]), int(parts[11][:-1])] for parts in rows] 18 | 19 | print(solve(discs)) 20 | 21 | discs += [[11, 0]] 22 | 23 | print(solve(discs)) 24 | -------------------------------------------------------------------------------- /2015/advent25/advent.py: -------------------------------------------------------------------------------- 1 | 2 | start = 20151125 3 | 4 | 5 | def next(x): 6 | return (x * 252533) % 33554393 7 | 8 | def count(row, col): 9 | x = y = 1 10 | while y != row: 11 | x += y 12 | y += 1 13 | n = 1 14 | y = row + 1 15 | while n != col: 16 | x += y 17 | n += 1 18 | y += 1 19 | return x 20 | 21 | n = count(3, 4) 22 | x = start 23 | for i in xrange(n - 1): 24 | x = next(x) 25 | 26 | n = count(2947, 3029) 27 | 28 | x = start 29 | for i in xrange(n - 1): 30 | x = next(x) 31 | print x 32 | 33 | 34 | -------------------------------------------------------------------------------- /2017/08/08.py: -------------------------------------------------------------------------------- 1 | registers = {} 2 | 3 | max_v = 0 4 | 5 | for instruction in open("input", "r").readlines(): 6 | parts = instruction.split() 7 | reg = parts[0] 8 | op = parts[1] 9 | value = int(parts[2]) 10 | reg_if = parts[4] 11 | op_if = parts[5] 12 | value_if = parts[6] 13 | if eval("{} {} {}".format(registers.get(reg_if, 0), op_if, value_if)): 14 | registers[reg] = registers.get(reg, 0) + (value if op == "inc" else - value) 15 | max_v = max(max_v, max(registers.values())) 16 | 17 | print(max(registers.values())) 18 | print(max_v) 19 | -------------------------------------------------------------------------------- /2017/24/input: -------------------------------------------------------------------------------- 1 | 14/42 2 | 2/3 3 | 6/44 4 | 4/10 5 | 23/49 6 | 35/39 7 | 46/46 8 | 5/29 9 | 13/20 10 | 33/9 11 | 24/50 12 | 0/30 13 | 9/10 14 | 41/44 15 | 35/50 16 | 44/50 17 | 5/11 18 | 21/24 19 | 7/39 20 | 46/31 21 | 38/38 22 | 22/26 23 | 8/9 24 | 16/4 25 | 23/39 26 | 26/5 27 | 40/40 28 | 29/29 29 | 5/20 30 | 3/32 31 | 42/11 32 | 16/14 33 | 27/49 34 | 36/20 35 | 18/39 36 | 49/41 37 | 16/6 38 | 24/46 39 | 44/48 40 | 36/4 41 | 6/6 42 | 13/6 43 | 42/12 44 | 29/41 45 | 39/39 46 | 9/3 47 | 30/2 48 | 25/20 49 | 15/6 50 | 15/23 51 | 28/40 52 | 8/7 53 | 26/23 54 | 48/10 55 | 28/28 56 | 2/13 57 | 48/14 58 | -------------------------------------------------------------------------------- /2018/19/input.txt: -------------------------------------------------------------------------------- 1 | #ip 5 2 | addi 5 16 5 3 | seti 1 2 2 4 | seti 1 0 4 5 | mulr 2 4 3 6 | eqrr 3 1 3 7 | addr 3 5 5 8 | addi 5 1 5 9 | addr 2 0 0 10 | addi 4 1 4 11 | gtrr 4 1 3 12 | addr 5 3 5 13 | seti 2 4 5 14 | addi 2 1 2 15 | gtrr 2 1 3 16 | addr 3 5 5 17 | seti 1 1 5 18 | mulr 5 5 5 19 | addi 1 2 1 20 | mulr 1 1 1 21 | mulr 5 1 1 22 | muli 1 11 1 23 | addi 3 6 3 24 | mulr 3 5 3 25 | addi 3 15 3 26 | addr 1 3 1 27 | addr 5 0 5 28 | seti 0 7 5 29 | setr 5 8 3 30 | mulr 3 5 3 31 | addr 5 3 3 32 | mulr 5 3 3 33 | muli 3 14 3 34 | mulr 3 5 3 35 | addr 1 3 1 36 | seti 0 0 0 37 | seti 0 6 5 38 | -------------------------------------------------------------------------------- /2021/06/input.txt: -------------------------------------------------------------------------------- 1 | 2,5,3,4,4,5,3,2,3,3,2,2,4,2,5,4,1,1,4,4,5,1,2,1,5,2,1,5,1,1,1,2,4,3,3,1,4,2,3,4,5,1,2,5,1,2,2,5,2,4,4,1,4,5,4,2,1,5,5,3,2,1,3,2,1,4,2,5,5,5,2,3,3,5,1,1,5,3,4,2,1,4,4,5,4,5,3,1,4,5,1,5,3,5,4,4,4,1,4,2,2,2,5,4,3,1,4,4,3,4,2,1,1,5,3,3,2,5,3,1,2,2,4,1,4,1,5,1,1,2,5,2,2,5,2,4,4,3,4,1,3,3,5,4,5,4,5,5,5,5,5,4,4,5,3,4,3,3,1,1,5,2,4,5,5,1,5,2,4,5,4,2,4,4,4,2,2,2,2,2,3,5,3,1,1,2,1,1,5,1,4,3,4,2,5,3,4,4,3,5,5,5,4,1,3,4,4,2,2,1,4,1,2,1,2,1,5,5,3,4,1,3,2,1,4,5,1,5,5,1,2,3,4,2,1,4,1,4,2,3,3,2,4,1,4,1,4,4,1,5,3,1,5,2,1,1,2,3,3,2,4,1,2,1,5,1,1,2,1,2,1,2,4,5,3,5,5,1,3,4,1,1,3,3,2,2,4,3,1,1,2,4,1,1,1,5,4,2,4,3 2 | -------------------------------------------------------------------------------- /2020/conftest.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | 4 | def pytest_addoption(parser): 5 | parser.addoption('--slow', action='store_true', dest="slow", default=False, help="Run slow tests") 6 | 7 | 8 | def pytest_configure(config): 9 | config.addinivalue_line("markers", "slow: mark test as slow test") 10 | 11 | 12 | def pytest_collection_modifyitems(config, items): 13 | slow = config.getoption("--slow") 14 | skip_slow = pytest.mark.skip(reason="need --slow option to run") 15 | for item in items: 16 | if not slow and "slow" in item.keywords: 17 | item.add_marker(skip_slow) 18 | -------------------------------------------------------------------------------- /2021/conftest.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | 4 | def pytest_addoption(parser): 5 | parser.addoption('--slow', action='store_true', dest="slow", default=False, help="Run slow tests") 6 | 7 | 8 | def pytest_configure(config): 9 | config.addinivalue_line("markers", "slow: mark test as slow test") 10 | 11 | 12 | def pytest_collection_modifyitems(config, items): 13 | slow = config.getoption("--slow") 14 | skip_slow = pytest.mark.skip(reason="need --slow option to run") 15 | for item in items: 16 | if not slow and "slow" in item.keywords: 17 | item.add_marker(skip_slow) 18 | -------------------------------------------------------------------------------- /2022/conftest.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | 4 | def pytest_addoption(parser): 5 | parser.addoption('--slow', action='store_true', dest="slow", default=False, help="Run slow tests") 6 | 7 | 8 | def pytest_configure(config): 9 | config.addinivalue_line("markers", "slow: mark test as slow test") 10 | 11 | 12 | def pytest_collection_modifyitems(config, items): 13 | slow = config.getoption("--slow") 14 | skip_slow = pytest.mark.skip(reason="need --slow option to run") 15 | for item in items: 16 | if not slow and "slow" in item.keywords: 17 | item.add_marker(skip_slow) 18 | -------------------------------------------------------------------------------- /2015/advent10.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | var step = 50 9 | str := []int{3, 1, 1, 3, 3, 2, 2, 1, 1, 3} 10 | for i := 0; i < step; i++ { 11 | last_chr := str[0] 12 | new_str := []int{} 13 | for n, counter := 1, 1; n <= len(str); n++ { 14 | next_chr := -1 15 | if n < len(str) { 16 | next_chr = str[n] 17 | } 18 | if last_chr != next_chr { 19 | new_str = append(new_str, counter, last_chr) 20 | counter = 0 21 | } 22 | last_chr = next_chr 23 | counter++ 24 | } 25 | str = new_str 26 | } 27 | fmt.Println(len(str)) 28 | } 29 | -------------------------------------------------------------------------------- /2020/02/day_02.py: -------------------------------------------------------------------------------- 1 | def solve(data): 2 | valid = valid2 = 0 3 | 4 | for l in data.strip().split('\n'): 5 | parts = l.split(' ') 6 | min_l, max_l = [int(p) for p in parts[0].split("-")] 7 | letter, password = parts[1][0], parts[2] 8 | if min_l <= password.count(letter) <= max_l: 9 | valid += 1 10 | if (password[min_l - 1] + password[max_l - 1]).count(letter) == 1: 11 | valid2 += 1 12 | return valid, valid2 13 | 14 | 15 | if __name__ == "__main__": 16 | part1, part2, = solve(open("input.txt").read()) 17 | print(part1) 18 | print(part2) 19 | -------------------------------------------------------------------------------- /2017/17/17.py: -------------------------------------------------------------------------------- 1 | def spinlock(n, step): 2 | buffer = [0] 3 | pos = 0 4 | last = None 5 | for cont in range(n): 6 | pos = (pos + step) % len(buffer) + 1 7 | buffer.insert(pos, cont + 1) 8 | return buffer[pos + 1] 9 | 10 | 11 | def spinlock_0(n, step): 12 | pos = 0 13 | buffer_1 = None 14 | len_buffer = 1 15 | for cont in range(n): 16 | pos = (pos + step) % len_buffer + 1 17 | len_buffer += 1 18 | if pos == 1: 19 | buffer_1 = cont + 1 20 | return buffer_1 21 | 22 | 23 | print(spinlock(2017, 354)) 24 | print(spinlock_0(50000000, 354)) 25 | -------------------------------------------------------------------------------- /2017/15/15.py: -------------------------------------------------------------------------------- 1 | def next_gen(gen, mult, mod): 2 | while True: 3 | gen = (gen * mult) % 2147483647 4 | if gen % mod == 0: 5 | return gen 6 | 7 | 8 | def judge(gen_a, gen_b, pairs, mod_a=1, mod_b=1): 9 | vote = 0 10 | while pairs > 0: 11 | gen_a = next_gen(gen_a, 16807, mod_a) 12 | gen_b = next_gen(gen_b, 48271, mod_b) 13 | if (gen_a & 65535) == (gen_b & 65535): 14 | vote += 1 15 | pairs -= 1 16 | return vote 17 | 18 | 19 | # print(judge(65, 8921, 40000000)) 20 | 21 | print(judge(883, 879, 40000000)) 22 | print(judge(883, 879, 5000000, 4, 8)) 23 | -------------------------------------------------------------------------------- /2021/07/test_07.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import day_07 as day 4 | 5 | 6 | class TestDay(unittest.TestCase): 7 | def setUp(self): 8 | self.data = """16,1,2,0,4,2,7,1,2,14 9 | """ 10 | 11 | def test_part_1(self): 12 | self.assertEqual(37, day.solve1(self.data)) 13 | 14 | def test_part_2(self): 15 | self.assertEqual(168, day.solve2(self.data)) 16 | 17 | def test_solution(self): 18 | import os 19 | data = open(os.path.dirname(__file__) + "/input.txt").read() 20 | self.assertEqual(day.solve1(data), 345197) 21 | self.assertEqual(day.solve2(data), 96361606) 22 | -------------------------------------------------------------------------------- /2018/12/input.txt: -------------------------------------------------------------------------------- 1 | initial state: ##..#..##....#..#..#..##.#.###.######..#..###.#.#..##.###.#.##..###..#.#..#.##.##..###.#.#...#.##.. 2 | 3 | ##### => # 4 | ##.## => # 5 | ..##. => . 6 | ..#.# => . 7 | ..### => # 8 | #..## => # 9 | .#.#. => # 10 | #.#.# => # 11 | #.##. => . 12 | ####. => . 13 | #..#. => # 14 | ..#.. => . 15 | .#### => . 16 | ##.#. => # 17 | #...# => . 18 | .##.# => # 19 | #.### => . 20 | .#..# => # 21 | .#... => # 22 | .##.. => # 23 | .###. => . 24 | #.... => . 25 | ###.. => . 26 | ##..# => . 27 | ...## => # 28 | ##... => . 29 | ..... => . 30 | ....# => . 31 | ###.# => # 32 | #.#.. => . 33 | .#.## => # 34 | ...#. => . 35 | -------------------------------------------------------------------------------- /2022/02/test_02.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | day = __import__('day_' + __file__[-5:-3]) 3 | 4 | 5 | class TestDay(unittest.TestCase): 6 | def setUp(self): 7 | self.data = """A Y 8 | B X 9 | C Z""" 10 | 11 | def test_part_1(self): 12 | self.assertEqual(15, day.solve1(self.data)) 13 | 14 | def test_part_2(self): 15 | self.assertEqual(12, day.solve2(self.data)) 16 | 17 | def test_solution(self): 18 | import os 19 | data = open(os.path.dirname(__file__) + "/input.txt").read() 20 | self.assertEqual(day.solve1(data), 12772) 21 | self.assertEqual(day.solve2(data), 11618) 22 | -------------------------------------------------------------------------------- /2016/05/05.py: -------------------------------------------------------------------------------- 1 | import hashlib 2 | 3 | door = u"ffykfhsq" 4 | 5 | pwd = "" 6 | pwd2 = [0]*8 7 | 8 | i = 0 9 | found = 0 10 | 11 | while len(pwd) < 8 or found < 8: 12 | dig = hashlib.md5((door + str(i)).encode('utf8')).hexdigest()[:7] 13 | if i % 100000 == 0: 14 | print(pwd, i, dig, pwd2) 15 | if dig.startswith("00000"): 16 | if len(pwd) < 8: 17 | pwd += dig[5] 18 | if dig[5] in "01234567": 19 | pos = int(dig[5]) 20 | if pwd2[pos] == 0: 21 | found += 1 22 | pwd2[pos] = dig[6] 23 | i += 1 24 | 25 | print(pwd) 26 | print("".join(pwd2)) 27 | -------------------------------------------------------------------------------- /2020/01/day_01.py: -------------------------------------------------------------------------------- 1 | from itertools import combinations 2 | 3 | 4 | def load(data): 5 | return [int(line) for line in data.strip().split("\n")] 6 | 7 | 8 | def solve1(data): 9 | numbers = load(data) 10 | for a, b in combinations(numbers, 2): 11 | if a + b == 2020: 12 | return (a * b) 13 | 14 | 15 | def solve2(data): 16 | numbers = load(data) 17 | for a, b, c in combinations(numbers, 3): 18 | if a + b + c == 2020: 19 | return (a * b * c) 20 | 21 | 22 | if __name__ == "__main__": 23 | data = open("input.txt").read() 24 | print(solve1(data)) 25 | print(solve2(data)) 26 | -------------------------------------------------------------------------------- /2020/12/test_12.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import day_12 as day 4 | 5 | 6 | class TestDay(unittest.TestCase): 7 | def setUp(self): 8 | self.data = """F10 9 | N3 10 | F7 11 | R90 12 | F11 13 | """ 14 | 15 | def test_part_1(self): 16 | self.assertEqual(day.solve1(self.data), 25) 17 | 18 | def test_part_2(self): 19 | self.assertEqual(day.solve2(self.data), 286) 20 | 21 | def test_solution(self): 22 | import os 23 | data = open(os.path.dirname(__file__) + "/input.txt").read() 24 | self.assertEqual(day.solve1(data), 445) 25 | self.assertEqual(day.solve2(data), 42495) 26 | -------------------------------------------------------------------------------- /2021/25/test_25.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import pytest 3 | 4 | import day_25 as day 5 | 6 | 7 | class TestDay(unittest.TestCase): 8 | def setUp(self): 9 | self.data_1 = """v...>>.vv> 10 | .vv>>.vv.. 11 | >>.>v>...v 12 | >>v>>.>.v. 13 | v>v.vv.v.. 14 | >.>>..v... 15 | .vv..>.>v. 16 | v.v..>>v.v 17 | ....v..v.> 18 | """ 19 | 20 | def test_part_1(self): 21 | self.assertEqual(day.solve1(self.data_1), 58) 22 | 23 | @pytest.mark.slow 24 | def test_solution(self): 25 | import os 26 | data = open(os.path.dirname(__file__) + "/input.txt").read() 27 | self.assertEqual(day.solve1(data), 380) 28 | -------------------------------------------------------------------------------- /2022/06/test_06.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | day = __import__('day_' + __file__[-5:-3]) 3 | 4 | 5 | class TestDay(unittest.TestCase): 6 | def setUp(self): 7 | self.data = """mjqjpqmgbljsphdztnvjfqwrcgsmlb""" 8 | 9 | def test_part_1(self): 10 | self.assertEqual(7, day.solve1(self.data)) 11 | 12 | def test_part_2(self): 13 | self.assertEqual(19, day.solve2(self.data)) 14 | 15 | def test_solution(self): 16 | import os 17 | data = open(os.path.dirname(__file__) + "/input.txt").read() 18 | self.assertEqual(day.solve1(data), 1582) 19 | self.assertEqual(day.solve2(data), 3588) 20 | -------------------------------------------------------------------------------- /2015/advent3.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | var c rune 7 | var x, y int 8 | houses := make(map[string]int) 9 | for { 10 | houses[fmt.Sprintf("%d_%d", x, y)] += 1 11 | if _, err := fmt.Scanf("%c", &c); err != nil { 12 | fmt.Println(err) 13 | break 14 | } 15 | if c == '^' { 16 | y += 1 17 | } else if c == 'v' { 18 | y -= 1 19 | } else if c == '>' { 20 | x += 1 21 | } else if c == '<' { 22 | x -= 1 23 | } 24 | } 25 | fmt.Printf("%d\n", len(houses)) 26 | } 27 | -------------------------------------------------------------------------------- /2016/09/09.py: -------------------------------------------------------------------------------- 1 | data = open("input").read().strip() 2 | 3 | 4 | def size(data, expand=False): 5 | l = 0 6 | while True: 7 | pos = data.find("(") 8 | if pos == -1: 9 | l += len(data) 10 | break 11 | l += pos 12 | pos2 = data.index(")") 13 | cont, mult = [int(p) for p in data[pos + 1: pos2].split("x")] 14 | buf, data = data[pos2 + 1: pos2 + 1 + cont], data[pos2 + 1 + cont:] 15 | if expand: 16 | l += mult * size(buf, expand) 17 | else: 18 | l += mult * cont 19 | return l 20 | 21 | print(size(data)) 22 | print(size(data, True)) 23 | -------------------------------------------------------------------------------- /2020/13/test_13.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import day_13 as day 4 | 5 | 6 | class TestDay(unittest.TestCase): 7 | def setUp(self): 8 | self.data = """939 9 | 7,13,x,x,59,x,31,19 10 | """ 11 | 12 | def test_part_1(self): 13 | self.assertEqual(day.solve1(self.data), 295) 14 | 15 | def test_part_2(self): 16 | self.assertEqual(day.solve2(self.data), 1068781) 17 | 18 | def test_solution(self): 19 | import os 20 | data = open(os.path.dirname(__file__) + "/input.txt").read() 21 | self.assertEqual(day.solve1(data), 2947) 22 | self.assertEqual(day.solve2(data), 526090562196173) 23 | -------------------------------------------------------------------------------- /2019/16/input.txt: -------------------------------------------------------------------------------- 1 | 59796737047664322543488505082147966997246465580805791578417462788780740484409625674676660947541571448910007002821454068945653911486140823168233915285229075374000888029977800341663586046622003620770361738270014246730936046471831804308263177331723460787712423587453725840042234550299991238029307205348958992794024402253747340630378944672300874691478631846617861255015770298699407254311889484508545861264449878984624330324228278057377313029802505376260196904213746281830214352337622013473019245081834854781277565706545720492282616488950731291974328672252657631353765496979142830459889682475397686651923318015627694176893643969864689257620026916615305397 2 | -------------------------------------------------------------------------------- /2016/01/input: -------------------------------------------------------------------------------- 1 | R1, L3, R5, R5, R5, L4, R5, R1, R2, L1, L1, R5, R1, L3, L5, L2, R4, L1, R4, R5, L3, R5, L1, R3, L5, R1, L2, R1, L5, L1, R1, R4, R1, L1, L3, R3, R5, L3, R4, L4, R5, L5, L1, L2, R4, R3, R3, L185, R3, R4, L5, L4, R48, R1, R2, L1, R1, L4, L4, R77, R5, L2, R192, R2, R5, L4, L5, L3, R2, L4, R1, L5, R5, R4, R1, R2, L3, R4, R4, L2, L4, L3, R5, R4, L2, L1, L3, R1, R5, R5, R2, L5, L2, L3, L4, R2, R1, L4, L1, R1, R5, R3, R3, R4, L1, L4, R1, L2, R3, L3, L2, L1, L2, L2, L1, L2, R3, R1, L4, R1, L1, L4, R1, L2, L5, R3, L5, L2, L2, L3, R1, L4, R1, R1, R2, L1, L4, L4, R2, R2, R2, R2, R5, R1, L1, L4, L5, R2, R4, L3, L5, R2, R3, L4, L1, R2, R3, R5, L2, L3, R3, R1, R3 2 | -------------------------------------------------------------------------------- /2020/01/test_01.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import day_01 as day 4 | 5 | 6 | class TestDay(unittest.TestCase): 7 | def setUp(self): 8 | self.data = """1721 9 | 979 10 | 366 11 | 299 12 | 675 13 | 1456""" 14 | 15 | def test_part_1(self): 16 | self.assertEqual(514579, day.solve1(self.data)) 17 | 18 | def test_part_2(self): 19 | self.assertEqual(241861950, day.solve2(self.data)) 20 | 21 | def test_solution(self): 22 | import os 23 | data = open(os.path.dirname(__file__) + "/input.txt").read() 24 | self.assertEqual(day.solve1(data), 889779) 25 | self.assertEqual(day.solve2(data), 76110336) 26 | -------------------------------------------------------------------------------- /2022/08/test_08.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | day = __import__('day_' + __file__[-5:-3]) 3 | 4 | 5 | class TestDay(unittest.TestCase): 6 | def setUp(self): 7 | self.data = """30373 8 | 25512 9 | 65332 10 | 33549 11 | 35390""" 12 | 13 | def test_part_1(self): 14 | self.assertEqual(21, day.solve1(self.data)) 15 | 16 | def test_part_2(self): 17 | self.assertEqual(8, day.solve2(self.data)) 18 | 19 | def test_solution(self): 20 | import os 21 | data = open(os.path.dirname(__file__) + "/input.txt").read() 22 | self.assertEqual(day.solve1(data), 1827) 23 | self.assertEqual(day.solve2(data), 335580) 24 | -------------------------------------------------------------------------------- /2022/13/eval.py: -------------------------------------------------------------------------------- 1 | def my_eval(parts, stack=None): 2 | if stack is None: 3 | stack, parts = [], line.replace(",", " ").replace("[", " [ ").replace("]", " ] ").split(" ")[::-1] 4 | while parts: 5 | part = parts.pop() 6 | if part.isdigit(): 7 | stack.append(int(part)) 8 | elif part == "[": 9 | stack.append(my_eval(parts, [])) 10 | elif part == "]": 11 | return stack 12 | return stack[0] 13 | 14 | 15 | for line in open("input.txt").read().split("\n"): 16 | if line: 17 | l1 = eval(line) 18 | l2 = my_eval(line) 19 | assert l1 == l2, f"\n{l1}\n !=\n{l2}" 20 | -------------------------------------------------------------------------------- /2020/02/test_02.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import day_02 as day 4 | 5 | 6 | class TestDay(unittest.TestCase): 7 | def setUp(self): 8 | self.data = """1-3 a: abcde 9 | 1-3 b: cdefg 10 | 2-9 c: ccccccccc 11 | """ 12 | 13 | def test_part_1(self): 14 | self.assertEqual(2, day.solve(self.data)[0]) 15 | 16 | def test_part_2(self): 17 | self.assertEqual(1, day.solve(self.data)[1]) 18 | 19 | def test_solution(self): 20 | import os 21 | data = open(os.path.dirname(__file__) + "/input.txt").read() 22 | part1, part2, = day.solve(data) 23 | self.assertEqual(part1, 580) 24 | self.assertEqual(part2, 611) 25 | -------------------------------------------------------------------------------- /2021/01/test_01.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import day_01 as day 4 | 5 | 6 | class TestDay(unittest.TestCase): 7 | def setUp(self): 8 | self.data = """199 9 | 200 10 | 208 11 | 210 12 | 200 13 | 207 14 | 240 15 | 269 16 | 260 17 | 263""" 18 | 19 | def test_part_1(self): 20 | self.assertEqual(7, day.solve1(self.data)) 21 | 22 | def test_part_2(self): 23 | self.assertEqual(5, day.solve2(self.data)) 24 | 25 | def test_solution(self): 26 | import os 27 | data = open(os.path.dirname(__file__) + "/input.txt").read() 28 | self.assertEqual(day.solve1(data), 1696) 29 | self.assertEqual(day.solve2(data), 1737) 30 | -------------------------------------------------------------------------------- /2018/06/input.txt: -------------------------------------------------------------------------------- 1 | 252, 125 2 | 128, 333 3 | 89, 324 4 | 141, 171 5 | 266, 338 6 | 117, 175 7 | 160, 236 8 | 234, 202 9 | 165, 192 10 | 204, 232 11 | 83, 192 12 | 229, 178 13 | 333, 57 14 | 70, 243 15 | 108, 350 16 | 161, 63 17 | 213, 277 18 | 87, 299 19 | 163, 68 20 | 135, 312 21 | 290, 87 22 | 73, 246 23 | 283, 146 24 | 80, 357 25 | 66, 312 26 | 159, 214 27 | 221, 158 28 | 175, 54 29 | 298, 342 30 | 348, 162 31 | 249, 90 32 | 189, 322 33 | 311, 181 34 | 194, 244 35 | 53, 295 36 | 80, 301 37 | 262, 332 38 | 268, 180 39 | 139, 287 40 | 115, 53 41 | 163, 146 42 | 220, 268 43 | 79, 85 44 | 95, 112 45 | 349, 296 46 | 179, 274 47 | 113, 132 48 | 158, 264 49 | 316, 175 50 | 268, 215 51 | -------------------------------------------------------------------------------- /2020/06/day_06.py: -------------------------------------------------------------------------------- 1 | def solve(data): 2 | tot = common = 0 3 | for group in data.split("\n\n"): 4 | subcommon = None 5 | for subgroup in group.strip().split("\n"): 6 | answers = set(subgroup) 7 | if subcommon is None: 8 | subcommon = answers 9 | else: 10 | subcommon = subcommon.intersection(answers) 11 | common += len(subcommon) 12 | tot += len(set(group.replace("\n", "").replace(" ", ""))) 13 | return tot, common 14 | 15 | 16 | if __name__ == "__main__": 17 | data = open("input.txt").read() 18 | tot, common = solve(data) 19 | print(tot) 20 | print(common) 21 | -------------------------------------------------------------------------------- /2021/02/test_02.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import day_02 as day 4 | 5 | 6 | class TestDay(unittest.TestCase): 7 | def setUp(self): 8 | self.data = """forward 5 9 | down 5 10 | forward 8 11 | up 3 12 | down 8 13 | forward 2""" 14 | 15 | def test_part_1(self): 16 | self.assertEqual(150, day.solve1(self.data)) 17 | 18 | def test_part_2(self): 19 | self.assertEqual(900, day.solve2(self.data)) 20 | 21 | def test_solution(self): 22 | import os 23 | data = open(os.path.dirname(__file__) + "/input.txt").read() 24 | self.assertEqual(day.solve1(data), 1693300) 25 | self.assertEqual(day.solve2(data), 1857958050) 26 | -------------------------------------------------------------------------------- /2021/09/test_09.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import day_09 as day 4 | 5 | 6 | class TestDay(unittest.TestCase): 7 | def setUp(self): 8 | self.data = """2199943210 9 | 3987894921 10 | 9856789892 11 | 8767896789 12 | 9899965678 13 | """ 14 | 15 | def test_part_1(self): 16 | self.assertEqual(15, day.solve1(self.data)) 17 | 18 | def test_part_2(self): 19 | self.assertEqual(1134, day.solve2(self.data)) 20 | 21 | def test_solution(self): 22 | import os 23 | data = open(os.path.dirname(__file__) + "/input.txt").read() 24 | self.assertEqual(day.solve1(data), 539) 25 | self.assertEqual(day.solve2(data), 736920) 26 | -------------------------------------------------------------------------------- /2021/17/test_17.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import pytest 3 | 4 | import day_17 as day 5 | 6 | 7 | class TestDay(unittest.TestCase): 8 | def setUp(self): 9 | self.data = """target area: x=20..30, y=-10..-5 10 | """ 11 | 12 | def test_part_1(self): 13 | self.assertEqual(day.solve1(self.data), 45) 14 | 15 | def test_part_2(self): 16 | self.assertEqual(day.solve2(self.data), 112) 17 | 18 | @pytest.mark.slow 19 | def test_solution(self): 20 | import os 21 | data = open(os.path.dirname(__file__) + "/input.txt").read() 22 | self.assertEqual(day.solve1(data), 11781) 23 | self.assertEqual(day.solve2(data), 4531) 24 | -------------------------------------------------------------------------------- /2022/04/test_04.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | day = __import__('day_' + __file__[-5:-3]) 3 | 4 | 5 | class TestDay(unittest.TestCase): 6 | def setUp(self): 7 | self.data = """2-4,6-8 8 | 2-3,4-5 9 | 5-7,7-9 10 | 2-8,3-7 11 | 6-6,4-6 12 | 2-6,4-8""" 13 | 14 | def test_part_1(self): 15 | self.assertEqual(2, day.solve1(self.data)) 16 | 17 | def test_part_2(self): 18 | self.assertEqual(4, day.solve2(self.data)) 19 | 20 | def test_solution(self): 21 | import os 22 | data = open(os.path.dirname(__file__) + "/input.txt").read() 23 | self.assertEqual(day.solve1(data), 448) 24 | self.assertEqual(day.solve2(data), 794) 25 | -------------------------------------------------------------------------------- /2016/20/20green.py: -------------------------------------------------------------------------------- 1 | blacklist = set() 2 | 3 | [blacklist.add(tuple([int(i) for i in l.strip().split('-')])) for l in open('input')] 4 | 5 | curmax = 0 6 | found = False 7 | foundmin = False 8 | whitelist = set() 9 | while curmax <= 2**32: 10 | found = True 11 | i = curmax 12 | for (start,end) in list(blacklist): 13 | if start <= i <= end: 14 | curmax = max(curmax, end+1) 15 | blacklist.remove((start,end)) 16 | found = False 17 | if found: 18 | if not foundmin: 19 | print(curmax) 20 | foundmin = True 21 | whitelist.add(curmax) 22 | curmax += 1 23 | print(len(whitelist)-1) 24 | 25 | -------------------------------------------------------------------------------- /2015/advent2b.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sort" 6 | ) 7 | 8 | func main() { 9 | var d, l [3]int 10 | var paper, ribbon int 11 | for { 12 | if _, err := fmt.Scanf("%dx%dx%d\n", &d[0], &d[1], &d[2]); err != nil { 13 | fmt.Println(err) 14 | break 15 | } else { 16 | l[0], l[1], l[2] = d[0]*d[1], d[1]*d[2], d[2]*d[0] 17 | sort.Ints(d[:]) 18 | sort.Ints(l[:]) 19 | paper += 3*l[0] + 2*l[1] + 2*l[2] 20 | ribbon += 2*d[0] + 2*d[1] + d[0]*d[1]*d[2] 21 | } 22 | } 23 | fmt.Println("paper:", paper) 24 | fmt.Println("ribbon:", ribbon) 25 | } 26 | -------------------------------------------------------------------------------- /2020/25/day_25.py: -------------------------------------------------------------------------------- 1 | def step(p, n): 2 | return (p * n) % 20201227 3 | 4 | 5 | def loop_size(e): 6 | n, m, s = 7, 1, 0 7 | while True: 8 | if m == e: 9 | return s 10 | m = step(m, n) 11 | s += 1 12 | 13 | 14 | def transform(m, s): 15 | n = m 16 | for i in range(s - 1): 17 | m = step(m, n) 18 | return m 19 | 20 | 21 | def parse(data): 22 | return list(int(n) for n in data.strip().split('\n')) 23 | 24 | 25 | def solve(data): 26 | card, door = parse(data) 27 | return transform(door, loop_size(card)) 28 | 29 | 30 | if __name__ == "__main__": 31 | data = open("input.txt").read() 32 | print(solve(data)) 33 | -------------------------------------------------------------------------------- /2022/17/test_17.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | day = __import__('day_' + __file__[-5:-3]) 3 | 4 | 5 | class TestDay(unittest.TestCase): 6 | def setUp(self): 7 | self.data = """>>><<><>><<<>><>>><<<>>><<<><<<>><>><<>>""" 8 | 9 | def test_part_1(self): 10 | self.assertEqual(3068, day.solve1(self.data)) 11 | 12 | def test_part_2(self): 13 | self.assertEqual(1514285714288, day.solve2(self.data)) 14 | pass 15 | 16 | def test_solution(self): 17 | import os 18 | data = open(os.path.dirname(__file__) + "/input.txt").read() 19 | self.assertEqual(3111, day.solve1(data)) 20 | self.assertEqual(1526744186042, day.solve2(data)) 21 | -------------------------------------------------------------------------------- /2021/21/test_21.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import day_21 as day 4 | 5 | 6 | class TestDay(unittest.TestCase): 7 | def setUp(self): 8 | self.data = """Player 1 starting position: 4 9 | Player 2 starting position: 8 10 | """ 11 | 12 | def test_part_1(self): 13 | self.assertEqual(day.solve1(self.data), 739785) 14 | 15 | def test_part_2(self): 16 | self.assertEqual(day.solve2(self.data), 444356092776315) 17 | 18 | def test_solution(self): 19 | import os 20 | data = open(os.path.dirname(__file__) + "/input.txt").read() 21 | self.assertEqual(day.solve1(data), 897798) 22 | self.assertEqual(day.solve2(data), 48868319769358) 23 | -------------------------------------------------------------------------------- /2016/19/19.py: -------------------------------------------------------------------------------- 1 | # The Josephus Problem 2 | # https://en.wikipedia.org/wiki/Josephus_problem 3 | # https://www.youtube.com/watch?v=uCsD3ZGzMgE 4 | 5 | def josephus_n(n_elfs): 6 | n = 1 7 | while n < n_elfs: 8 | n = n * 2 9 | n = n / 2 10 | return 1 + (n_elfs - n) * 2 11 | 12 | print(josephus_n(3017957)) 13 | 14 | def josephus(n, k): 15 | r = 0 16 | for i in xrange(1, n+1): 17 | r = (r+k)%i 18 | return r + 1 19 | 20 | print(josephus(3017957, 2)) 21 | 22 | def josephus_across(n): 23 | p = 1 24 | while 3 * p <= n: 25 | p*=3 26 | if n == p: 27 | return n 28 | return n - p + max(n - 2 * p, 0) 29 | 30 | print(josephus_across(3017957)) 31 | -------------------------------------------------------------------------------- /2015/advent14/input.txt: -------------------------------------------------------------------------------- 1 | Rudolph can fly 22 km/s for 8 seconds, but then must rest for 165 seconds. 2 | Cupid can fly 8 km/s for 17 seconds, but then must rest for 114 seconds. 3 | Prancer can fly 18 km/s for 6 seconds, but then must rest for 103 seconds. 4 | Donner can fly 25 km/s for 6 seconds, but then must rest for 145 seconds. 5 | Dasher can fly 11 km/s for 12 seconds, but then must rest for 125 seconds. 6 | Comet can fly 21 km/s for 6 seconds, but then must rest for 121 seconds. 7 | Blitzen can fly 18 km/s for 3 seconds, but then must rest for 50 seconds. 8 | Vixen can fly 20 km/s for 4 seconds, but then must rest for 75 seconds. 9 | Dancer can fly 7 km/s for 20 seconds, but then must rest for 119 seconds. 10 | -------------------------------------------------------------------------------- /2016/16/16.py: -------------------------------------------------------------------------------- 1 | def checksum(s): 2 | for n in range(0, len(s), 2): 3 | if s[n] == s[n + 1]: 4 | s[n / 2] = "1" 5 | else: 6 | s[n / 2] = "0" 7 | return s[:len(s) / 2] 8 | 9 | 10 | def fill(size, initial): 11 | while len(initial) < size: 12 | initial = initial + "0" + "".join("1" if c == "0" else "0" for c in initial[::-1]) 13 | initial = list(initial[:size]) 14 | while len(initial) % 2 == 0: 15 | initial = checksum(initial) 16 | return "".join(initial) 17 | 18 | 19 | size, initial = 20, "10000" 20 | 21 | print(fill(size, initial)) 22 | 23 | print(fill(272, "10001110011110000")) 24 | 25 | print(fill(35651584, "10001110011110000")) 26 | -------------------------------------------------------------------------------- /2020/03/day_03.py: -------------------------------------------------------------------------------- 1 | def solve1(wood, right, down): 2 | wood = [[1 if square == '#' else 0 for square in line] for line in wood.strip().split('\n')] 3 | start, trees, depth, width = [0, 0], 0, len(wood), len(wood[0]) 4 | while start[0] < depth: 5 | trees += wood[start[0]][start[1]] 6 | start = [start[0] + down, (start[1] + right) % width] 7 | return trees 8 | 9 | 10 | def solve2(wood): 11 | tot = 1 12 | for right, down in ((1, 1), (3, 1), (5, 1), (7, 1), (1, 2)): 13 | tot *= solve1(wood, right, down) 14 | return tot 15 | 16 | 17 | if __name__ == "__main__": 18 | wood = open("input.txt").read() 19 | print(solve1(wood, 3, 1)) 20 | print(solve2(wood)) 21 | -------------------------------------------------------------------------------- /2020/06/test_06.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import day_06 as day 4 | 5 | 6 | class TestDay(unittest.TestCase): 7 | def setUp(self): 8 | self.data = """abc 9 | 10 | a 11 | b 12 | c 13 | 14 | ab 15 | ac 16 | 17 | a 18 | a 19 | a 20 | a 21 | 22 | b 23 | """ 24 | 25 | def test_part_1(self): 26 | self.assertEqual(11, day.solve(self.data)[0]) 27 | 28 | def test_part_2(self): 29 | self.assertEqual(6, day.solve(self.data)[1]) 30 | 31 | def test_solution(self): 32 | import os 33 | data = open(os.path.dirname(__file__) + "/input.txt").read() 34 | part1, part2 = day.solve(data) 35 | self.assertEqual(part1, 6775) 36 | self.assertEqual(part2, 3356) 37 | -------------------------------------------------------------------------------- /2021/03/test_03.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import day_03 as day 4 | 5 | 6 | class TestDay(unittest.TestCase): 7 | def setUp(self): 8 | self.data = """00100 9 | 11110 10 | 10110 11 | 10111 12 | 10101 13 | 01111 14 | 00111 15 | 11100 16 | 10000 17 | 11001 18 | 00010 19 | 01010""" 20 | 21 | def test_part_1(self): 22 | self.assertEqual(198, day.solve1(self.data)) 23 | 24 | def test_part_2(self): 25 | self.assertEqual(230, day.solve2(self.data)) 26 | 27 | def test_solution(self): 28 | import os 29 | data = open(os.path.dirname(__file__) + "/input.txt").read() 30 | self.assertEqual(day.solve1(data), 3633500) 31 | self.assertEqual(day.solve2(data), 4550283) 32 | -------------------------------------------------------------------------------- /2021/06/test_06.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import day_06 as day 4 | 5 | 6 | class TestDay(unittest.TestCase): 7 | def setUp(self): 8 | self.data = """3,4,3,1,2""" 9 | 10 | def test_part_1_18(self): 11 | self.assertEqual(26, day.solve1(self.data, 18)) 12 | 13 | def test_part_1(self): 14 | self.assertEqual(5934, day.solve1(self.data)) 15 | 16 | def test_part_2(self): 17 | self.assertEqual(26984457539, day.solve1(self.data, 256)) 18 | 19 | def test_solution(self): 20 | import os 21 | data = open(os.path.dirname(__file__) + "/input.txt").read() 22 | self.assertEqual(day.solve1(data), 345387) 23 | self.assertEqual(day.solve2(data), 1574445493136) 24 | -------------------------------------------------------------------------------- /2022/01/test_01.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | day = __import__('day_' + __file__[-5:-3]) 3 | 4 | 5 | class TestDay(unittest.TestCase): 6 | def setUp(self): 7 | self.data = """1000 8 | 2000 9 | 3000 10 | 11 | 4000 12 | 13 | 5000 14 | 6000 15 | 16 | 7000 17 | 8000 18 | 9000 19 | 20 | 10000""" 21 | 22 | def test_part_1(self): 23 | self.assertEqual(24000, day.solve1(self.data)) 24 | 25 | def test_part_2(self): 26 | self.assertEqual(45000, day.solve2(self.data)) 27 | 28 | def test_solution(self): 29 | import os 30 | data = open(os.path.dirname(__file__) + "/input.txt").read() 31 | self.assertEqual(day.solve1(data), 67622) 32 | self.assertEqual(day.solve2(data), 201491) 33 | -------------------------------------------------------------------------------- /2021/05/test_05.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import day_05 as day 4 | 5 | 6 | class TestDay(unittest.TestCase): 7 | def setUp(self): 8 | self.data = """0,9 -> 5,9 9 | 8,0 -> 0,8 10 | 9,4 -> 3,4 11 | 2,2 -> 2,1 12 | 7,0 -> 7,4 13 | 6,4 -> 2,0 14 | 0,9 -> 2,9 15 | 3,4 -> 1,4 16 | 0,0 -> 8,8 17 | 5,5 -> 8,2""" 18 | 19 | def test_part_1(self): 20 | self.assertEqual(5, day.solve1(self.data)) 21 | 22 | def test_part_2(self): 23 | self.assertEqual(12, day.solve2(self.data)) 24 | 25 | def test_solution(self): 26 | import os 27 | data = open(os.path.dirname(__file__) + "/input.txt").read() 28 | self.assertEqual(day.solve1(data), 5774) 29 | self.assertEqual(day.solve2(data), 18423) 30 | -------------------------------------------------------------------------------- /2022/18/test_18.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | day = __import__('day_' + __file__[-5:-3]) 3 | 4 | 5 | class TestDay(unittest.TestCase): 6 | def setUp(self): 7 | self.data = """2,2,2 8 | 1,2,2 9 | 3,2,2 10 | 2,1,2 11 | 2,3,2 12 | 2,2,1 13 | 2,2,3 14 | 2,2,4 15 | 2,2,6 16 | 1,2,5 17 | 3,2,5 18 | 2,1,5 19 | 2,3,5 20 | """ 21 | 22 | def test_part_1(self): 23 | self.assertEqual(64, day.solve1(self.data)) 24 | 25 | def test_part_2(self): 26 | self.assertEqual(58, day.solve2(self.data)) 27 | 28 | def test_solution(self): 29 | import os 30 | data = open(os.path.dirname(__file__) + "/input.txt").read() 31 | self.assertEqual(4400, day.solve1(data)) 32 | self.assertEqual(2522, day.solve2(data)) 33 | -------------------------------------------------------------------------------- /2017/13/13.py: -------------------------------------------------------------------------------- 1 | raw = open("input").read().strip() 2 | 3 | layers = dict((int(l.strip()), int(r.strip())) for d in raw.split("\n") for l, r in [d.split(":")]) 4 | 5 | poses = tuple(layers.keys()) 6 | 7 | 8 | def gotcha(pos, time): 9 | try: 10 | return time % ((layers[pos] - 1) * 2) == 0 11 | except KeyError: 12 | return False 13 | 14 | delay = 0 15 | 16 | travel = max(layers.keys()) + 1 17 | 18 | while True: 19 | if delay == 0: 20 | print(sum(pos * layers[pos] for pos in range(travel) if gotcha(pos, pos))) 21 | else: 22 | for pos in poses: 23 | if gotcha(pos, delay + pos): 24 | break 25 | else: 26 | print(delay) 27 | break 28 | 29 | delay += 1 30 | -------------------------------------------------------------------------------- /2020/22/test_22.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import pytest 3 | 4 | import day_22 as day 5 | 6 | 7 | class TestDay(unittest.TestCase): 8 | def setUp(self): 9 | self.data = """Player 1: 10 | 9 11 | 2 12 | 6 13 | 3 14 | 1 15 | 16 | Player 2: 17 | 5 18 | 8 19 | 4 20 | 7 21 | 10 22 | """ 23 | 24 | def test_part1(self): 25 | self.assertEqual(day.solve(self.data), 306) 26 | 27 | def test_part2(self): 28 | self.assertEqual(day.solve(self.data, step=2), 291) 29 | 30 | @pytest.mark.slow 31 | def test_solution(self): 32 | import os 33 | data = open(os.path.dirname(__file__) + "/input.txt").read() 34 | self.assertEqual(day.solve(data), 32413) 35 | self.assertEqual(day.solve(data, step=2), 31596) 36 | -------------------------------------------------------------------------------- /2022/12/test_12.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import pytest 3 | day = __import__('day_' + __file__[-5:-3]) 4 | 5 | 6 | class TestDay(unittest.TestCase): 7 | def setUp(self): 8 | self.data = """Sabqponm 9 | abcryxxl 10 | accszExk 11 | acctuvwj 12 | abdefghi""" 13 | 14 | def test_part_1(self): 15 | self.assertEqual(31, day.solve1(self.data)) 16 | 17 | def test_part_2(self): 18 | self.assertEqual(29, day.solve2(self.data)) 19 | 20 | @pytest.mark.slow 21 | def test_solution(self): 22 | import os 23 | with open(os.path.dirname(__file__) + "/input.txt") as f_data: 24 | data = f_data.read() 25 | self.assertEqual(day.solve1(data), 534) 26 | self.assertEqual(day.solve2(data), 525) 27 | -------------------------------------------------------------------------------- /2017/22/input: -------------------------------------------------------------------------------- 1 | .########.....#...##.#### 2 | ....#..#.#.##.###..#.##.. 3 | ##.#.#..#.###.####.##.#.. 4 | ####...#...####...#.##.## 5 | ..#...###.#####.....##.## 6 | ..#.##.######.#...###...# 7 | .#....###..##....##...##. 8 | ##.##..####.#.######...## 9 | #...#..##.....#..#...#..# 10 | ........#.##..###.#.....# 11 | #.#..######.#.###..#...#. 12 | .#.##.##..##.####.....##. 13 | .....##..#....#####.#.#.. 14 | ...#.#.#..####.#..###..#. 15 | ##.#..##..##....#####.#.. 16 | .#.#..##...#.#####....##. 17 | .####.#.###.####...#####. 18 | ...#...######..#.##...#.# 19 | #..######...#.####.#..#.# 20 | ...##..##.#.##.#.#.#....# 21 | ###..###.#..#.....#.##.## 22 | ..#....##...#..#..##..#.. 23 | .#.###.##.....#.###.#.### 24 | ####.##...#.#....#..##... 25 | #.....#.#..#.##.#..###..# 26 | -------------------------------------------------------------------------------- /2022/14/test_14.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import pytest 3 | day = __import__('day_' + __file__[-5:-3]) 4 | 5 | 6 | class TestDay(unittest.TestCase): 7 | def setUp(self): 8 | self.data = """498,4 -> 498,6 -> 496,6 9 | 503,4 -> 502,4 -> 502,9 -> 494,9 10 | """ 11 | 12 | def test_part_1(self): 13 | self.assertEqual(24, day.solve1(self.data)) 14 | 15 | def test_part_2(self): 16 | self.assertEqual(93, day.solve2(self.data)) 17 | 18 | @pytest.mark.slow 19 | def test_solution(self): 20 | import os 21 | with open(os.path.dirname(__file__) + "/input.txt") as f_data: 22 | data = f_data.read() 23 | self.assertEqual(day.solve1(data), 858) 24 | self.assertEqual(day.solve2(data), 26845) 25 | -------------------------------------------------------------------------------- /2022/20/test_20.py: -------------------------------------------------------------------------------- 1 | import os 2 | import pytest 3 | import unittest 4 | day = __import__('day_' + __file__[-5:-3]) 5 | 6 | 7 | class TestDay(unittest.TestCase): 8 | def setUp(self): 9 | self.real_data = open(os.path.dirname(__file__) + "/input.txt").read() 10 | self.data = """1 11 | 2 12 | -3 13 | 3 14 | -2 15 | 0 16 | 4 17 | """ 18 | 19 | def test_part_1(self): 20 | self.assertEqual(3, day.solve1(self.data)) 21 | 22 | def test_part_2(self): 23 | self.assertEqual(1623178306, day.solve2(self.data)) 24 | 25 | def test_solution_part_1(self): 26 | self.assertEqual(7225, day.solve1(self.real_data)) 27 | 28 | def test_solution_part_2(self): 29 | self.assertEqual(548634267428, day.solve2(self.real_data)) 30 | -------------------------------------------------------------------------------- /2021/23/test_23.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import pytest 3 | 4 | import day_23 as day 5 | 6 | 7 | class TestDay(unittest.TestCase): 8 | def setUp(self): 9 | self.data = """############# 10 | #...........# 11 | ###B#C#B#D### 12 | #A#D#C#A# 13 | ######### 14 | """ 15 | 16 | def test_part_1(self): 17 | self.assertEqual(day.solve1(self.data), 12521) 18 | 19 | @pytest.mark.slow 20 | def test_part_2(self): 21 | self.assertEqual(day.solve2(self.data), 44169) 22 | 23 | @pytest.mark.slow 24 | def _test_solution(self): 25 | import os 26 | data = open(os.path.dirname(__file__) + "/input.txt").read() 27 | self.assertEqual(day.solve1(data), 11120) 28 | self.assertEqual(day.solve2(data), 1319618626668022) 29 | -------------------------------------------------------------------------------- /2016/04/04.py: -------------------------------------------------------------------------------- 1 | from collections import Counter 2 | 3 | tot = 0 4 | 5 | def dec(n, letter): 6 | if letter == ' ': 7 | return ' ' 8 | return chr(ord('a') + (ord(letter) - ord('a') + n) % 26) 9 | 10 | for room in open("input", "r").readlines(): 11 | parts = room.strip().split("-") 12 | name = " ".join(parts[:-1]) 13 | count = Counter(name.replace(" ", "")) 14 | parts = parts[-1].split("[") 15 | id = int(parts[0]) 16 | check = parts[1][:-1] 17 | if check == "".join(c[3] for c in sorted(["{:03d}".format(1000 - v) + k for k, v in count.most_common()])[:5]): 18 | tot += id 19 | name = "".join(dec(id, letter) for letter in name) 20 | if "north" in name: 21 | print(name, id) 22 | 23 | print(tot) 24 | 25 | 26 | -------------------------------------------------------------------------------- /2022/03/test_03.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | day = __import__('day_' + __file__[-5:-3]) 3 | 4 | 5 | class TestDay(unittest.TestCase): 6 | def setUp(self): 7 | self.data = """vJrwpWtwJgWrhcsFMMfFFhFp 8 | jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL 9 | PmmdzqPrVvPwwTWBwg 10 | wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn 11 | ttgJtRGJQctTZtZT 12 | CrZsJsPPZsGzwwsLwLmpwMDw""" 13 | 14 | def test_part_1(self): 15 | self.assertEqual(157, day.solve1(self.data)) 16 | 17 | def test_part_2(self): 18 | self.assertEqual(70, day.solve2(self.data)) 19 | 20 | def test_solution(self): 21 | import os 22 | data = open(os.path.dirname(__file__) + "/input.txt").read() 23 | self.assertEqual(day.solve1(data), 7746) 24 | self.assertEqual(day.solve2(data), 2604) 25 | -------------------------------------------------------------------------------- /2015/advent5b.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | func main() { 9 | var str string 10 | var good int 11 | for { 12 | if _, err := fmt.Scanf("%s\n", &str); err != nil { 13 | fmt.Println(err) 14 | break 15 | } 16 | dupl := false 17 | repeat := false 18 | for i, c := range str { 19 | if i < len(str) - 3 && strings.Contains(str[i+2:len(str)], str[i:i+2]) { 20 | dupl = true 21 | } 22 | if i < len(str) - 2 && byte(c) == str[i + 2] { 23 | repeat = true 24 | } 25 | } 26 | if dupl && repeat { 27 | good += 1 28 | } 29 | } 30 | fmt.Println(good) 31 | } 32 | 33 | -------------------------------------------------------------------------------- /2020/08/test_08.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import day_08 as day 4 | 5 | 6 | class TestDay(unittest.TestCase): 7 | def setUp(self): 8 | self.data = """nop +0 9 | acc +1 10 | jmp +4 11 | acc +3 12 | jmp -3 13 | acc -99 14 | acc +1 15 | jmp -4 16 | acc +6""" 17 | 18 | def test_part_1(self): 19 | acc, res = day.solve1(self.data) 20 | self.assertEqual(res, False) 21 | self.assertEqual(acc, 5) 22 | 23 | def test_part_2(self): 24 | acc = day.solve2(self.data) 25 | self.assertEqual(acc, 8) 26 | 27 | def test_solution(self): 28 | import os 29 | data = open(os.path.dirname(__file__) + "/input.txt").read() 30 | self.assertEqual(day.solve1(data)[0], 1614) 31 | self.assertEqual(day.solve2(data), 1260) 32 | -------------------------------------------------------------------------------- /2015/advent13/input_test.txt: -------------------------------------------------------------------------------- 1 | Alice would gain 54 happiness units by sitting next to Bob. 2 | Alice would lose 79 happiness units by sitting next to Carol. 3 | Alice would lose 2 happiness units by sitting next to David. 4 | Bob would gain 83 happiness units by sitting next to Alice. 5 | Bob would lose 7 happiness units by sitting next to Carol. 6 | Bob would lose 63 happiness units by sitting next to David. 7 | Carol would lose 62 happiness units by sitting next to Alice. 8 | Carol would gain 60 happiness units by sitting next to Bob. 9 | Carol would gain 55 happiness units by sitting next to David. 10 | David would gain 46 happiness units by sitting next to Alice. 11 | David would lose 7 happiness units by sitting next to Bob. 12 | David would gain 41 happiness units by sitting next to Carol. 13 | -------------------------------------------------------------------------------- /2020/03/test_03.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import day_03 as day 4 | 5 | 6 | class TestDay(unittest.TestCase): 7 | def setUp(self): 8 | self.wood = """..##....... 9 | #...#...#.. 10 | .#....#..#. 11 | ..#.#...#.# 12 | .#...##..#. 13 | ..#.##..... 14 | .#.#.#....# 15 | .#........# 16 | #.##...#... 17 | #...##....# 18 | .#..#...#.#""" 19 | 20 | def test_part_1(self): 21 | self.assertEqual(7, day.solve1(self.wood, 3, 1)) 22 | 23 | def test_part_2(self): 24 | self.assertEqual(336, day.solve2(self.wood)) 25 | 26 | def test_solution(self): 27 | import os 28 | data = open(os.path.dirname(__file__) + "/input.txt").read() 29 | self.assertEqual(day.solve1(data, 3, 1), 218) 30 | self.assertEqual(day.solve2(data), 3847183340) 31 | -------------------------------------------------------------------------------- /2016/03/03.py: -------------------------------------------------------------------------------- 1 | wrong = right = 0 2 | 3 | for l in open("input", "r").readlines(): 4 | side = [int(s) for s in l.split()] 5 | if side[0] >= side[1] + side[2] or side[1] >= side[0] + side[2] or side[2] >= side[1] + side[0]: 6 | wrong += 1 7 | else: 8 | right += 1 9 | 10 | print(right) 11 | 12 | 13 | wrong = right = 0 14 | 15 | side = [] 16 | for l in open("input", "r").readlines(): 17 | side.append([int(s) for s in l.split()]) 18 | if len(side) == 3: 19 | for n in range(3): 20 | if side[0][n] >= side[1][n] + side[2][n] or side[1][n] >= side[0][n] + side[2][n] or side[2][n] >= side[1][n] + side[0][n]: 21 | wrong += 1 22 | else: 23 | right += 1 24 | side = [] 25 | 26 | print(right) 27 | 28 | -------------------------------------------------------------------------------- /2021/15/test_15.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import pytest 3 | 4 | import day_15 as day 5 | 6 | 7 | class TestDay(unittest.TestCase): 8 | def setUp(self): 9 | self.data = """1163751742 10 | 1381373672 11 | 2136511328 12 | 3694931569 13 | 7463417111 14 | 1319128137 15 | 1359912421 16 | 3125421639 17 | 1293138521 18 | 2311944581 19 | """ 20 | 21 | def test_part_1(self): 22 | self.assertEqual(40, day.solve1(self.data)) 23 | 24 | def test_part_2(self): 25 | self.assertEqual(315, day.solve2(self.data)) 26 | 27 | @pytest.mark.slow 28 | def test_solution(self): 29 | import os 30 | data = open(os.path.dirname(__file__) + "/input.txt").read() 31 | self.assertEqual(day.solve1(data), 698) 32 | self.assertEqual(day.solve2(data), 3022) 33 | -------------------------------------------------------------------------------- /2022/05/test_05.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | day = __import__('day_' + __file__[-5:-3]) 3 | 4 | 5 | class TestDay(unittest.TestCase): 6 | def setUp(self): 7 | self.data = """ [D] 8 | [N] [C] 9 | [Z] [M] [P] 10 | 1 2 3 11 | 12 | move 1 from 2 to 1 13 | move 3 from 1 to 3 14 | move 2 from 2 to 1 15 | move 1 from 1 to 2""" 16 | 17 | 18 | def test_part_1(self): 19 | self.assertEqual("CMZ", day.solve1(self.data)) 20 | 21 | def test_part_2(self): 22 | self.assertEqual("MCD", day.solve2(self.data)) 23 | 24 | def test_solution(self): 25 | import os 26 | data = open(os.path.dirname(__file__) + "/input.txt").read() 27 | self.assertEqual(day.solve1(data), "ZWHVFWQWW") 28 | self.assertEqual(day.solve2(data), "HZFZCCWWV") 29 | -------------------------------------------------------------------------------- /2020/11/test_11.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import pytest 3 | 4 | import day_11 as day 5 | 6 | 7 | class TestDay(unittest.TestCase): 8 | def setUp(self): 9 | self.data = """L.LL.LL.LL 10 | LLLLLLL.LL 11 | L.L.L..L.. 12 | LLLL.LL.LL 13 | L.LL.LL.LL 14 | L.LLLLL.LL 15 | ..L.L..... 16 | LLLLLLLLLL 17 | L.LLLLLL.L 18 | L.LLLLL.LL 19 | """ 20 | 21 | def test_part_1(self): 22 | self.assertEqual(day.solve(self.data), 37) 23 | 24 | def test_part_2(self): 25 | self.assertEqual(day.solve(self.data, step=2), 26) 26 | 27 | @pytest.mark.slow 28 | def test_solution(self): 29 | import os 30 | data = open(os.path.dirname(__file__) + "/input.txt").read() 31 | self.assertEqual(day.solve(data), 2412) 32 | self.assertEqual(day.solve(data, step=2), 2176) 33 | -------------------------------------------------------------------------------- /2018/08/08.py: -------------------------------------------------------------------------------- 1 | raw = open("input.txt").read().strip() 2 | # raw = "2 3 0 3 10 11 12 1 1 0 1 99 2 1 1 2" 3 | 4 | data = [int(p) for p in raw.split(" ")] 5 | 6 | 7 | def explore(data): 8 | tot_meta = 0 9 | n_childs, n_meta, data, childs = data[0], data[1], data[2:], [] 10 | for child in range(n_childs): 11 | newborn, add_meta, data = explore(data) 12 | tot_meta += add_meta 13 | childs.append(newborn) 14 | meta, data = data[:n_meta], data[n_meta:] 15 | tot_meta += sum(meta) 16 | if n_childs == 0: 17 | value = tot_meta 18 | else: 19 | value = sum(childs[idx - 1][1] for idx in meta if idx <= n_childs) 20 | return [meta, value, childs], tot_meta, data 21 | 22 | 23 | tree, tot_meta = explore(data)[:2] 24 | 25 | print(tot_meta) 26 | print(tree[1]) 27 | -------------------------------------------------------------------------------- /2020/09/test_09.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import day_09 as day 4 | 5 | 6 | class TestDay(unittest.TestCase): 7 | def setUp(self): 8 | self.data = """35 9 | 20 10 | 15 11 | 25 12 | 47 13 | 40 14 | 62 15 | 55 16 | 65 17 | 95 18 | 102 19 | 117 20 | 150 21 | 182 22 | 127 23 | 219 24 | 299 25 | 277 26 | 309 27 | 576 28 | """ 29 | 30 | def test_part_1(self): 31 | self.assertEqual(day.solve1(self.data, 5), 127) 32 | 33 | def test_part_2(self): 34 | self.assertEqual(day.solve2(self.data, 127), 62) 35 | 36 | def test_solution(self): 37 | import os 38 | data = open(os.path.dirname(__file__) + "/input.txt").read() 39 | part1 = day.solve1(data, 25) 40 | self.assertEqual(part1, 133015568) 41 | self.assertEqual(day.solve2(data, part1), 16107959) 42 | -------------------------------------------------------------------------------- /2020/23/test_23.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import pytest 3 | 4 | import day_23 as day 5 | 6 | 7 | class TestDay(unittest.TestCase): 8 | def setUp(self): 9 | self.data = """389125467""" 10 | 11 | def test_part1_short(self): 12 | self.assertEqual(day.solve(self.data, moves=10), "92658374") 13 | 14 | def test_part1(self): 15 | self.assertEqual(day.solve(self.data), "67384529") 16 | 17 | @pytest.mark.slow 18 | def test_part2(self): 19 | self.assertEqual(day.solve(self.data, moves=10000000, n_cups=1000000), 149245887792) 20 | 21 | @pytest.mark.slow 22 | def test_solution(self): 23 | data = "123487596" 24 | self.assertEqual(day.solve(data), "47598263") 25 | self.assertEqual(day.solve(data, moves=10000000, n_cups=1000000), 248009574232) 26 | -------------------------------------------------------------------------------- /2019/10/input.txt: -------------------------------------------------------------------------------- 1 | .##.#.#....#.#.#..##..#.#. 2 | #.##.#..#.####.##....##.#. 3 | ###.##.##.#.#...#..###.... 4 | ####.##..###.#.#...####..# 5 | ..#####..#.#.#..#######..# 6 | .###..##..###.####.####### 7 | .##..##.###..##.##.....### 8 | #..#..###..##.#...#..####. 9 | ....#.#...##.##....#.#..## 10 | ..#.#.###.####..##.###.#.# 11 | .#..##.#####.##.####..#.#. 12 | #..##.#.#.###.#..##.##.... 13 | #.#.##.#.##.##......###.#. 14 | #####...###.####..#.##.... 15 | .#####.#.#..#.##.#.#...### 16 | .#..#.##.#.#.##.#....###.# 17 | .......###.#....##.....### 18 | #..#####.#..#..##..##.#.## 19 | ##.#.###..######.###..#..# 20 | #.#....####.##.###....#### 21 | ..#.#.#.########.....#.#.# 22 | .##.#.#..#...###.####..##. 23 | ##...###....#.##.##..#.... 24 | ..##.##.##.#######..#...#. 25 | .###..#.#..#...###..###.#. 26 | #..#..#######..#.#..#..#.# 27 | -------------------------------------------------------------------------------- /2022/04/day_04.py: -------------------------------------------------------------------------------- 1 | def load(data): 2 | sections = [] 3 | for line in data.strip().split("\n"): 4 | sections.append([int(x) for sec in line.split(",") for x in sec.split('-')]) 5 | return sections 6 | 7 | 8 | def contain(a1, a2, b1, b2): 9 | return a1 >= b1 and a2 <= b2 or b1 >= a1 and b2 <= a2 10 | 11 | 12 | def overlap(a1, a2, b1, b2): 13 | return a1 >= b2 and a2 <= b1 or b2 >= a1 and b1 <= a2 14 | 15 | 16 | def solve1(data): 17 | sections = load(data) 18 | return sum(1 if contain(*sec) else 0 for sec in sections) 19 | 20 | 21 | def solve2(data): 22 | sections = load(data) 23 | return sum(1 if overlap(*sec) else 0 for sec in sections) 24 | 25 | 26 | if __name__ == "__main__": 27 | data = open("input.txt").read() 28 | print(solve1(data)) 29 | print(solve2(data)) 30 | -------------------------------------------------------------------------------- /2022/01/day_01.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict 2 | 3 | 4 | def load(data): 5 | elves = defaultdict(list) 6 | cont = 0 7 | for line in data.strip().split("\n"): 8 | cal = int(line.strip() or "0") 9 | if not cal: 10 | cont += 1 11 | elves[cont].append(cal) 12 | return elves 13 | 14 | 15 | def solve1(data): 16 | most = 0 17 | for elves, items in load(data).items(): 18 | most = max(most, sum(items)) 19 | return most 20 | 21 | 22 | def solve2(data): 23 | mostest = [] 24 | for elves, items in load(data).items(): 25 | mostest.append(sum(items)) 26 | return sum(list(reversed(sorted(mostest)))[:3]) 27 | 28 | 29 | if __name__ == "__main__": 30 | data = open("input.txt").read() 31 | print(solve1(data)) 32 | print(solve2(data)) 33 | -------------------------------------------------------------------------------- /2022/09/test_09.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | day = __import__('day_' + __file__[-5:-3]) 3 | 4 | 5 | class TestDay(unittest.TestCase): 6 | def setUp(self): 7 | self.data = """R 4 8 | U 4 9 | L 3 10 | D 1 11 | R 4 12 | D 1 13 | L 5 14 | R 2""" 15 | 16 | self.data_2 = """R 5 17 | U 8 18 | L 8 19 | D 3 20 | R 17 21 | D 10 22 | L 25 23 | U 20""" 24 | 25 | def test_part_1(self): 26 | self.assertEqual(13, day.solve1(self.data)) 27 | 28 | def test_part_2(self): 29 | self.assertEqual(36, day.solve2(self.data_2)) 30 | 31 | def test_solution(self): 32 | import os 33 | with open(os.path.dirname(__file__) + "/input.txt") as f_data: 34 | data = f_data.read() 35 | self.assertEqual(day.solve1(data), 6067) 36 | self.assertEqual(day.solve2(data), 2471) 37 | -------------------------------------------------------------------------------- /2019/01/01.py: -------------------------------------------------------------------------------- 1 | def fuel(mass): 2 | return mass // 3 - 2 3 | 4 | 5 | def fuel_inc(mass): 6 | tot_fuel, add_fuel = 0, mass 7 | while True: 8 | add_fuel = fuel(add_fuel) 9 | if add_fuel <= 0: 10 | return tot_fuel 11 | tot_fuel += add_fuel 12 | 13 | 14 | def fuel_rec(mass): 15 | new_fuel = mass // 3 - 2 16 | return new_fuel + fuel_rec(new_fuel) if new_fuel > 0 else 0 17 | 18 | 19 | assert(fuel(12) == 2) 20 | assert(fuel(14) == 2) 21 | assert(fuel(1969) == 654) 22 | assert(fuel(100756) == 33583) 23 | 24 | print(sum(fuel(int(mass.strip())) for mass in open("input.txt").readlines())) 25 | 26 | assert(fuel_inc(14) == 2) 27 | assert(fuel_inc(1969) == 966) 28 | assert(fuel_inc(100756) == 50346) 29 | 30 | print(sum(fuel_inc(int(mass.strip())) for mass in open("input.txt").readlines())) 31 | -------------------------------------------------------------------------------- /2020/21/test_21.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import day_21 as day 4 | 5 | 6 | class TestDay(unittest.TestCase): 7 | def setUp(self): 8 | self.data = """mxmxvkd kfcds sqjhc nhms (contains dairy, fish) 9 | trh fvjkl sbzzf mxmxvkd (contains dairy) 10 | sqjhc fvjkl (contains soy) 11 | sqjhc mxmxvkd sbzzf (contains fish) 12 | """ 13 | 14 | def test_part1(self): 15 | self.assertEqual(day.solve(self.data), 5) 16 | 17 | def test_part2(self): 18 | self.assertEqual(day.solve(self.data, step=2), 'mxmxvkd,sqjhc,fvjkl') 19 | 20 | def test_solution(self): 21 | import os 22 | data = open(os.path.dirname(__file__) + "/input.txt").read() 23 | self.assertEqual(day.solve(data), 2302) 24 | self.assertEqual(day.solve(data, step=2), 'smfz,vhkj,qzlmr,tvdvzd,lcb,lrqqqsg,dfzqlk,shp') 25 | -------------------------------------------------------------------------------- /2021/14/test_14.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import day_14 as day 4 | 5 | 6 | class TestDay(unittest.TestCase): 7 | def setUp(self): 8 | self.data = """NNCB 9 | 10 | CH -> B 11 | HH -> N 12 | CB -> H 13 | NH -> C 14 | HB -> C 15 | HC -> B 16 | HN -> C 17 | NN -> C 18 | BH -> H 19 | NC -> B 20 | NB -> B 21 | BN -> B 22 | BB -> N 23 | BC -> B 24 | CC -> N 25 | CN -> C 26 | """ 27 | 28 | def test_part_1(self): 29 | self.assertEqual(1588, day.solve1(self.data)) 30 | 31 | def test_part_2(self): 32 | self.assertEqual(2188189693529, day.solve2(self.data)) 33 | 34 | def test_solution(self): 35 | import os 36 | data = open(os.path.dirname(__file__) + "/input.txt").read() 37 | self.assertEqual(day.solve1(data), 2233) 38 | self.assertEqual(day.solve2(data), 2884513602164) 39 | -------------------------------------------------------------------------------- /2015/advent9.txt: -------------------------------------------------------------------------------- 1 | Tristram to AlphaCentauri = 34 2 | Tristram to Snowdin = 100 3 | Tristram to Tambi = 63 4 | Tristram to Faerun = 108 5 | Tristram to Norrath = 111 6 | Tristram to Straylight = 89 7 | Tristram to Arbre = 132 8 | AlphaCentauri to Snowdin = 4 9 | AlphaCentauri to Tambi = 79 10 | AlphaCentauri to Faerun = 44 11 | AlphaCentauri to Norrath = 147 12 | AlphaCentauri to Straylight = 133 13 | AlphaCentauri to Arbre = 74 14 | Snowdin to Tambi = 105 15 | Snowdin to Faerun = 95 16 | Snowdin to Norrath = 48 17 | Snowdin to Straylight = 88 18 | Snowdin to Arbre = 7 19 | Tambi to Faerun = 68 20 | Tambi to Norrath = 134 21 | Tambi to Straylight = 107 22 | Tambi to Arbre = 40 23 | Faerun to Norrath = 11 24 | Faerun to Straylight = 66 25 | Faerun to Arbre = 144 26 | Norrath to Straylight = 115 27 | Norrath to Arbre = 135 28 | Straylight to Arbre = 127 29 | -------------------------------------------------------------------------------- /2020/25/test_25.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import day_25 as day 4 | 5 | 6 | class TestDay(unittest.TestCase): 7 | def setUp(self): 8 | self.data = """5764801 9 | 17807724 10 | """ 11 | 12 | def test_part1(self): 13 | card, door = day.parse(self.data) 14 | size_card = day.loop_size(card) 15 | size_door = day.loop_size(door) 16 | self.assertEqual(size_card, 8) 17 | self.assertEqual(size_door, 11) 18 | enc_card = day.transform(card, size_door) 19 | enc_door = day.transform(door, size_card) 20 | self.assertEqual(enc_card, enc_door) 21 | self.assertEqual(enc_card, 14897079) 22 | 23 | def test_solution(self): 24 | import os 25 | data = open(os.path.dirname(__file__) + "/input.txt").read() 26 | self.assertEqual(day.solve(data), 5414549) 27 | -------------------------------------------------------------------------------- /2020/15/day_15.py: -------------------------------------------------------------------------------- 1 | def parse(numbers, data): 2 | lasts = {} 3 | for i, p in enumerate(data.strip().split(",")): 4 | last = int(p) 5 | numbers[i] = last 6 | lasts[last] = (i + 1,) 7 | return lasts, last, len(lasts) 8 | 9 | 10 | def solve(data, n=2020): 11 | numbers = [None] * n 12 | lasts, last, turns = parse(numbers, data) 13 | while True: 14 | last = 0 if len(lasts[last]) == 1 else turns - lasts[last][-2] 15 | numbers[turns] = last 16 | turns += 1 17 | try: 18 | lasts[last] = (lasts[last][-1], turns) 19 | except KeyError: 20 | lasts[last] = (turns,) 21 | if turns == n: 22 | return last 23 | 24 | 25 | if __name__ == "__main__": 26 | data = "0,13,1,8,6,15" 27 | print(solve(data)) 28 | print(solve(data, n=30000000)) 29 | -------------------------------------------------------------------------------- /2020/14/test_14.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import day_14 as day 4 | 5 | 6 | class TestDay(unittest.TestCase): 7 | def setUp(self): 8 | self.data1 = """mask = XXXXXXXXXXXXXXXXXXXXXXXXXXXXX1XXXX0X 9 | mem[8] = 11 10 | mem[7] = 101 11 | mem[8] = 0 12 | """ 13 | self.data2 = """mask = 000000000000000000000000000000X1001X 14 | mem[42] = 100 15 | mask = 00000000000000000000000000000000X0XX 16 | mem[26] = 1 17 | """ 18 | 19 | def test_part_1(self): 20 | self.assertEqual(day.solve1(self.data1), 165) 21 | 22 | def test_part_2(self): 23 | self.assertEqual(day.solve2(self.data2), 208) 24 | 25 | def test_solution(self): 26 | import os 27 | data = open(os.path.dirname(__file__) + "/input.txt").read() 28 | self.assertEqual(day.solve1(data), 13105044880745) 29 | self.assertEqual(day.solve2(data), 3505392154485) 30 | -------------------------------------------------------------------------------- /2021/10/test_10.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import day_10 as day 4 | 5 | 6 | class TestDay(unittest.TestCase): 7 | def setUp(self): 8 | self.data = """[({(<(())[]>[[{[]{<()<>> 9 | [(()[<>])]({[<{<<[]>>( 10 | {([(<{}[<>[]}>{[]{[(<()> 11 | (((({<>}<{<{<>}{[]{[]{} 12 | [[<[([]))<([[{}[[()]]] 13 | [{[{({}]{}}([{[{{{}}([] 14 | {<[[]]>}<{[{[{[]{()[[[] 15 | [<(<(<(<{}))><([]([]() 16 | <{([([[(<>()){}]>(<<{{ 17 | <{([{{}}[<[[[<>{}]]]>[]] 18 | """ 19 | 20 | def test_part_1(self): 21 | self.assertEqual(26397, day.solve1(self.data)) 22 | 23 | def test_part_2(self): 24 | self.assertEqual(288957, day.solve2(self.data)) 25 | 26 | def test_solution(self): 27 | import os 28 | data = open(os.path.dirname(__file__) + "/input.txt").read() 29 | self.assertEqual(day.solve1(data), 392043) 30 | self.assertEqual(day.solve2(data), 1605968119) 31 | -------------------------------------------------------------------------------- /2015/advent14/advent_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "testing" 4 | 5 | func TestComet(t *testing.T) { 6 | deer := Deer{"Comet", 14, 10, 127} 7 | run := deer.Run(1000) 8 | run_ok := 1120 9 | if run != run_ok { 10 | t.Fatalf("%s deve correre %d invece che %d", deer.name, run_ok, run) 11 | } 12 | } 13 | 14 | func TestDancer(t *testing.T) { 15 | deer := Deer{"Dancer", 16, 11, 162} 16 | run := deer.Run(1000) 17 | run_ok := 1056 18 | if run != run_ok { 19 | t.Fatalf("%s deve correre %d invece che %d", deer.name, run_ok, run) 20 | } 21 | } 22 | 23 | func TestBoth(t *testing.T) { 24 | deer1 := Deer{"Comet", 14, 10, 127} 25 | deer2 := Deer{"Dancer", 16, 11, 162} 26 | deers := []Deer{deer1, deer2} 27 | score := BestScore(deers, 1000) 28 | score_ok := 689 29 | if score != score_ok { 30 | t.Fatalf("Il migliore deve aver preso %d punti invece che %d", score_ok, score) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /2017/05/05.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define SIZE 10000 4 | 5 | int main() { 6 | FILE *file; 7 | int maze[SIZE]; 8 | int times; 9 | int number; 10 | int length; 11 | int pos; 12 | int steps; 13 | int inc; 14 | 15 | for(times=0; times<2; times++) { 16 | 17 | // Fill maze 18 | length = 0; 19 | file = fopen("input", "r"); 20 | while( fscanf(file, "%d\n", &number) > 0 ) { 21 | maze[length++] = number; 22 | } 23 | fclose(file); 24 | 25 | pos = 0; 26 | steps = 0; 27 | 28 | while(pos >= 0 && pos < length) { 29 | inc = 1; 30 | if(times == 1 && maze[pos] >= 3) 31 | inc = -1; 32 | maze[pos] += inc; 33 | pos += maze[pos] - inc; 34 | steps += 1; 35 | } 36 | printf("%d\n", steps); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /2021/01/day_01.py: -------------------------------------------------------------------------------- 1 | from itertools import combinations 2 | 3 | 4 | def load(data): 5 | return [int(line) for line in data.strip().split("\n")] 6 | 7 | 8 | def solve1(data): 9 | increased = 0 10 | last = None 11 | numbers = load(data) 12 | for height in numbers: 13 | if last is not None: 14 | if height > last: 15 | increased += 1 16 | last = height 17 | return increased 18 | 19 | 20 | def solve2(data): 21 | increased = 0 22 | a = b = c = None 23 | numbers = load(data) 24 | for height in numbers: 25 | if a is not None: 26 | if height > a: 27 | increased += 1 28 | a = b 29 | b = c 30 | c = height 31 | return increased 32 | 33 | 34 | if __name__ == "__main__": 35 | data = open("input.txt").read() 36 | print(solve1(data)) 37 | print(solve2(data)) 38 | -------------------------------------------------------------------------------- /2021/24/test_24.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import day_24 as day 4 | 5 | 6 | class TestDay(unittest.TestCase): 7 | def setUp(self): 8 | self.data_1 = """inp x 9 | mul x -1 10 | """ 11 | 12 | self.data_2 = """inp z 13 | inp x 14 | mul z 3 15 | eql z x 16 | """ 17 | 18 | def test_part_1_1(self): 19 | self.assertEqual(day.ALU(self.data_1).run([10])['x'], -10) 20 | 21 | def test_part_1_2(self): 22 | self.assertEqual(day.ALU(self.data_2).run([10, 30])['z'], 1) 23 | self.assertEqual(day.ALU(self.data_2).run([10, 29])['z'], 0) 24 | self.assertEqual(day.ALU(self.data_2).run([10, 31])['z'], 0) 25 | 26 | def test_solution(self): 27 | import os 28 | data = open(os.path.dirname(__file__) + "/input.txt").read() 29 | self.assertEqual(day.solve1(data), "96299896449997") 30 | self.assertEqual(day.solve2(data), "31162141116841") 31 | -------------------------------------------------------------------------------- /2015/advent12/advent12.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | def deep_sum(struct, skip_red=False): 4 | tot = 0 5 | if isinstance(struct, unicode): 6 | pass 7 | elif isinstance(struct, int): 8 | tot = struct 9 | elif isinstance(struct, dict): 10 | if not skip_red or not "red" in struct.values(): 11 | for k, v in struct.items(): 12 | if isinstance(v, int): 13 | tot += v 14 | else: 15 | tot += deep_sum(v, skip_red) 16 | elif isinstance(struct, tuple) or isinstance(struct, list): 17 | for v in struct: 18 | tot += deep_sum(v, skip_red) 19 | else: 20 | print("Boh", struct) 21 | 22 | return tot 23 | 24 | if __name__ == "__main__": 25 | import sys 26 | struct = json.loads(file(sys.argv[1]).read()) 27 | print(deep_sum(struct)) 28 | print(deep_sum(struct, True)) 29 | -------------------------------------------------------------------------------- /2019/04/04.py: -------------------------------------------------------------------------------- 1 | def count(from_, to_): 2 | tot = tot2 = 0 3 | for pwd in range(from_, to_ + 1): 4 | parts = [int(p) for p in str(pwd)] 5 | if all(parts[n] <= parts[n + 1] for n in range(0, 5)) and any(parts[n] == parts[n + 1] for n in range(0, 5)): 6 | tot += 1 7 | simil = set() 8 | adiac = n = 0 9 | while True: 10 | if n == 5 or parts[n] != parts[n + 1]: 11 | simil.add(adiac + 1) 12 | if n == 5: 13 | break 14 | adiac = -1 15 | adiac += 1 16 | n += 1 17 | if 2 in simil: 18 | tot2 += 1 19 | return tot, tot2 20 | 21 | 22 | if __name__ == "__main__": 23 | from_, to_ = [int(p) for p in "357253-892942".split("-")] 24 | tot, tot2 = count(from_, to_) 25 | print(tot) 26 | print(tot2) 27 | -------------------------------------------------------------------------------- /2022/07/test_07.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | day = __import__('day_' + __file__[-5:-3]) 3 | 4 | 5 | class TestDay(unittest.TestCase): 6 | def setUp(self): 7 | self.data = """$ cd / 8 | $ ls 9 | dir a 10 | 14848514 b.txt 11 | 8504156 c.dat 12 | dir d 13 | $ cd a 14 | $ ls 15 | dir e 16 | 29116 f 17 | 2557 g 18 | 62596 h.lst 19 | $ cd e 20 | $ ls 21 | 584 i 22 | $ cd .. 23 | $ cd .. 24 | $ cd d 25 | $ ls 26 | 4060174 j 27 | 8033020 d.log 28 | 5626152 d.ext 29 | 7214296 k 30 | """ 31 | 32 | def test_part_1(self): 33 | self.assertEqual(95437, day.solve1(self.data)) 34 | 35 | def test_part_2(self): 36 | self.assertEqual(24933642, day.solve2(self.data)) 37 | 38 | def test_solution(self): 39 | import os 40 | data = open(os.path.dirname(__file__) + "/input.txt").read() 41 | self.assertEqual(day.solve1(data), 1886043) 42 | self.assertEqual(day.solve2(data), 3842121) 43 | -------------------------------------------------------------------------------- /2016/07/07.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | ABBA = re.compile(r"([a-z])([a-z])\2\1") 4 | ABA = re.compile(r"(?=([a-z])([a-z])\1)") 5 | 6 | tot_tls = tot_ssl = 0 7 | 8 | for net in open("input").readlines(): 9 | parts = net.strip().replace("]", "[").split("[") 10 | outside = " ".join([part for i, part in enumerate(parts) if i % 2 == 0]) 11 | inside = " ".join([part for i, part in enumerate(parts) if i % 2 == 1]) 12 | abba = [f for f in ABBA.findall(outside) if len(set(f)) == 2] 13 | abba_inside = [f for f in ABBA.findall(inside) if len(set(f)) == 2] 14 | aba = [m.groups() for m in ABA.finditer(outside) if len(set(m.groups())) == 2] 15 | if abba and not abba_inside: 16 | tot_tls += 1 17 | if aba: 18 | for c1, c2 in aba: 19 | if re.findall("{b}{a}{b}".format(a=c1, b=c2), inside): 20 | tot_ssl += 1 21 | break 22 | 23 | print(tot_tls) 24 | print(tot_ssl) 25 | -------------------------------------------------------------------------------- /2021/11/test_11.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import day_11 as day 4 | 5 | 6 | class TestDay(unittest.TestCase): 7 | def setUp(self): 8 | self.data = """5483143223 9 | 2745854711 10 | 5264556173 11 | 6141336146 12 | 6357385478 13 | 4167524645 14 | 2176841721 15 | 6882881134 16 | 4846848554 17 | 5283751526 18 | """ 19 | self.data_little = """11111 20 | 19991 21 | 19191 22 | 19991 23 | 11111 24 | """ 25 | 26 | def test_part_1_little(self): 27 | self.assertEqual(9, day.solve1(self.data_little, 2)) 28 | 29 | def test_part_1(self): 30 | self.assertEqual(1656, day.solve1(self.data)) 31 | 32 | def test_part_2(self): 33 | self.assertEqual(195, day.solve2(self.data)) 34 | 35 | def test_solution(self): 36 | import os 37 | data = open(os.path.dirname(__file__) + "/input.txt").read() 38 | self.assertEqual(day.solve1(data), 1675) 39 | self.assertEqual(day.solve2(data), 515) 40 | -------------------------------------------------------------------------------- /2016/12/12.py: -------------------------------------------------------------------------------- 1 | def get_val(registers, reg): 2 | try: 3 | return registers[reg] 4 | except: 5 | return int(reg) 6 | 7 | 8 | def execute(program, registers): 9 | CPY, INC, DEC, JNZ = 'cpy', 'inc', 'dec', 'jnz' 10 | 11 | step = 0 12 | 13 | while step < len(program): 14 | instr, regs = program[step][0], program[step][1:] 15 | if instr == CPY: 16 | registers[regs[1]] = get_val(registers, regs[0]) 17 | elif instr in (INC, DEC): 18 | registers[regs[0]] += 1 if instr == INC else -1 19 | elif instr == JNZ: 20 | if get_val(registers, regs[0]) != 0: 21 | step += int(regs[1]) - 1 22 | step += 1 23 | 24 | return registers 25 | 26 | 27 | program = [l.strip().split(" ") for l in open("input").readlines()] 28 | 29 | print(execute(program, {'a': 0, 'b': 0, 'c': 0, 'd': 0})['a']) 30 | print(execute(program, {'a': 0, 'b': 0, 'c': 1, 'd': 0})['a']) 31 | -------------------------------------------------------------------------------- /2022/13/test_13.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import pytest 3 | day = __import__('day_' + __file__[-5:-3]) 4 | 5 | 6 | class TestDay(unittest.TestCase): 7 | def setUp(self): 8 | self.data = """[1,1,3,1,1] 9 | [1,1,5,1,1] 10 | 11 | [[1],[2,3,4]] 12 | [[1],4] 13 | 14 | [9] 15 | [[8,7,6]] 16 | 17 | [[4,4],4,4] 18 | [[4,4],4,4,4] 19 | 20 | [7,7,7,7] 21 | [7,7,7] 22 | 23 | [] 24 | [3] 25 | 26 | [[[]]] 27 | [[]] 28 | 29 | [1,[2,[3,[4,[5,6,7]]]],8,9] 30 | [1,[2,[3,[4,[5,6,0]]]],8,9]""" 31 | 32 | def test_part_1(self): 33 | self.assertEqual(13, day.solve1(self.data)) 34 | 35 | def test_part_2(self): 36 | self.assertEqual(140, day.solve2(self.data)) 37 | 38 | def test_solution(self): 39 | import os 40 | with open(os.path.dirname(__file__) + "/input.txt") as f_data: 41 | data = f_data.read() 42 | self.assertEqual(day.solve1(data), 5208) 43 | self.assertEqual(day.solve2(data), 25792) 44 | -------------------------------------------------------------------------------- /2018/14/14.py: -------------------------------------------------------------------------------- 1 | def after(recipes, pe1, pe2, after=None, search=None): 2 | if search is not None: 3 | search = [int(n) for n in str(search)] 4 | l_search = len(search) 5 | while True: 6 | new = recipes[pe1] + recipes[pe2] 7 | if new > 9: 8 | recipes.append(new // 10) 9 | recipes.append(new % 10) 10 | pe1 = (pe1 + recipes[pe1] + 1) % len(recipes) 11 | pe2 = (pe2 + recipes[pe2] + 1) % len(recipes) 12 | if after is not None: 13 | if len(recipes) > after + 10: 14 | return("".join(str(r) for r in recipes[after:after + 10])) 15 | else: 16 | if recipes[-l_search:] == search: 17 | return(len(recipes) - l_search) 18 | if new > 9 and recipes[-l_search - 1:-1] == search: 19 | return(len(recipes) - l_search - 1) 20 | 21 | 22 | print(after([3, 7], 0, 1, after=380621)) 23 | print(after([3, 7], 0, 1, search=380621)) 24 | -------------------------------------------------------------------------------- /2015/advent8.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "os" 7 | "strings" 8 | ) 9 | 10 | func main() { 11 | in := bufio.NewReader(os.Stdin) 12 | tot_string := 0 13 | tot_memory := 0 14 | tot_encoded := 0 15 | for n := 0; ; n++ { 16 | if str, err := in.ReadString('\n'); err != nil { 17 | break 18 | } else { 19 | tot_string += len(str) - 1 20 | tot_memory += len(str) - 1 - 2 - (len(strings.Split(str, "\\\\")) - 1) 21 | tot_encoded += len(str) - 1 + 4 + 2*(len(strings.Split(str, "\\\\"))-1) 22 | str = strings.Replace(str, "\\\\", "", -1) 23 | tot_memory += -(len(strings.Split(str, "\\\"")) - 1) 24 | tot_encoded += 2 * (len(strings.Split(str, "\\\"")) - 1) 25 | str = strings.Replace(str, "\\\"", "", -1) 26 | tot_memory += -3 * (len(strings.Split(str, "\\x")) - 1) 27 | tot_encoded += (len(strings.Split(str, "\\x")) - 1) 28 | } 29 | } 30 | fmt.Println(tot_string - tot_memory) 31 | fmt.Println(tot_encoded - tot_string) 32 | } 33 | -------------------------------------------------------------------------------- /2021/04/test_04.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import day_04 as day 4 | 5 | 6 | class TestDay(unittest.TestCase): 7 | def setUp(self): 8 | self.data = """7,4,9,5,11,17,23,2,0,14,21,24,10,16,13,6,15,25,12,22,18,20,8,19,3,26,1 9 | 10 | 22 13 17 11 0 11 | 8 2 23 4 24 12 | 21 9 14 16 7 13 | 6 10 3 18 5 14 | 1 12 20 15 19 15 | 16 | 3 15 0 2 22 17 | 9 18 13 17 5 18 | 19 8 7 25 23 19 | 20 11 10 24 4 20 | 14 21 16 12 6 21 | 22 | 14 21 17 24 4 23 | 10 16 15 9 19 24 | 18 8 23 26 20 25 | 22 11 13 6 5 26 | 2 0 12 3 7""" 27 | 28 | def test_part_1(self): 29 | self.assertEqual(4512, day.solve1(self.data)) 30 | 31 | def test_part_2(self): 32 | self.assertEqual(1924, day.solve2(self.data)) 33 | 34 | def test_solution(self): 35 | import os 36 | data = open(os.path.dirname(__file__) + "/input.txt").read() 37 | self.assertEqual(day.solve1(data), 10680) 38 | self.assertEqual(day.solve2(data), 31892) 39 | -------------------------------------------------------------------------------- /2015/advent5.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | func main() { 9 | var str string 10 | var good int 11 | for { 12 | if _, err := fmt.Scanf("%s\n", &str); err != nil { 13 | fmt.Println(err) 14 | break 15 | } 16 | fmt.Println(str) 17 | if ! (strings.Contains(str, "ab") || strings.Contains(str, "cd") || strings.Contains(str, "pq") || strings.Contains(str, "xy")) { 18 | vowels := 0 19 | row2 := false 20 | for i, c := range str { 21 | if strings.Contains("aeiou", string(c)) { 22 | vowels += 1 23 | } 24 | if i < len(str) - 1 && byte(c) == str[i + 1] { 25 | row2 = true 26 | } 27 | } 28 | if vowels >= 3 && row2 { 29 | good += 1 30 | } 31 | } 32 | } 33 | fmt.Println(good) 34 | } 35 | 36 | -------------------------------------------------------------------------------- /2020/09/day_09.py: -------------------------------------------------------------------------------- 1 | def check(n, numbers): 2 | for i, n1 in enumerate(numbers[:-1]): 3 | for n2 in numbers[i + 1:]: 4 | if n1 + n2 == n: 5 | return True 6 | return False 7 | 8 | 9 | def parse(data): 10 | return [int(x) for x in data.strip().split("\n")] 11 | 12 | 13 | def solve2(data, value): 14 | numbers = parse(data) 15 | for n in range(2, len(numbers)): 16 | for pos in range(1, len(numbers) - n): 17 | if sum(numbers[pos:pos + n]) == value: 18 | return(min(numbers[pos:pos + n]) + max(numbers[pos:pos + n])) 19 | 20 | 21 | def solve1(data, preamble): 22 | numbers = parse(data) 23 | pos = preamble 24 | while True: 25 | if not check(numbers[pos], numbers[pos - preamble:pos]): 26 | return numbers[pos] 27 | pos += 1 28 | 29 | 30 | if __name__ == "__main__": 31 | data = open("input.txt").read() 32 | n = solve1(data, 25) 33 | print(n) 34 | print(solve2(data, n)) 35 | -------------------------------------------------------------------------------- /2020/10/input.txt: -------------------------------------------------------------------------------- 1 | 147 2 | 174 3 | 118 4 | 103 5 | 67 6 | 33 7 | 96 8 | 28 9 | 43 10 | 22 11 | 16 12 | 138 13 | 75 14 | 148 15 | 35 16 | 6 17 | 10 18 | 169 19 | 129 20 | 115 21 | 21 22 | 52 23 | 58 24 | 79 25 | 46 26 | 7 27 | 139 28 | 104 29 | 91 30 | 51 31 | 172 32 | 57 33 | 49 34 | 126 35 | 95 36 | 149 37 | 125 38 | 123 39 | 112 40 | 30 41 | 78 42 | 44 43 | 37 44 | 167 45 | 157 46 | 29 47 | 173 48 | 98 49 | 36 50 | 63 51 | 111 52 | 160 53 | 18 54 | 8 55 | 9 56 | 159 57 | 179 58 | 72 59 | 110 60 | 2 61 | 53 62 | 150 63 | 17 64 | 81 65 | 97 66 | 108 67 | 102 68 | 56 69 | 135 70 | 166 71 | 168 72 | 163 73 | 1 74 | 25 75 | 3 76 | 158 77 | 101 78 | 132 79 | 144 80 | 45 81 | 140 82 | 34 83 | 156 84 | 178 85 | 105 86 | 68 87 | 153 88 | 80 89 | 82 90 | 59 91 | 50 92 | 122 93 | 69 94 | 85 95 | 109 96 | 40 97 | 124 98 | 119 99 | 94 100 | 88 101 | 13 102 | 180 103 | 177 104 | 133 105 | 66 106 | 134 107 | 60 108 | 141 109 | -------------------------------------------------------------------------------- /2021/02/day_02.py: -------------------------------------------------------------------------------- 1 | def interpret(row): 2 | action, step = row.split(" ") 3 | step = int(step) 4 | if action == 'forward': 5 | op = (1, 0) 6 | elif action == 'down': 7 | op = (0, 1) 8 | elif action == 'up': 9 | op = (0, -1) 10 | else: 11 | raise Exception(row) 12 | return op, step 13 | 14 | 15 | def load(data): 16 | return [interpret(line) for line in data.strip().split("\n")] 17 | 18 | 19 | def solve1(data, aim=None): 20 | depth, horiz = 0, 0 21 | for op, step in load(data): 22 | if aim is None: 23 | horiz += op[0] * step 24 | depth += op[1] * step 25 | else: 26 | aim += op[1] * step 27 | horiz += op[0] * step 28 | depth += op[0] * aim * step 29 | return depth * horiz 30 | 31 | 32 | def solve2(data): 33 | return solve1(data, aim=0) 34 | 35 | 36 | if __name__ == "__main__": 37 | data = open("input.txt").read() 38 | print(solve1(data)) 39 | print(solve2(data)) 40 | -------------------------------------------------------------------------------- /2017/12/12.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict 2 | graph = defaultdict(list) 3 | 4 | for l in open("input").readlines(): 5 | parts = l.strip().split(" ") 6 | root = parts[0] 7 | children = [p.strip(",") for p in parts[2:]] 8 | graph[root].extend(children) 9 | for child in children: 10 | if child != root: 11 | graph[root].append(child) 12 | 13 | 14 | def visitable(graph, current, seen=None): 15 | if seen is None: 16 | seen = set() 17 | for child in graph.get(current, ()): 18 | if child in seen: 19 | continue 20 | seen.add(child) 21 | for s in visitable(graph, child, seen): 22 | seen.add(s) 23 | return seen 24 | 25 | 26 | seen = visitable(graph, '0') 27 | 28 | print(len(seen)) 29 | 30 | group = 1 31 | 32 | for current in graph.keys(): 33 | if current in seen: 34 | continue 35 | new_seen = visitable(graph, current) 36 | group += 1 37 | for s in new_seen: 38 | seen.add(s) 39 | 40 | print(group) 41 | -------------------------------------------------------------------------------- /2021/06/day_06.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict 2 | 3 | 4 | class Lanterfishes: 5 | def __init__(self, data): 6 | self.families = defaultdict(int) 7 | for day in [int(d) for d in data.strip().split(",")]: 8 | self.families[day] += 1 9 | 10 | def live(self, days): 11 | for day in range(days): 12 | new_families = defaultdict(int) 13 | for day, count in sorted(self.families.items()): 14 | day -= 1 15 | if day == -1: 16 | new_families[8] = count 17 | day = 6 18 | new_families[day] += count 19 | self.families = new_families 20 | return sum(self.families.values()) 21 | 22 | 23 | def solve1(data, days=80): 24 | return Lanterfishes(data).live(days) 25 | 26 | 27 | def solve2(data): 28 | return solve1(data, days=256) 29 | 30 | 31 | if __name__ == "__main__": 32 | data = open("input.txt").read() 33 | print(solve1(data)) 34 | print(solve2(data)) 35 | -------------------------------------------------------------------------------- /2018/06/06.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict 2 | 3 | points = dict((n, tuple(int(p.strip()) for p in l.strip().split(","))) 4 | for n, l in enumerate(open("input.txt").readlines())) 5 | 6 | X, Y = [max(p[0] for p in points.values()) + 1, max(p[1] for p in points.values()) + 1] 7 | 8 | border = set() 9 | areas = defaultdict(int) 10 | less10000 = 0 11 | 12 | for x in range(X + 1): 13 | for y in range(Y + 1): 14 | distance = defaultdict(list) 15 | tot_distance = 0 16 | for n, (px, py) in points.items(): 17 | d = abs(px - x) + abs(py - y) 18 | distance[d].append(n) 19 | tot_distance += d 20 | if tot_distance < 10000: 21 | less10000 += 1 22 | d, ns = min(distance.items()) 23 | if len(ns) == 1: 24 | n = ns[0] 25 | if x == 0 or y == 0 or x == X or y == Y: 26 | border.add(n) 27 | areas[n] += 1 28 | 29 | print(max(a for n, a in areas.items() if n not in border)) 30 | print(less10000) 31 | -------------------------------------------------------------------------------- /2021/07/day_07.py: -------------------------------------------------------------------------------- 1 | from collections import Counter 2 | 3 | 4 | class Crabs: 5 | def __init__(self, data): 6 | self.positions = Counter(int(n) for n in data.strip().split(",")) 7 | self.pos = min(self.positions.keys()) 8 | 9 | def dist(self, dist, inc): 10 | return (dist * (dist + 1)) // 2 if inc else dist 11 | 12 | def carb(self, pos, inc): 13 | return sum(self.dist(abs(pos - p), inc) * n for p, n in self.positions.items()) 14 | 15 | def best(self, inc=False): 16 | prev_carb = float("inf") 17 | while True: 18 | carb = self.carb(self.pos, inc) 19 | if prev_carb < carb: 20 | return prev_carb 21 | prev_carb = carb 22 | self.pos += 1 23 | 24 | 25 | def solve1(data): 26 | return Crabs(data).best() 27 | 28 | 29 | def solve2(data): 30 | return Crabs(data).best(inc=True) 31 | 32 | 33 | if __name__ == "__main__": 34 | data = open("input.txt").read() 35 | print(solve1(data)) 36 | print(solve2(data)) 37 | -------------------------------------------------------------------------------- /2018/03/03.py: -------------------------------------------------------------------------------- 1 | SIZE = 1000 2 | fabric = [[0] * SIZE for x in range(SIZE)] 3 | 4 | patches = {} 5 | 6 | for line in open("input.txt").readlines(): 7 | # Format: #16 @ 646,318: 24x21 8 | parts = line.strip().split(" ") 9 | id = int(parts[0][1:]) 10 | x, y = [int(p) for p in parts[2][:-1].split(",")] 11 | w, h = [int(p) for p in parts[3].split("x")] 12 | patches[id] = (x, y, w, h) 13 | 14 | for X, Y, W, H in patches.values(): 15 | for x in range(X, X + W): 16 | for y in range(Y, Y + H): 17 | fabric[x][y] += 1 18 | 19 | over = 0 20 | for x in range(SIZE): 21 | for y in range(SIZE): 22 | if fabric[x][y] > 1: 23 | over += 1 24 | 25 | print(over) 26 | 27 | for id, (X, Y, W, H) in patches.items(): 28 | found = True 29 | for x in range(X, X + W): 30 | for y in range(Y, Y + H): 31 | if fabric[x][y] > 1: 32 | found = False 33 | break 34 | if not found: 35 | break 36 | if found: 37 | print(id) 38 | break 39 | -------------------------------------------------------------------------------- /2016/18/18.py: -------------------------------------------------------------------------------- 1 | mine = tuple(0 if c == "." else 1 for c in open("input").read().strip()) 2 | steps = 40 3 | 4 | #mine = [0, 1, 1, 0, 1, 0, 1, 1, 1, 1] 5 | #steps = 10 6 | 7 | def next_row(mine, seen={}): 8 | try: 9 | return seen[mine] 10 | except KeyError: 11 | new_mine = [] 12 | for n, trap in enumerate(mine): 13 | trap_left = mine[n - 1] if n > 0 else 0 14 | trap_right = mine[n + 1] if n < len(mine) - 1 else 0 15 | new_mine.append(1 if (trap_left, trap, trap_right) in ((1, 0, 0), (0, 0, 1), (1, 1, 0), (0, 1, 1)) else 0) 16 | new_mine = tuple(new_mine) 17 | seen[mine] = new_mine 18 | return new_mine 19 | 20 | tot_mine = sum(mine) 21 | 22 | row = 1 23 | 24 | while row < steps: 25 | mine = next_row(mine) 26 | tot_mine += sum(mine) 27 | row += 1 28 | 29 | print(steps * len(mine) - tot_mine) 30 | 31 | steps = 400000 32 | 33 | while row < steps: 34 | mine = next_row(mine) 35 | tot_mine += sum(mine) 36 | row += 1 37 | 38 | print(steps * len(mine) - tot_mine) 39 | -------------------------------------------------------------------------------- /2020/13/day_13.py: -------------------------------------------------------------------------------- 1 | def parse(data): 2 | lines = data.strip().split() 3 | return int(lines[0]), [int(x) if x.isdigit() else 0 for x in lines[1].split(',')] 4 | 5 | 6 | def solve1(data): 7 | time, busses = parse(data) 8 | best_rest = (time, 0) 9 | for bus in busses: 10 | if bus == 0: 11 | continue 12 | loop = int(time / bus) 13 | rest = ((loop + 1) * bus) - time 14 | if rest < best_rest[0]: 15 | best_rest = (rest, bus) 16 | return best_rest[0] * best_rest[1] 17 | 18 | 19 | def solve2(data): 20 | _, busses = parse(data) 21 | n = step = rest = 1 22 | bus0 = busses[0] 23 | while rest < len(busses): 24 | bus = busses[rest] 25 | rest += 1 26 | while bus != 0: 27 | if ((bus0 * n) + rest - 1) % bus == 0: 28 | step *= bus 29 | break 30 | n += step 31 | return (n * bus0) 32 | 33 | 34 | if __name__ == "__main__": 35 | data = open("input.txt").read() 36 | print(solve1(data)) 37 | print(solve2(data)) 38 | -------------------------------------------------------------------------------- /2016/08/08.py: -------------------------------------------------------------------------------- 1 | ROWS, COLS = 6, 50 2 | 3 | matrix = [[' '] * COLS for x in range(ROWS)] 4 | 5 | for instruction in open("input").readlines(): 6 | parts = instruction.strip().split(" ") 7 | if parts[0] == "rect": 8 | sizes = parts[1].split("x") 9 | for x in range(int(sizes[0])): 10 | for y in range(int(sizes[1])): 11 | matrix[y][x] = "#" 12 | else: 13 | if parts[1] == "row": 14 | row = int(parts[2].split("=")[-1]) 15 | for by in range(int(parts[4])): 16 | matrix[row] = matrix[row][-1:] + matrix[row][:-1] 17 | else: 18 | column = int(parts[2].split("=")[-1]) 19 | for by in range(int(parts[4])): 20 | last = matrix[ROWS - 1][column] 21 | for n in range(ROWS - 1, 0, -1): 22 | matrix[n][column] = matrix[n - 1][column] 23 | matrix[0][column] = last 24 | 25 | tot = 0 26 | for line in matrix: 27 | print("".join(line)) 28 | tot += sum(1 for x in line if x == '#') 29 | 30 | print(tot) 31 | -------------------------------------------------------------------------------- /2021/05/day_05.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict 2 | 3 | 4 | def interpret(line): 5 | return tuple(tuple(int(p) for part in line.split(" -> ")for p in part.split(","))) 6 | 7 | 8 | def load(data): 9 | return tuple(interpret(line) for line in data.strip().split("\n")) 10 | 11 | 12 | def solve1(data, diagonal=False): 13 | lines = load(data) 14 | floor = defaultdict(int) 15 | for x1, y1, x2, y2 in lines: 16 | inc_x = -1 if x2 < x1 else 1 17 | inc_y = -1 if y2 < y1 else 1 18 | for x in range(x1, x2 + inc_x, inc_x): 19 | if x1 == x2 or y1 == y2: 20 | for y in range(y1, y2 + inc_y, inc_y): 21 | floor[x, y] += 1 22 | elif diagonal: 23 | floor[x, y1] += 1 24 | y1 += inc_y 25 | return sum(1 for cell in floor.values() if cell > 1) 26 | 27 | 28 | def solve2(data): 29 | return solve1(data, diagonal=True) 30 | 31 | 32 | if __name__ == "__main__": 33 | data = open("input.txt").read() 34 | print(solve1(data)) 35 | print(solve2(data)) 36 | -------------------------------------------------------------------------------- /2017/16/16.py: -------------------------------------------------------------------------------- 1 | instructions = open("input").read().strip().split(",") 2 | 3 | ALPHABET = [chr(ord('a') + n) for n in range(16)] 4 | letters = ALPHABET[:] 5 | 6 | 7 | def run(instructions, letters): 8 | for instruction in instructions: 9 | if instruction[0] == 's': 10 | pos = int(instruction[1:]) 11 | letters[:] = letters[-pos:] + letters[:-pos] 12 | elif instruction[0] == 'x': 13 | pos1, pos2 = [int(p) for p in instruction[1:].split("/")] 14 | letters[pos1], letters[pos2] = letters[pos2], letters[pos1] 15 | elif instruction[0] == 'p': 16 | pos1, pos2 = [letters.index(p) for p in instruction[1:].split("/")] 17 | letters[pos1], letters[pos2] = letters[pos2], letters[pos1] 18 | return letters 19 | 20 | n = 0 21 | while True: 22 | run(instructions, letters) 23 | if n == 0: 24 | print("".join(letters)) 25 | n += 1 26 | if letters == ALPHABET: 27 | break 28 | 29 | for n in range(1000000000 % n): 30 | run(instructions, letters) 31 | print("".join(letters)) 32 | -------------------------------------------------------------------------------- /2021/24/short_24.py: -------------------------------------------------------------------------------- 1 | raws = [("inp " + alu).strip().split('\n') for alu in open("input.txt").read().split("inp ") if alu.strip()] 2 | Ms = [int(raw[4].split(' ')[-1]) for raw in raws] 3 | Ns = [int(raw[5].split(' ')[-1]) for raw in raws] 4 | Ps = [int(raw[15].split(' ')[-1]) for raw in raws] 5 | stack, digits_deps = [], [] 6 | for n, op in enumerate(Ms): 7 | if op == 1: # push 8 | stack.append((n, Ps[n])) 9 | elif op == 26: # pop 10 | n_constraining, value = stack.pop() 11 | digits_deps.append((n, n_constraining, value + Ns[n])) 12 | min_digits, max_digits = {}, {} 13 | for digit_main, digit_dep, offset in digits_deps: 14 | first = True 15 | for digit in range(1, 10): 16 | if 0 < (digit + offset) < 10: 17 | if first: 18 | min_digits[digit_dep], min_digits[digit_main] = digit, digit + offset 19 | first = False 20 | max_digits[digit_dep], max_digits[digit_main] = digit, digit + offset 21 | print('\n'.join("".join(str(v) for k, v in sorted(digits.items())) for digits in (max_digits, min_digits))) 22 | -------------------------------------------------------------------------------- /2016/14/14.py: -------------------------------------------------------------------------------- 1 | import re 2 | import hashlib 3 | 4 | 5 | def md5(salt): 6 | return hashlib.md5(salt.encode('utf8')).hexdigest() 7 | 8 | 9 | def md5_times(salt, times=1, seen={}): 10 | try: 11 | return seen[salt, times] 12 | except KeyError: 13 | pass 14 | key = salt 15 | for i in range(times): 16 | key = md5(key) 17 | seen[salt, times] = key 18 | return key 19 | 20 | 21 | TRIPLET = re.compile(r"(.)\1{2}") 22 | 23 | 24 | def generate(salt, times=1, how_many=64): 25 | found = index = 0 26 | while found < how_many: 27 | key = md5_times(salt + str(index), times) 28 | triplets = TRIPLET.findall(key) 29 | if triplets: 30 | quintuplet = triplets[0] * 5 31 | for next_index in range(index + 1, index + 1001): 32 | if re.findall(quintuplet, md5_times(salt + str(next_index), times)): 33 | found += 1 34 | break 35 | index += 1 36 | return index - 1 37 | 38 | salt = 'qzyelonm' 39 | print(generate(salt)) 40 | print(generate(salt, 2017)) 41 | -------------------------------------------------------------------------------- /2015/advent3b.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | var c rune 7 | var x, y, xb, yb int 8 | houses := make(map[string]int) 9 | flip_flop := 1 10 | for { 11 | houses[fmt.Sprintf("%d_%d", x, y)] += 1 12 | houses[fmt.Sprintf("%d_%d", xb, yb)] += 1 13 | if _, err := fmt.Scanf("%c", &c); err != nil { 14 | break 15 | } 16 | if flip_flop == 1 { 17 | if c == '^' { 18 | y += 1 19 | } else if c == 'v' { 20 | y -= 1 21 | } else if c == '>' { 22 | x += 1 23 | } else if c == '<' { 24 | x -= 1 25 | } 26 | } else { 27 | if c == '^' { 28 | yb += 1 29 | } else if c == 'v' { 30 | yb -= 1 31 | } else if c == '>' { 32 | xb += 1 33 | } else if c == '<' { 34 | xb -= 1 35 | } 36 | } 37 | flip_flop = -flip_flop 38 | } 39 | fmt.Printf("%d\n", len(houses)) 40 | } 41 | -------------------------------------------------------------------------------- /2015/advent19/input.txt: -------------------------------------------------------------------------------- 1 | Al => ThF 2 | Al => ThRnFAr 3 | B => BCa 4 | B => TiB 5 | B => TiRnFAr 6 | Ca => CaCa 7 | Ca => PB 8 | Ca => PRnFAr 9 | Ca => SiRnFYFAr 10 | Ca => SiRnMgAr 11 | Ca => SiTh 12 | F => CaF 13 | F => PMg 14 | F => SiAl 15 | H => CRnAlAr 16 | H => CRnFYFYFAr 17 | H => CRnFYMgAr 18 | H => CRnMgYFAr 19 | H => HCa 20 | H => NRnFYFAr 21 | H => NRnMgAr 22 | H => NTh 23 | H => OB 24 | H => ORnFAr 25 | Mg => BF 26 | Mg => TiMg 27 | N => CRnFAr 28 | N => HSi 29 | O => CRnFYFAr 30 | O => CRnMgAr 31 | O => HP 32 | O => NRnFAr 33 | O => OTi 34 | P => CaP 35 | P => PTi 36 | P => SiRnFAr 37 | Si => CaSi 38 | Th => ThCa 39 | Ti => BP 40 | Ti => TiTi 41 | e => HF 42 | e => NAl 43 | e => OMg 44 | 45 | CRnCaSiRnBSiRnFArTiBPTiTiBFArPBCaSiThSiRnTiBPBPMgArCaSiRnTiMgArCaSiThCaSiRnFArRnSiRnFArTiTiBFArCaCaSiRnSiThCaCaSiRnMgArFYSiRnFYCaFArSiThCaSiThPBPTiMgArCaPRnSiAlArPBCaCaSiRnFYSiThCaRnFArArCaCaSiRnPBSiRnFArMgYCaCaCaCaSiThCaCaSiAlArCaCaSiRnPBSiAlArBCaCaCaCaSiThCaPBSiThPBPBCaSiRnFYFArSiThCaSiRnFArBCaCaSiRnFYFArSiThCaPBSiThCaSiRnPMgArRnFArPTiBCaPRnFArCaCaCaCaSiRnCaCaSiRnFYFArFArBCaSiThFArThSiThSiRnTiRnPMgArFArCaSiThCaPBCaSiRnBFArCaCaPRnCaCaPMgArSiRnFYFArCaSiThRnPBPMgAr 46 | -------------------------------------------------------------------------------- /2016/01/01.py: -------------------------------------------------------------------------------- 1 | istructions = [l.strip() for l in open("input", "r").readlines()[0].split(",")] 2 | 3 | def check(pos, seen=set()): 4 | if not None in seen: 5 | if tuple(pos[:2]) in seen: 6 | print("2: {}".format(sum(abs(x) for x in pos[:2]))) 7 | seen.add(None) 8 | else: 9 | seen.add(tuple(pos[:2])) 10 | 11 | def go(pos, where, step): 12 | if where == 'R': 13 | pos[2] -= 90 14 | else: 15 | pos[2] += 90 16 | pos[2] %= 360 17 | if pos[2] == 90: 18 | for s in range(step): 19 | pos[1] += 1 20 | check(pos) 21 | elif pos[2] == 180: 22 | for s in range(step): 23 | pos[0] -= 1 24 | check(pos) 25 | elif pos[2] == 270: 26 | for s in range(step): 27 | pos[1] -= 1 28 | check(pos) 29 | else: 30 | for s in range(step): 31 | pos[0] += 1 32 | check(pos) 33 | 34 | pos = [0, 0, 90] 35 | 36 | for instruction in istructions: 37 | where, step = instruction[0], int(instruction[1:]) 38 | go(pos, where, step) 39 | 40 | print("1: {}".format(sum(abs(x) for x in pos[:2]))) 41 | -------------------------------------------------------------------------------- /2018/15/input.txt: -------------------------------------------------------------------------------- 1 | ################################ 2 | ##############..###G.G#####..### 3 | #######...#####........#.##.#### 4 | #######..G######.#...........### 5 | #######..G..###.............#### 6 | ########.GG.##.G.##.......E##### 7 | ##########........#........##..# 8 | ##############GG...#...........# 9 | ##############.....#..........## 10 | #G.G...####....#G......G.#...### 11 | #G..#..##........G.........E.### 12 | #..###...G#............E.......# 13 | #...G...G.....#####............# 14 | #....#....#G.#######...........# 15 | #.##....#.#.#########.#..#...E.# 16 | ####...##G..#########.....E...E# 17 | #####...#...#########.#.#....E## 18 | #####.......#########.###......# 19 | ######......#########...######.# 20 | ########.....#######..#..####### 21 | ########......#####...##.####### 22 | ########............E.##.####### 23 | ####.........##......##..####### 24 | ####....#..E...E...####.######## 25 | ####.....#...........##.######## 26 | #####....##.#........########### 27 | #####.....#####....############# 28 | #####.#..######....############# 29 | ####..######....################ 30 | ####..###.#.....################ 31 | ####...##...#################### 32 | ################################ 33 | -------------------------------------------------------------------------------- /2020/17/day_17.py: -------------------------------------------------------------------------------- 1 | from itertools import product 2 | 3 | 4 | def parse(data, dimensions): 5 | return set(((col, row) + (0,) * (dimensions - 2)) 6 | for row, line in enumerate(data.strip().split('\n')) 7 | for col, pos in enumerate(line) if pos == '#') 8 | 9 | 10 | def around(point, dimensions): 11 | for deltas in product(range(-1, 2), repeat=dimensions): 12 | yield tuple(coord + delta for coord, delta in zip(point, deltas)) 13 | 14 | 15 | def solve(data, dimensions=3, cycle=6): 16 | space = parse(data, dimensions) 17 | for cont in range(cycle): 18 | adjacents = {} 19 | for point in space: 20 | for neigh in around(point, dimensions): 21 | if neigh != point: 22 | try: 23 | adjacents[neigh] += 1 24 | except KeyError: 25 | adjacents[neigh] = 1 26 | space = set(point for point, tot in adjacents.items() if tot == 3 or point in space and tot == 2) 27 | return len(space) 28 | 29 | 30 | if __name__ == "__main__": 31 | data = open("input.txt").read() 32 | print(solve(data)) 33 | print(solve(data, 4)) 34 | -------------------------------------------------------------------------------- /2022/02/day_02.py: -------------------------------------------------------------------------------- 1 | def load(data): 2 | steps = [] 3 | for line in data.strip().split("\n"): 4 | parts = line.split() 5 | steps.append(parts) 6 | return steps 7 | 8 | 9 | def point(their, your): 10 | outcome = {('A', 'X'): 3, ('B', 'Y'): 3, ('C', 'Z'): 3, 11 | ('A', 'Y'): 6, ('B', 'Z'): 6, ('C', 'X'): 6}.get((their, your), 0) 12 | return outcome + {'X': 1, 'Y': 2, 'Z': 3}[your] 13 | 14 | 15 | def strategy(their, your): 16 | return {('A', 'X'): 'Z', ('B', 'X'): 'X', ('C', 'X'): 'Y', 17 | ('A', 'Y'): 'X', ('B', 'Y'): 'Y', ('C', 'Y'): 'Z', 18 | ('A', 'Z'): 'Y', ('B', 'Z'): 'Z', ('C', 'Z'): 'X'}.get((their, your)) 19 | 20 | 21 | def solve1(data): 22 | steps = load(data) 23 | points = 0 24 | for their, your in steps: 25 | points += point(their, your) 26 | return points 27 | 28 | 29 | def solve2(data): 30 | steps = load(data) 31 | points = 0 32 | for their, your in steps: 33 | points += point(their, strategy(their, your)) 34 | return points 35 | 36 | 37 | if __name__ == "__main__": 38 | data = open("input.txt").read() 39 | print(solve1(data)) 40 | print(solve2(data)) 41 | -------------------------------------------------------------------------------- /2021/03/day_03.py: -------------------------------------------------------------------------------- 1 | def load(data): 2 | return [tuple(line) for line in data.strip().split("\n")] 3 | 4 | 5 | def find_commons(bits, most=True): 6 | length = len(bits[0]) 7 | commons = () 8 | find = (1, 0) if most else (0, 1) 9 | for n in range(length): 10 | tot1 = sum(int(line[n]) for line in bits) 11 | commons += (find[0] if tot1 >= (len(bits) + 1) // 2 else find[1],) 12 | return commons, length 13 | 14 | 15 | def solve1(data): 16 | commons, length = find_commons(load(data)) 17 | gamma = int("".join(str(c) for c in commons), 2) 18 | epsilon = 2**length - gamma - 1 19 | return epsilon * gamma 20 | 21 | 22 | def solve2(data): 23 | ratings = [] 24 | for gen in range(2): 25 | bits, pos = load(data), 0 26 | while len(bits) > 1: 27 | commons, length = find_commons(bits, gen == 0) 28 | bits = [line for line in bits if int(line[pos]) == commons[pos]] 29 | pos += 1 30 | ratings.append("".join(bits[0])) 31 | return int(ratings[0], 2) * int(ratings[1], 2) 32 | 33 | 34 | if __name__ == "__main__": 35 | data = open("input.txt").read() 36 | print(solve1(data)) 37 | print(solve2(data)) 38 | -------------------------------------------------------------------------------- /2022/05/day_05.py: -------------------------------------------------------------------------------- 1 | def load(data): 2 | moves, crates = [], [] 3 | for line in data.split("\n"): 4 | if not line: 5 | continue 6 | if line[1] == "1": 7 | stacks = [[] for n in range(len(line.split()))] 8 | elif line[0] == "m": 9 | moves.append([int(line.split()[n]) - (1 if n > 1 else 0) for n in (1, 3, 5)]) 10 | else: 11 | crates.append(line) 12 | for line in crates[::-1]: 13 | for n, pile in enumerate(stacks): 14 | crate = line[1 + 4*n].strip() 15 | if crate: 16 | pile.append(crate) 17 | return stacks, moves 18 | 19 | 20 | def move(stacks, moves, stacking=True): 21 | for how_many, pile_from, pile_to in moves: 22 | for n in range(how_many, 0, -1): 23 | stacks[pile_to].append(stacks[pile_from].pop(-1 if stacking else -n)) 24 | return "".join(pile.pop() for pile in stacks) 25 | 26 | def solve1(data): 27 | return move(*load(data)) 28 | 29 | 30 | def solve2(data): 31 | return move(*load(data), stacking=False) 32 | 33 | 34 | if __name__ == "__main__": 35 | data = open("input.txt").read() 36 | print(solve1(data)) 37 | print(solve2(data)) 38 | -------------------------------------------------------------------------------- /2020/05/day_05.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict 2 | 3 | 4 | def calc(strip, low): 5 | s = 2**len(strip) 6 | f, t = 0, s - 1 7 | for c in strip: 8 | s /= 2 9 | if c == low: 10 | t -= s 11 | else: 12 | f += s 13 | return int(t) 14 | 15 | 16 | def row_col(line): 17 | row = calc(line[:7], 'F') 18 | col = calc(line[7:], 'L') 19 | return row, col 20 | 21 | 22 | def calc_id(row, col): 23 | return row * 8 + col 24 | 25 | 26 | def solve1(data): 27 | seats = defaultdict(list) 28 | max_id = 0 29 | for line in data.strip().split('\n'): 30 | row, col = row_col(line) 31 | seats[row].append(col) 32 | max_id = max(calc_id(row, col), max_id) 33 | return max_id, seats 34 | 35 | 36 | def solve2(seats): 37 | for n, (row, cols) in enumerate(sorted(seats.items())): 38 | if n == 0: 39 | continue 40 | if len(cols) < 8: 41 | return(calc_id(row, (set(range(8)) - set(cols)).pop())) 42 | break 43 | 44 | 45 | if __name__ == "__main__": 46 | data = open("input.txt").read() 47 | max_id, seats = solve1(data) 48 | print(max_id) 49 | print(solve2(seats)) 50 | -------------------------------------------------------------------------------- /2019/01/input.txt: -------------------------------------------------------------------------------- 1 | 54172 2 | 58469 3 | 92948 4 | 143402 5 | 57563 6 | 54532 7 | 68042 8 | 89847 9 | 70872 10 | 54069 11 | 107310 12 | 146439 13 | 88851 14 | 142869 15 | 71309 16 | 89613 17 | 70338 18 | 87708 19 | 95305 20 | 134384 21 | 128250 22 | 134991 23 | 91270 24 | 127819 25 | 68650 26 | 102556 27 | 129882 28 | 68688 29 | 129939 30 | 137344 31 | 102624 32 | 90828 33 | 86487 34 | 91712 35 | 114866 36 | 75697 37 | 107599 38 | 99053 39 | 87511 40 | 128128 41 | 57772 42 | 69314 43 | 90771 44 | 145376 45 | 100730 46 | 142675 47 | 112731 48 | 83985 49 | 123565 50 | 127325 51 | 86597 52 | 121772 53 | 131992 54 | 148859 55 | 93348 56 | 77294 57 | 119763 58 | 74636 59 | 95592 60 | 79628 61 | 78861 62 | 68565 63 | 88820 64 | 134291 65 | 69262 66 | 128678 67 | 118216 68 | 52799 69 | 92731 70 | 61600 71 | 63477 72 | 64016 73 | 131872 74 | 131412 75 | 146579 76 | 104400 77 | 99110 78 | 63458 79 | 144393 80 | 54787 81 | 148622 82 | 91323 83 | 61137 84 | 106082 85 | 103644 86 | 63795 87 | 126648 88 | 61489 89 | 140964 90 | 110963 91 | 72696 92 | 124370 93 | 110466 94 | 139317 95 | 108440 96 | 148062 97 | 89992 98 | 145645 99 | 70556 100 | 95739 101 | -------------------------------------------------------------------------------- /2021/13/test_13.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import day_13 as day 4 | 5 | 6 | class TestDay(unittest.TestCase): 7 | def setUp(self): 8 | self.data = """6,10 9 | 0,14 10 | 9,10 11 | 0,3 12 | 10,4 13 | 4,11 14 | 6,0 15 | 6,12 16 | 4,1 17 | 0,13 18 | 10,12 19 | 3,4 20 | 3,0 21 | 8,4 22 | 1,10 23 | 2,14 24 | 8,10 25 | 9,0 26 | 27 | fold along y=7 28 | fold along x=5 29 | """ 30 | self.part_2 = """ 31 | ##### 32 | #...# 33 | #...# 34 | #...# 35 | ##### 36 | """ 37 | self.solution_2 = """ 38 | ####.###..#....#..#.###..###..####.#..# 39 | #....#..#.#....#..#.#..#.#..#.#....#..# 40 | ###..###..#....#..#.###..#..#.###..#### 41 | #....#..#.#....#..#.#..#.###..#....#..# 42 | #....#..#.#....#..#.#..#.#.#..#....#..# 43 | ####.###..####..##..###..#..#.#....#..# 44 | """ 45 | 46 | def test_part_1(self): 47 | self.assertEqual(17, day.solve1(self.data)) 48 | 49 | def test_part_2(self): 50 | self.assertEqual(self.part_2, day.solve2(self.data)) 51 | 52 | def test_solution(self): 53 | import os 54 | data = open(os.path.dirname(__file__) + "/input.txt").read() 55 | self.assertEqual(day.solve1(data), 708) 56 | self.assertEqual(day.solve2(data), self.solution_2) 57 | -------------------------------------------------------------------------------- /2016/10/10.py: -------------------------------------------------------------------------------- 1 | instructions = [i.strip() for i in open("input").readlines()] 2 | 3 | bots = {} 4 | gives = {} 5 | 6 | for instruction in instructions[:]: 7 | parts = instruction.split() 8 | if parts[0] == "value": 9 | name = parts[-1] 10 | bots[name] = sorted(bots.get(name, []) + [int(parts[1])]) 11 | instructions.remove(instruction) 12 | else: 13 | name = parts[1] 14 | assert name not in gives 15 | gives[name] = (parts[5], parts[6], parts[10], parts[11]) 16 | 17 | while True: 18 | twos = 0 19 | for name, chips in bots.items(): 20 | if len(chips) == 2: 21 | twos += 1 22 | if chips == [17, 61]: 23 | print(name) 24 | type_low, name_low, type_high, name_high = gives[name] 25 | if type_low == "output": 26 | name_low += "o" 27 | if type_high == "output": 28 | name_high += "o" 29 | bots[name_low] = sorted(bots.get(name_low, []) + [chips[0]]) 30 | bots[name_high] = sorted(bots.get(name_high, []) + [chips[1]]) 31 | bots[name] = [] 32 | if twos == 0: 33 | break 34 | print(bots["0o"][0] * bots["1o"][0] * bots["2o"][0]) 35 | -------------------------------------------------------------------------------- /2015/advent17/advent.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | var combinations = 0 8 | var combinations_min = 0 9 | var best_min = 9999 10 | 11 | func sum(numbers []int) int { 12 | total := 0 13 | for i := 0; i < len(numbers); i += 1 { 14 | total += numbers[i] 15 | } 16 | return total 17 | } 18 | 19 | func subset_sum(numbers []int, target int, partial []int) { 20 | s := sum(partial) 21 | 22 | // check if the partial sum is equals to target 23 | if s == target { 24 | if len(partial) < best_min { 25 | best_min = len(partial) 26 | combinations_min = 1 27 | } else if len(partial) == best_min { 28 | combinations_min += 1 29 | } 30 | combinations += 1 31 | //print "sum(%s)=%s" % (partial, target) 32 | } 33 | if s >= target { 34 | return // if we reach the number why bother to continue 35 | } 36 | 37 | for i := 0; i < len(numbers); i++ { 38 | n := numbers[i] 39 | remaining := numbers[i+1 : len(numbers)] 40 | subset_sum(remaining, target, append(partial, n)) 41 | } 42 | } 43 | 44 | func main() { 45 | subset_sum([]int{50, 44, 11, 49, 42, 46, 18, 32, 26, 40, 21, 7, 18, 43, 10, 47, 36, 24, 22, 40}, 150, []int{}) 46 | fmt.Println(combinations) 47 | fmt.Println(best_min, combinations_min) 48 | } 49 | -------------------------------------------------------------------------------- /2019/07/input.txt: -------------------------------------------------------------------------------- 1 | 3,8,1001,8,10,8,105,1,0,0,21,42,67,84,109,122,203,284,365,446,99999,3,9,1002,9,3,9,1001,9,5,9,102,4,9,9,1001,9,3,9,4,9,99,3,9,1001,9,5,9,1002,9,3,9,1001,9,4,9,102,3,9,9,101,3,9,9,4,9,99,3,9,101,5,9,9,1002,9,3,9,101,5,9,9,4,9,99,3,9,102,5,9,9,101,5,9,9,102,3,9,9,101,3,9,9,102,2,9,9,4,9,99,3,9,101,2,9,9,1002,9,3,9,4,9,99,3,9,101,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,101,1,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,1,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,1002,9,2,9,4,9,99,3,9,1001,9,1,9,4,9,3,9,101,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,1,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,1002,9,2,9,4,9,99,3,9,101,2,9,9,4,9,3,9,101,2,9,9,4,9,3,9,101,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,1001,9,1,9,4,9,99,3,9,1001,9,1,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,99,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,101,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,101,1,9,9,4,9,99 2 | -------------------------------------------------------------------------------- /2021/12/day_12.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict 2 | 3 | 4 | class Caves: 5 | def __init__(self, data): 6 | self.edges = defaultdict(list) 7 | for edge in data.strip().split("\n"): 8 | v1, v2 = edge.split("-") 9 | if v2 != 'start' and v1 != 'end': 10 | self.edges[v1].append(v2) 11 | if v2 != 'end' and v1 != 'start': 12 | self.edges[v2].append(v1) 13 | 14 | def count(self, cave, visited, double_cave=False): 15 | if cave == 'end': 16 | return 1 17 | if cave.islower() and cave in visited: 18 | if double_cave is False or double_cave: 19 | return 0 20 | double_cave = cave 21 | return sum(self.count(next_cave, visited | {cave}, double_cave) 22 | for next_cave in self.edges[cave]) 23 | 24 | def paths(self, double=False): 25 | return self.count('start', set(), double) 26 | 27 | 28 | def solve1(data): 29 | return Caves(data).paths() 30 | 31 | 32 | def solve2(data): 33 | return Caves(data).paths(None) 34 | 35 | 36 | if __name__ == "__main__": 37 | data = open("input.txt").read() 38 | print(solve1(data)) 39 | print(solve2(data)) 40 | -------------------------------------------------------------------------------- /2021/20/test_20.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import pytest 3 | 4 | import day_20 as day 5 | 6 | 7 | class TestDay(unittest.TestCase): 8 | def setUp(self): 9 | self.data = """..#.#..#####.#.#.#.###.##.....###.##.#..###.####..#####..#....#..#..##..## 10 | #..######.###...####..#..#####..##..#.#####...##.#.#..#.##..#.#......#.### 11 | .######.###.####...#.##.##..#..#..#####.....#.#....###..#.##......#.....#. 12 | .#..#..##..#...##.######.####.####.#.#...#.......#..#.#.#...####.##.#..... 13 | .#..#...##.#.##..#...##.#.##..###.#......#.#.......#.#.#.####.###.##...#.. 14 | ...####.#..#..#.##.#....##..#.####....##...##..#...#......#.#.......#..... 15 | ..##..####..#...#.#.#...##..#.#..###..#####........#..####......#..# 16 | 17 | #..#. 18 | #.... 19 | ##..# 20 | ..#.. 21 | ..### 22 | """ 23 | 24 | def test_part_1(self): 25 | self.assertEqual(day.solve1(self.data), 35) 26 | 27 | def test_part_2(self): 28 | self.assertEqual(day.solve2(self.data), 3351) 29 | 30 | @pytest.mark.slow 31 | def test_solution(self): 32 | import os 33 | data = open(os.path.dirname(__file__) + "/input.txt").read() 34 | self.assertEqual(day.solve1(data), 5057) 35 | self.assertEqual(day.solve2(data), 18502) 36 | -------------------------------------------------------------------------------- /2020/05/test_05.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import day_05 as day 4 | 5 | 6 | class TestDay(unittest.TestCase): 7 | def test_row_col_1(self): 8 | line = """BFFFBBFRRR""" 9 | row, col = 70, 7 10 | self.assertEqual((row, col), day.row_col(line)) 11 | 12 | def test_id_1(self): 13 | row, col = 70, 7 14 | self.assertEqual(567, day.calc_id(row, col)) 15 | 16 | def test_row_col_2(self): 17 | line = """FFFBBBFRRR""" 18 | row, col = 14, 7 19 | self.assertEqual((row, col), day.row_col(line)) 20 | 21 | def test_row_id_2(self): 22 | row, col = 14, 7 23 | self.assertEqual(119, day.calc_id(row, col)) 24 | 25 | def test_row_col_3(self): 26 | line = """BBFFBBFRLL""" 27 | row, col = 102, 4 28 | self.assertEqual((row, col), day.row_col(line)) 29 | 30 | def test_row_id_3(self): 31 | row, col = 102, 4 32 | self.assertEqual(820, day.calc_id(row, col)) 33 | 34 | def test_solution(self): 35 | import os 36 | data = open(os.path.dirname(__file__) + "/input.txt").read() 37 | part1, seats = day.solve1(data) 38 | part2 = day.solve2(seats) 39 | self.assertEqual(part1, 904) 40 | self.assertEqual(part2, 669) 41 | -------------------------------------------------------------------------------- /2017/11/11.py: -------------------------------------------------------------------------------- 1 | def dist(raw): 2 | data = raw.split(",") 3 | 4 | pos = [0, 0, 0] # x, y, z 5 | furthest = 0 6 | 7 | for move in data: 8 | if move == "n": 9 | pos[1] += 1 10 | pos[2] -= 1 11 | elif move == "s": 12 | pos[1] -= 1 13 | pos[2] += 1 14 | elif move == "ne": 15 | pos[0] -= 1 16 | pos[1] += 1 17 | elif move == "nw": 18 | pos[0] += 1 19 | pos[2] -= 1 20 | elif move == "se": 21 | pos[0] -= 1 22 | pos[2] += 1 23 | elif move == "sw": 24 | pos[0] += 1 25 | pos[1] -= 1 26 | else: 27 | assert False, move 28 | furthest = max(furthest, abs(pos[0]), abs(pos[1]), abs(pos[2])) 29 | 30 | return(max(abs(pos[0]), abs(pos[1]), abs(pos[2])), furthest) 31 | 32 | 33 | raw = "ne,ne,ne" # is 3 steps away. 34 | print(dist(raw)) 35 | 36 | raw = "ne,ne,sw,sw" # is 0 steps away (back where you started). 37 | print(dist(raw)) 38 | 39 | raw = "ne,ne,s,s" # is 2 steps away (se,se). 40 | print(dist(raw)) 41 | 42 | raw = "se,sw,se,sw,sw" # is 3 steps away (s,s,sw). 43 | print(dist(raw)) 44 | 45 | raw = open("input").read().strip() 46 | print(dist(raw)) 47 | -------------------------------------------------------------------------------- /2020/10/day_10.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict 2 | 3 | 4 | def parse(data): 5 | values = [int(x) for x in data.strip().split("\n")] 6 | return sorted(values) + [max(values) + 3] 7 | 8 | 9 | def solve1(data): 10 | adapters = parse(data) 11 | differences = defaultdict(int) 12 | jolt = 0 13 | while True: 14 | last_jolt = jolt 15 | while True: 16 | jolt += 1 17 | if jolt in adapters: 18 | break 19 | if jolt > adapters[-1]: 20 | return differences 21 | differences[jolt - last_jolt] += 1 22 | 23 | 24 | def explore(adapters, jolt, cached): 25 | try: 26 | return cached[jolt] 27 | except KeyError: 28 | ways = 0 29 | for n in range(1, 4): 30 | if jolt + n == adapters[-1]: 31 | ways += 1 32 | elif jolt + n in adapters: 33 | ways += explore(adapters, jolt + n, cached) 34 | cached[jolt] = ways 35 | return ways 36 | 37 | 38 | def solve2(data): 39 | return explore(parse(data), 0, {}) 40 | 41 | 42 | if __name__ == "__main__": 43 | data = open("input.txt").read() 44 | differences = solve1(data) 45 | print(differences[1] * differences[3]) 46 | print(solve2(data)) 47 | -------------------------------------------------------------------------------- /2022/16/test_16.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import pytest 3 | day = __import__('day_' + __file__[-5:-3]) 4 | 5 | 6 | class TestDay(unittest.TestCase): 7 | def setUp(self): 8 | self.data = """Valve AA has flow rate=0; tunnels lead to valves DD, II, BB 9 | Valve BB has flow rate=13; tunnels lead to valves CC, AA 10 | Valve CC has flow rate=2; tunnels lead to valves DD, BB 11 | Valve DD has flow rate=20; tunnels lead to valves CC, AA, EE 12 | Valve EE has flow rate=3; tunnels lead to valves FF, DD 13 | Valve FF has flow rate=0; tunnels lead to valves EE, GG 14 | Valve GG has flow rate=0; tunnels lead to valves FF, HH 15 | Valve HH has flow rate=22; tunnel leads to valve GG 16 | Valve II has flow rate=0; tunnels lead to valves AA, JJ 17 | Valve JJ has flow rate=21; tunnel leads to valve II 18 | """ 19 | 20 | def test_part_1(self): 21 | self.assertEqual(1651, day.solve1(self.data)) 22 | 23 | def test_part_2(self): 24 | self.assertEqual(1707, day.solve2(self.data)) 25 | 26 | @pytest.mark.slow 27 | def test_solution(self): 28 | import os 29 | with open(os.path.dirname(__file__) + "/input.txt") as f_data: 30 | data = f_data.read() 31 | self.assertEqual(day.solve1(data), 1789) 32 | self.assertEqual(day.solve2(data), 2496) 33 | -------------------------------------------------------------------------------- /2018/09/09.py: -------------------------------------------------------------------------------- 1 | # 400 players; last marble is worth 71864 points 2 | 3 | players = 400 4 | m_last = 71864 5 | 6 | 7 | class Marble: 8 | def __init__(self, value, previous=None, next=None, inserting=False): 9 | self.value = value 10 | self.next = next or self 11 | self.previous = previous or self 12 | if inserting: 13 | self.previous.next = self.next.previous = self 14 | 15 | def remove(self): 16 | self.previous.next, self.next.previous = self.next, self.previous 17 | return self.next 18 | 19 | def output(self): 20 | n = self 21 | while True: 22 | print(n.value, end=' ') 23 | n = n.next 24 | if n == self: 25 | break 26 | print() 27 | 28 | 29 | for last in (m_last, m_last * 100): 30 | points, player, current = [0] * players, 0, Marble(0) 31 | for m in range(1, last + 1): 32 | if m % 23 == 0: 33 | for step in range(7): 34 | current = current.previous 35 | points[player] += m + current.value 36 | current = current.remove() 37 | else: 38 | current = Marble(m, current.next, current.next.next, inserting=True) 39 | player = (player + 1) % players 40 | print(max(points)) 41 | -------------------------------------------------------------------------------- /2016/17/17.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | import hashlib 3 | 4 | 5 | def get_doors(pos, size, salt): 6 | hash_doors = hashlib.md5(salt.encode('utf8')).hexdigest()[:4] 7 | doors = [] 8 | for n, (d, d_x, d_y) in enumerate((("U", 0, -1), ("D", 0, 1), ("L", -1, 0), ("R", 1, 0))): 9 | if hash_doors[n] > 'a': 10 | if 0 <= pos[0] + d_x < size[0] and 0 <= pos[1] + d_y < size[1]: 11 | doors.append((d, d_x, d_y)) 12 | return doors 13 | 14 | 15 | def minimum_path_bfs(pos, size, passcode, longest=False): 16 | target = (size[0] - 1, size[1] - 1) 17 | queue = deque([("", pos)]) 18 | longest_path = "" 19 | while queue: 20 | path, current = queue.popleft() 21 | if current == target: 22 | if not longest: 23 | return path 24 | if len(path) > len(longest_path): 25 | longest_path = path 26 | continue 27 | for new_path, d_x, d_y in get_doors(current, size, passcode + path): 28 | queue.append((path + new_path, (current[0] + d_x, current[1] + d_y))) 29 | return longest_path 30 | 31 | path = minimum_path_bfs((0, 0), (4, 4), "gdjjyniy") 32 | print(path) 33 | 34 | path = minimum_path_bfs((0, 0), (4, 4), "gdjjyniy", longest=True) 35 | print(len(path)) 36 | 37 | 38 | -------------------------------------------------------------------------------- /2020/22/day_22.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | 3 | 4 | def parse(data): 5 | return [deque(int(c) for c in cards.split('\n')[1:]) for cards in data.strip().split('\n\n')] 6 | 7 | 8 | def points(deck): 9 | return sum((len(deck) - n) * card for n, card in enumerate(deck)) 10 | 11 | 12 | def dealt(decks): 13 | return [deck.popleft() for deck in decks] 14 | 15 | 16 | def win(decks, cards, step): 17 | if step == 2 and all(len(decks[n]) >= cards[n] for n in range(2)): 18 | return game([deque(list(decks[0])[:cards[0]]), deque(list(decks[1])[:cards[1]])], step) 19 | return cards.index(max(cards)) 20 | 21 | 22 | def game(decks, step): 23 | previous = set() 24 | while all(decks): 25 | this_round = tuple((tuple(decks[0]), tuple(decks[1]))) 26 | if this_round in previous: 27 | return 0 28 | previous.add(this_round) 29 | cards = dealt(decks) 30 | winner = win(decks, cards, step) 31 | decks[winner].extend([cards[winner], cards[1 - winner]]) 32 | return winner 33 | 34 | 35 | def solve(data, step=1): 36 | decks = parse(data) 37 | return points(decks[game(decks, step)]) 38 | 39 | 40 | if __name__ == "__main__": 41 | data = open("input.txt").read() 42 | print(solve(data)) 43 | print(solve(data, step=2)) 44 | -------------------------------------------------------------------------------- /2021/16/input.txt: -------------------------------------------------------------------------------- 1 | A052E04CFD9DC0249694F0A11EA2044E200E9266766AB004A525F86FFCDF4B25DFC401A20043A11C61838600FC678D51B8C0198910EA1200010B3EEA40246C974EF003331006619C26844200D414859049402D9CDA64BDEF3C4E623331FBCCA3E4DFBBFC79E4004DE96FC3B1EC6DE4298D5A1C8F98E45266745B382040191D0034539682F4E5A0B527FEB018029277C88E0039937D8ACCC6256092004165D36586CC013A008625A2D7394A5B1DE16C0E3004A8035200043220C5B838200EC4B8E315A6CEE6F3C3B9FFB8100994200CC59837108401989D056280803F1EA3C41130047003530004323DC3C860200EC4182F1CA7E452C01744A0A4FF6BBAE6A533BFCD1967A26E20124BE1920A4A6A613315511007A4A32BE9AE6B5CAD19E56BA1430053803341007E24C168A6200D46384318A6AAC8401907003EF2F7D70265EFAE04CCAB3801727C9EC94802AF92F493A8012D9EABB48BA3805D1B65756559231917B93A4B4B46009C91F600481254AF67A845BA56610400414E3090055525E849BE8010397439746400BC255EE5362136F72B4A4A7B721004A510A7370CCB37C2BA0010D3038600BE802937A429BD20C90CCC564EC40144E80213E2B3E2F3D9D6DB0803F2B005A731DC6C524A16B5F1C1D98EE006339009AB401AB0803108A12C2A00043A134228AB2DBDA00801EC061B080180057A88016404DA201206A00638014E0049801EC0309800AC20025B20080C600710058A60070003080006A4F566244012C4B204A83CB234C2244120080E6562446669025CD4802DA9A45F004658527FFEC720906008C996700397319DD7710596674004BE6A161283B09C802B0D00463AC9563C2B969F0E080182972E982F9718200D2E637DB16600341292D6D8A7F496800FD490BCDC68B33976A872E008C5F9DFD566490A14 2 | -------------------------------------------------------------------------------- /2019/02/02.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | 4 | class Computer: 5 | def __init__(self, program: str): 6 | self.program = [int(c.strip()) for c in program.split(',')] 7 | self._backup = self.program[:] 8 | 9 | def reset(self): 10 | self.program = self._backup[:] 11 | 12 | def run(self, pos=0): 13 | while True: 14 | if self.program[pos] == 99: 15 | break 16 | op1, op2 = self.program[self.program[pos + 1]], self.program[self.program[pos + 2]] 17 | func = self.program[pos] 18 | assert func in (1, 2) 19 | self.program[self.program[pos + 3]] = op1 + op2 if func == 1 else op1 * op2 20 | pos += 4 21 | 22 | 23 | def test_programs(): 24 | c = Computer("1,0,0,0,99") 25 | c.run() 26 | assert c.program == [2, 0, 0, 0, 99] 27 | 28 | 29 | if __name__ == "__main__": 30 | c = Computer(open('input.txt').read()) 31 | c.program[1] = 12 32 | c.program[2] = 2 33 | c.run() 34 | print(c.program[0]) 35 | 36 | for x in range(100): 37 | for y in range(100): 38 | c.reset() 39 | c.program[1] = x 40 | c.program[2] = y 41 | c.run() 42 | if c.program[0] == 19690720: 43 | print("{:02d}{:02d}".format(x, y)) 44 | sys.exit(0) 45 | -------------------------------------------------------------------------------- /2020/15/test_15.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import pytest 3 | 4 | import day_15 as day 5 | 6 | 7 | class TestDay(unittest.TestCase): 8 | def setUp(self): 9 | self.data = ("0,3,6", 10 | "1,3,2", 11 | "2,1,3", 12 | "1,2,3", 13 | "2,3,1", 14 | "3,2,1", 15 | "3,1,2") 16 | self.solve1 = (436, 1, 10, 27, 78, 438, 1836) 17 | self.solve2 = (175594, 2578, 3544142, 261214, 6895259, 18, 362) 18 | self.solve2_30000 = (7717, 13, 5124, 0, 42, 22, 10) 19 | 20 | def test_part_1(self): 21 | for data, sol in zip(self.data, self.solve1): 22 | self.assertEqual(day.solve(data), sol) 23 | 24 | def test_part_2_short(self): 25 | for data, sol, sol_quick in zip(self.data, self.solve2, self.solve2_30000): 26 | self.assertEqual(day.solve(data, 30000), sol_quick) 27 | 28 | @pytest.mark.slow 29 | def test_solution(self): 30 | data = "0,13,1,8,6,15" 31 | self.assertEqual(day.solve(data), 1618) 32 | self.assertEqual(day.solve(data, 30000000), 548531) 33 | 34 | @pytest.mark.slow 35 | def test_part_2(self): 36 | for data, sol, sol_quick in zip(self.data, self.solve2, self.solve2_30000): 37 | self.assertEqual(day.solve(data, 30000000), sol) 38 | -------------------------------------------------------------------------------- /2020/23/day_23.py: -------------------------------------------------------------------------------- 1 | def solve(data, moves=100, n_cups=9): 2 | cups = [int(cup) for cup in data] + [int(cup) for cup in range(len(data) + 1, n_cups + 1)] 3 | following = {} 4 | for n, cup in enumerate(cups): 5 | following[cup] = cups[(n + 1) % n_cups] 6 | current = cups[0] 7 | for move in range(moves): 8 | pick_up_1 = following[current] 9 | pick_up_2 = following[pick_up_1] 10 | pick_up_3 = following[pick_up_2] 11 | next_current = following[pick_up_3] 12 | following[current] = next_current 13 | destination = current 14 | while True: 15 | destination -= 1 16 | if destination == 0: 17 | destination = n_cups 18 | if destination not in (pick_up_1, pick_up_2, pick_up_3): 19 | break 20 | following[pick_up_3] = following[destination] 21 | following[destination] = pick_up_1 22 | current = next_current 23 | cups = [] 24 | next_1 = 1 25 | for n in range(1, n_cups): 26 | cups.append(following[next_1]) 27 | next_1 = cups[-1] 28 | if n_cups == 9: 29 | return "".join(str(cup) for cup in cups) 30 | return cups[0] * cups[1] 31 | 32 | 33 | if __name__ == "__main__": 34 | data = "123487596" 35 | print(solve(data)) 36 | print(solve(data, moves=10000000, n_cups=1000000)) 37 | -------------------------------------------------------------------------------- /2017/24/24.py: -------------------------------------------------------------------------------- 1 | class Port: 2 | def __init__(self, pin1, pin2): 3 | self.pin1 = pin1 4 | self.pin2 = pin2 5 | 6 | def other_pin(self, pin): 7 | if pin == self.pin1: 8 | return self.pin2 9 | return self.pin1 10 | 11 | 12 | def load(filename): 13 | ports = set() 14 | for l in open(filename).readlines(): 15 | pin1, pin2 = tuple(int(p) for p in l.strip().split("/")) 16 | ports.add(Port(pin1, pin2)) 17 | return ports 18 | 19 | 20 | def all_bridges(ports, path=None, bridges=None): 21 | if bridges is None: 22 | bridges = set() 23 | if path is None: 24 | path = (0,) 25 | last_pin = path[-1] 26 | availables = [p for p in ports if p.pin1 == last_pin or p.pin2 == last_pin] 27 | if not availables: 28 | bridges.add(path) 29 | return bridges 30 | else: 31 | for port in availables: 32 | ports.remove(port) 33 | all_bridges(ports, path + (port.other_pin(last_pin),), bridges) 34 | ports.add(port) 35 | return bridges 36 | 37 | ports = load("input") 38 | bridges = all_bridges(ports) 39 | 40 | print(max(sum(bridge[:-1]) * 2 + bridge[-1] for bridge in bridges)) 41 | longest = max(len(bridge) for bridge in bridges) 42 | print(max(sum(bridge[:-1]) * 2 + bridge[-1] for bridge in bridges if len(bridge) == longest)) 43 | -------------------------------------------------------------------------------- /2022/11/test_11.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | day = __import__('day_' + __file__[-5:-3]) 3 | 4 | 5 | class TestDay(unittest.TestCase): 6 | def setUp(self): 7 | self.data = """Monkey 0: 8 | Starting items: 79, 98 9 | Operation: new = old * 19 10 | Test: divisible by 23 11 | If true: throw to monkey 2 12 | If false: throw to monkey 3 13 | 14 | Monkey 1: 15 | Starting items: 54, 65, 75, 74 16 | Operation: new = old + 6 17 | Test: divisible by 19 18 | If true: throw to monkey 2 19 | If false: throw to monkey 0 20 | 21 | Monkey 2: 22 | Starting items: 79, 60, 97 23 | Operation: new = old * old 24 | Test: divisible by 13 25 | If true: throw to monkey 1 26 | If false: throw to monkey 3 27 | 28 | Monkey 3: 29 | Starting items: 74 30 | Operation: new = old + 3 31 | Test: divisible by 17 32 | If true: throw to monkey 0 33 | If false: throw to monkey 1 34 | """ 35 | 36 | def test_part_1(self): 37 | self.assertEqual(10605, day.solve1(self.data)) 38 | 39 | def test_part_2(self): 40 | self.assertEqual(2713310158, day.solve2(self.data)) 41 | 42 | def test_solution(self): 43 | import os 44 | with open(os.path.dirname(__file__) + "/input.txt") as f_data: 45 | data = f_data.read() 46 | self.assertEqual(day.solve1(data), 90294) 47 | self.assertEqual(day.solve2(data), 18170818354) 48 | -------------------------------------------------------------------------------- /2020/10/test_10.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import day_10 as day 4 | 5 | 6 | class TestDay(unittest.TestCase): 7 | def setUp(self): 8 | self.data = """16 9 | 10 10 | 15 11 | 5 12 | 1 13 | 11 14 | 7 15 | 19 16 | 6 17 | 12 18 | 4 19 | """ 20 | self.data_larger = """28 21 | 33 22 | 18 23 | 42 24 | 31 25 | 14 26 | 46 27 | 20 28 | 48 29 | 47 30 | 24 31 | 23 32 | 49 33 | 45 34 | 19 35 | 38 36 | 39 37 | 11 38 | 1 39 | 32 40 | 25 41 | 35 42 | 8 43 | 17 44 | 7 45 | 9 46 | 4 47 | 2 48 | 34 49 | 10 50 | 3 51 | """ 52 | 53 | def test_part_1(self): 54 | differences = day.solve1(self.data) 55 | self.assertEqual(differences[1], 7) 56 | self.assertEqual(differences[3], 5) 57 | 58 | def test_part_1_larger(self): 59 | differences = day.solve1(self.data_larger) 60 | self.assertEqual(differences[1], 22) 61 | self.assertEqual(differences[3], 10) 62 | 63 | def test_part_2(self): 64 | self.assertEqual(day.solve2(self.data), 8) 65 | 66 | def test_part_2_larger(self): 67 | self.assertEqual(day.solve2(self.data_larger), 19208) 68 | 69 | def test_solution(self): 70 | import os 71 | data = open(os.path.dirname(__file__) + "/input.txt").read() 72 | differences = day.solve1(data) 73 | self.assertEqual(differences[1] * differences[3], 2664) 74 | self.assertEqual(day.solve2(data), 148098383347712) 75 | -------------------------------------------------------------------------------- /2021/14/input.txt: -------------------------------------------------------------------------------- 1 | VPPHOPVVSFSVFOCOSBKF 2 | 3 | CO -> B 4 | CV -> N 5 | HV -> H 6 | ON -> O 7 | FS -> F 8 | NS -> S 9 | VK -> C 10 | BV -> F 11 | SC -> N 12 | NV -> V 13 | NC -> F 14 | NH -> B 15 | BO -> K 16 | FC -> H 17 | NB -> H 18 | HO -> F 19 | SB -> N 20 | KP -> V 21 | OS -> C 22 | OB -> P 23 | SH -> N 24 | BC -> H 25 | CK -> H 26 | SO -> N 27 | SP -> P 28 | CF -> P 29 | KV -> F 30 | CS -> V 31 | FF -> P 32 | VS -> V 33 | CP -> S 34 | PH -> V 35 | OP -> K 36 | KH -> B 37 | FB -> S 38 | CN -> H 39 | KS -> P 40 | FN -> O 41 | PV -> O 42 | VC -> S 43 | HF -> N 44 | OC -> O 45 | PK -> V 46 | KC -> C 47 | HK -> C 48 | PO -> N 49 | OO -> S 50 | VH -> N 51 | CC -> K 52 | BP -> K 53 | HC -> K 54 | FV -> K 55 | KF -> V 56 | VF -> C 57 | HN -> S 58 | VP -> B 59 | HH -> O 60 | FO -> O 61 | PC -> N 62 | KK -> C 63 | PN -> P 64 | NN -> C 65 | FH -> N 66 | VV -> O 67 | OK -> V 68 | CB -> N 69 | SN -> H 70 | VO -> H 71 | BB -> C 72 | PB -> F 73 | NF -> P 74 | KO -> S 75 | PP -> K 76 | NO -> O 77 | SF -> N 78 | KN -> S 79 | PS -> O 80 | VN -> V 81 | SS -> N 82 | BF -> O 83 | HP -> H 84 | HS -> N 85 | BS -> S 86 | VB -> F 87 | PF -> K 88 | SV -> V 89 | BH -> P 90 | FP -> O 91 | CH -> P 92 | OH -> K 93 | OF -> F 94 | HB -> V 95 | FK -> V 96 | BN -> V 97 | SK -> F 98 | OV -> C 99 | NP -> S 100 | NK -> S 101 | BK -> C 102 | KB -> F 103 | -------------------------------------------------------------------------------- /2022/03/day_03.py: -------------------------------------------------------------------------------- 1 | def load(data): 2 | racksacks = [] 3 | for line in data.strip().split("\n"): 4 | racksacks.append(Racksack(line)) 5 | return racksacks 6 | 7 | 8 | class Racksack: 9 | def __init__(self, line): 10 | middle = len(line)//2 11 | self.items = line[:middle], line[middle:] 12 | 13 | @property 14 | def pack(self): 15 | return "".join(self.items) 16 | 17 | def common(self, items=None): 18 | if not items: 19 | items = self.items 20 | first = set(items[0]) 21 | for other in items[1:]: 22 | first = first.intersection(other) 23 | return first.pop() 24 | 25 | def priority(self, item=None): 26 | if not item: 27 | item = self.common() 28 | return (ord(item) - ord('a') + 1) if item.islower() else (ord(item) - ord('A') + 27) 29 | 30 | 31 | def solve1(data): 32 | racksacks = load(data) 33 | return sum(racksack.priority() for racksack in racksacks) 34 | 35 | 36 | def solve2(data): 37 | racksacks = load(data) 38 | badges = 0 39 | for n in range(len(racksacks)//3): 40 | elv1, elv2, elv3 = racksacks[n*3:(n + 1)*3] 41 | badges += elv1.priority(elv1.common((elv1.pack, elv2.pack, elv3.pack))) 42 | return badges 43 | 44 | 45 | if __name__ == "__main__": 46 | data = open("input.txt").read() 47 | print(solve1(data)) 48 | print(solve2(data)) 49 | -------------------------------------------------------------------------------- /2019/19/input.txt: -------------------------------------------------------------------------------- 1 | 109,424,203,1,21101,11,0,0,1105,1,282,21101,18,0,0,1106,0,259,2102,1,1,221,203,1,21101,0,31,0,1106,0,282,21102,38,1,0,1105,1,259,20101,0,23,2,22101,0,1,3,21101,1,0,1,21101,0,57,0,1105,1,303,2101,0,1,222,20102,1,221,3,21001,221,0,2,21101,0,259,1,21101,80,0,0,1105,1,225,21101,137,0,2,21101,91,0,0,1105,1,303,1202,1,1,223,21001,222,0,4,21102,259,1,3,21101,225,0,2,21102,225,1,1,21101,0,118,0,1106,0,225,20102,1,222,3,21101,0,88,2,21102,133,1,0,1105,1,303,21202,1,-1,1,22001,223,1,1,21101,0,148,0,1106,0,259,1202,1,1,223,20102,1,221,4,20101,0,222,3,21101,24,0,2,1001,132,-2,224,1002,224,2,224,1001,224,3,224,1002,132,-1,132,1,224,132,224,21001,224,1,1,21102,1,195,0,106,0,108,20207,1,223,2,20102,1,23,1,21101,-1,0,3,21101,0,214,0,1105,1,303,22101,1,1,1,204,1,99,0,0,0,0,109,5,2102,1,-4,249,22102,1,-3,1,22102,1,-2,2,22102,1,-1,3,21101,0,250,0,1105,1,225,22102,1,1,-4,109,-5,2106,0,0,109,3,22107,0,-2,-1,21202,-1,2,-1,21201,-1,-1,-1,22202,-1,-2,-2,109,-3,2106,0,0,109,3,21207,-2,0,-1,1206,-1,294,104,0,99,22101,0,-2,-2,109,-3,2105,1,0,109,5,22207,-3,-4,-1,1206,-1,346,22201,-4,-3,-4,21202,-3,-1,-1,22201,-4,-1,2,21202,2,-1,-1,22201,-4,-1,1,22102,1,-2,3,21102,343,1,0,1105,1,303,1105,1,415,22207,-2,-3,-1,1206,-1,387,22201,-3,-2,-3,21202,-2,-1,-1,22201,-3,-1,3,21202,3,-1,-1,22201,-3,-1,2,21202,-4,1,1,21102,1,384,0,1106,0,303,1106,0,415,21202,-4,-1,-4,22201,-4,-3,-4,22202,-3,-2,-2,22202,-2,-4,-4,22202,-3,-2,-3,21202,-4,-1,-2,22201,-3,-2,1,22101,0,1,-4,109,-5,2106,0,0 2 | -------------------------------------------------------------------------------- /2020/18/day_18.py: -------------------------------------------------------------------------------- 1 | from operator import add, mul 2 | 3 | 4 | def parse(data): 5 | exprs = [] 6 | for line in data.strip().split('\n'): 7 | line = line.replace("(", "( ").replace(")", " )") 8 | exprs.append(list(int(x) if x.isdigit() else (add if x == '+' else mul if x == '*' else x) for x in line.split(" "))) 9 | return exprs 10 | 11 | 12 | def find_closing(expr, pos): 13 | opened = 1 14 | while opened > 0: 15 | pos += 1 16 | if expr[pos] == ")": 17 | opened -= 1 18 | elif expr[pos] == "(": 19 | opened += 1 20 | return pos 21 | 22 | 23 | def evaluate(expr, precedence): 24 | while "(" in expr: 25 | pos = expr.index("(") 26 | closing = find_closing(expr, pos) 27 | expr[pos:closing + 1] = [evaluate(expr[pos + 1:closing], precedence)] 28 | while precedence in expr: 29 | pos = expr.index(precedence) 30 | expr[pos - 1:pos + 2] = [precedence(expr[pos - 1], expr[pos + 1])] 31 | tot = expr.pop(0) 32 | while len(expr) > 1: 33 | tot = expr.pop(0)(tot, expr.pop(0)) 34 | return tot 35 | 36 | 37 | def solve(data, precedence=None): 38 | exprs = parse(data) 39 | tot = 0 40 | for expr in exprs: 41 | tot += evaluate(expr, precedence) 42 | return tot 43 | 44 | 45 | if __name__ == "__main__": 46 | data = open("input.txt").read() 47 | print(solve(data)) 48 | print(solve(data, precedence=add)) 49 | -------------------------------------------------------------------------------- /2021/14/14.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | ##**Version**| [0.0.27 2021-12-14T08:23:52+01:00](14.py) 3 | ##-----------|----------------------------------------------------------- 4 | ##**Author** | Carlo ㎝ Miron, carlo@miron.it 5 | 6 | from collections import Counter 7 | 8 | F, EXP = "input.txt", {10: 0, 40: 0} 9 | if True: 10 | template, x = open(F).read().split("\n\n") 11 | rules = {k: v for k, v in [i.strip().split(" -> ") for i in x.strip().split("\n")]} 12 | pairs = Counter(["".join(i) for i in zip(template, template[1:])]) 13 | for step in range(42): 14 | if step in EXP: 15 | polymer: Counter = Counter() 16 | for i in pairs: 17 | polymer[i[0]] += pairs[i] 18 | polymer[template[-1]] += 1 19 | got = max(polymer.values()) - min(polymer.values()) 20 | assert EXP[step] in (got, 0), f"expected {EXP[step]}, got {got}" 21 | print("ok" if EXP[step] else got) 22 | new_pairs: Counter = Counter() 23 | for i in pairs: 24 | new_pairs[i[0] + rules[i]] += pairs[i] 25 | new_pairs[rules[i] + i[1]] += pairs[i] 26 | pairs = new_pairs 27 | 28 | ##-- 29 | ##!!!! THE BEER-WARE LICENSE (Revision 42): 30 | ## carlo@miron.it wrote this file. As long as you retain this notice 31 | ## you can do whatever you want with this stuff. If we meet some day, and 32 | ## you think this stuff is worth it, you can buy me a beer in return. --㎝ 33 | -------------------------------------------------------------------------------- /2017/10/10.py: -------------------------------------------------------------------------------- 1 | data = [n for n in range(256)] 2 | lengths = [46,41,212,83,1,255,157,65,139,52,39,254,2,86,0,204] 3 | 4 | pos = skip = 0 5 | l = len(data) 6 | 7 | for length in lengths: 8 | new_data = [data[d % l] for d in range(pos + length - 1, pos - 1, -1)] 9 | if pos + length <= l: 10 | data[pos:pos + length] = new_data 11 | else: 12 | delta = pos + length - l 13 | data[pos:pos + length - delta] = new_data[:-delta] 14 | data[:delta] = new_data[-delta:] 15 | 16 | pos = (pos + length + skip) % l 17 | skip += 1 18 | 19 | print(data[0] * data[1]) 20 | 21 | data = [n for n in range(256)] 22 | lengths = [ord(c) for c in "46,41,212,83,1,255,157,65,139,52,39,254,2,86,0,204"] + [17, 31, 73, 47, 23] 23 | 24 | 25 | pos = skip = 0 26 | l = len(data) 27 | 28 | for round in range(64): 29 | for length in lengths: 30 | new_data = [data[d % l] for d in range(pos + length - 1, pos - 1, -1)] 31 | if pos + length <= l: 32 | data[pos:pos + length] = new_data 33 | else: 34 | delta = pos + length - l 35 | data[pos:pos + length - delta] = new_data[:-delta] 36 | data[:delta] = new_data[-delta:] 37 | 38 | pos = (pos + length + skip) % l 39 | skip += 1 40 | 41 | dense = "" 42 | for n in range(16): 43 | d = data[n * 16] 44 | for m in range(16 * n + 1, 16 * (n + 1)): 45 | d = d ^ data[m] 46 | dense += hex(256 + d)[-2:] 47 | 48 | print(dense) 49 | -------------------------------------------------------------------------------- /2017/02/02.py: -------------------------------------------------------------------------------- 1 | import itertools 2 | 3 | d = """3093 749 3469 142 2049 3537 1596 3035 2424 3982 3290 125 249 131 118 3138 4 | 141 677 2705 2404 2887 2860 1123 2714 117 1157 2607 1800 153 130 1794 3272 5 | 182 93 2180 114 103 1017 95 580 2179 2470 2487 2806 1574 1325 1898 1706 6 | 3753 233 3961 3747 3479 3597 1303 2612 4043 1815 3318 737 197 3943 239 254 7 | 113 147 961 157 3514 3045 1270 3528 1369 3377 492 156 1410 3251 1839 1249 8 | 3948 3651 888 3631 253 220 4266 1284 3595 237 2138 3799 2319 254 267 1182 9 | 399 446 795 653 154 762 140 487 750 457 730 150 175 841 323 492 10 | 999 979 103 99 1544 1404 100 1615 840 92 1552 1665 1686 76 113 1700 11 | 4049 182 3583 1712 200 3326 3944 715 213 1855 2990 3621 2560 842 249 2082 12 | 2610 4749 2723 2915 2189 3911 124 164 1895 3095 3992 134 127 4229 3453 4428 13 | 105 692 101 150 193 755 84 185 622 851 706 251 86 408 774 831 14 | 238 217 224 1409 1850 2604 363 265 596 2933 2641 2277 803 2557 1399 237 15 | 304 247 192 4369 997 5750 85 1248 4718 3888 5228 5116 5880 5348 6052 245 16 | 238 373 228 395 86 59 289 87 437 384 233 79 470 403 441 352 17 | 151 3473 1435 87 1517 1480 140 2353 1293 118 163 3321 2537 3061 1532 3402 18 | 127 375 330 257 220 295 145 335 304 165 151 141 289 256 195 272""" 19 | 20 | print(sum([max(r) - min(r) for r in [[int(f) for f in r.split('\t')] for r in d.split('\n')]])) 21 | 22 | print(int(sum([(a / b if a % b == 0 else 0) for r in [[int(f) for f in r.split('\t')] for r in d.split('\n')] for a, b in itertools.permutations(r, 2)]))) 23 | -------------------------------------------------------------------------------- /2021/12/test_12.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import pytest 3 | 4 | import day_12 as day 5 | 6 | 7 | class TestDay(unittest.TestCase): 8 | def setUp(self): 9 | self.data_1 = """start-A 10 | start-b 11 | A-c 12 | A-b 13 | b-d 14 | A-end 15 | b-end 16 | """ 17 | self.data_2 = """dc-end 18 | HN-start 19 | start-kj 20 | dc-start 21 | dc-HN 22 | LN-dc 23 | HN-end 24 | kj-sa 25 | kj-HN 26 | kj-dc""" 27 | self.data_3 = """fs-end 28 | he-DX 29 | fs-he 30 | start-DX 31 | pj-DX 32 | end-zg 33 | zg-sl 34 | zg-pj 35 | pj-he 36 | RW-he 37 | fs-DX 38 | pj-RW 39 | zg-RW 40 | start-pj 41 | he-WI 42 | zg-he 43 | pj-fs 44 | start-RW""" 45 | 46 | def test_part_1_1(self): 47 | self.assertEqual(10, day.solve1(self.data_1)) 48 | 49 | def test_part_1_2(self): 50 | self.assertEqual(19, day.solve1(self.data_2)) 51 | 52 | def test_part_1_3(self): 53 | self.assertEqual(226, day.solve1(self.data_3)) 54 | 55 | def test_part_2_1(self): 56 | self.assertEqual(36, day.solve2(self.data_1)) 57 | 58 | def test_part_2_2(self): 59 | self.assertEqual(103, day.solve2(self.data_2)) 60 | 61 | def test_part_2_3(self): 62 | self.assertEqual(3509, day.solve2(self.data_3)) 63 | 64 | @pytest.mark.slow 65 | def test_solution(self): 66 | import os 67 | data = open(os.path.dirname(__file__) + "/input.txt").read() 68 | self.assertEqual(day.solve1(data), 4186) 69 | self.assertEqual(day.solve2(data), 92111) 70 | -------------------------------------------------------------------------------- /2016/02/02.py: -------------------------------------------------------------------------------- 1 | keys = { 2 | (0,0): 1, (1,0): 2, (2,0): 3, 3 | (0,1): 4, (1,1): 5, (2,1): 6, 4 | (0,2): 7, (1,2): 8, (2,2): 9, 5 | } 6 | 7 | pos = [1, 1] 8 | 9 | code = "" 10 | for instruction in open("input", "r").readlines(): 11 | for step in instruction: 12 | if step == 'U': 13 | pos[1] = max(0, pos[1] - 1) 14 | elif step == 'D': 15 | pos[1] = min(2, pos[1] + 1) 16 | elif step == 'L': 17 | pos[0] = max(0, pos[0] - 1) 18 | elif step == 'R': 19 | pos[0] = min(2, pos[0] + 1) 20 | code += str(keys[tuple(pos)]) 21 | print(code) 22 | 23 | 24 | keys = { 25 | (2,0): '1', 26 | (1,1): '2', (2,1): '3', (3,1): '4', 27 | (0,2): '5', (1,2): '6', (2,2): '7', (3,2): '8', (4,2): '9', 28 | (1,3): 'A', (2,3): 'B', (3,3): 'C', 29 | (2,4): 'D', 30 | } 31 | 32 | pos = [0, 2] 33 | 34 | code = "" 35 | for instruction in open("input", "r").readlines(): 36 | for step in instruction: 37 | new_pos = pos.copy() 38 | if step == 'U': 39 | new_pos[1] = new_pos[1] - 1 40 | elif step == 'D': 41 | new_pos[1] = new_pos[1] + 1 42 | elif step == 'L': 43 | new_pos[0] = new_pos[0] - 1 44 | elif step == 'R': 45 | new_pos[0] = new_pos[0] + 1 46 | if tuple(new_pos) in keys: 47 | pos = new_pos 48 | code += str(keys[tuple(pos)]) 49 | 50 | print(code) 51 | -------------------------------------------------------------------------------- /2022/11/input.txt: -------------------------------------------------------------------------------- 1 | Monkey 0: 2 | Starting items: 66, 59, 64, 51 3 | Operation: new = old * 3 4 | Test: divisible by 2 5 | If true: throw to monkey 1 6 | If false: throw to monkey 4 7 | 8 | Monkey 1: 9 | Starting items: 67, 61 10 | Operation: new = old * 19 11 | Test: divisible by 7 12 | If true: throw to monkey 3 13 | If false: throw to monkey 5 14 | 15 | Monkey 2: 16 | Starting items: 86, 93, 80, 70, 71, 81, 56 17 | Operation: new = old + 2 18 | Test: divisible by 11 19 | If true: throw to monkey 4 20 | If false: throw to monkey 0 21 | 22 | Monkey 3: 23 | Starting items: 94 24 | Operation: new = old * old 25 | Test: divisible by 19 26 | If true: throw to monkey 7 27 | If false: throw to monkey 6 28 | 29 | Monkey 4: 30 | Starting items: 71, 92, 64 31 | Operation: new = old + 8 32 | Test: divisible by 3 33 | If true: throw to monkey 5 34 | If false: throw to monkey 1 35 | 36 | Monkey 5: 37 | Starting items: 58, 81, 92, 75, 56 38 | Operation: new = old + 6 39 | Test: divisible by 5 40 | If true: throw to monkey 3 41 | If false: throw to monkey 6 42 | 43 | Monkey 6: 44 | Starting items: 82, 98, 77, 94, 86, 81 45 | Operation: new = old + 7 46 | Test: divisible by 17 47 | If true: throw to monkey 7 48 | If false: throw to monkey 2 49 | 50 | Monkey 7: 51 | Starting items: 54, 95, 70, 93, 88, 93, 63, 50 52 | Operation: new = old + 4 53 | Test: divisible by 13 54 | If true: throw to monkey 2 55 | If false: throw to monkey 0 56 | -------------------------------------------------------------------------------- /2022/15/test_15.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import pytest 3 | day = __import__('day_' + __file__[-5:-3]) 4 | 5 | 6 | class TestDay(unittest.TestCase): 7 | def setUp(self): 8 | self.data = """Sensor at x=2, y=18: closest beacon is at x=-2, y=15 9 | Sensor at x=9, y=16: closest beacon is at x=10, y=16 10 | Sensor at x=13, y=2: closest beacon is at x=15, y=3 11 | Sensor at x=12, y=14: closest beacon is at x=10, y=16 12 | Sensor at x=10, y=20: closest beacon is at x=10, y=16 13 | Sensor at x=14, y=17: closest beacon is at x=10, y=16 14 | Sensor at x=8, y=7: closest beacon is at x=2, y=10 15 | Sensor at x=2, y=0: closest beacon is at x=2, y=10 16 | Sensor at x=0, y=11: closest beacon is at x=2, y=10 17 | Sensor at x=20, y=14: closest beacon is at x=25, y=17 18 | Sensor at x=17, y=20: closest beacon is at x=21, y=22 19 | Sensor at x=16, y=7: closest beacon is at x=15, y=3 20 | Sensor at x=14, y=3: closest beacon is at x=15, y=3 21 | Sensor at x=20, y=1: closest beacon is at x=15, y=3 22 | """ 23 | 24 | def test_part_1(self): 25 | self.assertEqual(26, day.solve1(self.data, row=10)) 26 | 27 | def test_part_2(self): 28 | self.assertEqual(56000011, day.solve2(self.data, space=20)) 29 | 30 | @pytest.mark.slow 31 | def test_solution(self): 32 | import os 33 | with open(os.path.dirname(__file__) + "/input.txt") as f_data: 34 | data = f_data.read() 35 | self.assertEqual(day.solve1(data), 4883971) 36 | self.assertEqual(day.solve2(data), 12691026767556) 37 | -------------------------------------------------------------------------------- /2015/advent2.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "strconv" 7 | "strings" 8 | ) 9 | 10 | func check(e error) { 11 | if e != nil { 12 | panic(e) 13 | } 14 | } 15 | 16 | func main() { 17 | var dim [3]int 18 | 19 | area_tot := 0 20 | ribbon_tot := 0 21 | dat, err := ioutil.ReadFile("src/advent/advent2.txt") 22 | check(err) 23 | result := strings.Split(string(dat), "\n") 24 | for i := range result { 25 | result := strings.Split(result[i], "x") 26 | if len(result) == 3 { 27 | for i := 0; i < 3; i++ { 28 | dim[i], _ = strconv.Atoi(result[i]) 29 | } 30 | area1 := dim[0] * dim[1] 31 | area2 := dim[0] * dim[2] 32 | area3 := dim[1] * dim[2] 33 | area_min := 0 34 | if area1 < area2 { 35 | if area3 < area1 { 36 | area_min = area3 37 | } else { 38 | area_min = area1 39 | } 40 | } else { 41 | if area3 < area2 { 42 | area_min = area3 43 | } else { 44 | area_min = area2 45 | } 46 | } 47 | area_tot += area1*2 + area2*2 + area3*2 + area_min 48 | 49 | ribbon_tot += dim[0] * dim[1] * dim[2] 50 | if dim[0] > dim[1] { 51 | if dim[0] > dim[2] { 52 | ribbon_tot += 2 * (dim[1] + dim[2]) 53 | } else { 54 | ribbon_tot += 2 * (dim[0] + dim[1]) 55 | } 56 | } else { 57 | if dim[1] > dim[2] { 58 | ribbon_tot += 2 * (dim[0] + dim[2]) 59 | } else { 60 | ribbon_tot += 2 * (dim[0] + dim[1]) 61 | } 62 | } 63 | } 64 | } 65 | fmt.Printf("Area %d\n", area_tot) 66 | fmt.Printf("Ribbon %d\n", ribbon_tot) 67 | } 68 | -------------------------------------------------------------------------------- /2020/18/test_18.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from operator import add, mul 3 | 4 | import day_18 as day 5 | 6 | 7 | class TestDay(unittest.TestCase): 8 | def test_part1_1(self): 9 | self.assertEqual(day.solve("2 * 3 + (4 * 5)"), 26) 10 | 11 | def test_part1_2(self): 12 | self.assertEqual(day.solve("5 + (8 * 3 + 9 + 3 * 4 * 3)"), 437) 13 | 14 | def test_part1_3(self): 15 | self.assertEqual(day.solve("5 * 9 * (7 * 3 * 3 + 9 * 3 + (8 + 6 * 4))"), 12240) 16 | 17 | def test_part1_4(self): 18 | self.assertEqual(day.solve("((2 + 4 * 9) * (6 + 9 * 8 + 6) + 6) + 2 + 4 * 2"), 13632) 19 | 20 | def test_part2_1(self): 21 | self.assertEqual(day.solve("1 + (2 * 3) + (4 * (5 + 6))", add), 51) 22 | 23 | def test_part2_2(self): 24 | self.assertEqual(day.solve("2 * 3 + (4 * 5)", add), 46) 25 | 26 | def test_part2_3(self): 27 | self.assertEqual(day.solve("5 + (8 * 3 + 9 + 3 * 4 * 3)", add), 1445) 28 | 29 | def test_part2_4(self): 30 | self.assertEqual(day.solve("5 * 9 * (7 * 3 * 3 + 9 * 3 + (8 + 6 * 4))", add), 669060) 31 | 32 | def test_part2_5(self): 33 | self.assertEqual(day.solve("((2 + 4 * 9) * (6 + 9 * 8 + 6) + 6) + 2 + 4 * 2", add), 23340) 34 | 35 | def test_solution(self): 36 | import os 37 | data = open(os.path.dirname(__file__) + "/input.txt").read() 38 | self.assertEqual(day.solve(data), 701339185745) 39 | self.assertEqual(day.solve(data, add), 4208490449905) 40 | self.assertEqual(day.solve(data, mul), 12312398996) 41 | -------------------------------------------------------------------------------- /2016/13/13.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | 3 | 4 | def maze(val, x, y): 5 | def wall(val, x, y): 6 | n = x**2 + 3 * x + 2 * x * y + y + y * y + val 7 | bits = sum(1 if c == "1" else 0 for c in bin(n)) 8 | return 1 if bits % 2 == 1 else 0 9 | 10 | grid = [[wall(val, i, j) for i in range(x)] for j in range(y)] 11 | return grid 12 | 13 | 14 | def minimum_path_bfs(grid, pos, target): 15 | queue = deque([("", pos)]) 16 | visited = set() 17 | while queue: 18 | path, current = queue.popleft() 19 | if current == target: 20 | return path 21 | if current in visited: 22 | continue 23 | visited.add(current) 24 | for new_path, d_x, d_y in (("n", 0, -1), ("s", 0, 1), ("e", -1, 0), ("w", 1, 0)): 25 | new_pos = (current[0] + d_x, current[1] + d_y) 26 | if new_pos[0] >= 0 and new_pos[0] <= len(grid[0]) and new_pos[1] >= 0 and new_pos[1] <= len(grid): 27 | if grid[new_pos[1]][new_pos[0]] == 0: 28 | queue.append((path + new_path, new_pos)) 29 | return "" 30 | 31 | 32 | grid = maze(10, 30, 30) 33 | path = minimum_path_bfs(grid, (1, 1), (7, 4)) 34 | print(len(path), path) 35 | 36 | grid = maze(1364, 100, 100) 37 | path = minimum_path_bfs(grid, (1, 1), (31, 39)) 38 | print(len(path), path) 39 | 40 | max_50 = 1 41 | for x in range(55): 42 | for y in range(55): 43 | path = minimum_path_bfs(grid, (1, 1), (x, y)) 44 | if path > "" and len(path) <= 50: 45 | max_50 += 1 46 | print(max_50) 47 | 48 | 49 | -------------------------------------------------------------------------------- /2021/25/day_25.py: -------------------------------------------------------------------------------- 1 | class Cucumbers: 2 | def __init__(self, data): 3 | raw_data = data.strip().split('\n') 4 | self.cucumbers = dict(((x, y), c) for y, line in enumerate(raw_data) for x, c in enumerate(line) if c in 'v>') 5 | self.size = (len(raw_data[0]), len(raw_data)) 6 | 7 | def move(self): 8 | steps = 0 9 | while True: 10 | steps += 1 11 | moved = 0 12 | for direction, dx, dy in (('>', 1, 0), ('v', 0, 1)): 13 | moving = set() 14 | for y in range(self.size[1]): 15 | for x in range(self.size[0]): 16 | cucumber = self.cucumbers.get((x, y), '.') 17 | if cucumber != direction: 18 | continue 19 | next_x = (x + dx) % self.size[0] 20 | next_y = (y + dy) % self.size[1] 21 | if (next_x, next_y) not in self.cucumbers: 22 | moving.add((cucumber, x, y, next_x, next_y)) 23 | if moving: 24 | moved += len(moving) 25 | for cucumber, x, y, next_x, next_y in moving: 26 | del self.cucumbers[x, y] 27 | self.cucumbers[next_x, next_y] = cucumber 28 | if moved == 0: 29 | break 30 | return steps 31 | 32 | 33 | def solve1(data): 34 | return Cucumbers(data).move() 35 | 36 | 37 | if __name__ == "__main__": 38 | data = open("input.txt").read() 39 | print(solve1(data)) 40 | -------------------------------------------------------------------------------- /2015/advent18/advent.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "os" 7 | ) 8 | 9 | const DIM = 100 10 | 11 | var life [DIM]([DIM]int) 12 | 13 | func neighbours(x, y int) int { 14 | on := 0 15 | for x1 := x - 1; x1 <= x+1; x1++ { 16 | for y1 := y - 1; y1 <= y+1; y1++ { 17 | if x1 >= 0 && x1 < DIM && y1 >= 0 && y1 < DIM && !(x1 == x && y1 == y) && life[x1][y1] == 1 { 18 | on += 1 19 | } 20 | } 21 | } 22 | return on 23 | } 24 | 25 | func loop() { 26 | var next_life [DIM]([DIM]int) 27 | for x := 0; x < DIM; x++ { 28 | for y := 0; y < DIM; y++ { 29 | near_on := neighbours(x, y) 30 | if life[x][y] == 1 { 31 | if near_on == 2 || near_on == 3 { 32 | next_life[x][y] = 1 33 | } 34 | } else { 35 | if near_on == 3 { 36 | next_life[x][y] = 1 37 | } 38 | } 39 | } 40 | } 41 | life = next_life 42 | } 43 | 44 | func show() { 45 | fmt.Println("=================") 46 | for x := 0; x < DIM; x++ { 47 | fmt.Println(life[x]) 48 | } 49 | } 50 | 51 | func main() { 52 | in := bufio.NewReader(os.Stdin) 53 | for n := 0; ; n++ { 54 | if str, err := in.ReadString('\n'); err != nil { 55 | break 56 | } else { 57 | for i := 0; i < len(str)-1; i++ { 58 | if str[i] == byte('#') { 59 | life[n][i] = 1 60 | } else { 61 | life[n][i] = 0 62 | } 63 | } 64 | } 65 | } 66 | for n := 0; n < 100; n++ { 67 | //show() 68 | loop() 69 | } 70 | on := 0 71 | for x := 0; x < DIM; x++ { 72 | for y := 0; y < DIM; y++ { 73 | if life[x][y] == 1 { 74 | on += 1 75 | } 76 | } 77 | } 78 | fmt.Println(on) 79 | } 80 | -------------------------------------------------------------------------------- /2021/13/day_13.py: -------------------------------------------------------------------------------- 1 | class Fold: 2 | def __init__(self, data): 3 | dots_lines, folds_lines = [p.strip().split("\n") for p in data.strip().split("\n\n")] 4 | self.dots = set((tuple(int(p) for p in line.split(","))) for line in dots_lines) 5 | self.folds = [] 6 | for line in folds_lines: 7 | parts = line.split("=") 8 | self.folds.append(int(parts[1]) * (1 if parts[0][-1] == 'x' else -1)) 9 | 10 | def folded(self): 11 | while self.folds: 12 | self.fold() 13 | size_x = size_y = 0 14 | for x, y in self.dots: 15 | size_x, size_y = max(size_x, x), max(size_y, y) 16 | folded = "\n" 17 | for y in range(size_y + 1): 18 | line = "" 19 | for x in range(size_x + 1): 20 | line += '#' if (x, y) in self.dots else '.' 21 | folded += line + '\n' 22 | return folded 23 | 24 | def fold(self): 25 | fold = self.folds.pop(0) 26 | dots = set() 27 | for x, y in self.dots: 28 | if fold > 0: 29 | if x > fold: 30 | x = fold * 2 - x 31 | elif y > -fold: 32 | y = -fold * 2 - y 33 | dots.add((x, y)) 34 | self.dots = dots 35 | return self 36 | 37 | 38 | def solve1(data): 39 | return len(Fold(data).fold().dots) 40 | 41 | 42 | def solve2(data): 43 | return Fold(data).folded() 44 | 45 | 46 | if __name__ == "__main__": 47 | data = open("input.txt").read() 48 | print(solve1(data)) 49 | print(solve2(data)) 50 | -------------------------------------------------------------------------------- /2022/13/day_13.py: -------------------------------------------------------------------------------- 1 | from functools import cmp_to_key 2 | 3 | 4 | def load(data): 5 | pairs = [] 6 | for lines in data.strip().split("\n\n"): 7 | pairs.append([eval(line) for line in lines.split("\n")]) 8 | return pairs 9 | 10 | 11 | def compare(left, right): 12 | if isinstance(left, int) and isinstance(right, int): 13 | if right == left: 14 | return None 15 | return right >= left 16 | if isinstance(left, int): 17 | left = [left] 18 | if isinstance(right, int): 19 | right = [right] 20 | assert type(left) == type(right) == list, f"{left} != {right}" 21 | for left_item, right_item in zip(left, right): 22 | if((ret := compare(left_item, right_item)) is not None): 23 | return ret 24 | if len(left) == len(right): 25 | return None 26 | return len(left) < len(right) 27 | 28 | 29 | def compute(pairs): 30 | return sum(n for n, couple in enumerate(pairs, 1) if compare(*couple)) 31 | 32 | 33 | def sort(pairs): 34 | p2 = [[2]] 35 | p6 = [[6]] 36 | ordered = sorted((p for pair in pairs + [[p2, p6]] for p in pair), 37 | key=cmp_to_key(lambda x, y: 1 if compare(x, y) else -1), 38 | reverse=True) 39 | return (1 + ordered.index(p2)) * (1 + ordered.index(p6)) 40 | 41 | 42 | def solve1(data): 43 | return compute(load(data)) 44 | 45 | 46 | def solve2(data): 47 | return sort(load(data)) 48 | 49 | 50 | if __name__ == "__main__": 51 | data = open("input.txt").read() 52 | print(solve1(data)) 53 | print(solve2(data)) 54 | -------------------------------------------------------------------------------- /2020/07/test_07.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import day_07 as day 4 | 5 | 6 | class TestDay(unittest.TestCase): 7 | def setUp(self): 8 | self.data = """light red bags contain 1 bright white bag, 2 muted yellow bags. 9 | dark orange bags contain 3 bright white bags, 4 muted yellow bags. 10 | bright white bags contain 1 shiny gold bag. 11 | muted yellow bags contain 2 shiny gold bags, 9 faded blue bags. 12 | shiny gold bags contain 1 dark olive bag, 2 vibrant plum bags. 13 | dark olive bags contain 3 faded blue bags, 4 dotted black bags. 14 | vibrant plum bags contain 5 faded blue bags, 6 dotted black bags. 15 | faded blue bags contain no other bags. 16 | dotted black bags contain no other bags.""" 17 | self.data2 = """shiny gold bags contain 2 dark red bags. 18 | dark red bags contain 2 dark orange bags. 19 | dark orange bags contain 2 dark yellow bags. 20 | dark yellow bags contain 2 dark green bags. 21 | dark green bags contain 2 dark blue bags. 22 | dark blue bags contain 2 dark violet bags. 23 | dark violet bags contain no other bags.""" 24 | 25 | def test_part_1(self): 26 | self.assertEqual(4, day.solve(self.data)[0]) 27 | 28 | def test_part_2_1(self): 29 | self.assertEqual(32, day.solve(self.data)[1]) 30 | 31 | def test_part_2_2(self): 32 | self.assertEqual(126, day.solve(self.data2)[1]) 33 | 34 | def test_solution(self): 35 | import os 36 | data = open(os.path.dirname(__file__) + "/input.txt").read() 37 | part1, part2 = day.solve(data) 38 | self.assertEqual(part1, 103) 39 | self.assertEqual(part2, 1469) 40 | -------------------------------------------------------------------------------- /2019/08/08.py: -------------------------------------------------------------------------------- 1 | from collections import Counter 2 | 3 | 4 | class Image: 5 | def __init__(self, width, height, pixels): 6 | self.width = width 7 | self.height = height 8 | self.size = width * height 9 | self.pixels = pixels.strip() 10 | self.decode() 11 | 12 | def decode(self): 13 | self.layers = [self.pixels[n * self.size:(n + 1) * self.size] for n in range(len(self.pixels) // self.size)] 14 | final = [None for n in range(self.size)] 15 | for layer in self.layers: 16 | for n, pixel in enumerate(layer): 17 | if pixel in ('0', '1'): 18 | if final[n] is None: 19 | final[n] = "#" if pixel == '1' else " " 20 | self.final = ''.join(pixel or '2' for pixel in final) 21 | 22 | def check(self): 23 | self.counters = [] 24 | min_0 = {'0': len(self.pixels)} 25 | for layer in self.layers: 26 | counter = Counter(layer) 27 | if counter['0'] < min_0['0']: 28 | min_0 = counter 29 | return min_0['1'] * min_0['2'] 30 | 31 | def show(self): 32 | for n in range(self.height): 33 | print(self.final[n * self.width:(n + 1) * self.width]) 34 | 35 | 36 | def test(): 37 | image = Image(3, 2, "123456789012") 38 | assert image.layers == ["123456", "789012"] 39 | image = Image(2, 2, "0222112222120000") 40 | assert image.final == " ## " 41 | 42 | 43 | if __name__ == "__main__": 44 | image = Image(25, 6, open("input.txt").read()) 45 | print(image.check()) 46 | image.show() 47 | -------------------------------------------------------------------------------- /2015/advent11/advent11.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func ComparePwd(pwd1, pwd2 []rune) bool { 8 | if len(pwd1) == len(pwd2) { 9 | for i, ch1 := range pwd1 { 10 | if ch1 != pwd2[i] { 11 | return false 12 | } 13 | } 14 | } 15 | return true 16 | } 17 | 18 | func ConvertCodes(codes []rune) string { 19 | return string(codes) 20 | } 21 | 22 | func ConvertPwd(pwd string) []rune { 23 | return []rune(pwd) 24 | } 25 | 26 | func TestPwd(pwd []rune) bool { 27 | ok1 := false 28 | ok2 := false 29 | first_pair := rune(' ') 30 | for i := 0; i < len(pwd); i++ { 31 | if pwd[i] == rune('i') || pwd[i] == rune('o') || pwd[i] == rune('l') { 32 | return false 33 | } 34 | if !ok1 && i < len(pwd)-2 && (int(pwd[i]) == int(pwd[i+1])-1 && int(pwd[i+1]) == int(pwd[i+2])-1) { 35 | ok1 = true 36 | } else if !ok2 && i < len(pwd)-1 && int(pwd[i]) == int(pwd[i+1]) { 37 | if first_pair == rune(' ') { 38 | first_pair = pwd[i] 39 | } else if first_pair != pwd[i] { 40 | ok2 = true 41 | } 42 | } 43 | } 44 | return ok1 && ok2 45 | } 46 | 47 | func GetNextPwd(pwd []rune) []rune { 48 | i := len(pwd) - 1 49 | for { 50 | pwd[i] += 1 51 | if pwd[i] <= rune('z') { 52 | return pwd 53 | } 54 | pwd[i] = 'a' 55 | i -= 1 56 | } 57 | } 58 | 59 | func NextPwd(pwd []rune) []rune { 60 | for { 61 | pwd = GetNextPwd(pwd) 62 | if TestPwd(pwd) { 63 | return pwd 64 | } 65 | } 66 | } 67 | 68 | func main() { 69 | pwd := ConvertPwd("hxbxwxba") 70 | pwd = NextPwd(pwd) 71 | fmt.Println(ConvertCodes(pwd)) 72 | pwd = NextPwd(pwd) 73 | fmt.Println(ConvertCodes(pwd)) 74 | } 75 | -------------------------------------------------------------------------------- /2021/19/rotations.py: -------------------------------------------------------------------------------- 1 | # http://www.euclideanspace.com/maths/algebra/matrix/transforms/examples/index.htm 2 | 3 | rotations_raw_matrices = """ 4 | 1 0 0 5 | 0 1 0 6 | 0 0 1 7 | 8 | 0 0 1 9 | 0 1 0 10 | -1 0 0 11 | 12 | -1 0 0 13 | 0 1 0 14 | 0 0 -1 15 | 16 | 0 0 -1 17 | 0 1 0 18 | 1 0 0 19 | 20 | 0 -1 0 21 | 1 0 0 22 | 0 0 1 23 | 24 | 0 0 1 25 | 1 0 0 26 | 0 1 0 27 | 28 | 0 1 0 29 | 1 0 0 30 | 0 0 -1 31 | 32 | 0 0 -1 33 | 1 0 0 34 | 0 -1 0 35 | 36 | 0 1 0 37 | -1 0 0 38 | 0 0 1 39 | 40 | 0 0 1 41 | -1 0 0 42 | 0 -1 0 43 | 44 | 0 -1 0 45 | -1 0 0 46 | 0 0 -1 47 | 48 | 0 0 -1 49 | -1 0 0 50 | 0 1 0 51 | 52 | 1 0 0 53 | 0 0 -1 54 | 0 1 0 55 | 56 | 0 1 0 57 | 0 0 -1 58 | -1 0 0 59 | 60 | -1 0 0 61 | 0 0 -1 62 | 0 -1 0 63 | 64 | 0 -1 0 65 | 0 0 -1 66 | 1 0 0 67 | 68 | 1 0 0 69 | 0 -1 0 70 | 0 0 -1 71 | 72 | 0 0 -1 73 | 0 -1 0 74 | -1 0 0 75 | 76 | -1 0 0 77 | 0 -1 0 78 | 0 0 1 79 | 80 | 0 0 1 81 | 0 -1 0 82 | 1 0 0 83 | 84 | 1 0 0 85 | 0 0 1 86 | 0 -1 0 87 | 88 | 0 -1 0 89 | 0 0 1 90 | -1 0 0 91 | 92 | -1 0 0 93 | 0 0 1 94 | 0 1 0 95 | 96 | 0 1 0 97 | 0 0 1 98 | 1 0 0 99 | """ 100 | 101 | 102 | base = [1, 2, 4] 103 | results = set() 104 | for raw_matrix in rotations_raw_matrices.strip().split('\n\n'): 105 | matrix = [[int(s) for s in line.split(' ')] for line in raw_matrix.split('\n')] 106 | results.add(tuple(sum(base[m] * matrix[n][m] for m in range(3)) for n in range(3))) 107 | for a, b, c in results: 108 | print(f" lambda x, y, z: ({a}, {b}, {c}),".replace('1', 'x').replace('2', 'y').replace('4', 'z')) 109 | -------------------------------------------------------------------------------- /2022/10/day_10.py: -------------------------------------------------------------------------------- 1 | def noop(registers): 2 | return 1 3 | 4 | 5 | def addx(registers, value): 6 | registers['x'] += value 7 | return 2 8 | 9 | 10 | def load(data): 11 | instructions = [] 12 | for line in data.strip().split("\n"): 13 | if line == "noop": 14 | instructions.append((noop, [])) 15 | elif line.startswith("addx"): 16 | instructions.append((addx, [int(line[5:])])) 17 | else: 18 | assert False, f"Unknown instruction: \"{line}\"" 19 | return instructions 20 | 21 | 22 | def read(pixels, width): 23 | n = 0 24 | screen = "" 25 | while n < len(pixels): 26 | screen += "".join(pixels[n:n + width]) + '\n' 27 | n += width 28 | return screen.strip() 29 | 30 | 31 | def compute(instructions): 32 | registers = {'x': 1} 33 | clock, strength, check, width = 0, 0, 20, 40 34 | cycle, scan, pixels = 0, 0, [] 35 | for func, args in instructions: 36 | prev = registers['x'] 37 | clock += func(*([registers] + args)) 38 | while scan < clock: 39 | pixels.append('#' if scan % width >= prev - 1 and scan % width < prev + 2 else '.') 40 | scan += 1 41 | if clock >= check: 42 | strength += check * prev 43 | check += width 44 | return strength, read(pixels, width) 45 | 46 | 47 | def solve1(data): 48 | return compute(load(data))[0] 49 | 50 | 51 | def solve2(data): 52 | return compute(load(data))[1] 53 | 54 | 55 | if __name__ == "__main__": 56 | data = open("input.txt").read() 57 | 58 | print(solve1(data)) 59 | print(solve2(data)) 60 | -------------------------------------------------------------------------------- /2021/15/day_15.py: -------------------------------------------------------------------------------- 1 | import bisect 2 | 3 | 4 | class Cave: 5 | def __init__(self, data, mult=1): 6 | matrix = tuple(tuple(int(n) for n in line) for line in data.strip().split("\n")) 7 | matrix_size = len(matrix) 8 | self.size = matrix_size * mult 9 | self.chitons = [[(matrix[y % matrix_size][x % matrix_size] + x // matrix_size + y // matrix_size - 1) % 9 + 1 10 | for x in range(self.size)] for y in range(self.size)] 11 | 12 | def adj(self, x, y): 13 | for x0, y0 in ((x - 1, y), (x + 1, y), (x, y - 1), (x, y + 1)): 14 | if y0 < 0 or y0 >= self.size or x0 < 0 or x0 >= self.size: 15 | continue 16 | yield x0, y0 17 | 18 | def dijkstra(self, exploring): 19 | weights = {} 20 | while exploring: 21 | prev_path, x, y = exploring.pop(0) 22 | path = prev_path + self.chitons[y][x] 23 | if (x, y) not in weights or path < weights[x, y]: 24 | weights[x, y] = path 25 | if x == y == self.size - 1: 26 | return weights[x, y] - weights[0, 0] 27 | else: 28 | continue 29 | for x0, y0 in self.adj(x, y): 30 | bisect.insort(exploring, (path, x0, y0)) 31 | 32 | def best(self): 33 | return self.dijkstra([(0, 0, 0)]) 34 | 35 | 36 | def solve1(data): 37 | return Cave(data).best() 38 | 39 | 40 | def solve2(data): 41 | return Cave(data, 5).best() 42 | 43 | 44 | if __name__ == "__main__": 45 | data = open("input.txt").read() 46 | print(solve1(data)) 47 | print(solve2(data)) 48 | -------------------------------------------------------------------------------- /2022/07/day_07.py: -------------------------------------------------------------------------------- 1 | class Item: 2 | dirs = set() 3 | 4 | def __init__(self, father=None, size = 0, directory=True): 5 | self.father = father 6 | self.size = 0 7 | if directory: 8 | self.items = {} 9 | self.dirs.add(self) 10 | else: 11 | self.add_size(size) 12 | 13 | def add_size(self, size): 14 | self.size += size 15 | if self.father: 16 | self.father.add_size(size) 17 | 18 | 19 | def load(data): 20 | tree = Item() 21 | tree.dirs.clear() 22 | for line in data.strip().split("\n"): 23 | if line.startswith('$ cd'): 24 | name = line.split()[2] 25 | if name == '/': 26 | current = tree 27 | elif name == '..': 28 | current = current.father 29 | else: 30 | current = current.items[name] 31 | elif line.startswith('$ ls'): 32 | continue 33 | elif line.startswith('dir'): 34 | name = line.split()[1] 35 | current.items[name] = Item(current) 36 | else: 37 | size, name = line.split() 38 | current.items[name] = Item(current, int(size), False) 39 | return tree 40 | 41 | 42 | def solve1(data): 43 | tree = load(data) 44 | return sum(d.size for d in tree.dirs if d.size <= 100000) 45 | 46 | 47 | def solve2(data): 48 | tree = load(data) 49 | return min(d.size for d in tree.dirs if d.size > tree.size - 40000000) 50 | 51 | 52 | if __name__ == "__main__": 53 | data = open("input.txt").read() 54 | print(solve1(data)) 55 | print(solve2(data)) 56 | -------------------------------------------------------------------------------- /2021/17/day_17.py: -------------------------------------------------------------------------------- 1 | class Trench: 2 | cache = {} 3 | 4 | def __init__(self, data): 5 | target_x = tuple(int(p) for p in data.split("x=")[1].split(",")[0].split("..")) 6 | target_y = tuple(int(p) for p in data.split("y=")[-1].split("..")) 7 | self.target = (target_x, target_y) 8 | 9 | def probe(self, vel_x, vel_y): 10 | x, y, max_y = 0, 0, 0 11 | while True: 12 | if x > self.target[0][1] or -y > -self.target[1][0]: 13 | return None 14 | if x >= self.target[0][0] and -y >= -self.target[1][1]: 15 | return max_y 16 | x, vel_x = x + vel_x, max(0, vel_x - 1) 17 | y, vel_y = y + vel_y, vel_y - 1 18 | if y > max_y: 19 | max_y = y 20 | 21 | def highest(self): 22 | try: 23 | return Trench.cache[self.target] 24 | except KeyError: 25 | pass 26 | max_max_y, max_val, cont = 0, 200, 0 27 | for vel_x in range(1, max_val): 28 | for vel_y in range(-max_val, max_val): 29 | if (max_y := self.probe(vel_x, vel_y)) is not None: 30 | cont += 1 31 | if max_y is not None and max_y > max_max_y: 32 | max_max_y = max_y 33 | Trench.cache[self.target] = max_max_y, cont 34 | return max_max_y, cont 35 | 36 | 37 | def solve1(data): 38 | return Trench(data).highest()[0] 39 | 40 | 41 | def solve2(data): 42 | return Trench(data).highest()[1] 43 | 44 | 45 | if __name__ == "__main__": 46 | data = open("input.txt").read() 47 | print(solve1(data)) 48 | print(solve2(data)) 49 | -------------------------------------------------------------------------------- /2015/advent19/advent.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "os" 7 | "strings" 8 | ) 9 | 10 | var molecule string 11 | var transformations = make(map[string][]string) 12 | var target = make(map[string]bool) 13 | 14 | func isInMap(key string, set map[string][]string) bool { 15 | value := set[key] 16 | if value == nil { 17 | return false 18 | } 19 | return true 20 | } 21 | 22 | func main() { 23 | in := bufio.NewReader(os.Stdin) 24 | status := 0 25 | for n := 0; ; n++ { 26 | if str, err := in.ReadString('\n'); err != nil { 27 | break 28 | } else { 29 | if len(str) == 1 { 30 | status = 1 31 | } else if status == 1 { 32 | molecule = str 33 | } else { 34 | result := strings.Split(str[:len(str)-1], " => ") 35 | from, to := result[0], result[1] 36 | if !isInMap(from, transformations) { 37 | transformations[from] = []string{to} 38 | } else { 39 | transformations[from] = append(transformations[from], to) 40 | } 41 | } 42 | } 43 | } 44 | for key, value := range transformations { 45 | new_pos := 0 46 | for pos := 0; ; { 47 | new_pos = strings.Index(molecule[pos:len(molecule)], key) 48 | if new_pos == -1 { 49 | break 50 | } 51 | pos += new_pos 52 | for _, repl := range value { 53 | //fmt.Println("===========") 54 | //fmt.Println(molecule) 55 | //fmt.Println(key, value, pos) 56 | //fmt.Println(molecule[:pos] + repl + molecule[pos+len(key):]) 57 | target[molecule[:pos]+repl+molecule[pos+len(key):]] = true 58 | } 59 | pos += 1 60 | } 61 | 62 | } 63 | fmt.Println(len(target)) 64 | //fmt.Println(molecule) 65 | //fmt.Println(transformations) 66 | } 67 | -------------------------------------------------------------------------------- /2020/24/test_24.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import pytest 3 | 4 | import day_24 as day 5 | 6 | 7 | class TestDay(unittest.TestCase): 8 | def setUp(self): 9 | self.data = """sesenwnenenewseeswwswswwnenewsewsw 10 | neeenesenwnwwswnenewnwwsewnenwseswesw 11 | seswneswswsenwwnwse 12 | nwnwneseeswswnenewneswwnewseswneseene 13 | swweswneswnenwsewnwneneseenw 14 | eesenwseswswnenwswnwnwsewwnwsene 15 | sewnenenenesenwsewnenwwwse 16 | wenwwweseeeweswwwnwwe 17 | wsweesenenewnwwnwsenewsenwwsesesenwne 18 | neeswseenwwswnwswswnw 19 | nenwswwsewswnenenewsenwsenwnesesenew 20 | enewnwewneswsewnwswenweswnenwsenwsw 21 | sweneswneswneneenwnewenewwneswswnese 22 | swwesenesewenwneswnwwneseswwne 23 | enesenwswwswneneswsenwnewswseenwsese 24 | wnwnesenesenenwwnenwsewesewsesesew 25 | nenewswnwewswnenesenwnesewesw 26 | eneswnwswnwsenenwnwnwwseeswneewsenese 27 | neswnwewnwnwseenwseesewsenwsweewe 28 | wseweeenwnesenwwwswnew 29 | """ 30 | 31 | def test_parse_line(self): 32 | self.assertEqual(list(day.parse_line("nwwswee")), [(-1, 0, 1), (-1, 1, 0), (0, 1, -1), (1, -1, 0), (1, -1, 0)]) 33 | 34 | def test_parse_move(self): 35 | self.assertEqual(day.move((1, 1, 1), day.parse_line("nwwswee")), (1, 1, 1)) 36 | 37 | def test_part1(self): 38 | self.assertEqual(len(day.solve1(self.data)), 10) 39 | 40 | def test_part2(self): 41 | self.assertEqual(day.solve2(day.solve1(self.data)), 2208) 42 | 43 | def test_solution(self): 44 | import os 45 | data = open(os.path.dirname(__file__) + "/input.txt").read() 46 | blacks = day.solve1(data) 47 | self.assertEqual(len(blacks), 317) 48 | self.assertEqual(day.solve2(blacks), 3804) 49 | -------------------------------------------------------------------------------- /2021/08/test_08.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import day_08 as day 4 | 5 | 6 | class TestDay(unittest.TestCase): 7 | def setUp(self): 8 | self.data_simple = "acedgfb cdfbe gcdfa fbcad dab cefabd cdfgeb eafb cagedb ab | cdfeb fcadb cdfeb cdbaf" 9 | self.data = """be cfbegad cbdgef fgaecd cgeb fdcge agebfd fecdb fabcd edb | fdgacbe cefdb cefbgd gcbe 10 | edbfga begcd cbg gc gcadebf fbgde acbgfd abcde gfcbed gfec | fcgedb cgb dgebacf gc 11 | fgaebd cg bdaec gdafb agbcfd gdcbef bgcad gfac gcb cdgabef | cg cg fdcagb cbg 12 | fbegcd cbd adcefb dageb afcb bc aefdc ecdab fgdeca fcdbega | efabcd cedba gadfec cb 13 | aecbfdg fbg gf bafeg dbefa fcge gcbea fcaegb dgceab fcbdga | gecf egdcabf bgf bfgea 14 | fgeab ca afcebg bdacfeg cfaedg gcfdb baec bfadeg bafgc acf | gebdcfa ecba ca fadegcb 15 | dbcfg fgd bdegcaf fgec aegbdf ecdfab fbedc dacgb gdcebf gf | cefg dcbef fcge gbcadfe 16 | bdfegc cbegaf gecbf dfcage bdacg ed bedf ced adcbefg gebcd | ed bcgafe cdgba cbgef 17 | egadfb cdbfeg cegd fecab cgb gbdefca cg fgcdab egfdb bfceg | gbdfcae bgc cg cgb 18 | gcafb gcf dcaebfg ecagb gf abcdeg gaef cafbge fdbac fegbdc | fgae cfgab fg bagce 19 | """ 20 | 21 | def test_part_1(self): 22 | self.assertEqual(26, day.solve1(self.data)) 23 | 24 | def test_decode(self): 25 | self.assertEqual(5353, day.Digits(self.data_simple).decode()) 26 | 27 | def test_part_2(self): 28 | self.assertEqual(61229, day.solve2(self.data)) 29 | 30 | def test_solution(self): 31 | import os 32 | data = open(os.path.dirname(__file__) + "/input.txt").read() 33 | self.assertEqual(day.solve1(data), 264) 34 | self.assertEqual(day.solve2(data), 1063760) 35 | -------------------------------------------------------------------------------- /2015/advent6.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "bufio" 6 | "os" 7 | "strings" 8 | ) 9 | 10 | func main() { 11 | var x1, y1, x2, y2 int 12 | var lights [1000][1000] int 13 | in := bufio.NewReader(os.Stdin) 14 | for { 15 | if str, err := in.ReadString('\n'); err != nil { 16 | fmt.Println(err) 17 | break 18 | } else { 19 | toggle := false 20 | on := false 21 | if strings.HasPrefix(str, "toggle ") { 22 | toggle = true 23 | str = str[7:] 24 | } else if strings.HasPrefix(str, "turn on ") { 25 | on = true 26 | str = str[8:] 27 | } else { 28 | str = str[9:] 29 | } 30 | f := func(x int) int { 31 | return 0 32 | } 33 | if toggle { 34 | f = func(x int) int { 35 | return 1 - x 36 | } 37 | } else if on { 38 | f = func(x int) int { 39 | return 1 40 | } 41 | } 42 | fmt.Sscanf(str, "%d,%d through %d,%d\n", &x1, &y1, &x2, &y2) 43 | for x := x1; x<=x2; x++ { 44 | for y := y1; y<=y2; y++ { 45 | lights[x][y] = f(lights[x][y]) 46 | } 47 | } 48 | } 49 | } 50 | light_on := 0 51 | for x := 0; x<1000; x++ { 52 | for y := 0; y<1000; y++ { 53 | if lights[x][y] == 1 { 54 | light_on += 1 55 | } 56 | } 57 | } 58 | fmt.Println(light_on) 59 | } 60 | 61 | -------------------------------------------------------------------------------- /2015/advent11/advent11_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "testing" 4 | 5 | // hijklmmn meets the first requirement (because it contains the straight hij) but fails the second requirement requirement (because it contains i and l). 6 | func TestPwdOk1(t *testing.T) { 7 | pwd := "hijklmmn" 8 | if TestPwd(ConvertPwd(pwd)) { 9 | t.Fatalf("Password %s dovrebbe essere ko", pwd) 10 | } 11 | } 12 | 13 | // abbceffg meets the third requirement (because it repeats bb and ff) but fails the first requirement. 14 | func TestPwdOk2(t *testing.T) { 15 | pwd := "abbceffg" 16 | if TestPwd(ConvertPwd(pwd)) { 17 | t.Fatalf("Password %s dovrebbe essere ko", pwd) 18 | } 19 | } 20 | 21 | // abbcegjk fails the third requirement, because it only has one double letter (bb). 22 | func TestPwdKo3(t *testing.T) { 23 | pwd := "aabbcegjk" 24 | if TestPwd(ConvertPwd(pwd)) { 25 | t.Fatalf("Password %s dovrebbe essere ko", pwd) 26 | } 27 | } 28 | 29 | // The next password after abcdefgh is abcdffaa 30 | func TestNextPwd1(t *testing.T) { 31 | pwd1 := "abcdefgh" 32 | pwd2 := "abcdffaa" 33 | next_pwd := NextPwd(ConvertPwd(pwd1)) 34 | if !ComparePwd(next_pwd, ConvertPwd(pwd2)) { 35 | t.Fatalf("Next password %s dovrebbe essere %s e non %s", pwd1, pwd2, string(next_pwd)) 36 | } 37 | } 38 | 39 | // The next password after ghijklmn is ghjaabcc, because you eventually skip all the passwords that start with ghi..., since i is not allowed. 40 | func TestNextPwd2(t *testing.T) { 41 | pwd1 := "ghijklmn" 42 | pwd2 := "ghjaabcc" 43 | next_pwd := NextPwd(ConvertPwd(pwd1)) 44 | if !ComparePwd(next_pwd, ConvertPwd(pwd2)) { 45 | t.Fatalf("Next password %s dovrebbe essere %s e non %s", pwd1, pwd2, string(next_pwd)) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /2021/10/day_10.py: -------------------------------------------------------------------------------- 1 | class Subsystem: 2 | OPENED = {"<": (25137, 4), "{": (1197, 3), "[": (57, 2), "(": (3, 1)} 3 | CLOSED = {">": "<", "}": "{", "]": "[", ")": "("} 4 | 5 | def __init__(self, data): 6 | self.lines = [list(line) for line in data.strip().split("\n")] 7 | 8 | def compile(self): 9 | errors = dict((par, 0) for par in self.OPENED.keys()) 10 | incompletes = [] 11 | for line in self.lines: 12 | opened = [] 13 | for par in line: 14 | if par in self.OPENED: 15 | opened.append(par) 16 | else: 17 | par = self.CLOSED[par] 18 | if opened.pop() != par: 19 | errors[par] += 1 20 | break 21 | else: 22 | incompletes.append(opened) 23 | return errors, incompletes 24 | 25 | def sum_errors(self): 26 | return sum(self.OPENED[error][0] * count for error, count in self.compile()[0].items()) 27 | 28 | def complete(self): 29 | _, incompletes = self.compile() 30 | points = [] 31 | for opened in incompletes: 32 | point = 0 33 | for par in reversed(opened): 34 | point = point * 5 + self.OPENED[par][1] 35 | points.append(point) 36 | points.sort() 37 | return points[len(points) // 2] 38 | 39 | 40 | def solve1(data): 41 | return Subsystem(data).sum_errors() 42 | 43 | 44 | def solve2(data): 45 | return Subsystem(data).complete() 46 | 47 | 48 | if __name__ == "__main__": 49 | data = open("input.txt").read() 50 | print(solve1(data)) 51 | print(solve2(data)) 52 | -------------------------------------------------------------------------------- /2021/09/day_09.py: -------------------------------------------------------------------------------- 1 | class Floor: 2 | def __init__(self, data): 3 | self.map = tuple(tuple(int(c) for c in line) for line in data.strip().split("\n")) 4 | self.rows = len(self.map) 5 | self.cols = len(self.map[0]) 6 | 7 | def adj(self, x, y): 8 | adj = [] 9 | for x0, y0 in ((x - 1, y), (x + 1, y), (x, y - 1), (x, y + 1)): 10 | if y0 < 0 or y0 >= self.rows or x0 < 0 or x0 >= self.cols: 11 | continue 12 | adj.append((self.map[y0][x0], x0, y0)) 13 | return adj 14 | 15 | def low_points(self): 16 | lows = [] 17 | for y in range(self.rows): 18 | for x in range(self.cols): 19 | point = self.map[y][x] 20 | if point < min(ad[0] for ad in self.adj(x, y)): 21 | lows.append((point, x, y)) 22 | return lows 23 | 24 | def explore(self, basin): 25 | p, x, y = basin[-1] 26 | for p0, x0, y0 in self.adj(x, y): 27 | if p0 > p and not (p0 == 9 or (p0, x0, y0) in basin): 28 | basin.append((p0, x0, y0)) 29 | self.explore(basin) 30 | return basin 31 | 32 | def max_basins(self): 33 | len_basins = sorted(len(self.explore([(p, x, y)])) for p, x, y in self.low_points()) 34 | return len_basins[-1] * len_basins[-2] * len_basins[-3] 35 | 36 | 37 | def solve1(data): 38 | lows = Floor(data).low_points() 39 | return sum(low[0] for low in lows) + len(lows) 40 | 41 | 42 | def solve2(data): 43 | return Floor(data).max_basins() 44 | 45 | 46 | if __name__ == "__main__": 47 | data = open("input.txt").read() 48 | print(solve1(data)) 49 | print(solve2(data)) 50 | -------------------------------------------------------------------------------- /2015/advent6b.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "bufio" 6 | "os" 7 | "strings" 8 | ) 9 | 10 | func main() { 11 | var x1, y1, x2, y2 int 12 | var lights [1000][1000] int 13 | in := bufio.NewReader(os.Stdin) 14 | for { 15 | if str, err := in.ReadString('\n'); err != nil { 16 | fmt.Println(err) 17 | break 18 | } else { 19 | toggle := false 20 | on := false 21 | if strings.HasPrefix(str, "toggle ") { 22 | toggle = true 23 | str = str[7:] 24 | } else if strings.HasPrefix(str, "turn on ") { 25 | on = true 26 | str = str[8:] 27 | } else { 28 | str = str[9:] 29 | } 30 | f := func(x int) int { 31 | if x == 0 { 32 | return 0 33 | } 34 | return x - 1 35 | } 36 | if toggle { 37 | f = func(x int) int { 38 | return x + 2 39 | } 40 | } else if on { 41 | f = func(x int) int { 42 | return x + 1 43 | } 44 | } 45 | fmt.Sscanf(str, "%d,%d through %d,%d\n", &x1, &y1, &x2, &y2) 46 | for x := x1; x<=x2; x++ { 47 | for y := y1; y<=y2; y++ { 48 | lights[x][y] = f(lights[x][y]) 49 | } 50 | } 51 | } 52 | } 53 | light_on := 0 54 | for x := 0; x<1000; x++ { 55 | for y := 0; y<1000; y++ { 56 | light_on += lights[x][y] 57 | } 58 | } 59 | fmt.Println(light_on) 60 | } 61 | 62 | -------------------------------------------------------------------------------- /2018/12/12.py: -------------------------------------------------------------------------------- 1 | raw = """initial state: #..#.#..##......###...### 2 | 3 | ...## => # 4 | ..#.. => # 5 | .#... => # 6 | .#.#. => # 7 | .#.## => # 8 | .##.. => # 9 | .#### => # 10 | #.#.# => # 11 | #.### => # 12 | ##.#. => # 13 | ##.## => # 14 | ###.. => # 15 | ###.# => # 16 | ####. => #""" 17 | 18 | raw = open("input.txt").read() 19 | 20 | 21 | def potify(pot): 22 | return 0 if pot == '.' else 1 23 | 24 | 25 | def grow(pots, rules): 26 | pots = (0, 0, 0, 0, 0) + pots[:] + (0, 0, 0, 0, 0) 27 | next_pots = list(pots) 28 | for pos in range(len(pots) - 5): 29 | try: 30 | next_pots[pos + 2] = rules[tuple(pots[pos:pos + 5])] 31 | except KeyError: 32 | next_pots[pos + 2] = 0 33 | pass 34 | return tuple(next_pots) 35 | 36 | 37 | def read(raw): 38 | rules = {} 39 | for n, line in enumerate(raw.split("\n")): 40 | if n == 0: 41 | pots = tuple(potify(pot) for pot in list(line.split(":")[1].strip())) 42 | elif n > 1 and line: 43 | next_pot = potify(line[9]) 44 | if next_pot: 45 | rules[tuple(potify(pot) for pot in list(line[:5]))] = next_pot 46 | return pots, rules 47 | 48 | 49 | def tot(pots, gen): 50 | return sum((gen * -5 + i) for i, pot in enumerate(pots) if pot) 51 | 52 | 53 | pots, rules = read(raw) 54 | 55 | 56 | last_tot, last_diff = 0, None 57 | 58 | gen = 0 59 | while True: 60 | gen += 1 61 | pots = grow(pots, rules) 62 | next_tot = tot(pots, gen) 63 | if gen == 20: 64 | print(next_tot) 65 | next_diff = next_tot - last_tot 66 | if next_diff == last_diff: 67 | print(next_tot + last_diff * (50000000000 - gen)) 68 | break 69 | last_tot, last_diff = next_tot, next_diff 70 | -------------------------------------------------------------------------------- /2020/07/day_07.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict 2 | 3 | 4 | def count(tree, main_bag): 5 | tot = 0 6 | for bag, how_many in tree[main_bag].items(): 7 | tot += how_many + how_many * count(tree, bag) 8 | return tot 9 | 10 | 11 | def explore(tree, what, main_bag): 12 | if what in tree[main_bag]: 13 | return True 14 | for bag, contain in tree[main_bag].items(): 15 | if bag == what: 16 | return True 17 | else: 18 | if explore(tree, what, bag): 19 | return True 20 | return False 21 | 22 | 23 | def solve(data): 24 | tree = defaultdict(dict) 25 | for rule in data.strip().split("\n"): 26 | parts = rule.strip(".").split(" bags contain ") 27 | main_bag = parts[0] 28 | others = parts[1].split(", ") 29 | if others[0] == 'no other bags': 30 | tree[main_bag] = {} 31 | else: 32 | for other in others: 33 | other = other.rstrip("s")[:-4] 34 | parts = other.split(" ") 35 | how_many = int(parts[0].replace("no", "0")) 36 | bag = " ".join(parts[1:]) 37 | tree[main_bag][bag] = how_many 38 | what = 'shiny gold' 39 | bags = list(tree.keys()) 40 | tot = 0 41 | for main_bag in bags: 42 | if main_bag == what: 43 | continue 44 | if explore(tree, what, main_bag): 45 | tot += 1 46 | tot2 = 0 47 | for main_bag, how_many in tree[what].items(): 48 | tot2 += how_many + how_many * count(tree, main_bag) 49 | return tot, tot2 50 | 51 | 52 | if __name__ == "__main__": 53 | data = open("input.txt").read() 54 | part1, part2 = solve(data) 55 | print(part1) 56 | print(part2) 57 | -------------------------------------------------------------------------------- /2022/15/day_15.py: -------------------------------------------------------------------------------- 1 | import bisect 2 | 3 | 4 | def load(data): 5 | sensors = [] 6 | for line in data.strip().split("\n"): 7 | parts = line.replace(",", "=").replace(":", "=").split("=") 8 | sensors.append(tuple(int(parts[n]) for n in (1, 3, 5, 7))) 9 | return sensors 10 | 11 | 12 | class Ground: 13 | def __init__(self, sensors): 14 | self.sensors = sensors 15 | 16 | def empty_row(self, row): 17 | empty_zones = [] 18 | for sx, sy, bx, by in self.sensors: 19 | length = abs(sx - bx) + abs(sy - by) - abs(row - sy) 20 | if length > 0: 21 | bisect.insort(empty_zones, (sx - length, sx + length)) 22 | empty = [] 23 | for x1, x2 in empty_zones: 24 | # First zone 25 | if not empty: 26 | empty.append([x1, x2]) 27 | # Extend last zone 28 | elif x1 <= empty[-1][1] + 1: 29 | if x2 > empty[-1][1]: 30 | empty[-1][1] = x2 31 | # Add another zone 32 | else: 33 | empty.append([x1, x2]) 34 | return empty 35 | 36 | def beacon(self, row): 37 | return sum(abs(x2 - x1) for x1, x2 in self.empty_row(row)) 38 | 39 | def distress(self, space): 40 | for row in range(space, -1, -1): 41 | empty = self.empty_row(row) 42 | if len(empty) == 2: 43 | return (empty[0][1] + 1) * 4000000 + row 44 | 45 | 46 | def solve1(data, row=2000000): 47 | return Ground(load(data)).beacon(row) 48 | 49 | def solve2(data, space=4000000): 50 | return Ground(load(data)).distress(space) 51 | 52 | 53 | if __name__ == "__main__": 54 | data = open("input.txt").read() 55 | print(solve1(data)) 56 | print(solve2(data)) 57 | --------------------------------------------------------------------------------