Initial commit d01-24
This commit is contained in:
commit
071c20222a
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
*.pyc
|
||||
__pycache__
|
||||
tags
|
||||
tags.lock
|
||||
tags.temp
|
5
.golangci.yml
Normal file
5
.golangci.yml
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
linters:
|
||||
disable:
|
||||
- gochecknoglobals
|
||||
- goerr113
|
5
README.md
Normal file
5
README.md
Normal file
@ -0,0 +1,5 @@
|
||||
https://adventofcode.com/
|
||||
|
||||
Each day is organized in a subfolder. There is no consistency at all.
|
||||
|
||||
Good luck!
|
200
d01/aoc-d1-input.txt
Normal file
200
d01/aoc-d1-input.txt
Normal file
@ -0,0 +1,200 @@
|
||||
1934
|
||||
1702
|
||||
1571
|
||||
1737
|
||||
1977
|
||||
1531
|
||||
1428
|
||||
1695
|
||||
1794
|
||||
1101
|
||||
13
|
||||
1164
|
||||
1235
|
||||
1289
|
||||
1736
|
||||
1814
|
||||
1363
|
||||
1147
|
||||
1111
|
||||
1431
|
||||
1765
|
||||
1515
|
||||
1184
|
||||
1036
|
||||
1803
|
||||
1791
|
||||
1638
|
||||
1809
|
||||
1283
|
||||
1980
|
||||
1854
|
||||
1878
|
||||
1574
|
||||
1352
|
||||
1151
|
||||
730
|
||||
1581
|
||||
1990
|
||||
1919
|
||||
2003
|
||||
1538
|
||||
1663
|
||||
1735
|
||||
1772
|
||||
1830
|
||||
1152
|
||||
1022
|
||||
1774
|
||||
1544
|
||||
1551
|
||||
1835
|
||||
1383
|
||||
1614
|
||||
1396
|
||||
1715
|
||||
1530
|
||||
295
|
||||
1208
|
||||
1978
|
||||
1104
|
||||
1691
|
||||
1176
|
||||
1183
|
||||
1909
|
||||
1192
|
||||
1535
|
||||
1924
|
||||
1268
|
||||
1969
|
||||
1954
|
||||
1760
|
||||
1077
|
||||
1734
|
||||
1371
|
||||
1676
|
||||
1933
|
||||
1400
|
||||
1928
|
||||
1982
|
||||
1541
|
||||
1106
|
||||
1248
|
||||
1346
|
||||
1782
|
||||
1142
|
||||
1849
|
||||
1798
|
||||
1362
|
||||
1379
|
||||
1886
|
||||
1265
|
||||
1226
|
||||
1751
|
||||
1575
|
||||
1027
|
||||
1710
|
||||
1601
|
||||
1205
|
||||
1922
|
||||
1452
|
||||
1206
|
||||
1263
|
||||
2000
|
||||
1957
|
||||
1951
|
||||
1834
|
||||
1533
|
||||
1149
|
||||
1245
|
||||
1564
|
||||
1182
|
||||
1237
|
||||
1013
|
||||
1254
|
||||
1895
|
||||
1504
|
||||
1480
|
||||
1556
|
||||
1821
|
||||
1589
|
||||
1864
|
||||
1573
|
||||
1698
|
||||
1927
|
||||
1434
|
||||
516
|
||||
1722
|
||||
1360
|
||||
1940
|
||||
1212
|
||||
1329
|
||||
1675
|
||||
1812
|
||||
1917
|
||||
1302
|
||||
1604
|
||||
1336
|
||||
1233
|
||||
1405
|
||||
1179
|
||||
1169
|
||||
1081
|
||||
1941
|
||||
1553
|
||||
1236
|
||||
1824
|
||||
1923
|
||||
1938
|
||||
1475
|
||||
1446
|
||||
1545
|
||||
1853
|
||||
1664
|
||||
317
|
||||
1489
|
||||
1884
|
||||
1743
|
||||
1621
|
||||
1128
|
||||
1474
|
||||
1505
|
||||
394
|
||||
1387
|
||||
1509
|
||||
1627
|
||||
1914
|
||||
1913
|
||||
1949
|
||||
1843
|
||||
1847
|
||||
1882
|
||||
1486
|
||||
1082
|
||||
1802
|
||||
1645
|
||||
1690
|
||||
1629
|
||||
1377
|
||||
2004
|
||||
1044
|
||||
1191
|
||||
1014
|
||||
1857
|
||||
1813
|
||||
1572
|
||||
1055
|
||||
1002
|
||||
1721
|
||||
1273
|
||||
1417
|
||||
1968
|
||||
1888
|
||||
1863
|
||||
1278
|
||||
1141
|
||||
1964
|
||||
1259
|
||||
1823
|
||||
1181
|
||||
1779
|
81
d01/main.go
Normal file
81
d01/main.go
Normal file
@ -0,0 +1,81 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func proccessLines(path string, f func(string) (stop bool, err error)) error {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
scanner := bufio.NewScanner(file)
|
||||
for scanner.Scan() {
|
||||
stop, err := f(scanner.Text())
|
||||
if stop || err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func part1() {
|
||||
seen := map[int]bool{}
|
||||
err := proccessLines("./aoc-d1-input.txt", func(line string) (bool, error) {
|
||||
num, err := strconv.Atoi(line)
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
pair := 2020 - num
|
||||
if _, ok := seen[pair]; ok {
|
||||
fmt.Printf("Found pair! %d + %d = 2020 Product = %d\n", num, pair, num*pair)
|
||||
return true, nil
|
||||
}
|
||||
seen[num] = true
|
||||
return false, nil
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
type numberPair struct {
|
||||
A, B int
|
||||
}
|
||||
|
||||
func part2() {
|
||||
singles := map[int]bool{}
|
||||
doubles := map[int]numberPair{}
|
||||
err := proccessLines("./aoc-d1-input.txt", func(line string) (bool, error) {
|
||||
num, err := strconv.Atoi(line)
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
remain := 2020 - num
|
||||
if pair, ok := doubles[remain]; ok {
|
||||
fmt.Printf("Found set! %d + %d + %d = 2020 Prouct = %d\n", num, pair.A, pair.B, num*pair.A*pair.B)
|
||||
return true, nil
|
||||
}
|
||||
for single := range singles {
|
||||
doubles[num+single] = numberPair{num, single}
|
||||
}
|
||||
singles[num] = true
|
||||
return false, nil
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
part1()
|
||||
part2()
|
||||
}
|
36
d01/main.py
Executable file
36
d01/main.py
Executable file
@ -0,0 +1,36 @@
|
||||
#! /usr/bin/env python3
|
||||
|
||||
|
||||
def part1():
|
||||
print("Part1:")
|
||||
seen = set()
|
||||
with open("./aoc-d1-input.txt", "r") as f:
|
||||
for line in f:
|
||||
v = int(line)
|
||||
remain = 2020 - v
|
||||
if remain in seen:
|
||||
print(f"{v} * {remain} = {v*remain}")
|
||||
break
|
||||
seen.add(v)
|
||||
|
||||
|
||||
def part2():
|
||||
print("Part2:")
|
||||
singles = set()
|
||||
doubles = {}
|
||||
with open("./aoc-d1-input.txt", "r") as f:
|
||||
for line in f:
|
||||
v = int(line)
|
||||
remain = 2020 - v
|
||||
if remain in doubles:
|
||||
n2, n3 = doubles[remain]
|
||||
print(f"{v} * {n2} * {n3} = {v*n2*n3}")
|
||||
break
|
||||
for n1 in singles:
|
||||
doubles[v+n1] = (v, n1)
|
||||
singles.add(v)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
part1()
|
||||
part2()
|
1000
d02/input.txt
Normal file
1000
d02/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
110
d02/main.go
Normal file
110
d02/main.go
Normal file
@ -0,0 +1,110 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func proccessLines(path string, f func(string) (stop bool, err error)) error {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
scanner := bufio.NewScanner(file)
|
||||
for scanner.Scan() {
|
||||
stop, err := f(scanner.Text())
|
||||
if stop || err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var matcher = regexp.MustCompile(`([0-9]+)-([0-9]+) ([a-zA-Z]): ([a-zA-Z]+)`)
|
||||
|
||||
func part1() {
|
||||
totalValid := 0
|
||||
err := proccessLines("input.txt", func(line string) (stop bool, err error) {
|
||||
results := matcher.FindStringSubmatch(line)
|
||||
if results == nil {
|
||||
err = fmt.Errorf("invalid line %s", line)
|
||||
return
|
||||
}
|
||||
minCount, err := strconv.Atoi(results[1])
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
maxCount, err := strconv.Atoi(results[2])
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
letter := results[3]
|
||||
password := results[4]
|
||||
// fmt.Printf("Make sure %s is in %s between %d and %d times\n", letter, password, minCount, maxCount)
|
||||
// Validate
|
||||
count := strings.Count(password, letter)
|
||||
if minCount <= count && count <= maxCount {
|
||||
totalValid++
|
||||
}
|
||||
return
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
fmt.Printf("Total valid %d\n", totalValid)
|
||||
}
|
||||
|
||||
func part2() {
|
||||
totalValid := 0
|
||||
err := proccessLines("input.txt", func(line string) (stop bool, err error) {
|
||||
results := matcher.FindStringSubmatch(line)
|
||||
if results == nil {
|
||||
err = fmt.Errorf("invalid line %s", line)
|
||||
return
|
||||
}
|
||||
pos1, err := strconv.Atoi(results[1])
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
pos2, err := strconv.Atoi(results[2])
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// 1 vs 0 indexed
|
||||
pos1--
|
||||
pos2--
|
||||
letter := results[3]
|
||||
password := results[4]
|
||||
// fmt.Printf("Make sure %s is in %s between %d and %d times\n", letter, password, minCount, maxCount)
|
||||
// Validate
|
||||
if pos1 >= len(password) || pos2 >= len(password) {
|
||||
return
|
||||
}
|
||||
letter1 := string(password[pos1])
|
||||
letter2 := string(password[pos2])
|
||||
if (letter == letter1 || letter == letter2) && letter1 != letter2 {
|
||||
totalValid++
|
||||
}
|
||||
return
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
fmt.Printf("Total valid %d\n", totalValid)
|
||||
}
|
||||
|
||||
func main() {
|
||||
part1()
|
||||
part2()
|
||||
}
|
44
d02/main.py
Executable file
44
d02/main.py
Executable file
@ -0,0 +1,44 @@
|
||||
#! /usr/bin/env python3
|
||||
import re
|
||||
|
||||
|
||||
def part1():
|
||||
print("Part1:")
|
||||
total_valid = 0
|
||||
with open("./input.txt", "r") as f:
|
||||
for line in f:
|
||||
g = re.search("([0-9]+)-([0-9]+) ([a-zA-Z]): ([a-zA-Z]+)", line)
|
||||
min_count = int(g.group(1))
|
||||
max_count = int(g.group(2))
|
||||
letter = g.group(3)
|
||||
password = g.group(4)
|
||||
# print(f"min: {min_count} max: {max_count} letter: {letter} password: {password}")
|
||||
count = password.count(letter)
|
||||
if min_count <= count <= max_count:
|
||||
total_valid += 1
|
||||
|
||||
print(f"Total valid {total_valid}")
|
||||
|
||||
|
||||
def part2():
|
||||
print("Part2:")
|
||||
total_valid = 0
|
||||
with open("./input.txt", "r") as f:
|
||||
for line in f:
|
||||
g = re.search("([0-9]+)-([0-9]+) ([a-zA-Z]): ([a-zA-Z]+)", line)
|
||||
password = g.group(4)
|
||||
try:
|
||||
pos1 = password[int(g.group(1))-1]
|
||||
pos2 = password[int(g.group(2))-1]
|
||||
except IndexError:
|
||||
continue
|
||||
letter = g.group(3)
|
||||
if (pos1 == letter or pos2 == letter) and pos1 != pos2:
|
||||
total_valid += 1
|
||||
|
||||
print(f"Total valid {total_valid}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
part1()
|
||||
part2()
|
323
d03/input.txt
Normal file
323
d03/input.txt
Normal file
@ -0,0 +1,323 @@
|
||||
.........#..##..#..#........#..
|
||||
#...#..#..#...##.....##.##.#...
|
||||
....#..............#....#....#.
|
||||
#.#..#.....#...#.##..#.#.#.....
|
||||
........#..#.#..#.......#......
|
||||
.#........#.#..###.#....#.#.#..
|
||||
........#........#.......#.....
|
||||
...##..#.#.#........##.........
|
||||
#.#.##..###............#...#...
|
||||
............#....#.......###.##
|
||||
....##....##..#........#......#
|
||||
............#.#..........#.....
|
||||
#.#....#....##...#.....#.....#.
|
||||
......#.#.#...#.....###....#..#
|
||||
...........##..#.........#..#.#
|
||||
..#..#.................#..#..#.
|
||||
.#....###...#.......#.........#
|
||||
#.#.#.#...#......#.......#...#.
|
||||
.......#.#.#...#..............#
|
||||
...##.......#..##.#.......##...
|
||||
#.#.##....#..##..##..###...###.
|
||||
.#......##.##.#....#.##........
|
||||
..###.............##..##..#....
|
||||
.....#.#...........#..##..##...
|
||||
.###.#.#......#.....#........##
|
||||
...#.......#...##..#..#..#.....
|
||||
..............#.#..##.##..##..#
|
||||
#..#.#......#............#.....
|
||||
........#..#....#..............
|
||||
...#...#..............#.#####..
|
||||
...##......#........#.#...#....
|
||||
..##......#............#..#..#.
|
||||
....#.........#.#.#.....###.#..
|
||||
#....#........#........#....#.#
|
||||
.....#...#..##.....##...#.....#
|
||||
#...#.#.#...##..##.###.#.#.....
|
||||
......#.#..........#...#.##....
|
||||
..............##...#..#.......#
|
||||
........##.....#.....#.#....#..
|
||||
..............#..#..#...#.....#
|
||||
##......##.......##...#.#....#.
|
||||
.....#.............#.#.........
|
||||
#.........##..#..#.........##..
|
||||
..#..#.....#####.........##.#..
|
||||
.......##.#......#........#....
|
||||
#.................#.#...#....#.
|
||||
...#........#.###.##.##.....#..
|
||||
#.....##..#...##.#.#......#....
|
||||
.....#..#.#..........##..#.##..
|
||||
..###.............#..#..#...#..
|
||||
...###..#...#.....##..........#
|
||||
#.......#.#...#....#..##..#..#.
|
||||
.#..#.........#..............#.
|
||||
..######.....#....##......#....
|
||||
#..##...#......#..#.#....#.....
|
||||
.#...................#.#.....#.
|
||||
..#...#.#..#.#......#..#...#..#
|
||||
..##..##.#.##.........#.#.#....
|
||||
...#...#...........#..##.##...#
|
||||
#...#....#....#....#..#.##..#..
|
||||
..#.##....#....###..#..........
|
||||
#.#..##.#.#...##.#..#.##..#.#..
|
||||
#......##...#.#..........#..#..
|
||||
#.#...#..#...#.#.#..#........#.
|
||||
#.#.##.#..#...#..#.#.##........
|
||||
.....#......#........#..#......
|
||||
...#....#.#....#...............
|
||||
....#..###..#....#..#....#....#
|
||||
.#........###..........##.##.#.
|
||||
#.#......##....##...##.#......#
|
||||
#..##.##...#...........##.#.#..
|
||||
.#.....#.#...#.................
|
||||
##..........#..#....#.....#...#
|
||||
....#.#..........##..#.....#.##
|
||||
#.#..#..#..##..........#.......
|
||||
..#.#.###......................
|
||||
......##..##.....#..##.##....#.
|
||||
...#.......#.##....#......#....
|
||||
...#...#........#...#.#...#..##
|
||||
##...#....#.#...#.#.##..##...#.
|
||||
...#.....#...#...#....###.#..#.
|
||||
..#.#..#........#......#..##..#
|
||||
...#......#...#.#.##...##.#.#.#
|
||||
....#.#....#....#.....#.....##.
|
||||
.....#.#..##.#....##....##.....
|
||||
.#...###..#.....#............#.
|
||||
#..#.#.#..#..#...#....#...#....
|
||||
#.....#..#...#................#
|
||||
..........#..#.......#......#.#
|
||||
...#..#......#...#......#......
|
||||
.#.#.....#.#.#.#......#..#..#..
|
||||
.....#.........#.#.#.....##.#..
|
||||
.....#.#.....#..#..#..#.....###
|
||||
##....#......##....##.#....#.#.
|
||||
#####........#..........##.....
|
||||
.#...##...#...#.......#....#...
|
||||
#.#.##...##...##..##........#..
|
||||
#.#..............#.#...#...###.
|
||||
...#.....##..#.........#....#.#
|
||||
#.#....#....#..##.#..#...#.....
|
||||
..#....#.#..#...#...##.....#...
|
||||
....#...#......................
|
||||
..#...#.......#..#...##....#...
|
||||
.#........#...#.....##.##...#..
|
||||
#......#..............#..#..#..
|
||||
...........#.#..#.#.#....#....#
|
||||
.##..##.......#...#..#.....#..#
|
||||
...#.........#.........###..#..
|
||||
...#.##....#....#.....#.....#..
|
||||
.#.#.#.........#.#.#....#....#.
|
||||
...#..........##..#....#.#.....
|
||||
...#....##................#....
|
||||
#....##..#..#........##...#....
|
||||
#...#...##.#............#....#.
|
||||
##..#....#...#...............#.
|
||||
..........#.#...#..##..#.#.....
|
||||
..##...##..#....#.#......#.....
|
||||
.......#......#.#.....#.....##.
|
||||
#...###.....##..##....#.#....#.
|
||||
.###......#.....#.#............
|
||||
#.....#.....####.##....#..#....
|
||||
......###.............#......##
|
||||
.........##.......##..#..#..#..
|
||||
.#.......#....#...#...#.#......
|
||||
#...#..#...#........#...##..#..
|
||||
.#....#........#.........##..#.
|
||||
..............##.#...##..#.##.#
|
||||
.#....#...#....#......#..#.....
|
||||
#....##.#...#.#.....###..#....#
|
||||
#.......##.#..###..............
|
||||
#..#..#..#......#.#..#...#..#.#
|
||||
.......#.#.#..#..#...#..#......
|
||||
.#..#......#.....#......##..##.
|
||||
....#....#.......#.......#.#.##
|
||||
.......#.#................#...#
|
||||
#.#.....#.......#.#........#...
|
||||
.....#....##...#......#.....##.
|
||||
.#......#.#...#..#....#....#.##
|
||||
##...#.###.#....#..#....#.#...#
|
||||
....#.##..##.#.............#...
|
||||
#..#.............##.......#.#..
|
||||
##.#..#..#.#...........###...##
|
||||
.#.#.....#......###........#...
|
||||
#.#...#.#....##......#.#....#..
|
||||
#.........#..........#.........
|
||||
.......#....#...#..#.....#...##
|
||||
.......................#...#..#
|
||||
.###...........##...#........##
|
||||
#.#....######.#........#..##.#.
|
||||
..#.##.#...#.#.......#.##.##..#
|
||||
#.............###..#.##.#......
|
||||
...#..##......#...#..###.....#.
|
||||
..........#.....#..#...##..#...
|
||||
..##..........#.#..#.....#...#.
|
||||
...#.......#.....##.........#..
|
||||
#..#.#...#..#...###...#...#.#..
|
||||
#.##....#..#.#.......#..#..#...
|
||||
..#.##.#......#.#......#....#..
|
||||
..........#...##.....###.......
|
||||
...#...##..#......#...##.......
|
||||
....#........#.#.......#..###..
|
||||
.....#.#..........##.#..#..#.#.
|
||||
.............##.....#.#..##....
|
||||
...#...............##...#......
|
||||
....#......#..#....#...##..#...
|
||||
.##.#....#.#.....#.#.........#.
|
||||
.....#.###....#..###..#.#.....#
|
||||
.#.........##.........##...#...
|
||||
..#.....###....##..........#..#
|
||||
........#..#.#.#..#.......#..##
|
||||
..#.#..#.#............#.##.#..#
|
||||
.#....#.....#..#...#.......##..
|
||||
.#...........#.#..#..###.###...
|
||||
..#.....#..#........#.#........
|
||||
.#........##........#..#.##....
|
||||
......#.....##........##..#....
|
||||
.#..................##....#.#..
|
||||
.#..#.#..#.#...#........#......
|
||||
...#..##.#......#..#..........#
|
||||
....#.##...#....##.............
|
||||
#....#.##....##.###..#..#..#...
|
||||
..........#..#...##.##....#..#.
|
||||
.###.#.....#...#...#...#.......
|
||||
............#...............#.#
|
||||
#....#...#......#....#.#.#.#.##
|
||||
...#..........#.#.#.....###....
|
||||
#.#...##...#..#.....###...#....
|
||||
......#...#..#..#..#.##...##...
|
||||
...#..#.#....#...#.#.........##
|
||||
##....#..###.#.##.....##.......
|
||||
..#.#...#..##.......#.#.......#
|
||||
##......#...........#......#...
|
||||
.......#..###....###..##.#...##
|
||||
.........#.....#..#.......##..#
|
||||
.......#.##..#....#...#.#...#..
|
||||
#..#.#..................##.#..#
|
||||
...#..#..#.....#..#........#...
|
||||
...#.#..###..#.....##...#....#.
|
||||
..#..#......#...........#...#..
|
||||
#...##.##..###.......##........
|
||||
.#.....#..#....#.....#.##....#.
|
||||
#..#........#.#....#..#...#.###
|
||||
..#...#.#.#.....#.....#..#.....
|
||||
.##.............#.#......##...#
|
||||
.#....#####............#.....##
|
||||
#.###.......#.#...##.....#.....
|
||||
......#.##..#...#..#..##.#..##.
|
||||
......#.#...##.....#...#....##.
|
||||
....#............#...#...#....#
|
||||
.........##.#.#....#....#....##
|
||||
.#...##.#...#.......#.##....#.#
|
||||
#....#.#...#.#...#.#.#...#.....
|
||||
.#.#.........##..#..#..........
|
||||
.#.........#.#.....#..#.#..###.
|
||||
....##.#.#..........#..####....
|
||||
....#..#.#.#...#...#..#....#...
|
||||
..#.#...#...##.......#.#.#..#..
|
||||
...##...#......#.....#.#...#..#
|
||||
......#.###.#.......##...#...#.
|
||||
.....#.#.#......##..........###
|
||||
##.#.#.#..#....#...............
|
||||
.#.#.##.......#....#.#.....#..#
|
||||
.........#...#.#..#.......#....
|
||||
....#.####.#......#...#...##...
|
||||
#..#..#..#..#....#...##.....##.
|
||||
......####.#..##..#.....##.....
|
||||
##.#.........#........#..#.#...
|
||||
.#.#....#....#.......#.#....##.
|
||||
....#....#.......##..#.....#...
|
||||
.#......#..#....#.#............
|
||||
#..#.#.##.....#..#.#.#.#.#.##..
|
||||
.#.....#.....#...#..#.#...#.#..
|
||||
.#.#.##............#.#.#.#.#.#.
|
||||
.##..........#.....#...###.....
|
||||
#.#...#...#................#.#.
|
||||
##...#.##.....#.....#.#.##.....
|
||||
####.....##..........#......#..
|
||||
#.............#..............#.
|
||||
.###....#.#...#..#..#..#.......
|
||||
..#.#.....#...#..#..####.......
|
||||
...#.#..#........#..##..#..#.##
|
||||
.#........#..........#.#...##..
|
||||
.#.......#.#.#..#...#..#.#...##
|
||||
.#.....##......##..............
|
||||
......#..#.#.##...##.#.....#...
|
||||
.........#.#...##.....##....#.#
|
||||
.....##...#........#..#.#..#.#.
|
||||
.#.##..#.....##...#...###.#.#..
|
||||
...##...#...#..#.#..#..........
|
||||
##..............#...#...#.#..#.
|
||||
......#..#......#..#.....#...#.
|
||||
.......#...#..#....#.....#.....
|
||||
..##.....##..#.#........#......
|
||||
.###.#...#.....................
|
||||
..#...#.................#...#..
|
||||
#..#.##...####.............#...
|
||||
.##....#..####.......#.........
|
||||
#..#...###...#...#..#..##......
|
||||
....#.##.#.#.........#.....#..#
|
||||
.....#...#.....#.#.#.##.#...##.
|
||||
.............#........#.....#..
|
||||
...##.###.#....##.......#..#...
|
||||
#..#....#....#.#............#..
|
||||
.........#.##........##.....#..
|
||||
.........#.#.#..#..#.......#...
|
||||
.......#.#..#.......#.....#.#..
|
||||
##.#.....##...##.....#.#.......
|
||||
.#.#.#......##.##.#.........#..
|
||||
..#.##..###.....###.........##.
|
||||
.#......#..#..##...#.#...##.#.#
|
||||
......#.#............#.....#...
|
||||
###.#..#..#..#..#.##...#.......
|
||||
.#.#.##..###....#......##..###.
|
||||
#...#.#.#..#..#..##.#.##....#..
|
||||
..#...#...####...#......####.##
|
||||
..##.#.####........#..#......#.
|
||||
.#..#.......#...#.#.........#..
|
||||
........#.#....#..#####..#.....
|
||||
.#...........#..#..#..#...#....
|
||||
....#....#...#.................
|
||||
....##..#....##....#..#....#.##
|
||||
....#.##.....###...#...##.##...
|
||||
......##.#..##.#.#.#....#.#.#..
|
||||
##.#...###....#.#..#.#.###....#
|
||||
......###..#..#..........##...#
|
||||
..........#.##...##..#....##.#.
|
||||
.#...#.#..#.#.#..#.....#.......
|
||||
.#....#..#.#..#.#...##.#.#.....
|
||||
.##.....#...#..##.#........#...
|
||||
....#......#.........#....#..##
|
||||
.#..#.#.#.#..#..#.#.........#..
|
||||
.........#.....#...#....#......
|
||||
#..#..#........#...#.#.........
|
||||
...#.#.#...##.#.#...#..#......#
|
||||
#.#.#.#........#...#..#.....#..
|
||||
.###..#..#..###..#..#..........
|
||||
.....#......#.#..#...#.......#.
|
||||
##.##.........#.......##.......
|
||||
#...##.......#..#.#.......#....
|
||||
#..#..#.....#...#......#.......
|
||||
.#..#..#.##....#.#..#...#...#..
|
||||
.#...#.....#..#.........#..#...
|
||||
...#.#.#.......#....#..##.....#
|
||||
.........#..##.#..#..#.#.......
|
||||
#.##.....##..###..#..#..#.##...
|
||||
........#......#...##...###..##
|
||||
.##....##..#..#..###......#....
|
||||
............##......#...#..##..
|
||||
...##.......#......#...##.##..#
|
||||
...#..#..#.#...####.#.......#..
|
||||
..#.##..#....#......#.#.....#..
|
||||
..#.##..............#..##.....#
|
||||
.....##....#......#....#......#
|
||||
......#..#......#.........#..#.
|
||||
...#.##.###...###..#.##........
|
||||
..........####.#.##.....#..#.##
|
||||
#...##...........#...........##
|
||||
#.#..#.#....#.#..#....##......#
|
||||
.......#...#.....#......#.#.##.
|
||||
....#.##..##..........#..#.....
|
||||
#.#.#...#......#...#.....#.##.#
|
||||
........#.......#..##.....##...
|
||||
.....####.#....#.#.............
|
120
d03/main.go
Normal file
120
d03/main.go
Normal file
@ -0,0 +1,120 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
)
|
||||
|
||||
var (
|
||||
tree = "#"
|
||||
snow = "."
|
||||
)
|
||||
|
||||
func proccessLines(path string, f func(string) (stop bool, err error)) error {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
scanner := bufio.NewScanner(file)
|
||||
for scanner.Scan() {
|
||||
stop, err := f(scanner.Text())
|
||||
if stop || err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type world struct {
|
||||
x, y int
|
||||
dx, dy int
|
||||
worldMap []string
|
||||
}
|
||||
|
||||
func (w *world) move(dx, dy int) string {
|
||||
result := w.peek(dx, dy)
|
||||
w.x += dx
|
||||
w.y += dy
|
||||
return result
|
||||
}
|
||||
|
||||
func (w world) peek(dx, dy int) string {
|
||||
row := w.worldMap[w.y+dy]
|
||||
return string(row[(w.x+dx)%len(row)])
|
||||
}
|
||||
|
||||
func (w world) atEnd() bool {
|
||||
return w.y >= len(w.worldMap)-1
|
||||
}
|
||||
|
||||
func (w *world) setSlope(dx, dy int) {
|
||||
w.dx = dx
|
||||
w.dy = dy
|
||||
}
|
||||
|
||||
func (w *world) ski() int {
|
||||
trees := 0
|
||||
for !w.atEnd() {
|
||||
space := w.move(w.dx, w.dy)
|
||||
if space == tree {
|
||||
trees++
|
||||
}
|
||||
}
|
||||
return trees
|
||||
}
|
||||
|
||||
func (w *world) takeLift() {
|
||||
w.x, w.y = 0, 0
|
||||
}
|
||||
|
||||
func readMap() world {
|
||||
worldMap := []string{}
|
||||
err := proccessLines("input.txt", func(line string) (stop bool, err error) {
|
||||
worldMap = append(worldMap, line)
|
||||
return
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
return world{worldMap: worldMap}
|
||||
}
|
||||
|
||||
func part1() {
|
||||
theWorld := readMap()
|
||||
theWorld.setSlope(3, 1)
|
||||
trees := theWorld.ski()
|
||||
fmt.Printf("Total trees: %d\n", trees)
|
||||
}
|
||||
|
||||
func part2() {
|
||||
trees := []int{}
|
||||
theWorld := readMap()
|
||||
|
||||
product := 1
|
||||
for _, slope := range [][]int{
|
||||
[]int{1, 1},
|
||||
[]int{3, 1},
|
||||
[]int{5, 1},
|
||||
[]int{7, 1},
|
||||
[]int{1, 2},
|
||||
} {
|
||||
theWorld.setSlope(slope[0], slope[1])
|
||||
count := theWorld.ski()
|
||||
product *= count
|
||||
trees = append(trees, count)
|
||||
theWorld.takeLift()
|
||||
}
|
||||
|
||||
fmt.Printf("Total trees: %v, product: %d\n", trees, product)
|
||||
}
|
||||
|
||||
func main() {
|
||||
part1()
|
||||
part2()
|
||||
}
|
107
d03/main.py
Executable file
107
d03/main.py
Executable file
@ -0,0 +1,107 @@
|
||||
#! /usr/bin/env python3
|
||||
import functools
|
||||
|
||||
|
||||
TREE = "#"
|
||||
SNOW = "."
|
||||
|
||||
|
||||
class LoopingList(list):
|
||||
|
||||
def __getitem__(self, key):
|
||||
if isinstance(key, int):
|
||||
return super().__getitem__(key % len(self))
|
||||
if isinstance(key, slice):
|
||||
return [
|
||||
self[x]
|
||||
for x in range(key.start, key.stop, key.step or 1)
|
||||
]
|
||||
|
||||
|
||||
def read_map():
|
||||
world_map = []
|
||||
with open("input.txt") as f:
|
||||
for line in f:
|
||||
world_map.append(LoopingList(line.strip()))
|
||||
return world_map
|
||||
|
||||
|
||||
class World(object):
|
||||
|
||||
def __init__(self, world_map, x=0, y=0):
|
||||
self._world_map = world_map
|
||||
self._x = x
|
||||
self._y = y
|
||||
# Default slopes
|
||||
self._dx = 1
|
||||
self._dy = 1
|
||||
|
||||
def move(self, dx, dy, should_print=False, print_buffer=0):
|
||||
self._x += dx
|
||||
self._y += dy
|
||||
if should_print:
|
||||
print("".join(self._world_map[self._y][0:self._x+print_buffer]))
|
||||
return self._world_map[self._y][self._x]
|
||||
|
||||
def print_row(self):
|
||||
print("".join(self._world_map[self._y]))
|
||||
|
||||
def peek(self, dx, dy):
|
||||
return self._world_map[dy + self._y][dx + self._x]
|
||||
|
||||
def at_end(self):
|
||||
return self._y >= len(self._world_map) - 1
|
||||
|
||||
def set_slope(self, dx, dy):
|
||||
self._dx = dx
|
||||
self._dy = dy
|
||||
|
||||
def ski(self, count_trees=True):
|
||||
trees = 0
|
||||
while not self.at_end():
|
||||
try:
|
||||
space = self.move(self._dx, self._dy)
|
||||
if count_trees and space == TREE:
|
||||
trees += 1
|
||||
except IndexError:
|
||||
print("At end of the world")
|
||||
return trees
|
||||
|
||||
def take_lift(self):
|
||||
self._x = 0
|
||||
self._y = 0
|
||||
|
||||
|
||||
def part1():
|
||||
world_map = read_map()
|
||||
world = World(world_map)
|
||||
world.set_slope(3, 1)
|
||||
trees = world.ski()
|
||||
|
||||
print("Total trees", trees)
|
||||
|
||||
|
||||
def part2():
|
||||
slopes = {
|
||||
(1, 1): None,
|
||||
(3, 1): None,
|
||||
(5, 1): None,
|
||||
(7, 1): None,
|
||||
(1, 2): None,
|
||||
}
|
||||
|
||||
world_map = read_map()
|
||||
world = World(world_map)
|
||||
|
||||
for slope in slopes:
|
||||
world.take_lift()
|
||||
world.set_slope(*slope)
|
||||
slopes[slope] = world.ski()
|
||||
|
||||
print(slopes)
|
||||
print("Answer:", functools.reduce(lambda x, y: x*y, slopes.values()))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
part1()
|
||||
part2()
|
1100
d04/input.txt
Normal file
1100
d04/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
13
d04/invalid.txt
Normal file
13
d04/invalid.txt
Normal file
@ -0,0 +1,13 @@
|
||||
eyr:1972 cid:100
|
||||
hcl:#18171d ecl:amb hgt:170 pid:186cm iyr:2018 byr:1926
|
||||
|
||||
iyr:2019
|
||||
hcl:#602927 eyr:1967 hgt:170cm
|
||||
ecl:grn pid:012533040 byr:1946
|
||||
|
||||
hcl:dab227 iyr:2012
|
||||
ecl:brn hgt:182cm pid:021572410 eyr:2020 byr:1992 cid:277
|
||||
|
||||
hgt:59cm ecl:zzz
|
||||
eyr:2038 hcl:74454a iyr:2023
|
||||
pid:3556412378 byr:2007
|
149
d04/main.go
Normal file
149
d04/main.go
Normal file
@ -0,0 +1,149 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func proccessLines(path string, f func(string) (stop bool, err error)) error {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
scanner := bufio.NewScanner(file)
|
||||
for scanner.Scan() {
|
||||
stop, err := f(scanner.Text())
|
||||
if stop || err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func between(low, mid, high int) bool {
|
||||
return low <= mid && mid <= high
|
||||
}
|
||||
|
||||
type validator = func(v string) bool
|
||||
|
||||
var heightMatcher = regexp.MustCompile(`^([0-9]+)(cm|in)$`)
|
||||
|
||||
func heightValidator(v string) bool {
|
||||
result := heightMatcher.FindStringSubmatch(v)
|
||||
if result == nil {
|
||||
return false
|
||||
}
|
||||
value, err := strconv.Atoi(result[1])
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
switch result[2] {
|
||||
case "cm":
|
||||
return between(150, value, 193)
|
||||
case "in":
|
||||
return between(59, value, 76)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func betweenValidator(low, high int) validator {
|
||||
return func(v string) bool {
|
||||
val, err := strconv.Atoi(v)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return between(low, val, high)
|
||||
}
|
||||
}
|
||||
|
||||
func valueInValidator(valid ...string) validator {
|
||||
validValues := map[string]bool{}
|
||||
for _, value := range valid {
|
||||
validValues[value] = true
|
||||
}
|
||||
return func(v string) bool {
|
||||
_, ok := validValues[v]
|
||||
return ok
|
||||
}
|
||||
}
|
||||
|
||||
var requiredKeys = map[string]validator{
|
||||
"byr": betweenValidator(1920, 2002),
|
||||
"iyr": betweenValidator(2010, 2020),
|
||||
"eyr": betweenValidator(2020, 2030),
|
||||
"hgt": heightValidator,
|
||||
"hcl": regexp.MustCompile(`^#[0-9a-f]{6}$`).MatchString,
|
||||
"ecl": valueInValidator("amb", "blu", "brn", "gry", "grn", "hzl", "oth"),
|
||||
"pid": regexp.MustCompile(`^[0-9]{9}$`).MatchString,
|
||||
}
|
||||
|
||||
func parseKeys(text string) map[string]string {
|
||||
d := map[string]string{}
|
||||
for _, kvp := range strings.Split(text, " ") {
|
||||
parts := strings.Split(kvp, ":")
|
||||
d[parts[0]] = parts[1]
|
||||
}
|
||||
return d
|
||||
}
|
||||
|
||||
func validateKeys(d map[string]string) bool {
|
||||
for key := range requiredKeys {
|
||||
if _, ok := d[key]; !ok {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func validateValues(d map[string]string) bool {
|
||||
for key, f := range requiredKeys {
|
||||
var v string
|
||||
var ok bool
|
||||
if v, ok = d[key]; !ok {
|
||||
return false
|
||||
}
|
||||
if !f(v) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func main() {
|
||||
validKeys, validValues, total := 0, 0, 0
|
||||
buffer := []string{}
|
||||
processBuffer := func(buffer []string) {
|
||||
d := parseKeys(strings.Join(buffer, " "))
|
||||
if validateKeys(d) {
|
||||
validKeys++
|
||||
}
|
||||
if validateValues(d) {
|
||||
validValues++
|
||||
}
|
||||
total++
|
||||
}
|
||||
err := proccessLines("input.txt", func(line string) (stop bool, err error) {
|
||||
if line == "" {
|
||||
processBuffer(buffer)
|
||||
buffer = []string{}
|
||||
} else {
|
||||
buffer = append(buffer, line)
|
||||
}
|
||||
return
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
processBuffer(buffer)
|
||||
|
||||
fmt.Printf("Total: %d, Valid keys: %d, Valid values: %d\n", total, validKeys, validValues)
|
||||
}
|
121
d04/main.py
Executable file
121
d04/main.py
Executable file
@ -0,0 +1,121 @@
|
||||
#! /usr/bin/env python3
|
||||
|
||||
import re
|
||||
|
||||
|
||||
def height_validator(x):
|
||||
match = re.match(r"^([0-9]+)(cm|in)$", x.strip())
|
||||
if not match:
|
||||
return False
|
||||
if match.group(2) == "cm":
|
||||
return 150 <= int(match.group(1)) <= 193
|
||||
elif match.group(2) == "in":
|
||||
return 59 <= int(match.group(1)) <= 76
|
||||
return False
|
||||
|
||||
|
||||
required_keys = {
|
||||
"byr": lambda x: 1920 <= int(x) <= 2002,
|
||||
"iyr": lambda x: 2010 <= int(x) <= 2020,
|
||||
"eyr": lambda x: 2020 <= int(x) <= 2030,
|
||||
"hgt": height_validator,
|
||||
"hcl": lambda x: re.match(r"^#[0-9a-f]{6}$", x.strip()),
|
||||
"ecl": lambda x: x in ("amb", "blu", "brn", "gry", "grn", "hzl", "oth"),
|
||||
"pid": lambda x: re.match(r"^[0-9]{9}$", x.strip()),
|
||||
}
|
||||
|
||||
optional_keys = {
|
||||
"cid": lambda x: True,
|
||||
}
|
||||
|
||||
|
||||
class Passport(object):
|
||||
|
||||
def __init__(self, s):
|
||||
self.d = {}
|
||||
for kvp in s.split():
|
||||
parts = kvp.partition(":")
|
||||
self.d[parts[0]] = parts[2]
|
||||
|
||||
def key_set(self):
|
||||
return set(self.d.keys())
|
||||
|
||||
def is_valid(self, deep=False):
|
||||
valid = set(required_keys.keys()) <= self.key_set()
|
||||
if not valid or not deep:
|
||||
# print(f"Valid: {valid}. Missing: {set(required_keys.keys()) - self.key_set()}")
|
||||
return valid
|
||||
|
||||
for key, validator in required_keys.items():
|
||||
valid = validator(self.d[key])
|
||||
if not valid:
|
||||
# print(f"Invalid value for {key}: {self.d[key]}")
|
||||
return False
|
||||
# print("Valid!", self.d)
|
||||
return valid
|
||||
|
||||
|
||||
def parse_passport(buffer):
|
||||
s = " ".join(buffer)
|
||||
return Passport(s)
|
||||
|
||||
|
||||
def part1():
|
||||
num_valid = 0
|
||||
total_passports = 0
|
||||
with open("input.txt") as f:
|
||||
buffer = []
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if line == "":
|
||||
p = parse_passport(buffer)
|
||||
total_passports += 1
|
||||
if p.is_valid():
|
||||
num_valid += 1
|
||||
buffer = []
|
||||
else:
|
||||
buffer.append(line)
|
||||
# if total_passports == 4:
|
||||
# break
|
||||
if buffer:
|
||||
p = parse_passport(buffer)
|
||||
total_passports += 1
|
||||
if p.is_valid():
|
||||
num_valid += 1
|
||||
|
||||
print("Total passports:", total_passports)
|
||||
print("Total valid passports:", num_valid)
|
||||
|
||||
|
||||
def part2():
|
||||
num_valid = 0
|
||||
total_passports = 0
|
||||
# with open("valid.txt") as f:
|
||||
# with open("invalid.txt") as f:
|
||||
with open("input.txt") as f:
|
||||
buffer = []
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if line == "":
|
||||
p = parse_passport(buffer)
|
||||
total_passports += 1
|
||||
if p.is_valid(deep=True):
|
||||
num_valid += 1
|
||||
buffer = []
|
||||
else:
|
||||
buffer.append(line)
|
||||
# if total_passports == 4:
|
||||
# break
|
||||
if buffer:
|
||||
p = parse_passport(buffer)
|
||||
total_passports += 1
|
||||
if p.is_valid(deep=True):
|
||||
num_valid += 1
|
||||
|
||||
print("Total passports:", total_passports)
|
||||
print("Total valid passports:", num_valid)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
part1()
|
||||
part2()
|
12
d04/valid.txt
Normal file
12
d04/valid.txt
Normal file
@ -0,0 +1,12 @@
|
||||
pid:087499704 hgt:74in ecl:grn iyr:2012 eyr:2030 byr:1980
|
||||
hcl:#623a2f
|
||||
|
||||
eyr:2029 ecl:blu cid:129 byr:1989
|
||||
iyr:2014 pid:896056539 hcl:#a97842 hgt:165cm
|
||||
|
||||
hcl:#888785
|
||||
hgt:164cm byr:2001 iyr:2015 cid:88
|
||||
pid:545766238 ecl:hzl
|
||||
eyr:2022
|
||||
|
||||
iyr:2010 hgt:158cm hcl:#b6652a ecl:blu byr:1944 eyr:2021 pid:093154719
|
874
d05/input.txt
Normal file
874
d05/input.txt
Normal file
@ -0,0 +1,874 @@
|
||||
FBFBFFFLLL
|
||||
FFBBBBFLRR
|
||||
BFBFBBBLLL
|
||||
FFBBBBBLLL
|
||||
BFFBBBBRLL
|
||||
BBBFFBFRLL
|
||||
FFBBFFFRRR
|
||||
FFBFFBBLRL
|
||||
FBFFBFBRRR
|
||||
FBFFBFBRLL
|
||||
BFFBFFFRLR
|
||||
FFFBBFFRRR
|
||||
BFBFBBFLLL
|
||||
FBFBBFFRRL
|
||||
BFFBFBFLRL
|
||||
FBFFFBFRRL
|
||||
FBFBFFBRRR
|
||||
FBFBFFBRLL
|
||||
BFBFFFBLLL
|
||||
BFBFFBBLRL
|
||||
FBFFFFBRRL
|
||||
BFFFBFFRRL
|
||||
FBFBFFFRLR
|
||||
BFFFFBBLLR
|
||||
FFBFFFFRLR
|
||||
BBFBBFFLLL
|
||||
FFBFFBFRRR
|
||||
FBFBFBBRRR
|
||||
BBBFFFFLRR
|
||||
FFFBFFBRRR
|
||||
BFFBFBFLRR
|
||||
BFFFBBBRLL
|
||||
FFBFBBBRLR
|
||||
FBFFFFBLLR
|
||||
FBBFBFFLRL
|
||||
FBFFFFFRLL
|
||||
FBBBBFBRLL
|
||||
BFBBBBFLLL
|
||||
FBBBFBBRRR
|
||||
BFFFBFBLLL
|
||||
FBBBBBFLRL
|
||||
BFBBBFFLRR
|
||||
BFBBFBBLRR
|
||||
FFBBBFFLRR
|
||||
FFBBBBFRLR
|
||||
BFFFBFFLLR
|
||||
FBBFFFBRRL
|
||||
FBBBFBBLRR
|
||||
FFBBFBFRRL
|
||||
FFFBFBBLRR
|
||||
FBFBBBBRLR
|
||||
FBFFBFBLLL
|
||||
FBBFFFFRLL
|
||||
BBBFFFBLRL
|
||||
FBBFBBBLLL
|
||||
FFBBFBBLLR
|
||||
FBFFFBBRLR
|
||||
BBFBBFFRRL
|
||||
FFFBBFFRLL
|
||||
FBFFBBBLRL
|
||||
BFFBFFFLRL
|
||||
FFFFBBFRRR
|
||||
FBBFBBFLLR
|
||||
BFBFBFBRRL
|
||||
BBFBFBBRRR
|
||||
BBBFFFBLLL
|
||||
BFBFFBFRLL
|
||||
FFBBFFBRRR
|
||||
BFBBFFFRRL
|
||||
BFBBBFBRRL
|
||||
BFBBBBBRRR
|
||||
BBFBFBFRLL
|
||||
BBFFBFFLRL
|
||||
BFFBBFFLLL
|
||||
BFBFBFFLLL
|
||||
FBBBFFFRLR
|
||||
BFFFBBBLRL
|
||||
FBFBFFFLRR
|
||||
FBBBFBBLRL
|
||||
FFBBFBBRLR
|
||||
FBBFFFFLRL
|
||||
FFFBFBBLLL
|
||||
FBFBFFBRRL
|
||||
BBFFBBFRRR
|
||||
BFFFFBFRLR
|
||||
FBFBFFBLRL
|
||||
FFBFFBBLLL
|
||||
FBFBBFBRLR
|
||||
BFFBBFBRLR
|
||||
FFBFBFBLLL
|
||||
FFBBFFBRLR
|
||||
FBBBBBBLLL
|
||||
FFFBBBBRRL
|
||||
BFBBFBBRLL
|
||||
BBFFFBFLLR
|
||||
FFBBBBFRRR
|
||||
BFBFFFBRLL
|
||||
BFBFFBFLRR
|
||||
FFFFBBBLLR
|
||||
FBFFBBFRLL
|
||||
FFFFBBBRRL
|
||||
FFBFFBBLLR
|
||||
FBFFFBBLLL
|
||||
FFBBBBFRLL
|
||||
BBFFBFFLLL
|
||||
BFBBBBBRRL
|
||||
BFFBFBFLLL
|
||||
FFBFBBFLLR
|
||||
FFBFBBBLRL
|
||||
BFFBFFBLRL
|
||||
FBBBFFFRRR
|
||||
FBBFFBBRRL
|
||||
FBBFFBBLLR
|
||||
BBFBBBFLRR
|
||||
BBFFFBFRRL
|
||||
FBFBFBFRRL
|
||||
FFBFBBFRRR
|
||||
FBFFBBBLLR
|
||||
BBFBFFBRLL
|
||||
BFBBBFBLRL
|
||||
FFBBFFFLRR
|
||||
BFFFBFFLRL
|
||||
BFFBBBFLLL
|
||||
FBBFFFBLRL
|
||||
BBBFFBFLLL
|
||||
BFBBFBBRLR
|
||||
FBBBBBFRLL
|
||||
FBBBBFBLRR
|
||||
FFBFBBFRLR
|
||||
BBFFFFBLLL
|
||||
FBFBBBFRLR
|
||||
FBBFBBBLRL
|
||||
BBFFBBBRLL
|
||||
FFBFBFFLLR
|
||||
FFFBBFBRLL
|
||||
FFBBBFFRLL
|
||||
BFBBFFFLRR
|
||||
FBBBFBFRLL
|
||||
BBFBFBFLRR
|
||||
BFBBBFFRLL
|
||||
FFBFFFFRRR
|
||||
BFBBBBBLLR
|
||||
FBBBBBBRRR
|
||||
BBFBBFFLRR
|
||||
BFBFFBBLRR
|
||||
BFFBFBBLRR
|
||||
BFFBBFFRLR
|
||||
FBBBFFBRRR
|
||||
FFFFBBBRLR
|
||||
FBFFFFFLLL
|
||||
BBFFFBFLRR
|
||||
BFFFFBFLRL
|
||||
BFFBFFBLLL
|
||||
BFFBBFBRRL
|
||||
FFFBBFFLLR
|
||||
FBFFFFBLRL
|
||||
FBFFFBFLLR
|
||||
FFBBFBBRLL
|
||||
FFBFFBBRLR
|
||||
FFBFFFBRRL
|
||||
FFFBFBFLRR
|
||||
BBFFBFFRRR
|
||||
BBFFFFFLLL
|
||||
FBBFBFBRLR
|
||||
BBFBBFBLLR
|
||||
BBFBBBFRRL
|
||||
BFBFFBBLLR
|
||||
FBBFFFFLLR
|
||||
FFBFBFFRRL
|
||||
FFFBFFBRRL
|
||||
FBFBFFBRLR
|
||||
BFBBFBFRLL
|
||||
BBFBBBBLLR
|
||||
BFBBBFFLLL
|
||||
BBFBBBBRRL
|
||||
BFBFBFBRLR
|
||||
BFFFBFBRRL
|
||||
BFFBBBFRRL
|
||||
BFFFBFBRLL
|
||||
FBFBFBFLRR
|
||||
FFBFFBFLRR
|
||||
BBFBBBBRLL
|
||||
BFBBBFFLRL
|
||||
FBBBBFBLLL
|
||||
BBFBBBFLRL
|
||||
BFBBFBFLLL
|
||||
FBBBBBBLRL
|
||||
FFBFFFBLLL
|
||||
FFBBBBBRRL
|
||||
FBBFFFBLLL
|
||||
FBBBFFBLRR
|
||||
BBBFFBFLLR
|
||||
FFFFBBBLLL
|
||||
FBBBBBBRLR
|
||||
FFBFFBBRRR
|
||||
BFFFBFFRLL
|
||||
BBBFFFBRRR
|
||||
FBBFBFFLLL
|
||||
FBFBFBBRLR
|
||||
FBFFFFFLRL
|
||||
FFBBBBBRLR
|
||||
FBBBFFBRRL
|
||||
BFBBBBFRRL
|
||||
FBFBBFBLLR
|
||||
BBFFBBBLLL
|
||||
BBBFFBFRLR
|
||||
FFBBFFFLLL
|
||||
FFBFFBBRRL
|
||||
FBBBBFFLLL
|
||||
FBBBBBFRRR
|
||||
FBFFBBFLLR
|
||||
FFFBFFFLRL
|
||||
FFFBFBBRRL
|
||||
BFFFBFFLLL
|
||||
FBBBFBBLLL
|
||||
FFBFBBBLLL
|
||||
BFFFFFBLRL
|
||||
FBBBFBFLRR
|
||||
BBFFBBFLLR
|
||||
FBFFBBBRLR
|
||||
BFBFFFFLLR
|
||||
BFBBBFBLLL
|
||||
BBFBFBBRLR
|
||||
FFFBBFBLLR
|
||||
BFFBFBBRRL
|
||||
BBFFBBFLRR
|
||||
BFFBBBFLRR
|
||||
FBFBBBBRRL
|
||||
BFBFBFFRRL
|
||||
BBFBBFFRLR
|
||||
BBFBBBBRLR
|
||||
FFBBFFFLLR
|
||||
BBFBFBBLRR
|
||||
FBFBFBFLLL
|
||||
BFFFFBBRRR
|
||||
BFBBBBFRRR
|
||||
BFFFFFFLRL
|
||||
BBBFFBFLRR
|
||||
FFFBBBBRLR
|
||||
FBBFFFBRLL
|
||||
BBFFBBFLRL
|
||||
FFBBBBBRRR
|
||||
BBFFBFFRLL
|
||||
BFFFFFBRRR
|
||||
FBBFBFBRRR
|
||||
BFFFFBFRRR
|
||||
FBBFBBBRLL
|
||||
FFFBFBBRLR
|
||||
FBBBBFFRLR
|
||||
FBBFFFBLLR
|
||||
FFBBFFBLLR
|
||||
BFBFFFBLRR
|
||||
FFBFBBBRRR
|
||||
BFBFBFBLRR
|
||||
BFFBBFBLRR
|
||||
FBFFBFFRLL
|
||||
BFFBBBFRLR
|
||||
FBFFFBFRLR
|
||||
FFFBFBFRLL
|
||||
FBBFBBFLLL
|
||||
BFBBFFFLRL
|
||||
FBBFBFFLRR
|
||||
BBFFFBFRRR
|
||||
FBBFBFBLRL
|
||||
FBBBFBFLLR
|
||||
FBFBBBBLLR
|
||||
BBBFFFFLLR
|
||||
BFBBFBFRRR
|
||||
FFBFBFFRLR
|
||||
FFBBFBBLLL
|
||||
BFFFFFBLLR
|
||||
FBBBFBFLLL
|
||||
FBBFBBFRLR
|
||||
BBFFFFFRLL
|
||||
BFBFBFFLRR
|
||||
FBFBBFFLRR
|
||||
BBFBBFBRLR
|
||||
BFFFBBFRLR
|
||||
FBFFBBFRRR
|
||||
FBFFFBFLLL
|
||||
FBBFBBBRRR
|
||||
BBFFFBBLRL
|
||||
FFBFFBFLLR
|
||||
BBFFBFFLLR
|
||||
BBBFFBFRRL
|
||||
FBFBBFBRRR
|
||||
FBBBBBBRLL
|
||||
FBFFFBBLRR
|
||||
FFFBFFFLLL
|
||||
BBFBBFFRLL
|
||||
BBFFFBFRLL
|
||||
BBFFFBFLLL
|
||||
FFBBFBBRRL
|
||||
FFFFBBFLRL
|
||||
BFBBBBFLRL
|
||||
BBFBBFFLLR
|
||||
BBFFBFBRRR
|
||||
FBFBBFFRLL
|
||||
FBFBBFBLLL
|
||||
BFBBBFFRRR
|
||||
FFBBBFBRLL
|
||||
FFBFBBBRRL
|
||||
BFBBFBFRLR
|
||||
BBFBFBFRLR
|
||||
FBFBBBFLLR
|
||||
FBFBBBFLRL
|
||||
BBFFBBFRLR
|
||||
FFBBFFFLRL
|
||||
FFFFBBFLRR
|
||||
FFFBBFFLRL
|
||||
FFFBFBFRRR
|
||||
FBBFFBBLRR
|
||||
BBFBBFBLRR
|
||||
BFFBBBFLRL
|
||||
FBFFBFFRLR
|
||||
FBFFFBFRRR
|
||||
BFFBBFFRRL
|
||||
BFFFBBFRLL
|
||||
BFBFBBBLRR
|
||||
FFBFFFBLRL
|
||||
FBFBBFBRLL
|
||||
FBBBBFBLLR
|
||||
FFBFBFBLRL
|
||||
FBFBBBFLRR
|
||||
FFBBBBBLRR
|
||||
FFBFFFBLLR
|
||||
BBFFFBBRLL
|
||||
BBFFBBFLLL
|
||||
FFFBBFBLRL
|
||||
FBBBFBFRRR
|
||||
BBFBBBBRRR
|
||||
FBBBFFBLLR
|
||||
FBBBBFBLRL
|
||||
FBFBFFFRRL
|
||||
FBBFFFFLRR
|
||||
BFFFBFBLRL
|
||||
BFFBFFBRLL
|
||||
BFBFFFBLRL
|
||||
FBFBFBFRLL
|
||||
BBFBFBFLLL
|
||||
FBBBBBFRRL
|
||||
BFFBFFFRLL
|
||||
FBBBFBBRRL
|
||||
BFBBFFBRLR
|
||||
FFBFBFFLLL
|
||||
FFBBBBBLLR
|
||||
FFBFBFBRRL
|
||||
FFFBFFBLRL
|
||||
BBFFFBFLRL
|
||||
FBFBFBBRRL
|
||||
BFFBFFBRRL
|
||||
BBFBFBBLRL
|
||||
BBFBFBFRRR
|
||||
FBFFBBFRLR
|
||||
FBFBBFBLRR
|
||||
FBBFFFFLLL
|
||||
FFFBFFFLRR
|
||||
FFFBBBBRRR
|
||||
BBFFFBBRLR
|
||||
FFBFFFFRLL
|
||||
FBFFBFBRLR
|
||||
FBFBFBBRLL
|
||||
FBBBBFFLRR
|
||||
FBBFBFBRLL
|
||||
FBBBFBFLRL
|
||||
BBFBBBFLLR
|
||||
FFBFBBBLLR
|
||||
BFFBBBFRRR
|
||||
FFBBFBFLLL
|
||||
BFBBBFBRLR
|
||||
FFBFBBBRLL
|
||||
FFBFBFFLRR
|
||||
FBFBFBBLLL
|
||||
BFBBBBFLLR
|
||||
FFBBFBFRRR
|
||||
FBFBFBBLRR
|
||||
BFFFBFBLLR
|
||||
BFFBFBFRRL
|
||||
FFFBBBFRLR
|
||||
FFFBBFFRRL
|
||||
FFFBBBFLRL
|
||||
FFFFBBFLLL
|
||||
BBBFFFBLRR
|
||||
FBFFFFBRRR
|
||||
FFFFBBFRRL
|
||||
FBFBBFFRLR
|
||||
BFFBBBBLRL
|
||||
FBFFFFBLRR
|
||||
FFFBBFBLRR
|
||||
FFFFBBFRLL
|
||||
FFFBBFBRRR
|
||||
FBFFBBBRRL
|
||||
BBFFFFFLRL
|
||||
BBFFBBFRRL
|
||||
BFFFBBBLLL
|
||||
FBBBBBBLRR
|
||||
FBBBFFFRLL
|
||||
FBFFBFFLRR
|
||||
FFBFBBFLLL
|
||||
FFBBBFBRRR
|
||||
BFFFBFBRRR
|
||||
BBFFBFBRRL
|
||||
BFFFBBBRLR
|
||||
FBFFFBBRRR
|
||||
BBFBBFBRLL
|
||||
BBFFBBBRRR
|
||||
FBFFBFBLLR
|
||||
FFBFFBBLRR
|
||||
FBBFBBFLRL
|
||||
FFBFFBFLLL
|
||||
FFFBFFFRRL
|
||||
BBBFFFBRLL
|
||||
BFBFBBBRRL
|
||||
FFBFBFBLLR
|
||||
FFFBBBFRLL
|
||||
BFFFBBFRRR
|
||||
BFBBFFFRLR
|
||||
FBBFFBBRLL
|
||||
BFBBBBBLRL
|
||||
BBFBFBFLRL
|
||||
BFBBBFBLLR
|
||||
FBBFFBBRRR
|
||||
BFFFFBBLRR
|
||||
FBBFBBBLLR
|
||||
BFBFBFBRLL
|
||||
BFBFBFBRRR
|
||||
BFFFFBFRRL
|
||||
FBFBBFFLLR
|
||||
FBBFBBFRRL
|
||||
BBFBFBBLLL
|
||||
BFFBFFBRRR
|
||||
FBBFBFBLRR
|
||||
BFFBBFBLLR
|
||||
BFBFBBBRLL
|
||||
FBFFBBBLRR
|
||||
BBFFBFBLRR
|
||||
BBFFFFFRLR
|
||||
BBBFFBBLLR
|
||||
BBFBBFFRRR
|
||||
BBFFFBBLLR
|
||||
BFFBFFBRLR
|
||||
FBFFBFFLLL
|
||||
BFBBFFFRLL
|
||||
FFFBFBBRLL
|
||||
FBFBFBBLRL
|
||||
FFFBBBFRRL
|
||||
BFBFBBFRLR
|
||||
BBFFFFFRRL
|
||||
FBBFBFFLLR
|
||||
BFFFBBFLRR
|
||||
BBFBBFBRRR
|
||||
BBFFBBBLRR
|
||||
FBFBBFFRRR
|
||||
BFFFBFFRLR
|
||||
FFBBFBFLLR
|
||||
FBFBFFBLRR
|
||||
FBFFBFBLRL
|
||||
FFBFBFBRLR
|
||||
FBBFBBBRRL
|
||||
FFBBFFFRLR
|
||||
FFFBFBBRRR
|
||||
FBBFBFFRLL
|
||||
FFBFBFFRLL
|
||||
FFBFBBBLRR
|
||||
FFBBBFFLLR
|
||||
BFBFFFFLRR
|
||||
FFBBBFBLRL
|
||||
BBFFFBBRRL
|
||||
FFBFFBFRRL
|
||||
FFBBBFBRLR
|
||||
BFBFFBFLLL
|
||||
BBFBBBFRLR
|
||||
BFBFFBFRLR
|
||||
FFBBBBBLRL
|
||||
FFFBBFFLLL
|
||||
BBFFBFFRRL
|
||||
BFBBFBBLRL
|
||||
BFFBFFFLRR
|
||||
BBBFFFFLRL
|
||||
BFBFFBBRLL
|
||||
FBBBFFBLLL
|
||||
FBBFFBBLLL
|
||||
BBFFFFFLLR
|
||||
FFBBFFBLRR
|
||||
BFBBFBFLRR
|
||||
BBFFFFFLRR
|
||||
BFFBFBFLLR
|
||||
FBFBBBBLLL
|
||||
FBBBFFBRLR
|
||||
FBBBFBBLLR
|
||||
BFBFBBBLRL
|
||||
BFFFBFBRLR
|
||||
FBBFFBFRRR
|
||||
BFFFBBFLLL
|
||||
FFBFFFBRLR
|
||||
FFBFFFBRRR
|
||||
FFFBFFBRLR
|
||||
BBFBFFFRLL
|
||||
BFBFFBFRRL
|
||||
BFBFBBFRRL
|
||||
FBBBBBFLRR
|
||||
BFFBBBBLRR
|
||||
FFBFFBFLRL
|
||||
BFBFBBFLRL
|
||||
BFFFFFFLLR
|
||||
FBFFBBBRRR
|
||||
BFBFFBBRLR
|
||||
FBBFBFFRLR
|
||||
BFFBBBFLLR
|
||||
BFBFFFBLLR
|
||||
FFBFFFFRRL
|
||||
FFFBBBBLRR
|
||||
FFFBBFBLLL
|
||||
BFFBFBBLLR
|
||||
FBFFBFBLRR
|
||||
FFFBBBBRLL
|
||||
BBBFFFBRLR
|
||||
BFBBFFFLLL
|
||||
BFBBBFFLLR
|
||||
BFBFBFFRRR
|
||||
BFFFFBFLLR
|
||||
FBBBBFBRLR
|
||||
BFFBBBBRRL
|
||||
FBFBFBFRLR
|
||||
FFBFBBFRRL
|
||||
BFFFBBFLLR
|
||||
FFBBBFBLLL
|
||||
FFBFBBFLRR
|
||||
BFFFFBFLLL
|
||||
FBBBBBFRLR
|
||||
BBFBBBFLLL
|
||||
FBFBBFBRRL
|
||||
FFBBFBFRLL
|
||||
BFBFFFFRRR
|
||||
FBFFFFFRLR
|
||||
FFBBFFBLRL
|
||||
BBFBBBBLRL
|
||||
FBBFFBFLRL
|
||||
BFFFBFBLRR
|
||||
FBFFFBBRRL
|
||||
BBFBFFBRLR
|
||||
FFBBFBBLRL
|
||||
FBBBBFFLRL
|
||||
BFFFFBBRLR
|
||||
FBFFBBFLRR
|
||||
FFBFBFFRRR
|
||||
FFBBFBFLRR
|
||||
BFFBFFFRRL
|
||||
FBBFFBFRLR
|
||||
FBBFBFBLLR
|
||||
BFBFFBBRRL
|
||||
FBFFFBFLRR
|
||||
FBFBBFBLRL
|
||||
BFFFFBFRLL
|
||||
BFBFBBBRRR
|
||||
FFFBFFFLLR
|
||||
FBBBFFFLRR
|
||||
FFBFBBFLRL
|
||||
BFFFFBBLRL
|
||||
BBFFBFFLRR
|
||||
FBBFFFFRRR
|
||||
FFFBFBBLRL
|
||||
BFFFBFFLRR
|
||||
BFBBFBFLRL
|
||||
FBFFBFBRRL
|
||||
BFBFFFFLRL
|
||||
FBBFFFBRRR
|
||||
FFBBFFBRLL
|
||||
FFBFFBFRLL
|
||||
BBFBFBBLLR
|
||||
BFBFBFFLLR
|
||||
BFFFBBBRRL
|
||||
BBFBFFFLLR
|
||||
FBFBFFFLRL
|
||||
BFFBBFFRRR
|
||||
BFFBFBBRLR
|
||||
BBBFFBFLRL
|
||||
BBFBFFBLRR
|
||||
BBFBFFFLLL
|
||||
FFBBBBFLLL
|
||||
BFBBFBBRRR
|
||||
BBFFFFBRRL
|
||||
FFBFFBBRLL
|
||||
FBBFFFBLRR
|
||||
FFFFBBBLRL
|
||||
FFBFBFFLRL
|
||||
FBBBBFBRRR
|
||||
BFFBBFBRRR
|
||||
BFFFBBBLLR
|
||||
BFFBFBFRLR
|
||||
BFFBBBFRLL
|
||||
FFFFBBBLRR
|
||||
BFBFBBBRLR
|
||||
BFBFBFFRLL
|
||||
FFBBFFFRRL
|
||||
FBBFFBFRRL
|
||||
BBFFBBFRLL
|
||||
FBBFFBBRLR
|
||||
BFBBFFFRRR
|
||||
BFBBFFBRRL
|
||||
FBFFFBBRLL
|
||||
FBBBBBBRRL
|
||||
FBFFFFBRLR
|
||||
BFBBFFBLLR
|
||||
BBFBFFBRRL
|
||||
BFFBBFFLLR
|
||||
BFFFFBBRLL
|
||||
BBFFBFBLLL
|
||||
FBBFFFFRLR
|
||||
FBBFFBFLRR
|
||||
BFFBBFFRLL
|
||||
BFBBFBBLLL
|
||||
FBFBFBFLLR
|
||||
BFFFBBBLRR
|
||||
BFBFBFBLRL
|
||||
BBBFFFFRRR
|
||||
FFBFBFBRLL
|
||||
FBFFBFFRRR
|
||||
FFBFFFBRLL
|
||||
FBBFBBFRRR
|
||||
FFFBBBFRRR
|
||||
FBFFBFFRRL
|
||||
FFBBFFBRRL
|
||||
FBBBFFFLLR
|
||||
BBFBBFBRRL
|
||||
BBFBFFFRRL
|
||||
FFFBBBBLRL
|
||||
FBBBFFFRRL
|
||||
BFBBFFBLRL
|
||||
FBFFFFFLRR
|
||||
FBFFBBFLRL
|
||||
BBFFBBBRRL
|
||||
BBBFFBBLLL
|
||||
FBFFBBBRLL
|
||||
BBBFFFFRLL
|
||||
FFBBBFFRLR
|
||||
BBFFFFBRLL
|
||||
FBFFFBBLLR
|
||||
BFFBFBFRRR
|
||||
FBFFBBBLLL
|
||||
FBFBBBFRLL
|
||||
BFFFFFBLRR
|
||||
BFFBBFFLRL
|
||||
FFBBFBBRRR
|
||||
FBFFBFFLLR
|
||||
BFFBBBBLLR
|
||||
BFFFFFFRRR
|
||||
BBFBBBFRRR
|
||||
BBFFFFBLRR
|
||||
BFFBBFBLLL
|
||||
FFBBFFBLLL
|
||||
BBBFFFFRRL
|
||||
FBBFBBFLRR
|
||||
FBBFFFBRLR
|
||||
FBFBBFFLRL
|
||||
FBFBFFFRLL
|
||||
FBBFFBBLRL
|
||||
BFFBBBBRRR
|
||||
FFFFBBFLLR
|
||||
BBFFBBBRLR
|
||||
BFFFFFFRLL
|
||||
FBBBBBBLLR
|
||||
BBFFFBBLRR
|
||||
BFFFFFBLLL
|
||||
FBBBBFFLLR
|
||||
BBFBFFFRRR
|
||||
FBFBFFBLLL
|
||||
FBFFFFBLLL
|
||||
FFBFFBFRLR
|
||||
BFBFFBBLLL
|
||||
BFFBBFFLRR
|
||||
FBBBBBFLLL
|
||||
FFBBBFBLRR
|
||||
BFFFFFBRLR
|
||||
BBFBFBBRRL
|
||||
BBFFFFBRRR
|
||||
FFFBFBFLRL
|
||||
FBFBBBBLRR
|
||||
BFBFFBBRRR
|
||||
FFBFFFFLLL
|
||||
BFBFFBFLLR
|
||||
FBBFBBBRLR
|
||||
FFFBFFFRLL
|
||||
FFFBFBFRLR
|
||||
FFBBBFFLRL
|
||||
BFFBBBBRLR
|
||||
FBFFBBFLLL
|
||||
FFFBBFFLRR
|
||||
BBFBFBFLLR
|
||||
FFBBFBFLRL
|
||||
BBFFBBBLRL
|
||||
BBFFFFBLLR
|
||||
FFBFFFBLRR
|
||||
BFBBFBFLLR
|
||||
BFBBBBBLLL
|
||||
BBFBBFBLRL
|
||||
BBFBFFFRLR
|
||||
BFFBFFFLLL
|
||||
BBFBFFBRRR
|
||||
FBFBBBFRRR
|
||||
FBBBBFFRLL
|
||||
BFFBBFBLRL
|
||||
BBFBFFBLRL
|
||||
BFBBFFBRRR
|
||||
BBBFFFFLLL
|
||||
BFBFFFFRRL
|
||||
FBFFFFFRRR
|
||||
BFFFFBBLLL
|
||||
BFBBFFBRLL
|
||||
FFBBBBBRLL
|
||||
BFFBFBBRRR
|
||||
BFBBFFFLLR
|
||||
BFBBFBBLLR
|
||||
FBBBBFBRRL
|
||||
FBFBFBFLRL
|
||||
BFBBBBFRLL
|
||||
FFFBFFBLLL
|
||||
BFFBFFFLLR
|
||||
BFBBBFBRLL
|
||||
FFFBBFBRRL
|
||||
FFBFBFBRRR
|
||||
FFFBFBBLLR
|
||||
BFBBBFBRRR
|
||||
FBBFBBFRLL
|
||||
BFBBFBBRRL
|
||||
BFBBBBFRLR
|
||||
FFFBBBBLLL
|
||||
BBFFFBBLLL
|
||||
FFBBBBFLRL
|
||||
BFBBBBBRLL
|
||||
FBBFFBFRLL
|
||||
FBFFFBBLRL
|
||||
FBBFBFFRRR
|
||||
FFFBFBFLLR
|
||||
FFBBBFFRRL
|
||||
FBBBFBBRLR
|
||||
BBFBFFFLRR
|
||||
FBFBBFFLLL
|
||||
BBFFBFFRLR
|
||||
BBFBFFFLRL
|
||||
FBBBBFFRRR
|
||||
FFBBBFBLLR
|
||||
BBBFFFBRRL
|
||||
FBFBFFFLLR
|
||||
BBFBFFBLLL
|
||||
FFFBBFBRLR
|
||||
FBFFFBFLRL
|
||||
BFFBFBBLLL
|
||||
BBFBFBBRLL
|
||||
FBFFBBFRRL
|
||||
BFBFFFFRLL
|
||||
BBBFFBBLRL
|
||||
FFFBFFBLLR
|
||||
BFFBFBBRLL
|
||||
FFBFBFBLRR
|
||||
BBFBFBFRRL
|
||||
FBBBFBFRRL
|
||||
FFFBBBBLLR
|
||||
FBBBFBBRLL
|
||||
BFBFBBFLRR
|
||||
BFFFFFFLLL
|
||||
FFFBFFFRLR
|
||||
BFBBBFFRLR
|
||||
BFFFFFBRLL
|
||||
FBFFFFFLLR
|
||||
FBBBFFBRLL
|
||||
FBBFFBFLLR
|
||||
BFFBFFBLRR
|
||||
FBFBBBFLLL
|
||||
FBFFFFFRRL
|
||||
BBFFFFBLRL
|
||||
BFBFFFFRLR
|
||||
FBBFFFFRRL
|
||||
BFFBBBBLLL
|
||||
FFFFBBBRRR
|
||||
FFBBFBBLRR
|
||||
FBBFFBFLLL
|
||||
BFFFFBBRRL
|
||||
FFBBBBFRRL
|
||||
BFFFFBFLRR
|
||||
BFFFBBFRRL
|
||||
BFBBBFFRRL
|
||||
BFFFBFFRRR
|
||||
FBFBBBBRRR
|
||||
FBFFBFFLRL
|
||||
FBBBBBFLLR
|
||||
BFBFBBFLLR
|
||||
BBBFFBFRRR
|
||||
BFBBFFBLRR
|
||||
FBBFBFFRRL
|
||||
BBFBBFBLLL
|
||||
BFBBFFBLLL
|
||||
FFBBBFBRRL
|
||||
BFBFBFBLLL
|
||||
BFFBFBFRLL
|
||||
BBFFBBBLLR
|
||||
FFFBFBFLLL
|
||||
FFBBBBFLLR
|
||||
FFFBFBFRRL
|
||||
BFBFFFBRRR
|
||||
FFBFBBFRLL
|
||||
FFFBBBFLLR
|
||||
FBBFBFBLLL
|
||||
BBFFFFFRRR
|
||||
FFFBFFFRRR
|
||||
BFFFBBBRRR
|
||||
FFBFFFFLRL
|
||||
FFFBFFBLRR
|
||||
FFBBFBFRLR
|
||||
FBBFBBBLRR
|
||||
BFFBBFBRLL
|
||||
BBFFFBBRRR
|
||||
FFFFBBFRLR
|
||||
FBBFBFBRRL
|
||||
FBFBFFBLLR
|
||||
FBFBFBBLLR
|
||||
BFBFBBFRRR
|
||||
BBFFBFBLLR
|
||||
FFBBBFFLLL
|
||||
BBFFBFBRLL
|
||||
BFFFBBFLRL
|
||||
BFBFBFFRLR
|
||||
BFBFFFFLLL
|
||||
FFBBBFFRRR
|
||||
BBFBFFBLLR
|
||||
BFBBBBFLRR
|
||||
BFFBFBBLRL
|
||||
FFBBFFFRLL
|
||||
FFBFFFFLLR
|
||||
BFBFFFBRRL
|
||||
BFBFBFFLRL
|
||||
BFFFFFFLRR
|
||||
BBFBBFFLRL
|
||||
FBFFFFBRLL
|
||||
BBFFBFBRLR
|
||||
FBBBFFFLLL
|
||||
FFFBBBFLLL
|
||||
BFFBFFFRRR
|
||||
BBFBBBBLLL
|
||||
BBFFFBFRLR
|
||||
FBFBFFFRRR
|
||||
FFFBBFFRLR
|
||||
BFFBFFBLLR
|
||||
BBFFBFBLRL
|
||||
BFBFBFBLLR
|
||||
FBFFFBFRLL
|
||||
BBFBBBFRLL
|
||||
BFBBBBBRLR
|
||||
BFBFFFBRLR
|
||||
FFFBBBFLRR
|
||||
BFBFFBFLRL
|
||||
BBFBBBBLRR
|
||||
BFBFBBFRLL
|
||||
FFFFBBBRLL
|
||||
BFBBBBBLRR
|
||||
FBFBBBBRLL
|
||||
BFBBFBFRRL
|
||||
BBFFFFBRLR
|
||||
FBBBFBFRLR
|
||||
BFBFFBFRRR
|
||||
FBFBBBBLRL
|
||||
BFBFBBBLLR
|
||||
FFBFFFFLRR
|
||||
FBFBBBFRRL
|
||||
FBFBFBFRRR
|
||||
BFFFFFFRLR
|
||||
FBBBBFFRRL
|
||||
BFFFFFBRRL
|
||||
BBBFFFFRLR
|
||||
FBBBFFBLRL
|
||||
FBBBFFFLRL
|
||||
FFFBFFBRLL
|
||||
BFFFFFFRRL
|
||||
BBBFFFBLLR
|
128
d05/main.go
Normal file
128
d05/main.go
Normal file
@ -0,0 +1,128 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"sort"
|
||||
)
|
||||
|
||||
func proccessLines(path string, f func(string) (stop bool, err error)) error {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
scanner := bufio.NewScanner(file)
|
||||
for scanner.Scan() {
|
||||
stop, err := f(scanner.Text())
|
||||
if stop || err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type seat struct {
|
||||
row, column, id int
|
||||
}
|
||||
|
||||
func paritionSearch(partitions string, start, end float64, lower, upper string) (int, error) {
|
||||
if start == end {
|
||||
return int(start), nil
|
||||
}
|
||||
if partitions == "" {
|
||||
return 0, fmt.Errorf("empty partitions are invalid")
|
||||
}
|
||||
if start > end {
|
||||
return 0, fmt.Errorf("start cannot be greater than end")
|
||||
}
|
||||
if lower == "" || upper == "" {
|
||||
return 0, fmt.Errorf("invalid upper and lower bounds")
|
||||
}
|
||||
|
||||
mid := (end - start) / 2.0
|
||||
direction := string(partitions[0])
|
||||
switch direction {
|
||||
case lower:
|
||||
return paritionSearch(partitions[1:], start, mid+start-.5, lower, upper)
|
||||
case upper:
|
||||
return paritionSearch(partitions[1:], mid+start+.5, end, lower, upper)
|
||||
}
|
||||
|
||||
return 0, fmt.Errorf("unknown direction %s", direction)
|
||||
}
|
||||
|
||||
func parseSeat(code string) (seat, error) {
|
||||
totalRows, totalCols := 128, 8
|
||||
if len(code) != 10 {
|
||||
return seat{}, fmt.Errorf("invalid code length %s", code)
|
||||
}
|
||||
row, err := paritionSearch(code[:7], 0.0, float64(totalRows-1), "F", "B")
|
||||
if err != nil {
|
||||
return seat{}, err
|
||||
}
|
||||
col, err := paritionSearch(code[7:], 0.0, float64(totalCols-1), "L", "R")
|
||||
if err != nil {
|
||||
return seat{}, err
|
||||
}
|
||||
|
||||
return seat{
|
||||
row: row,
|
||||
column: col,
|
||||
id: row*8 + col,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func part1() {
|
||||
max := -1
|
||||
err := proccessLines("input.txt", func(line string) (stop bool, err error) {
|
||||
s, err := parseSeat(line)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if s.id > max {
|
||||
max = s.id
|
||||
}
|
||||
return
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
fmt.Printf("Max id is %d\n", max)
|
||||
}
|
||||
|
||||
func part2() {
|
||||
seatIds := []int{}
|
||||
err := proccessLines("input.txt", func(line string) (stop bool, err error) {
|
||||
s, err := parseSeat(line)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
seatIds = append(seatIds, s.id)
|
||||
return
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
sort.Ints(seatIds)
|
||||
lastID := -3
|
||||
for _, id := range seatIds {
|
||||
if id == lastID+2 {
|
||||
fmt.Printf("Found my seat! %d", lastID+1)
|
||||
break
|
||||
}
|
||||
lastID = id
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
part1()
|
||||
part2()
|
||||
}
|
65
d05/main.py
Executable file
65
d05/main.py
Executable file
@ -0,0 +1,65 @@
|
||||
#! /usr/bin/env python3
|
||||
from collections import namedtuple
|
||||
|
||||
|
||||
Seat = namedtuple("Seat", ["row", "column", "id"])
|
||||
|
||||
|
||||
def partition_search(partitions, start, end, lower, upper):
|
||||
if start == end:
|
||||
return start
|
||||
assert partitions
|
||||
assert start < end
|
||||
assert all((lower, upper))
|
||||
# print(f"Searching: range {start}:{end} {partitions[0]}")
|
||||
|
||||
mid = (end - start) / 2
|
||||
direction = partitions.pop(0)
|
||||
if direction == lower:
|
||||
return partition_search(partitions, start, start + mid - .5, lower, upper)
|
||||
elif direction == upper:
|
||||
return partition_search(partitions, start + mid + .5, end, lower, upper)
|
||||
|
||||
raise ValueError(f"Unknown direction {direction}")
|
||||
|
||||
|
||||
def parse_seat(code, total_rows=128, total_cols=8):
|
||||
if len(code) != 10:
|
||||
raise ValueError(f"Invalid code length: {code}")
|
||||
row_partitions = list(code[:7])
|
||||
row = partition_search(row_partitions, 0, total_rows-1, "F", "B")
|
||||
col_partitions = list(code[7:])
|
||||
col = partition_search(col_partitions, 0, total_cols-1, "L", "R")
|
||||
return Seat(int(row), int(col), int(row*8+col))
|
||||
|
||||
|
||||
def part1():
|
||||
with open("input.txt") as f:
|
||||
max_seat = max((parse_seat(line.strip()).id
|
||||
for line in f))
|
||||
print(f"Max seat id: {max_seat}")
|
||||
|
||||
|
||||
def part2():
|
||||
seats = []
|
||||
with open("input.txt") as f:
|
||||
seats = list(sorted((parse_seat(line.strip()).id
|
||||
for line in f)))
|
||||
last_id = None
|
||||
for id in seats:
|
||||
# print("Seat:", id)
|
||||
if last_id is None:
|
||||
last_id = id
|
||||
continue
|
||||
if id == last_id + 2:
|
||||
print(f"My seat: {last_id+1}")
|
||||
return
|
||||
last_id = id
|
||||
else:
|
||||
print("Didn't find seat")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# print(parse_seat("FBFBBFFRLR"))
|
||||
part1()
|
||||
part2()
|
2199
d06/input.txt
Normal file
2199
d06/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
141
d06/main.go
Normal file
141
d06/main.go
Normal file
@ -0,0 +1,141 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
)
|
||||
|
||||
func processLines(path string, f func(string) (stop bool, err error)) error {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
scanner := bufio.NewScanner(file)
|
||||
for scanner.Scan() {
|
||||
stop, err := f(scanner.Text())
|
||||
if stop || err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func processGroups(path string, f func([]string) (stop bool, err error)) error {
|
||||
group := []string{}
|
||||
if err := processLines(path, func(line string) (stop bool, err error) {
|
||||
if strings.HasPrefix(line, "mask") {
|
||||
stop, err = f(group)
|
||||
if stop || err != nil {
|
||||
return
|
||||
}
|
||||
group = []string{}
|
||||
} else {
|
||||
group = append(group, line)
|
||||
}
|
||||
|
||||
return
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err := f(group)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// StringSet is a set of strings
|
||||
type StringSet struct {
|
||||
d map[string]bool
|
||||
}
|
||||
|
||||
// Add an item to a StringSet
|
||||
func (s *StringSet) Add(v string) {
|
||||
s.d[v] = true
|
||||
}
|
||||
|
||||
// Len gives the length of a StringSet
|
||||
func (s StringSet) Len() int {
|
||||
return len(s.d)
|
||||
}
|
||||
|
||||
// NewStringSet creates an empty string set
|
||||
func NewStringSet() StringSet {
|
||||
return StringSet{map[string]bool{}}
|
||||
}
|
||||
|
||||
// Union returns the union of two SringSets
|
||||
func Union(s1, s2 StringSet) StringSet {
|
||||
union := NewStringSet()
|
||||
for v := range s1.d {
|
||||
union.Add(v)
|
||||
}
|
||||
for v := range s2.d {
|
||||
union.Add(v)
|
||||
}
|
||||
return union
|
||||
}
|
||||
|
||||
// Intersection returns the union of two SringSets
|
||||
func Intersection(s1, s2 StringSet) StringSet {
|
||||
intersect := NewStringSet()
|
||||
for v := range s1.d {
|
||||
if _, ok := s2.d[v]; ok {
|
||||
intersect.Add(v)
|
||||
}
|
||||
}
|
||||
return intersect
|
||||
}
|
||||
|
||||
func part1() {
|
||||
total := 0
|
||||
err := processGroups("input.txt", func(group []string) (stop bool, err error) {
|
||||
questions := NewStringSet()
|
||||
for _, person := range group {
|
||||
for _, q := range person {
|
||||
questions.Add(string(q))
|
||||
}
|
||||
}
|
||||
total += questions.Len()
|
||||
return
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
fmt.Printf("Part 1 answer %d\n", total)
|
||||
}
|
||||
|
||||
func part2() {
|
||||
total := 0
|
||||
err := processGroups("input.txt", func(group []string) (stop bool, err error) {
|
||||
result := NewStringSet()
|
||||
for _, q := range group[0] {
|
||||
result.Add(string(q))
|
||||
}
|
||||
for _, person := range group[1:] {
|
||||
questions := NewStringSet()
|
||||
for _, q := range person {
|
||||
questions.Add(string(q))
|
||||
}
|
||||
result = Intersection(result, questions)
|
||||
}
|
||||
total += result.Len()
|
||||
return
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
fmt.Printf("Part 2 answer %d\n", total)
|
||||
}
|
||||
|
||||
func main() {
|
||||
part1()
|
||||
part2()
|
||||
}
|
43
d06/main.py
Executable file
43
d06/main.py
Executable file
@ -0,0 +1,43 @@
|
||||
#! /usr/bin/env python3
|
||||
|
||||
|
||||
def iter_groups():
|
||||
group_responses = []
|
||||
with open("input.txt") as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if line == "":
|
||||
# Group divider
|
||||
yield group_responses
|
||||
group_responses = []
|
||||
else:
|
||||
group_responses.append(line)
|
||||
else:
|
||||
if group_responses:
|
||||
yield group_responses
|
||||
|
||||
|
||||
def part1():
|
||||
total = 0
|
||||
for group in iter_groups():
|
||||
questions = set()
|
||||
for person in group:
|
||||
for question in person:
|
||||
questions.add(question)
|
||||
total += len(questions)
|
||||
print("Total", total)
|
||||
|
||||
|
||||
def part2():
|
||||
total = 0
|
||||
for group in iter_groups():
|
||||
result = set(group[0])
|
||||
for person in group[1:]:
|
||||
result = result & set(person)
|
||||
total += len(result)
|
||||
print("Total", total)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
part1()
|
||||
part2()
|
594
d07/input.txt
Normal file
594
d07/input.txt
Normal file
@ -0,0 +1,594 @@
|
||||
striped green bags contain 5 posh indigo bags.
|
||||
light yellow bags contain 3 wavy turquoise bags.
|
||||
bright lime bags contain 2 striped crimson bags, 3 dull red bags.
|
||||
dull blue bags contain 4 posh coral bags, 3 mirrored coral bags, 2 striped fuchsia bags.
|
||||
vibrant coral bags contain 2 shiny blue bags, 2 muted gray bags.
|
||||
mirrored gold bags contain 2 dotted maroon bags.
|
||||
drab lavender bags contain 4 pale turquoise bags, 5 faded lime bags, 2 bright aqua bags.
|
||||
mirrored red bags contain 4 shiny tan bags, 4 muted aqua bags, 4 pale salmon bags, 5 bright violet bags.
|
||||
clear gray bags contain 4 bright lavender bags, 2 dotted plum bags, 1 drab coral bag, 3 faded aqua bags.
|
||||
dull aqua bags contain 2 wavy coral bags.
|
||||
muted yellow bags contain 3 drab olive bags, 4 pale lime bags, 2 striped crimson bags, 3 wavy blue bags.
|
||||
shiny chartreuse bags contain 5 bright yellow bags.
|
||||
posh turquoise bags contain 3 dotted blue bags, 4 pale lime bags, 1 mirrored fuchsia bag.
|
||||
faded maroon bags contain 5 striped indigo bags, 2 light aqua bags, 3 dim chartreuse bags, 4 vibrant tomato bags.
|
||||
dotted lavender bags contain 3 pale crimson bags, 3 wavy gray bags, 2 plaid plum bags, 5 mirrored bronze bags.
|
||||
striped olive bags contain 5 dull lime bags.
|
||||
vibrant aqua bags contain 3 drab tan bags, 5 bright coral bags, 3 pale brown bags.
|
||||
wavy aqua bags contain 4 dim lime bags, 4 dotted bronze bags, 1 bright gray bag.
|
||||
pale green bags contain 1 shiny purple bag, 4 dim plum bags.
|
||||
vibrant purple bags contain 2 pale gray bags, 2 dull crimson bags.
|
||||
faded green bags contain 4 dotted plum bags, 1 light white bag.
|
||||
posh orange bags contain 4 light blue bags.
|
||||
drab tomato bags contain 1 dull salmon bag, 3 plaid orange bags, 3 posh gray bags.
|
||||
vibrant beige bags contain 2 dull fuchsia bags.
|
||||
wavy orange bags contain 2 bright tan bags, 5 light beige bags, 2 vibrant turquoise bags.
|
||||
light salmon bags contain 1 dark blue bag, 2 bright orange bags.
|
||||
light blue bags contain 3 clear chartreuse bags, 5 dull olive bags.
|
||||
dull crimson bags contain 4 dim gold bags, 5 dark tan bags, 5 dark lavender bags.
|
||||
dim teal bags contain 3 striped gray bags, 4 shiny fuchsia bags, 2 vibrant chartreuse bags, 2 drab plum bags.
|
||||
striped crimson bags contain no other bags.
|
||||
dark brown bags contain 1 dim plum bag.
|
||||
dotted tan bags contain 1 striped fuchsia bag.
|
||||
bright turquoise bags contain 3 light orange bags, 2 wavy bronze bags, 2 light beige bags.
|
||||
drab salmon bags contain 4 wavy silver bags.
|
||||
light brown bags contain 1 clear gold bag.
|
||||
plaid aqua bags contain 4 shiny maroon bags, 2 mirrored gray bags.
|
||||
posh chartreuse bags contain 3 clear maroon bags, 4 wavy black bags, 3 vibrant white bags.
|
||||
wavy gray bags contain 3 shiny violet bags, 2 striped silver bags, 5 pale lime bags.
|
||||
dim crimson bags contain 1 wavy blue bag, 1 dull red bag, 1 dotted plum bag.
|
||||
wavy black bags contain 5 dim crimson bags, 5 dotted chartreuse bags.
|
||||
faded gray bags contain 4 plaid white bags, 2 mirrored yellow bags.
|
||||
muted violet bags contain 5 vibrant blue bags, 5 shiny beige bags.
|
||||
dull white bags contain 1 dull olive bag, 5 clear chartreuse bags, 1 dull red bag, 1 wavy red bag.
|
||||
light bronze bags contain 4 bright gray bags, 3 light tomato bags, 2 shiny white bags, 2 clear silver bags.
|
||||
plaid violet bags contain 2 vibrant indigo bags, 2 dim turquoise bags.
|
||||
posh purple bags contain 5 wavy purple bags.
|
||||
bright olive bags contain 4 muted bronze bags, 4 mirrored green bags, 2 dim plum bags, 5 bright silver bags.
|
||||
vibrant olive bags contain 1 vibrant beige bag, 4 striped gold bags, 4 shiny beige bags, 1 faded blue bag.
|
||||
muted fuchsia bags contain 3 vibrant red bags.
|
||||
plaid indigo bags contain 4 dull lime bags, 3 faded violet bags.
|
||||
wavy chartreuse bags contain 3 dotted yellow bags.
|
||||
posh magenta bags contain 4 bright gray bags, 4 dotted turquoise bags.
|
||||
drab teal bags contain 5 dotted plum bags, 2 light white bags, 2 dark plum bags, 4 dim crimson bags.
|
||||
dark coral bags contain 3 wavy chartreuse bags, 3 plaid bronze bags, 1 muted magenta bag.
|
||||
posh white bags contain 4 dotted turquoise bags, 1 mirrored lime bag.
|
||||
mirrored brown bags contain 2 shiny chartreuse bags, 1 light bronze bag, 4 bright bronze bags, 5 dotted crimson bags.
|
||||
faded cyan bags contain 2 dull crimson bags, 4 light chartreuse bags, 4 light salmon bags.
|
||||
bright maroon bags contain 3 dotted yellow bags, 1 bright gray bag, 2 dim yellow bags, 5 light fuchsia bags.
|
||||
clear silver bags contain 4 faded green bags, 4 posh white bags, 4 dark plum bags.
|
||||
shiny crimson bags contain 4 dark lavender bags, 3 dotted gold bags, 3 dark tan bags.
|
||||
wavy olive bags contain 4 dotted cyan bags.
|
||||
wavy coral bags contain 3 dim gold bags, 4 dim silver bags, 4 faded green bags, 2 muted purple bags.
|
||||
striped chartreuse bags contain 4 mirrored plum bags, 4 dull tan bags, 5 muted gold bags.
|
||||
bright blue bags contain 5 mirrored beige bags, 4 muted bronze bags, 1 dark tan bag, 5 dark cyan bags.
|
||||
vibrant red bags contain 3 light chartreuse bags, 2 faded indigo bags, 3 drab teal bags, 1 striped indigo bag.
|
||||
dim cyan bags contain 5 faded silver bags, 3 wavy coral bags.
|
||||
muted gold bags contain 4 pale coral bags.
|
||||
wavy violet bags contain 2 dotted gray bags, 1 clear tan bag, 5 plaid brown bags.
|
||||
light maroon bags contain 5 faded silver bags.
|
||||
light cyan bags contain 5 pale brown bags, 3 pale black bags, 3 light tomato bags, 2 faded violet bags.
|
||||
pale turquoise bags contain 1 dull white bag, 1 muted tomato bag, 2 clear gold bags.
|
||||
clear plum bags contain 2 dotted orange bags, 1 bright olive bag, 3 striped violet bags.
|
||||
plaid silver bags contain 5 muted olive bags, 1 vibrant bronze bag, 5 dull lavender bags, 3 dark purple bags.
|
||||
clear gold bags contain 1 dotted turquoise bag, 3 dark indigo bags.
|
||||
muted indigo bags contain 1 mirrored orange bag, 3 dull beige bags.
|
||||
light plum bags contain 3 drab brown bags, 4 wavy cyan bags, 3 vibrant lavender bags.
|
||||
dim maroon bags contain 4 dull tan bags.
|
||||
pale lime bags contain 4 dotted maroon bags, 2 faded silver bags, 5 shiny tomato bags.
|
||||
shiny black bags contain 2 dull crimson bags.
|
||||
wavy indigo bags contain 1 light fuchsia bag.
|
||||
dull lime bags contain no other bags.
|
||||
shiny fuchsia bags contain 2 drab fuchsia bags, 1 shiny cyan bag, 1 muted black bag, 2 dull aqua bags.
|
||||
muted lavender bags contain 4 dull fuchsia bags, 1 dim chartreuse bag, 1 vibrant gold bag, 2 shiny beige bags.
|
||||
bright cyan bags contain 5 dark gold bags, 2 vibrant cyan bags, 1 pale coral bag.
|
||||
posh black bags contain 3 dull violet bags, 5 drab coral bags.
|
||||
posh olive bags contain 3 muted magenta bags, 3 dark plum bags, 1 shiny violet bag.
|
||||
dull coral bags contain 1 dark gold bag, 2 striped silver bags, 5 vibrant lavender bags, 2 light red bags.
|
||||
clear bronze bags contain 4 striped cyan bags, 4 dotted chartreuse bags, 4 shiny maroon bags.
|
||||
bright red bags contain 2 dark violet bags, 4 pale brown bags.
|
||||
muted silver bags contain 3 bright blue bags, 1 shiny blue bag, 5 muted bronze bags, 1 bright tan bag.
|
||||
dotted maroon bags contain 5 muted white bags, 4 dull lime bags, 2 dim gold bags, 2 faded fuchsia bags.
|
||||
clear lime bags contain 4 striped gold bags, 2 vibrant purple bags, 5 dotted green bags, 2 light tomato bags.
|
||||
shiny tan bags contain 5 dark lavender bags, 1 dull red bag, 4 vibrant turquoise bags, 5 faded fuchsia bags.
|
||||
dark teal bags contain 2 dotted brown bags, 5 clear salmon bags, 5 wavy coral bags, 3 light fuchsia bags.
|
||||
shiny cyan bags contain 1 mirrored gold bag, 1 mirrored aqua bag, 1 posh magenta bag.
|
||||
pale red bags contain 1 vibrant turquoise bag.
|
||||
drab coral bags contain 2 faded tomato bags, 3 plaid aqua bags.
|
||||
clear white bags contain 1 dull white bag, 5 shiny tan bags, 1 mirrored yellow bag, 1 wavy chartreuse bag.
|
||||
clear crimson bags contain 5 muted white bags, 1 vibrant yellow bag.
|
||||
posh lavender bags contain 2 mirrored aqua bags, 4 faded aqua bags, 2 light red bags.
|
||||
dim violet bags contain 4 dull orange bags, 5 dull turquoise bags, 5 dark purple bags.
|
||||
pale beige bags contain 3 wavy indigo bags, 5 dark plum bags, 2 dark purple bags, 2 dim turquoise bags.
|
||||
striped brown bags contain 4 bright lime bags, 5 wavy coral bags.
|
||||
shiny blue bags contain 2 wavy coral bags, 2 dotted plum bags.
|
||||
pale black bags contain 5 clear maroon bags, 4 striped crimson bags, 4 dark gold bags.
|
||||
drab plum bags contain 3 clear gold bags.
|
||||
posh beige bags contain 3 faded silver bags, 3 dim gold bags, 5 shiny gold bags.
|
||||
clear lavender bags contain 1 clear white bag.
|
||||
light lavender bags contain 4 dotted violet bags, 3 dull violet bags, 4 dark maroon bags, 2 striped violet bags.
|
||||
plaid brown bags contain 4 dotted yellow bags.
|
||||
dotted green bags contain 3 dull red bags, 2 faded green bags, 3 muted white bags, 1 dim turquoise bag.
|
||||
muted olive bags contain 4 vibrant tan bags, 3 dotted black bags.
|
||||
light turquoise bags contain 3 wavy blue bags, 4 dim plum bags, 4 dim chartreuse bags.
|
||||
dim salmon bags contain 2 mirrored yellow bags.
|
||||
shiny white bags contain 1 mirrored violet bag.
|
||||
drab olive bags contain 3 striped crimson bags, 3 dotted maroon bags.
|
||||
drab silver bags contain 5 shiny cyan bags, 1 dull teal bag, 4 dark lime bags.
|
||||
vibrant turquoise bags contain 4 striped crimson bags, 5 dark plum bags, 3 dark lavender bags, 5 dark purple bags.
|
||||
shiny purple bags contain 1 posh beige bag, 1 dark indigo bag, 4 plaid fuchsia bags, 5 dotted green bags.
|
||||
bright brown bags contain 1 striped lavender bag, 5 light gold bags, 1 dim maroon bag.
|
||||
dotted violet bags contain 3 striped blue bags.
|
||||
bright crimson bags contain 2 muted gold bags, 3 vibrant turquoise bags, 3 wavy green bags, 5 dull white bags.
|
||||
striped tan bags contain 2 wavy gray bags, 4 bright gray bags, 1 plaid cyan bag, 1 vibrant magenta bag.
|
||||
dull green bags contain 1 bright brown bag, 5 posh beige bags, 5 mirrored crimson bags, 1 dark silver bag.
|
||||
mirrored lime bags contain 4 muted tomato bags, 5 wavy chartreuse bags, 5 dotted plum bags.
|
||||
striped beige bags contain 2 striped bronze bags, 2 shiny yellow bags, 4 pale gray bags, 2 vibrant tomato bags.
|
||||
vibrant lime bags contain 4 striped crimson bags, 2 pale silver bags, 4 clear purple bags.
|
||||
pale blue bags contain 1 bright cyan bag, 1 shiny fuchsia bag, 5 wavy turquoise bags, 5 dotted silver bags.
|
||||
striped maroon bags contain 1 muted lime bag.
|
||||
faded chartreuse bags contain 2 mirrored white bags.
|
||||
mirrored crimson bags contain 2 dotted gold bags, 5 shiny red bags, 5 wavy red bags.
|
||||
dull beige bags contain 2 posh red bags, 1 vibrant turquoise bag, 5 dark plum bags, 5 clear aqua bags.
|
||||
wavy green bags contain 3 shiny crimson bags.
|
||||
striped salmon bags contain 2 dim plum bags, 2 mirrored indigo bags.
|
||||
faded coral bags contain 3 muted tomato bags, 1 light chartreuse bag.
|
||||
dark blue bags contain 2 shiny violet bags.
|
||||
shiny gold bags contain 1 dull lime bag, 2 pale coral bags, 1 wavy silver bag, 5 muted black bags.
|
||||
clear turquoise bags contain 1 posh magenta bag.
|
||||
dotted salmon bags contain 2 mirrored lime bags, 1 mirrored salmon bag.
|
||||
pale gray bags contain 3 bright blue bags, 5 muted tan bags.
|
||||
shiny teal bags contain 5 pale indigo bags.
|
||||
drab beige bags contain 5 faded indigo bags, 5 vibrant bronze bags, 4 pale lime bags, 3 dark black bags.
|
||||
vibrant white bags contain 5 striped violet bags, 3 bright blue bags, 2 dim gold bags.
|
||||
posh aqua bags contain 5 plaid violet bags, 3 drab chartreuse bags.
|
||||
plaid gray bags contain 5 dotted cyan bags, 2 mirrored silver bags.
|
||||
clear indigo bags contain 1 bright tan bag, 2 dull yellow bags, 5 mirrored lavender bags, 2 mirrored fuchsia bags.
|
||||
mirrored turquoise bags contain 3 faded chartreuse bags, 2 drab turquoise bags.
|
||||
dark chartreuse bags contain 2 mirrored silver bags, 3 vibrant crimson bags, 4 shiny green bags, 1 pale brown bag.
|
||||
pale tomato bags contain 2 light gold bags.
|
||||
mirrored purple bags contain 1 light magenta bag, 3 shiny yellow bags, 4 striped lavender bags.
|
||||
mirrored blue bags contain 3 posh magenta bags, 4 dark lavender bags, 5 striped crimson bags.
|
||||
dull purple bags contain 4 mirrored indigo bags, 2 wavy bronze bags, 4 muted white bags, 4 shiny crimson bags.
|
||||
mirrored teal bags contain 5 dim teal bags, 4 dark lime bags, 4 mirrored yellow bags, 3 mirrored turquoise bags.
|
||||
drab gold bags contain 3 dark maroon bags, 2 plaid beige bags.
|
||||
dotted gold bags contain 2 striped crimson bags, 3 clear red bags.
|
||||
posh fuchsia bags contain 4 dim cyan bags, 4 vibrant turquoise bags, 4 dotted plum bags.
|
||||
dim lime bags contain 4 posh indigo bags.
|
||||
dim tan bags contain 3 pale indigo bags, 1 striped turquoise bag, 4 plaid coral bags.
|
||||
plaid red bags contain 5 wavy gold bags, 1 muted plum bag, 2 vibrant plum bags, 1 dim brown bag.
|
||||
light orange bags contain 4 dotted teal bags, 4 dotted yellow bags.
|
||||
dark green bags contain 1 dull cyan bag.
|
||||
posh coral bags contain 3 shiny green bags, 3 dotted red bags, 1 drab silver bag.
|
||||
striped orange bags contain 3 plaid plum bags.
|
||||
pale purple bags contain 1 vibrant coral bag, 2 shiny olive bags, 1 clear orange bag.
|
||||
bright fuchsia bags contain 3 bright yellow bags.
|
||||
striped red bags contain 2 bright orange bags, 3 mirrored yellow bags, 1 dotted coral bag, 3 clear aqua bags.
|
||||
faded plum bags contain 2 shiny tan bags, 4 dull tan bags.
|
||||
striped gold bags contain 1 shiny crimson bag.
|
||||
faded olive bags contain 2 shiny lavender bags, 5 posh fuchsia bags, 3 pale gray bags.
|
||||
pale aqua bags contain 3 posh beige bags.
|
||||
dotted plum bags contain 4 clear red bags.
|
||||
dotted chartreuse bags contain 1 light white bag, 5 drab turquoise bags.
|
||||
striped tomato bags contain 4 dim plum bags, 1 striped black bag, 4 drab black bags.
|
||||
shiny lime bags contain 3 drab coral bags, 1 drab green bag, 4 muted salmon bags.
|
||||
dim orange bags contain 2 striped chartreuse bags.
|
||||
plaid tan bags contain 5 light chartreuse bags, 1 dotted maroon bag, 2 clear silver bags.
|
||||
dull olive bags contain 3 muted gold bags, 5 dotted gold bags, 4 muted white bags, 1 shiny violet bag.
|
||||
dotted beige bags contain 1 clear tan bag.
|
||||
dotted silver bags contain 2 faded crimson bags.
|
||||
muted black bags contain 3 clear red bags, 3 dotted maroon bags.
|
||||
clear purple bags contain 5 dotted plum bags.
|
||||
striped indigo bags contain 5 mirrored blue bags, 2 striped violet bags, 3 striped yellow bags.
|
||||
faded teal bags contain 2 light black bags, 1 vibrant maroon bag.
|
||||
drab red bags contain 3 dark tan bags, 4 pale red bags, 5 faded salmon bags, 3 dotted tomato bags.
|
||||
muted aqua bags contain 2 striped purple bags, 3 vibrant orange bags, 3 bright cyan bags.
|
||||
mirrored black bags contain 4 muted yellow bags, 5 light fuchsia bags.
|
||||
dark gold bags contain 2 dark indigo bags, 3 muted magenta bags, 3 dull white bags.
|
||||
dotted lime bags contain 4 shiny blue bags, 3 striped fuchsia bags.
|
||||
posh brown bags contain 2 muted beige bags.
|
||||
muted green bags contain 5 bright white bags, 5 dim gold bags.
|
||||
vibrant salmon bags contain 1 pale green bag, 5 light maroon bags, 4 striped violet bags.
|
||||
drab white bags contain 2 drab fuchsia bags, 4 dull beige bags, 2 pale coral bags, 1 shiny tan bag.
|
||||
light lime bags contain 4 dotted salmon bags, 5 dark fuchsia bags, 2 vibrant indigo bags.
|
||||
shiny tomato bags contain 5 wavy green bags, 2 striped blue bags, 3 faded green bags, 3 muted tomato bags.
|
||||
mirrored aqua bags contain 2 dark gold bags, 2 shiny green bags.
|
||||
plaid cyan bags contain 5 shiny brown bags, 2 pale aqua bags, 3 striped turquoise bags, 5 plaid yellow bags.
|
||||
light crimson bags contain 3 bright silver bags, 2 dark lime bags.
|
||||
dull cyan bags contain 3 pale gray bags, 5 light beige bags, 3 striped blue bags.
|
||||
muted plum bags contain 2 muted turquoise bags, 5 wavy lavender bags, 3 striped blue bags, 3 striped gray bags.
|
||||
posh tan bags contain 4 dark brown bags, 1 drab crimson bag.
|
||||
clear yellow bags contain 3 striped purple bags, 4 faded blue bags.
|
||||
wavy fuchsia bags contain 2 light beige bags, 3 faded fuchsia bags.
|
||||
pale gold bags contain 4 faded green bags, 5 clear bronze bags, 5 vibrant aqua bags, 3 muted cyan bags.
|
||||
shiny gray bags contain 3 plaid chartreuse bags.
|
||||
bright indigo bags contain 3 drab fuchsia bags.
|
||||
drab black bags contain 3 shiny brown bags, 3 posh blue bags.
|
||||
dark crimson bags contain 5 faded olive bags, 1 mirrored green bag.
|
||||
vibrant silver bags contain 1 dark black bag, 2 drab tan bags.
|
||||
shiny green bags contain 4 dark plum bags, 4 drab fuchsia bags, 3 dim plum bags, 3 mirrored gold bags.
|
||||
plaid crimson bags contain 1 dim olive bag, 5 bright brown bags, 5 dull lavender bags.
|
||||
dark salmon bags contain 2 light gold bags, 4 shiny blue bags.
|
||||
faded blue bags contain 4 striped crimson bags, 1 muted tomato bag.
|
||||
wavy magenta bags contain 5 wavy purple bags, 3 bright yellow bags, 3 shiny maroon bags, 1 wavy orange bag.
|
||||
striped cyan bags contain 1 dotted plum bag, 1 bright coral bag.
|
||||
faded crimson bags contain 5 pale aqua bags, 3 light blue bags.
|
||||
muted gray bags contain 3 shiny tomato bags.
|
||||
striped aqua bags contain 3 dim crimson bags.
|
||||
wavy salmon bags contain 5 drab bronze bags, 4 light maroon bags.
|
||||
drab fuchsia bags contain 3 faded black bags, 4 shiny crimson bags, 5 shiny tan bags.
|
||||
clear black bags contain 4 dark crimson bags, 5 pale lavender bags.
|
||||
dotted orange bags contain 1 dotted coral bag, 1 shiny gold bag, 3 wavy coral bags.
|
||||
plaid tomato bags contain 4 wavy orange bags.
|
||||
dark white bags contain 3 posh cyan bags.
|
||||
wavy lime bags contain 4 faded silver bags, 3 vibrant gold bags, 3 vibrant coral bags.
|
||||
faded tomato bags contain 1 striped bronze bag, 4 dotted green bags.
|
||||
mirrored salmon bags contain 1 faded crimson bag, 3 muted gold bags, 4 clear aqua bags.
|
||||
drab maroon bags contain 5 clear silver bags, 4 vibrant cyan bags, 5 faded gold bags.
|
||||
dull violet bags contain 4 shiny tomato bags.
|
||||
bright orange bags contain 4 bright tan bags.
|
||||
plaid magenta bags contain 3 light fuchsia bags.
|
||||
shiny turquoise bags contain 5 muted bronze bags, 4 bright lavender bags, 4 dark tan bags.
|
||||
pale fuchsia bags contain 4 dull crimson bags, 3 wavy red bags, 5 dark gold bags.
|
||||
plaid fuchsia bags contain 2 dim cyan bags, 5 bright coral bags.
|
||||
dark indigo bags contain 3 dotted teal bags, 3 striped blue bags.
|
||||
vibrant bronze bags contain 4 mirrored plum bags, 5 faded silver bags.
|
||||
light tomato bags contain 3 posh fuchsia bags, 4 mirrored magenta bags, 1 muted gold bag, 3 dim green bags.
|
||||
shiny silver bags contain 2 dim yellow bags, 1 wavy coral bag.
|
||||
bright bronze bags contain 3 plaid coral bags, 2 wavy coral bags, 2 bright gray bags.
|
||||
plaid turquoise bags contain 3 dim lime bags.
|
||||
plaid teal bags contain 1 vibrant teal bag, 3 dark indigo bags, 4 plaid fuchsia bags.
|
||||
striped purple bags contain 2 striped chartreuse bags, 2 clear chartreuse bags, 4 dark cyan bags, 5 striped salmon bags.
|
||||
pale orange bags contain 5 muted green bags.
|
||||
light green bags contain 2 plaid plum bags.
|
||||
plaid purple bags contain 4 muted lime bags.
|
||||
dark cyan bags contain no other bags.
|
||||
wavy teal bags contain 5 dull black bags, 3 striped teal bags, 4 dotted cyan bags, 5 vibrant olive bags.
|
||||
shiny indigo bags contain 3 dull lavender bags.
|
||||
bright beige bags contain 1 bright bronze bag.
|
||||
light white bags contain no other bags.
|
||||
muted red bags contain 3 light tan bags, 4 clear cyan bags.
|
||||
light coral bags contain 2 dull aqua bags, 1 bright beige bag, 4 wavy maroon bags, 3 posh tan bags.
|
||||
bright violet bags contain 2 drab beige bags, 3 shiny fuchsia bags, 2 shiny cyan bags, 5 light gray bags.
|
||||
striped fuchsia bags contain 1 striped black bag, 4 shiny white bags, 3 dim plum bags.
|
||||
vibrant teal bags contain 1 faded tomato bag, 3 dim gray bags.
|
||||
striped turquoise bags contain 3 wavy silver bags, 3 bright orange bags, 5 plaid coral bags, 1 clear red bag.
|
||||
mirrored fuchsia bags contain 1 dotted green bag, 1 plaid cyan bag.
|
||||
dim green bags contain 1 posh olive bag, 1 dim silver bag.
|
||||
faded orange bags contain 4 drab beige bags, 1 vibrant salmon bag, 2 plaid orange bags.
|
||||
bright tomato bags contain 4 dim aqua bags, 2 posh beige bags, 4 striped purple bags.
|
||||
faded lime bags contain 1 bright tan bag.
|
||||
mirrored indigo bags contain 4 shiny tan bags, 3 faded blue bags.
|
||||
vibrant orange bags contain 3 vibrant olive bags, 2 bright olive bags, 3 wavy violet bags.
|
||||
plaid beige bags contain 2 shiny violet bags, 3 faded violet bags.
|
||||
muted purple bags contain 3 light beige bags, 3 bright tan bags.
|
||||
mirrored orange bags contain 5 plaid lime bags, 4 dotted olive bags.
|
||||
wavy purple bags contain 3 dim chartreuse bags.
|
||||
wavy blue bags contain 5 striped blue bags, 5 posh olive bags.
|
||||
dull black bags contain 3 dotted plum bags.
|
||||
drab bronze bags contain 5 dim olive bags, 3 vibrant gray bags, 3 pale green bags, 1 dull cyan bag.
|
||||
pale coral bags contain 5 dim gold bags, 1 vibrant bronze bag.
|
||||
dull orange bags contain 1 shiny turquoise bag.
|
||||
mirrored gray bags contain 1 mirrored plum bag, 5 dim silver bags.
|
||||
drab cyan bags contain 1 dark fuchsia bag, 1 striped salmon bag, 4 plaid beige bags, 5 dim olive bags.
|
||||
dark bronze bags contain 2 pale salmon bags, 5 dull magenta bags, 5 clear indigo bags, 3 wavy plum bags.
|
||||
dim tomato bags contain 5 striped lavender bags.
|
||||
faded white bags contain 3 striped lime bags, 4 dotted orange bags.
|
||||
dull teal bags contain 4 vibrant yellow bags.
|
||||
clear teal bags contain 4 wavy gold bags.
|
||||
muted tan bags contain 3 faded green bags.
|
||||
dim gold bags contain no other bags.
|
||||
dim turquoise bags contain 3 mirrored plum bags, 3 bright orange bags, 1 muted tan bag.
|
||||
striped silver bags contain 4 dull lime bags, 5 striped blue bags.
|
||||
striped yellow bags contain 2 vibrant crimson bags.
|
||||
striped violet bags contain 1 clear beige bag, 2 dim indigo bags, 3 muted lime bags.
|
||||
posh cyan bags contain 4 faded blue bags, 2 vibrant magenta bags, 3 dull lime bags, 3 shiny blue bags.
|
||||
vibrant brown bags contain 5 shiny violet bags.
|
||||
pale chartreuse bags contain 1 wavy teal bag, 1 muted maroon bag, 5 clear turquoise bags.
|
||||
vibrant indigo bags contain 5 drab teal bags, 1 bright aqua bag.
|
||||
bright green bags contain 4 drab silver bags, 5 shiny gold bags.
|
||||
dim black bags contain 1 faded violet bag.
|
||||
muted orange bags contain 3 dull yellow bags, 1 vibrant blue bag, 3 plaid tan bags, 2 dotted teal bags.
|
||||
muted crimson bags contain 4 muted silver bags, 5 shiny lavender bags, 3 posh beige bags, 2 shiny purple bags.
|
||||
clear tomato bags contain 4 dotted teal bags, 2 vibrant olive bags, 5 plaid magenta bags, 4 bright chartreuse bags.
|
||||
vibrant fuchsia bags contain 5 dim cyan bags, 4 light white bags, 1 dull orange bag, 5 dark gold bags.
|
||||
muted magenta bags contain no other bags.
|
||||
dim brown bags contain 1 striped red bag, 4 posh fuchsia bags, 3 mirrored gold bags.
|
||||
dim plum bags contain 1 vibrant turquoise bag, 1 clear chartreuse bag, 3 faded brown bags.
|
||||
plaid gold bags contain 5 drab tomato bags.
|
||||
wavy tomato bags contain 3 dark gold bags, 1 light orange bag, 4 muted salmon bags, 2 muted olive bags.
|
||||
pale olive bags contain 2 plaid cyan bags.
|
||||
wavy plum bags contain 4 faded aqua bags, 5 dull olive bags, 3 bright lavender bags, 2 drab chartreuse bags.
|
||||
posh tomato bags contain 5 drab blue bags.
|
||||
dull gray bags contain 5 dull olive bags, 3 mirrored coral bags, 4 striped lavender bags.
|
||||
posh plum bags contain 5 dull cyan bags, 2 dotted orange bags, 3 plaid indigo bags, 5 light beige bags.
|
||||
striped plum bags contain 2 drab white bags, 2 mirrored yellow bags, 3 dim crimson bags, 2 pale salmon bags.
|
||||
light beige bags contain 3 dark cyan bags, 3 striped crimson bags.
|
||||
dark maroon bags contain 5 light tan bags, 5 faded green bags, 3 striped gold bags, 4 bright aqua bags.
|
||||
faded brown bags contain 5 dotted gold bags, 3 striped turquoise bags, 4 bright tan bags, 3 clear chartreuse bags.
|
||||
striped lime bags contain 4 dim gold bags, 5 pale coral bags, 4 mirrored plum bags.
|
||||
light olive bags contain 1 shiny white bag, 3 dotted plum bags, 3 clear orange bags, 3 posh turquoise bags.
|
||||
light magenta bags contain 2 shiny turquoise bags.
|
||||
dotted turquoise bags contain 5 posh olive bags.
|
||||
dark violet bags contain 1 faded blue bag, 1 shiny green bag.
|
||||
shiny plum bags contain 2 dotted blue bags, 1 clear gold bag.
|
||||
striped bronze bags contain 5 dim chartreuse bags, 1 shiny violet bag.
|
||||
vibrant lavender bags contain 1 faded fuchsia bag, 2 shiny blue bags, 2 dotted plum bags.
|
||||
dotted crimson bags contain 2 dark cyan bags, 1 dim chartreuse bag, 4 light red bags.
|
||||
posh blue bags contain 2 bright silver bags, 4 drab beige bags, 2 dim salmon bags.
|
||||
plaid orange bags contain 3 dark lime bags.
|
||||
wavy gold bags contain 1 drab olive bag, 1 shiny cyan bag, 3 drab brown bags.
|
||||
muted lime bags contain 2 dull teal bags.
|
||||
vibrant magenta bags contain 3 muted gray bags.
|
||||
posh silver bags contain 4 bright lavender bags, 5 light gold bags, 2 posh beige bags, 2 dull crimson bags.
|
||||
shiny bronze bags contain 5 pale lavender bags, 3 plaid bronze bags, 3 mirrored blue bags, 4 bright olive bags.
|
||||
dotted tomato bags contain 2 drab yellow bags.
|
||||
posh violet bags contain 4 muted fuchsia bags, 1 dark blue bag, 1 shiny indigo bag.
|
||||
wavy turquoise bags contain 5 shiny yellow bags.
|
||||
plaid lavender bags contain 3 dim lavender bags, 3 dotted salmon bags.
|
||||
striped teal bags contain 5 mirrored crimson bags, 1 mirrored violet bag, 1 dark violet bag, 5 dotted yellow bags.
|
||||
faded black bags contain 5 posh red bags.
|
||||
faded tan bags contain 1 mirrored violet bag, 4 dark lime bags, 4 dim green bags, 4 muted green bags.
|
||||
clear brown bags contain 3 pale coral bags, 1 plaid coral bag, 4 pale gray bags.
|
||||
light violet bags contain 5 dim plum bags, 4 muted violet bags, 3 drab teal bags.
|
||||
dotted gray bags contain 4 mirrored white bags, 3 vibrant lavender bags, 4 dark lime bags, 5 vibrant coral bags.
|
||||
faded yellow bags contain 2 plaid bronze bags, 1 dark purple bag, 5 shiny crimson bags, 3 shiny tan bags.
|
||||
shiny violet bags contain 4 dull lime bags, 4 muted white bags, 2 dark cyan bags.
|
||||
faded gold bags contain 5 plaid aqua bags.
|
||||
bright salmon bags contain 2 shiny lavender bags, 5 plaid red bags.
|
||||
clear violet bags contain 4 posh turquoise bags.
|
||||
light silver bags contain 1 light salmon bag, 2 clear aqua bags, 4 mirrored plum bags, 2 striped silver bags.
|
||||
pale cyan bags contain 4 vibrant orange bags, 3 light salmon bags, 4 striped cyan bags, 4 wavy gray bags.
|
||||
wavy cyan bags contain 3 light orange bags, 1 bright yellow bag, 2 pale fuchsia bags.
|
||||
clear maroon bags contain 1 dotted coral bag, 4 plaid yellow bags.
|
||||
striped blue bags contain 5 light white bags, 2 dull lime bags, 1 shiny maroon bag.
|
||||
clear red bags contain no other bags.
|
||||
pale tan bags contain 5 light gold bags, 5 dark brown bags, 1 wavy black bag, 5 drab blue bags.
|
||||
mirrored magenta bags contain 4 dotted plum bags, 3 posh beige bags.
|
||||
dull maroon bags contain 1 mirrored fuchsia bag.
|
||||
dim silver bags contain 5 striped crimson bags, 1 light beige bag.
|
||||
plaid olive bags contain 3 shiny white bags, 2 bright lavender bags.
|
||||
shiny magenta bags contain 3 dotted gray bags, 1 shiny blue bag, 3 faded silver bags, 2 dark tomato bags.
|
||||
mirrored green bags contain 4 dim cyan bags, 2 bright tan bags.
|
||||
faded silver bags contain 1 dark plum bag, 5 dotted plum bags, 1 dark cyan bag, 5 dull red bags.
|
||||
vibrant cyan bags contain 5 vibrant lavender bags.
|
||||
shiny brown bags contain 4 striped blue bags, 1 light beige bag, 1 muted tan bag, 5 bright orange bags.
|
||||
wavy maroon bags contain 3 vibrant white bags, 1 pale red bag, 5 striped yellow bags, 4 plaid bronze bags.
|
||||
shiny aqua bags contain 5 dotted salmon bags, 5 bright maroon bags, 1 wavy red bag.
|
||||
clear cyan bags contain 2 striped red bags, 5 plaid coral bags, 2 dark fuchsia bags.
|
||||
dotted red bags contain 5 dim orange bags, 4 striped tan bags.
|
||||
vibrant green bags contain 1 dark plum bag.
|
||||
striped black bags contain 5 dull white bags.
|
||||
dotted indigo bags contain 2 vibrant orange bags, 5 vibrant lavender bags, 4 shiny bronze bags.
|
||||
dark tan bags contain 1 muted tan bag.
|
||||
dotted yellow bags contain 3 dark cyan bags, 2 shiny maroon bags.
|
||||
dull chartreuse bags contain 4 vibrant red bags, 4 dim salmon bags, 5 drab salmon bags.
|
||||
shiny beige bags contain 3 dotted yellow bags, 2 muted tomato bags, 4 wavy red bags.
|
||||
faded indigo bags contain 4 faded green bags.
|
||||
light chartreuse bags contain 1 mirrored violet bag, 5 striped lavender bags.
|
||||
dark red bags contain 5 dark green bags, 3 clear beige bags, 5 wavy tan bags, 4 striped cyan bags.
|
||||
muted blue bags contain 3 dark beige bags, 2 bright lavender bags, 5 dull teal bags.
|
||||
mirrored olive bags contain 5 dark lavender bags, 1 clear blue bag.
|
||||
pale yellow bags contain 2 dark chartreuse bags, 4 posh silver bags, 2 dim crimson bags, 3 wavy gold bags.
|
||||
dull brown bags contain 1 light aqua bag, 2 pale aqua bags, 1 faded red bag, 1 wavy white bag.
|
||||
clear chartreuse bags contain 2 wavy coral bags.
|
||||
bright white bags contain 4 light fuchsia bags, 5 drab turquoise bags, 5 striped lime bags.
|
||||
light gray bags contain 4 mirrored violet bags, 5 dotted maroon bags, 3 pale lime bags.
|
||||
mirrored cyan bags contain 4 mirrored salmon bags, 2 drab olive bags.
|
||||
dark orange bags contain 3 vibrant lavender bags.
|
||||
drab chartreuse bags contain 2 wavy orange bags.
|
||||
muted white bags contain no other bags.
|
||||
dull red bags contain 1 faded fuchsia bag, 2 dark purple bags, 4 clear red bags.
|
||||
shiny red bags contain 2 bright gray bags, 4 drab blue bags, 2 bright aqua bags.
|
||||
vibrant gold bags contain 3 shiny tan bags, 5 mirrored gold bags.
|
||||
wavy red bags contain 1 dark plum bag, 3 striped blue bags, 4 light white bags, 1 wavy silver bag.
|
||||
mirrored coral bags contain 4 dark indigo bags.
|
||||
mirrored beige bags contain 1 muted white bag.
|
||||
faded bronze bags contain 5 bright aqua bags, 2 dotted chartreuse bags, 2 faded tomato bags.
|
||||
bright plum bags contain 3 drab chartreuse bags.
|
||||
shiny coral bags contain 2 dark yellow bags, 5 dark blue bags, 4 dotted green bags.
|
||||
mirrored yellow bags contain 1 dotted plum bag.
|
||||
faded fuchsia bags contain no other bags.
|
||||
bright magenta bags contain 4 muted orange bags, 3 striped red bags, 5 light bronze bags.
|
||||
drab aqua bags contain 5 dotted indigo bags, 3 dim gray bags.
|
||||
faded violet bags contain 2 shiny gold bags.
|
||||
dull lavender bags contain 1 drab chartreuse bag, 2 shiny plum bags, 4 vibrant tan bags, 5 dark tomato bags.
|
||||
shiny lavender bags contain 2 light fuchsia bags.
|
||||
dotted brown bags contain 5 shiny brown bags, 4 light fuchsia bags, 3 plaid cyan bags.
|
||||
dark olive bags contain 2 wavy red bags, 5 striped lavender bags, 4 vibrant lavender bags, 2 shiny gold bags.
|
||||
dotted black bags contain 1 dark lime bag.
|
||||
faded aqua bags contain 2 dim turquoise bags, 3 muted green bags, 5 clear aqua bags.
|
||||
plaid yellow bags contain 1 striped turquoise bag, 4 striped lime bags.
|
||||
pale bronze bags contain 4 muted tan bags, 5 dotted fuchsia bags.
|
||||
muted coral bags contain 2 striped bronze bags, 1 dark violet bag.
|
||||
dim indigo bags contain 1 shiny red bag.
|
||||
drab gray bags contain 3 posh white bags, 2 plaid indigo bags.
|
||||
pale silver bags contain 1 faded coral bag, 5 shiny lavender bags, 5 wavy lime bags.
|
||||
wavy silver bags contain 1 vibrant bronze bag.
|
||||
wavy crimson bags contain 1 mirrored orange bag.
|
||||
dotted aqua bags contain 4 drab plum bags, 5 faded indigo bags, 3 dark violet bags, 3 pale gray bags.
|
||||
mirrored violet bags contain 5 mirrored white bags.
|
||||
dotted white bags contain 3 muted plum bags, 3 bright bronze bags, 2 dark salmon bags.
|
||||
bright coral bags contain 5 mirrored gray bags.
|
||||
dim aqua bags contain 3 mirrored plum bags, 3 plaid olive bags, 1 light gold bag.
|
||||
drab crimson bags contain 5 faded purple bags.
|
||||
pale crimson bags contain 4 dotted orange bags, 2 faded silver bags.
|
||||
mirrored tan bags contain 3 posh gray bags, 2 dark silver bags, 3 dim tan bags.
|
||||
clear olive bags contain 1 dim yellow bag, 1 bright blue bag, 3 bright tomato bags.
|
||||
dim blue bags contain 3 drab black bags, 1 light blue bag, 5 light orange bags, 5 bright white bags.
|
||||
mirrored chartreuse bags contain 4 drab beige bags, 1 pale indigo bag.
|
||||
dark turquoise bags contain 1 vibrant black bag, 1 light turquoise bag, 5 pale aqua bags.
|
||||
posh yellow bags contain 4 dim teal bags, 2 dark black bags.
|
||||
clear aqua bags contain 2 drab teal bags, 5 light gold bags, 4 dim crimson bags.
|
||||
dotted purple bags contain 4 striped salmon bags.
|
||||
light indigo bags contain 3 faded red bags, 2 shiny crimson bags, 3 wavy green bags, 2 striped coral bags.
|
||||
vibrant yellow bags contain 1 dotted cyan bag, 3 posh silver bags.
|
||||
faded lavender bags contain 5 dull cyan bags.
|
||||
dull magenta bags contain 2 dotted green bags.
|
||||
posh indigo bags contain 1 dull lime bag, 4 striped lavender bags, 1 faded silver bag.
|
||||
light aqua bags contain 3 posh maroon bags, 3 dotted black bags, 4 muted tomato bags, 4 mirrored magenta bags.
|
||||
mirrored maroon bags contain 3 light aqua bags.
|
||||
dim red bags contain 2 muted green bags, 1 vibrant tan bag.
|
||||
wavy yellow bags contain 3 dotted cyan bags.
|
||||
bright aqua bags contain 1 dotted maroon bag, 1 muted white bag, 3 striped turquoise bags.
|
||||
clear fuchsia bags contain 2 mirrored fuchsia bags, 4 bright white bags, 3 mirrored white bags, 1 bright coral bag.
|
||||
dotted olive bags contain 3 pale aqua bags, 4 light gold bags, 5 dim yellow bags.
|
||||
light black bags contain 4 clear tan bags, 5 wavy lime bags, 3 dim fuchsia bags, 3 pale indigo bags.
|
||||
dark purple bags contain 5 dark cyan bags.
|
||||
dim purple bags contain 2 wavy crimson bags, 2 dim chartreuse bags, 3 shiny yellow bags, 1 light black bag.
|
||||
plaid salmon bags contain 1 faded lime bag.
|
||||
dotted cyan bags contain 2 shiny tomato bags, 1 mirrored plum bag.
|
||||
posh maroon bags contain 1 light bronze bag, 4 muted tan bags, 5 vibrant plum bags.
|
||||
dim fuchsia bags contain 3 dim plum bags, 5 dark gray bags.
|
||||
bright tan bags contain 1 shiny maroon bag, 1 light beige bag, 2 faded fuchsia bags.
|
||||
plaid green bags contain 3 wavy cyan bags, 5 dark chartreuse bags, 5 dark blue bags.
|
||||
plaid black bags contain 4 dull olive bags, 4 mirrored white bags, 4 plaid white bags.
|
||||
clear beige bags contain 1 dull tan bag.
|
||||
mirrored tomato bags contain 5 drab tomato bags, 1 plaid bronze bag.
|
||||
dim yellow bags contain 4 dark indigo bags, 4 bright silver bags, 3 muted purple bags.
|
||||
clear tan bags contain 4 light gold bags, 3 bright lavender bags, 2 mirrored fuchsia bags.
|
||||
dim lavender bags contain 3 vibrant aqua bags.
|
||||
striped white bags contain 3 posh tomato bags, 3 dark gold bags, 2 clear olive bags, 1 dotted bronze bag.
|
||||
wavy bronze bags contain 1 plaid lime bag, 4 plaid yellow bags, 1 bright white bag.
|
||||
shiny orange bags contain 3 drab chartreuse bags, 1 shiny gold bag.
|
||||
dim coral bags contain 2 faded silver bags.
|
||||
bright gold bags contain 5 dim aqua bags, 2 drab bronze bags.
|
||||
vibrant black bags contain 4 dotted green bags, 2 light brown bags.
|
||||
bright teal bags contain 1 light gold bag, 2 bright aqua bags.
|
||||
drab brown bags contain 2 wavy blue bags, 5 wavy orange bags.
|
||||
dull yellow bags contain 4 striped green bags, 4 bright lime bags, 2 faded tan bags, 5 dotted green bags.
|
||||
vibrant maroon bags contain 4 mirrored fuchsia bags.
|
||||
vibrant gray bags contain 3 faded turquoise bags, 5 pale black bags, 3 drab aqua bags.
|
||||
pale white bags contain 3 shiny beige bags.
|
||||
dim beige bags contain 1 pale fuchsia bag, 1 muted lime bag, 3 dotted plum bags.
|
||||
drab blue bags contain 4 dim crimson bags, 4 shiny beige bags, 2 bright silver bags.
|
||||
dark black bags contain 5 light beige bags, 5 muted gold bags.
|
||||
plaid bronze bags contain 3 wavy indigo bags.
|
||||
posh salmon bags contain 3 dark salmon bags, 2 posh purple bags, 5 dim yellow bags.
|
||||
mirrored lavender bags contain 4 wavy chartreuse bags, 4 plaid bronze bags.
|
||||
muted brown bags contain 1 drab magenta bag, 2 vibrant plum bags, 4 clear purple bags, 4 dark blue bags.
|
||||
wavy white bags contain 2 striped red bags.
|
||||
dark gray bags contain 5 bright blue bags, 2 light brown bags.
|
||||
mirrored silver bags contain 2 dotted chartreuse bags, 1 dotted fuchsia bag, 4 mirrored lavender bags, 2 mirrored white bags.
|
||||
wavy brown bags contain 5 posh teal bags, 4 drab white bags, 5 shiny chartreuse bags, 4 light maroon bags.
|
||||
posh gray bags contain 1 striped turquoise bag, 4 muted crimson bags, 3 clear yellow bags, 3 striped crimson bags.
|
||||
dull tomato bags contain 5 drab purple bags, 4 faded yellow bags.
|
||||
dotted blue bags contain 2 dull cyan bags, 3 dim plum bags.
|
||||
vibrant tomato bags contain 5 plaid coral bags, 5 pale fuchsia bags.
|
||||
wavy beige bags contain 3 dull magenta bags, 3 dotted beige bags, 3 bright white bags, 2 striped fuchsia bags.
|
||||
plaid lime bags contain 3 light blue bags, 3 drab brown bags, 1 drab teal bag.
|
||||
dim white bags contain 5 wavy coral bags, 5 vibrant bronze bags, 2 dark cyan bags, 2 dark plum bags.
|
||||
bright yellow bags contain 4 pale aqua bags, 2 dim turquoise bags, 4 faded brown bags.
|
||||
plaid maroon bags contain 1 dark teal bag, 4 vibrant white bags, 5 striped coral bags, 4 shiny white bags.
|
||||
pale lavender bags contain 2 shiny violet bags.
|
||||
drab magenta bags contain 5 bright gray bags.
|
||||
clear salmon bags contain 4 wavy purple bags, 1 bright olive bag, 1 clear yellow bag.
|
||||
dark yellow bags contain 1 bright bronze bag, 3 striped plum bags.
|
||||
posh bronze bags contain 1 shiny maroon bag, 4 drab olive bags, 2 mirrored green bags, 5 light silver bags.
|
||||
drab green bags contain 3 dim orange bags, 5 vibrant chartreuse bags.
|
||||
light fuchsia bags contain 2 wavy silver bags, 4 muted white bags, 5 muted black bags, 1 faded green bag.
|
||||
dark plum bags contain 4 bright tan bags, 4 dull lime bags, 2 faded fuchsia bags, 4 shiny maroon bags.
|
||||
light teal bags contain 4 light lavender bags.
|
||||
vibrant tan bags contain 1 vibrant bronze bag.
|
||||
muted teal bags contain 5 wavy green bags, 5 plaid turquoise bags.
|
||||
bright chartreuse bags contain 2 muted gold bags, 5 posh olive bags, 1 vibrant tan bag, 2 faded salmon bags.
|
||||
dotted fuchsia bags contain 3 pale lime bags.
|
||||
pale teal bags contain 5 plaid silver bags, 4 shiny turquoise bags, 3 dim coral bags, 2 vibrant bronze bags.
|
||||
drab orange bags contain 2 shiny silver bags, 2 vibrant indigo bags, 5 mirrored lavender bags, 5 dark yellow bags.
|
||||
clear green bags contain 4 vibrant beige bags, 1 bright crimson bag, 5 muted gray bags.
|
||||
shiny yellow bags contain 4 light fuchsia bags, 2 mirrored plum bags.
|
||||
plaid blue bags contain 4 mirrored blue bags, 1 plaid olive bag.
|
||||
mirrored plum bags contain 2 dull red bags, 3 muted magenta bags.
|
||||
dim bronze bags contain 3 vibrant olive bags.
|
||||
posh green bags contain 3 mirrored blue bags, 4 vibrant yellow bags, 5 bright yellow bags, 2 wavy fuchsia bags.
|
||||
clear blue bags contain 5 mirrored yellow bags.
|
||||
dotted teal bags contain 5 shiny brown bags, 2 faded silver bags, 3 plaid coral bags.
|
||||
muted cyan bags contain 4 clear aqua bags.
|
||||
dark fuchsia bags contain 1 shiny blue bag, 1 dull fuchsia bag, 2 dull lime bags, 5 drab salmon bags.
|
||||
dark silver bags contain 2 dim salmon bags.
|
||||
muted beige bags contain 1 shiny lavender bag, 1 striped chartreuse bag.
|
||||
dull indigo bags contain 1 bright beige bag, 2 dark gold bags, 1 mirrored magenta bag.
|
||||
bright silver bags contain 3 faded violet bags, 4 dim cyan bags, 5 faded indigo bags, 1 clear chartreuse bag.
|
||||
dim olive bags contain 1 mirrored plum bag, 1 clear indigo bag, 2 striped crimson bags.
|
||||
pale magenta bags contain 5 vibrant black bags, 3 muted salmon bags, 1 dotted fuchsia bag.
|
||||
faded turquoise bags contain 2 light lavender bags, 3 clear lavender bags, 3 dull coral bags.
|
||||
posh gold bags contain 5 clear blue bags.
|
||||
muted maroon bags contain 5 dark fuchsia bags, 2 muted red bags, 5 dim salmon bags.
|
||||
muted tomato bags contain 4 striped blue bags, 3 dark plum bags, 5 faded green bags, 4 bright tan bags.
|
||||
dark lime bags contain 2 posh white bags, 4 dull crimson bags, 2 dark cyan bags, 4 mirrored plum bags.
|
||||
posh lime bags contain 1 wavy violet bag, 3 dotted teal bags, 5 shiny cyan bags.
|
||||
light tan bags contain 4 striped turquoise bags, 4 dim white bags, 4 shiny violet bags.
|
||||
dull bronze bags contain 2 drab teal bags, 5 light red bags, 4 muted indigo bags.
|
||||
plaid coral bags contain 5 dark purple bags, 5 striped crimson bags, 4 light beige bags.
|
||||
wavy lavender bags contain 5 muted white bags.
|
||||
drab indigo bags contain 4 dotted green bags, 1 striped silver bag.
|
||||
dull silver bags contain 1 dark yellow bag, 2 light beige bags, 3 striped indigo bags, 4 wavy violet bags.
|
||||
dark aqua bags contain 1 drab violet bag.
|
||||
muted bronze bags contain 4 clear chartreuse bags, 4 drab turquoise bags, 3 pale coral bags.
|
||||
striped coral bags contain 1 shiny red bag, 1 dark purple bag.
|
||||
faded beige bags contain 2 bright fuchsia bags, 2 mirrored turquoise bags.
|
||||
dull plum bags contain 5 dull aqua bags.
|
||||
drab lime bags contain 3 clear aqua bags, 4 shiny cyan bags.
|
||||
pale plum bags contain 5 shiny silver bags, 5 dull coral bags.
|
||||
pale violet bags contain 1 wavy purple bag, 1 light plum bag, 3 striped silver bags, 3 drab teal bags.
|
||||
clear magenta bags contain 2 dark plum bags, 2 striped tan bags, 4 posh plum bags, 4 dark turquoise bags.
|
||||
vibrant plum bags contain 3 dotted teal bags, 5 vibrant gold bags.
|
||||
bright gray bags contain 3 muted white bags, 2 striped crimson bags, 3 mirrored gray bags, 4 wavy silver bags.
|
||||
clear coral bags contain 2 vibrant magenta bags, 2 dim orange bags, 3 dark black bags.
|
||||
vibrant chartreuse bags contain 3 dark lime bags, 1 mirrored turquoise bag, 2 vibrant indigo bags, 1 dull gray bag.
|
||||
faded purple bags contain 2 mirrored indigo bags, 3 dark indigo bags, 2 pale fuchsia bags, 5 muted olive bags.
|
||||
drab violet bags contain 4 muted black bags, 1 clear maroon bag, 1 clear gold bag.
|
||||
dim magenta bags contain 5 wavy tan bags.
|
||||
clear orange bags contain 5 shiny tomato bags, 1 faded fuchsia bag.
|
||||
mirrored white bags contain 5 dim plum bags, 3 mirrored magenta bags.
|
||||
plaid white bags contain 1 pale tomato bag, 2 posh magenta bags, 5 vibrant maroon bags, 5 shiny fuchsia bags.
|
||||
shiny olive bags contain 4 striped salmon bags, 2 mirrored gray bags, 5 plaid beige bags.
|
||||
plaid plum bags contain 3 bright bronze bags.
|
||||
dull salmon bags contain 3 bright white bags, 2 muted cyan bags.
|
||||
pale maroon bags contain 3 muted tan bags, 1 bright gray bag.
|
||||
faded salmon bags contain 1 bright silver bag.
|
||||
striped magenta bags contain 5 dark plum bags, 5 faded bronze bags, 4 striped brown bags.
|
||||
vibrant crimson bags contain 2 muted lime bags, 5 plaid indigo bags.
|
||||
wavy tan bags contain 2 shiny yellow bags, 3 clear beige bags, 2 dotted gold bags.
|
||||
posh teal bags contain 4 striped gold bags, 3 drab salmon bags, 3 shiny plum bags, 2 pale gray bags.
|
||||
dotted coral bags contain 2 wavy chartreuse bags, 3 wavy blue bags.
|
||||
light purple bags contain 1 mirrored lime bag.
|
||||
bright lavender bags contain 5 faded brown bags.
|
||||
muted turquoise bags contain 2 shiny maroon bags, 3 light purple bags, 2 striped tan bags, 4 plaid cyan bags.
|
||||
posh red bags contain 2 striped lavender bags, 1 dark black bag, 5 dark purple bags, 3 drab olive bags.
|
||||
bright black bags contain 3 dark brown bags, 4 clear olive bags, 4 plaid olive bags.
|
||||
mirrored bronze bags contain 1 wavy turquoise bag.
|
||||
vibrant violet bags contain 2 plaid indigo bags, 4 faded orange bags.
|
||||
drab tan bags contain 3 clear crimson bags, 4 mirrored turquoise bags, 2 muted magenta bags.
|
||||
dim gray bags contain 5 striped black bags, 5 muted silver bags, 1 dotted blue bag, 3 posh gray bags.
|
||||
dull tan bags contain 1 clear maroon bag, 4 posh beige bags, 2 striped crimson bags, 5 dim gold bags.
|
||||
vibrant blue bags contain 4 bright beige bags, 5 bright bronze bags, 2 plaid salmon bags.
|
||||
posh crimson bags contain 2 mirrored purple bags, 1 striped silver bag, 2 bright magenta bags, 5 bright blue bags.
|
||||
dotted bronze bags contain 2 wavy crimson bags, 5 muted purple bags, 5 light gold bags.
|
||||
pale brown bags contain 1 drab coral bag, 2 mirrored lavender bags, 4 dark tomato bags, 3 plaid indigo bags.
|
||||
shiny maroon bags contain 5 light beige bags, 3 light white bags.
|
||||
dark tomato bags contain 5 shiny gold bags, 5 clear aqua bags, 2 dotted gold bags.
|
||||
dark beige bags contain 2 bright gray bags, 3 light beige bags, 1 dull lime bag.
|
||||
light red bags contain 5 mirrored magenta bags, 1 mirrored lime bag, 4 dotted teal bags.
|
||||
faded magenta bags contain 1 dim maroon bag, 3 mirrored gray bags, 1 dotted beige bag.
|
||||
drab turquoise bags contain no other bags.
|
||||
shiny salmon bags contain 5 shiny tan bags, 2 posh magenta bags, 4 clear turquoise bags.
|
||||
dark magenta bags contain 1 light fuchsia bag, 3 muted yellow bags, 5 dotted olive bags, 4 dark crimson bags.
|
||||
light gold bags contain 5 clear red bags.
|
||||
faded red bags contain 4 clear beige bags, 3 dim silver bags, 4 posh gray bags.
|
||||
pale salmon bags contain 5 mirrored white bags.
|
||||
striped lavender bags contain 2 striped blue bags.
|
||||
dull fuchsia bags contain 1 bright orange bag.
|
||||
dull turquoise bags contain 1 vibrant tomato bag, 3 clear tan bags, 3 bright teal bags, 1 drab maroon bag.
|
||||
dotted magenta bags contain 5 drab gold bags, 2 muted beige bags.
|
||||
pale indigo bags contain 4 plaid brown bags, 1 plaid cyan bag, 1 mirrored black bag, 5 drab magenta bags.
|
||||
drab yellow bags contain 5 dark turquoise bags, 2 dotted beige bags, 5 clear red bags, 2 muted lavender bags.
|
||||
striped gray bags contain 5 bright orange bags, 5 muted white bags, 2 clear chartreuse bags.
|
||||
dark lavender bags contain 5 dim gold bags, 2 pale coral bags.
|
||||
dull gold bags contain 1 dull beige bag.
|
||||
muted chartreuse bags contain 3 muted bronze bags, 1 faded black bag, 4 bright tan bags.
|
||||
plaid chartreuse bags contain 4 dim indigo bags, 4 mirrored gold bags, 4 dim lime bags.
|
||||
muted salmon bags contain 4 faded brown bags, 1 dotted black bag, 5 muted black bags.
|
||||
bright purple bags contain 5 shiny red bags, 5 vibrant cyan bags, 4 plaid cyan bags, 5 bright silver bags.
|
||||
dim chartreuse bags contain 1 faded indigo bag.
|
||||
drab purple bags contain 4 muted cyan bags, 3 wavy lavender bags, 2 dotted blue bags.
|
82
d07/main.py
Executable file
82
d07/main.py
Executable file
@ -0,0 +1,82 @@
|
||||
#! /usr/bin/env python3
|
||||
import itertools
|
||||
import re
|
||||
from collections import namedtuple
|
||||
|
||||
line_matcher = re.compile(r"(\w+ \w+) bags contain ([\w+ ,]+)+.")
|
||||
child_matcher = re.compile(r"([0-9]+) (\w+ \w+) bag[s]{0,1}")
|
||||
|
||||
|
||||
BagRule = namedtuple("BagRule", ["parent_bag", "bag_counts"])
|
||||
|
||||
|
||||
def parse_line(line):
|
||||
result = line_matcher.match(line)
|
||||
if result is None:
|
||||
# print(f"{line}: No match")
|
||||
return None
|
||||
else:
|
||||
parent_bag = result.group(1)
|
||||
bag_counts = {}
|
||||
# print(result.groups())
|
||||
for bags in result.group(2).split(","):
|
||||
if bags == "no other bags":
|
||||
break
|
||||
child_result = child_matcher.search(bags.strip())
|
||||
# print(bags.strip(), child_result.groups())
|
||||
if child_result is None:
|
||||
print(f"Invalid child bags: {bags}")
|
||||
bag_counts[child_result.group(2)] = int(child_result.group(1))
|
||||
|
||||
return BagRule(parent_bag, bag_counts)
|
||||
|
||||
|
||||
def get_direct_carriers(contained_in, bags):
|
||||
return set(itertools.chain.from_iterable((
|
||||
contained_in.get(bag, [])
|
||||
for bag in bags
|
||||
)))
|
||||
|
||||
|
||||
def part1():
|
||||
contained_in = {}
|
||||
with open("input.txt") as f:
|
||||
for line in f:
|
||||
rule = parse_line(line)
|
||||
for bag in rule.bag_counts.keys():
|
||||
contained_in.setdefault(bag, []).append(rule.parent_bag)
|
||||
|
||||
my_bag = "shiny gold"
|
||||
holding_bags = set()
|
||||
last_level = set((my_bag,))
|
||||
while last_level:
|
||||
last_level = get_direct_carriers(contained_in, last_level)
|
||||
holding_bags |= last_level
|
||||
|
||||
print(f"Holding bags: {len(holding_bags)}")
|
||||
|
||||
|
||||
def count_children(contents, bag):
|
||||
rule = contents.get(bag)
|
||||
if rule is None:
|
||||
return 0
|
||||
return sum(
|
||||
count * (1 + count_children(contents, child_bag))
|
||||
for child_bag, count in rule.bag_counts.items()
|
||||
)
|
||||
|
||||
|
||||
def part2():
|
||||
contents = {}
|
||||
with open("input.txt") as f:
|
||||
for line in f:
|
||||
rule = parse_line(line)
|
||||
contents[rule.parent_bag] = rule
|
||||
|
||||
children = count_children(contents, "shiny gold")
|
||||
print(f"Holds {children} bags")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
part1()
|
||||
part2()
|
596
d08/input.txt
Normal file
596
d08/input.txt
Normal file
@ -0,0 +1,596 @@
|
||||
acc +40
|
||||
jmp +187
|
||||
acc +47
|
||||
acc +20
|
||||
acc -12
|
||||
jmp +225
|
||||
nop +488
|
||||
acc +13
|
||||
nop +462
|
||||
jmp +374
|
||||
acc +15
|
||||
acc +42
|
||||
jmp +116
|
||||
acc +23
|
||||
nop +216
|
||||
acc -15
|
||||
jmp +398
|
||||
jmp +103
|
||||
acc +17
|
||||
acc +7
|
||||
jmp +571
|
||||
jmp +1
|
||||
jmp +217
|
||||
acc +7
|
||||
jmp +1
|
||||
acc +35
|
||||
jmp +257
|
||||
acc +24
|
||||
nop +20
|
||||
jmp +309
|
||||
acc +2
|
||||
acc -15
|
||||
acc -13
|
||||
nop +457
|
||||
jmp +19
|
||||
acc +46
|
||||
acc +45
|
||||
acc +35
|
||||
jmp +295
|
||||
acc -15
|
||||
acc +49
|
||||
acc +22
|
||||
jmp +400
|
||||
jmp +202
|
||||
nop -38
|
||||
jmp +381
|
||||
acc +0
|
||||
jmp +137
|
||||
acc +27
|
||||
jmp +196
|
||||
acc +46
|
||||
acc -15
|
||||
jmp +348
|
||||
jmp +457
|
||||
acc +50
|
||||
acc +8
|
||||
jmp +452
|
||||
acc -14
|
||||
nop +321
|
||||
acc +39
|
||||
jmp +273
|
||||
acc -9
|
||||
jmp +413
|
||||
acc +32
|
||||
jmp +64
|
||||
acc +18
|
||||
jmp +152
|
||||
acc -4
|
||||
acc +9
|
||||
acc +10
|
||||
acc -1
|
||||
jmp +433
|
||||
acc +40
|
||||
jmp -55
|
||||
acc +28
|
||||
nop +279
|
||||
jmp +145
|
||||
acc +24
|
||||
nop +416
|
||||
acc +45
|
||||
jmp +45
|
||||
acc +0
|
||||
acc +49
|
||||
acc -14
|
||||
jmp +44
|
||||
acc +17
|
||||
acc +18
|
||||
nop +224
|
||||
acc +3
|
||||
jmp +261
|
||||
jmp -84
|
||||
acc -11
|
||||
acc +29
|
||||
acc +42
|
||||
jmp -13
|
||||
acc -5
|
||||
jmp +210
|
||||
acc +26
|
||||
acc -19
|
||||
acc -19
|
||||
jmp -82
|
||||
acc +29
|
||||
acc +31
|
||||
acc -4
|
||||
jmp +53
|
||||
acc +46
|
||||
jmp +139
|
||||
acc +45
|
||||
acc +30
|
||||
jmp +1
|
||||
jmp +418
|
||||
jmp +248
|
||||
acc +24
|
||||
acc +15
|
||||
acc +34
|
||||
acc +17
|
||||
jmp +52
|
||||
acc +23
|
||||
acc +18
|
||||
jmp +65
|
||||
jmp +1
|
||||
acc +37
|
||||
acc +25
|
||||
jmp +385
|
||||
jmp +281
|
||||
nop +345
|
||||
jmp -25
|
||||
jmp +149
|
||||
acc +21
|
||||
acc +28
|
||||
acc +15
|
||||
jmp -74
|
||||
jmp +179
|
||||
jmp +287
|
||||
acc +14
|
||||
acc -3
|
||||
acc -7
|
||||
jmp -9
|
||||
acc +17
|
||||
acc -8
|
||||
jmp +344
|
||||
jmp +1
|
||||
acc +36
|
||||
acc -16
|
||||
acc -17
|
||||
jmp -82
|
||||
jmp +1
|
||||
acc +41
|
||||
acc -8
|
||||
acc +27
|
||||
jmp +381
|
||||
acc -10
|
||||
nop -71
|
||||
acc +23
|
||||
nop +377
|
||||
jmp -125
|
||||
jmp +319
|
||||
nop +119
|
||||
nop +309
|
||||
nop +195
|
||||
jmp +307
|
||||
acc +8
|
||||
acc +31
|
||||
jmp +1
|
||||
acc -15
|
||||
jmp +398
|
||||
jmp +265
|
||||
jmp -55
|
||||
nop +143
|
||||
jmp -36
|
||||
acc +38
|
||||
nop -38
|
||||
jmp +298
|
||||
acc -17
|
||||
acc +39
|
||||
acc -13
|
||||
jmp -38
|
||||
acc +23
|
||||
jmp +133
|
||||
acc +23
|
||||
jmp -90
|
||||
acc +14
|
||||
jmp +1
|
||||
jmp +100
|
||||
nop +230
|
||||
jmp +346
|
||||
acc +36
|
||||
jmp +14
|
||||
jmp +126
|
||||
jmp -32
|
||||
jmp -142
|
||||
acc +25
|
||||
jmp +146
|
||||
nop +118
|
||||
acc -3
|
||||
jmp +1
|
||||
acc -8
|
||||
jmp +101
|
||||
nop +277
|
||||
acc +27
|
||||
jmp +328
|
||||
acc -11
|
||||
acc +17
|
||||
nop +135
|
||||
jmp +196
|
||||
acc -9
|
||||
jmp +39
|
||||
nop +110
|
||||
acc +14
|
||||
nop +3
|
||||
jmp +17
|
||||
jmp +220
|
||||
acc +17
|
||||
jmp +5
|
||||
acc +18
|
||||
acc +39
|
||||
acc -12
|
||||
jmp -204
|
||||
jmp +317
|
||||
acc +37
|
||||
jmp +222
|
||||
nop +146
|
||||
nop +248
|
||||
jmp +182
|
||||
acc +48
|
||||
acc -13
|
||||
jmp +174
|
||||
jmp +342
|
||||
nop -189
|
||||
jmp +324
|
||||
acc +35
|
||||
acc +25
|
||||
acc +21
|
||||
jmp -152
|
||||
nop -92
|
||||
acc -3
|
||||
acc -15
|
||||
acc +30
|
||||
jmp -157
|
||||
acc -17
|
||||
acc +37
|
||||
acc +7
|
||||
acc +5
|
||||
jmp -225
|
||||
jmp -177
|
||||
acc +21
|
||||
jmp +244
|
||||
acc +42
|
||||
acc -4
|
||||
jmp -116
|
||||
nop +225
|
||||
nop -63
|
||||
acc +20
|
||||
jmp +195
|
||||
acc +20
|
||||
acc +21
|
||||
jmp +228
|
||||
acc +16
|
||||
acc -8
|
||||
acc +12
|
||||
nop +188
|
||||
jmp +9
|
||||
acc +6
|
||||
acc -13
|
||||
acc +36
|
||||
jmp -86
|
||||
jmp -253
|
||||
nop -60
|
||||
acc +25
|
||||
jmp -174
|
||||
acc +10
|
||||
nop -114
|
||||
jmp -65
|
||||
jmp +1
|
||||
acc +24
|
||||
jmp -150
|
||||
acc +27
|
||||
jmp -47
|
||||
acc +50
|
||||
nop -58
|
||||
acc -17
|
||||
acc -16
|
||||
jmp -170
|
||||
jmp -104
|
||||
jmp -177
|
||||
acc +46
|
||||
jmp +106
|
||||
jmp -206
|
||||
acc +2
|
||||
acc +10
|
||||
acc +17
|
||||
nop -107
|
||||
jmp -126
|
||||
jmp +1
|
||||
acc +50
|
||||
acc -14
|
||||
acc +29
|
||||
jmp -234
|
||||
nop +144
|
||||
acc +43
|
||||
acc +34
|
||||
jmp +221
|
||||
jmp +1
|
||||
nop +97
|
||||
acc +39
|
||||
jmp -60
|
||||
acc +44
|
||||
jmp -240
|
||||
acc +11
|
||||
acc +36
|
||||
jmp -71
|
||||
acc -5
|
||||
jmp +149
|
||||
jmp +54
|
||||
acc +38
|
||||
jmp +44
|
||||
jmp -165
|
||||
acc +14
|
||||
jmp -134
|
||||
acc +3
|
||||
acc +22
|
||||
nop +46
|
||||
acc -12
|
||||
jmp -57
|
||||
acc +49
|
||||
acc +24
|
||||
acc +16
|
||||
jmp +27
|
||||
acc +6
|
||||
nop -5
|
||||
acc +45
|
||||
acc +34
|
||||
jmp -175
|
||||
jmp -76
|
||||
acc +3
|
||||
acc +15
|
||||
acc -19
|
||||
jmp +1
|
||||
nop -226
|
||||
acc -2
|
||||
jmp -55
|
||||
jmp -284
|
||||
acc +2
|
||||
jmp +1
|
||||
jmp +15
|
||||
acc +11
|
||||
acc +12
|
||||
acc -1
|
||||
acc +2
|
||||
jmp +179
|
||||
acc +19
|
||||
acc +17
|
||||
jmp -329
|
||||
jmp -272
|
||||
jmp -104
|
||||
acc +41
|
||||
nop +189
|
||||
acc +47
|
||||
jmp -88
|
||||
acc +4
|
||||
acc +16
|
||||
acc +43
|
||||
acc +25
|
||||
jmp +71
|
||||
acc -2
|
||||
acc +45
|
||||
jmp -173
|
||||
jmp +1
|
||||
acc +44
|
||||
acc +33
|
||||
jmp -53
|
||||
acc +45
|
||||
acc +9
|
||||
acc +0
|
||||
acc +12
|
||||
jmp +178
|
||||
jmp -100
|
||||
acc +14
|
||||
jmp -67
|
||||
acc +42
|
||||
jmp +201
|
||||
acc +30
|
||||
jmp -319
|
||||
nop -4
|
||||
nop -211
|
||||
acc -3
|
||||
nop -165
|
||||
jmp -175
|
||||
acc +12
|
||||
acc -10
|
||||
acc -14
|
||||
jmp -53
|
||||
acc -13
|
||||
nop -143
|
||||
jmp +159
|
||||
acc -5
|
||||
nop +18
|
||||
nop -5
|
||||
acc +13
|
||||
jmp -248
|
||||
jmp +114
|
||||
acc +10
|
||||
nop -396
|
||||
nop -246
|
||||
jmp +16
|
||||
acc -3
|
||||
acc +33
|
||||
nop +174
|
||||
acc +48
|
||||
jmp -289
|
||||
nop +98
|
||||
acc +18
|
||||
acc -17
|
||||
jmp -137
|
||||
jmp +1
|
||||
acc +34
|
||||
acc +36
|
||||
jmp -216
|
||||
acc +11
|
||||
jmp -102
|
||||
acc +10
|
||||
jmp +10
|
||||
acc +26
|
||||
acc +35
|
||||
acc -9
|
||||
jmp -83
|
||||
acc +15
|
||||
nop -397
|
||||
jmp -140
|
||||
nop +111
|
||||
jmp +139
|
||||
jmp -165
|
||||
acc +16
|
||||
jmp -343
|
||||
acc +8
|
||||
acc +35
|
||||
acc -17
|
||||
acc -8
|
||||
jmp +29
|
||||
acc +50
|
||||
nop -256
|
||||
jmp -268
|
||||
jmp +132
|
||||
acc +13
|
||||
acc +38
|
||||
acc -6
|
||||
acc -7
|
||||
jmp -327
|
||||
acc -8
|
||||
jmp -256
|
||||
nop -139
|
||||
acc +30
|
||||
jmp -60
|
||||
acc -1
|
||||
acc +11
|
||||
jmp -216
|
||||
acc -12
|
||||
nop -390
|
||||
acc +17
|
||||
acc +39
|
||||
jmp +101
|
||||
acc +28
|
||||
jmp +1
|
||||
acc -7
|
||||
acc -18
|
||||
jmp -277
|
||||
jmp -90
|
||||
acc -10
|
||||
jmp -326
|
||||
jmp -368
|
||||
nop -396
|
||||
jmp -320
|
||||
acc +42
|
||||
acc +3
|
||||
jmp -430
|
||||
acc +47
|
||||
acc +11
|
||||
acc +19
|
||||
acc +41
|
||||
jmp -354
|
||||
acc +30
|
||||
acc +7
|
||||
nop -106
|
||||
jmp -420
|
||||
acc +22
|
||||
acc -15
|
||||
jmp -296
|
||||
acc -7
|
||||
acc +48
|
||||
jmp -19
|
||||
jmp -148
|
||||
acc +10
|
||||
jmp +1
|
||||
jmp +17
|
||||
nop -273
|
||||
acc +42
|
||||
acc -4
|
||||
nop -130
|
||||
jmp +47
|
||||
nop -436
|
||||
acc -7
|
||||
jmp +1
|
||||
acc +42
|
||||
jmp -330
|
||||
acc +35
|
||||
jmp +56
|
||||
acc -19
|
||||
jmp -440
|
||||
jmp -335
|
||||
jmp -279
|
||||
nop -390
|
||||
jmp +74
|
||||
acc -5
|
||||
jmp -456
|
||||
acc +38
|
||||
acc +3
|
||||
jmp +47
|
||||
acc +50
|
||||
acc +26
|
||||
acc +46
|
||||
acc -7
|
||||
jmp -491
|
||||
acc -4
|
||||
acc -7
|
||||
acc +14
|
||||
nop -105
|
||||
jmp -487
|
||||
jmp -326
|
||||
nop -360
|
||||
jmp -378
|
||||
jmp -285
|
||||
acc +46
|
||||
jmp -190
|
||||
acc +10
|
||||
jmp -346
|
||||
acc +49
|
||||
jmp -492
|
||||
acc -9
|
||||
acc -17
|
||||
jmp -147
|
||||
acc +20
|
||||
jmp -217
|
||||
nop -183
|
||||
acc +35
|
||||
jmp -268
|
||||
nop -51
|
||||
jmp +1
|
||||
jmp -440
|
||||
acc +22
|
||||
acc +24
|
||||
jmp +1
|
||||
acc +26
|
||||
jmp -451
|
||||
acc -14
|
||||
acc +48
|
||||
acc +3
|
||||
jmp -363
|
||||
acc +21
|
||||
acc +24
|
||||
acc +36
|
||||
jmp -418
|
||||
jmp -108
|
||||
jmp -323
|
||||
jmp +20
|
||||
acc +1
|
||||
acc +21
|
||||
nop -212
|
||||
acc -3
|
||||
jmp -338
|
||||
acc +36
|
||||
acc -19
|
||||
jmp -192
|
||||
acc +49
|
||||
jmp -380
|
||||
acc -12
|
||||
acc +14
|
||||
acc +38
|
||||
acc +4
|
||||
jmp -228
|
||||
acc +2
|
||||
jmp -197
|
||||
jmp -41
|
||||
jmp -265
|
||||
jmp -113
|
||||
jmp -459
|
||||
jmp +1
|
||||
acc +38
|
||||
jmp -79
|
||||
acc +16
|
||||
nop -456
|
||||
jmp -129
|
||||
acc +12
|
||||
acc +29
|
||||
nop -575
|
||||
acc -7
|
||||
jmp +1
|
94
d08/main.py
Executable file
94
d08/main.py
Executable file
@ -0,0 +1,94 @@
|
||||
#! /usr/bin/env python3
|
||||
from copy import copy
|
||||
|
||||
sample = [
|
||||
"nop +0",
|
||||
"acc +1",
|
||||
"jmp +4",
|
||||
"acc +3",
|
||||
"jmp -3",
|
||||
"acc -99",
|
||||
"acc +1",
|
||||
"jmp -4",
|
||||
"acc +6",
|
||||
]
|
||||
|
||||
|
||||
def parse_lines(lines):
|
||||
def parse_line(line):
|
||||
inst, _, num = line.partition(" ")
|
||||
return (inst, int(num))
|
||||
|
||||
return [
|
||||
parse_line(line)
|
||||
for line in lines
|
||||
]
|
||||
|
||||
|
||||
def run_line(instructions, index):
|
||||
inst, num = instructions[index]
|
||||
if inst == "nop":
|
||||
return index+1, 0
|
||||
elif inst == "acc":
|
||||
return index+1, num
|
||||
elif inst == "jmp":
|
||||
return index+num, 0
|
||||
|
||||
|
||||
def part1():
|
||||
with open("input.txt") as f:
|
||||
instructions = parse_lines(f)
|
||||
_, acc = run_until_loop(instructions, 0)
|
||||
print("Total accumulated:", acc)
|
||||
|
||||
|
||||
def run_until_loop(instructions, line, seen_lines=None):
|
||||
if seen_lines is None:
|
||||
seen_lines = set()
|
||||
acc = 0
|
||||
while line < len(instructions):
|
||||
seen_lines.add(line)
|
||||
# print(f"Inner: {line}:{instructions[line]}")
|
||||
line, num = run_line(instructions, line)
|
||||
acc += num
|
||||
if line in seen_lines:
|
||||
# print(f"Inner loop, break out")
|
||||
return True, acc
|
||||
return False, acc
|
||||
|
||||
|
||||
def part2():
|
||||
with open("input.txt") as f:
|
||||
instructions = parse_lines(f)
|
||||
|
||||
accum = 0
|
||||
line = 0
|
||||
seen_lines = set()
|
||||
|
||||
while line < len(instructions):
|
||||
if line in seen_lines:
|
||||
print(f"Ugh, looping")
|
||||
return
|
||||
|
||||
# print(f"{line}:{instructions[line]}")
|
||||
inst, num = instructions[line]
|
||||
if inst != "acc":
|
||||
# print(f"Found an alternate, check for loop")
|
||||
# Possible change
|
||||
new_inst = copy(instructions)
|
||||
new_seen = copy(seen_lines)
|
||||
new_inst[line] = ("nop" if inst == "jmp" else "jmp", num)
|
||||
has_loop, acc_d = run_until_loop(new_inst, line, new_seen)
|
||||
if not has_loop:
|
||||
accum += acc_d
|
||||
print(f"Found solution! Changing {line}: Total {accum}")
|
||||
return
|
||||
|
||||
seen_lines.add(line)
|
||||
line, num = run_line(instructions, line)
|
||||
accum += num
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
part1()
|
||||
part2()
|
1000
d09/input.txt
Normal file
1000
d09/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
273
d09/main.go
Normal file
273
d09/main.go
Normal file
@ -0,0 +1,273 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"container/list"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func processLines(path string, f func(string) (stop bool, err error)) error {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
scanner := bufio.NewScanner(file)
|
||||
for scanner.Scan() {
|
||||
stop, err := f(scanner.Text())
|
||||
if stop || err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// LimitedList acts as a list with a fixed size
|
||||
type LimitedList struct {
|
||||
elements *list.List
|
||||
maxLength int
|
||||
}
|
||||
|
||||
// Len returns the current length of the fixed list
|
||||
func (ll *LimitedList) Len() int {
|
||||
return ll.elements.Len()
|
||||
}
|
||||
|
||||
// Full checks if the fixed list is full
|
||||
func (ll *LimitedList) Full() bool {
|
||||
return ll.Len() == ll.maxLength
|
||||
}
|
||||
|
||||
// Front moves the pointer to the front of the list
|
||||
func (ll *LimitedList) Front() *list.Element {
|
||||
return ll.elements.Front()
|
||||
}
|
||||
|
||||
// Push adds an item to the back of the fixed list
|
||||
func (ll *LimitedList) Push(v interface{}) *list.Element {
|
||||
if ll.Full() {
|
||||
_ = ll.elements.Remove(ll.Front())
|
||||
}
|
||||
return ll.elements.PushBack(v)
|
||||
}
|
||||
|
||||
// NewLimitedList initializes a new list limited to the given length
|
||||
func NewLimitedList(size int) *LimitedList {
|
||||
return &LimitedList{
|
||||
list.New(),
|
||||
size,
|
||||
}
|
||||
}
|
||||
|
||||
// Pair of numbers
|
||||
type Pair struct {
|
||||
A, B int
|
||||
}
|
||||
|
||||
func searchPairs(l LimitedList, target int) (Pair, error) {
|
||||
var x, y int
|
||||
for ex := l.Front(); ex != nil; ex = ex.Next() {
|
||||
x = ex.Value.(int)
|
||||
for ey := ex.Next(); ey != nil; ey = ey.Next() {
|
||||
y = ey.Value.(int)
|
||||
if x+y == target {
|
||||
return Pair{x, y}, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Pair{}, fmt.Errorf("could not find pair matching %d in %v", target, l)
|
||||
}
|
||||
|
||||
func searchPairsSlice(numbers []int, target int) (Pair, error) {
|
||||
for i, x := range numbers {
|
||||
for _, y := range numbers[i:] {
|
||||
if x+y == target {
|
||||
return Pair{x, y}, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Pair{}, fmt.Errorf("could not find pair matching %d in %v", target, numbers)
|
||||
}
|
||||
|
||||
func part1Old() int {
|
||||
bufferSize := 25
|
||||
buffer := []int{}
|
||||
result := -1
|
||||
err := processLines("input.txt", func(line string) (stop bool, err error) {
|
||||
v, err := strconv.Atoi(line)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if len(buffer) < bufferSize {
|
||||
buffer = append(buffer, v)
|
||||
} else {
|
||||
// Check number
|
||||
_, err = searchPairsSlice(buffer[len(buffer)-bufferSize:], v)
|
||||
if err != nil {
|
||||
stop = true
|
||||
err = nil
|
||||
result = v
|
||||
return
|
||||
}
|
||||
buffer = append(buffer, v)
|
||||
}
|
||||
return
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if result < 0 {
|
||||
fmt.Println("All valid")
|
||||
} else {
|
||||
fmt.Printf("First non matching is %d\n", result)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func part1() int {
|
||||
ll := NewLimitedList(25)
|
||||
result := -1
|
||||
err := processLines("input.txt", func(line string) (stop bool, err error) {
|
||||
v, err := strconv.Atoi(line)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if !ll.Full() {
|
||||
ll.Push(v)
|
||||
} else {
|
||||
// Check number
|
||||
_, err = searchPairs(*ll, v)
|
||||
if err != nil {
|
||||
stop = true
|
||||
err = nil
|
||||
result = v
|
||||
return
|
||||
}
|
||||
ll.Push(v)
|
||||
}
|
||||
return
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if result < 0 {
|
||||
fmt.Println("All valid")
|
||||
} else {
|
||||
fmt.Printf("First non matching is %d\n", result)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// SumQueue acts as a list with a fixed size
|
||||
type SumQueue struct {
|
||||
elements *list.List
|
||||
sum int
|
||||
}
|
||||
|
||||
// Len returns the current length of the queue
|
||||
func (sq *SumQueue) Len() int {
|
||||
return sq.elements.Len()
|
||||
}
|
||||
|
||||
// Sum returns the sum of the items in the queue
|
||||
func (sq *SumQueue) Sum() int {
|
||||
return sq.sum
|
||||
}
|
||||
|
||||
// Front moves the pointer to the front of the list
|
||||
func (sq *SumQueue) Front() *list.Element {
|
||||
return sq.elements.Front()
|
||||
}
|
||||
|
||||
// Push adds an item to the back of the queue
|
||||
func (sq *SumQueue) Push(v int) *list.Element {
|
||||
sq.sum = sq.sum + v
|
||||
return sq.elements.PushBack(v)
|
||||
}
|
||||
|
||||
// Pop removes an item from the queue
|
||||
func (sq *SumQueue) Pop() int {
|
||||
v := sq.elements.Remove(sq.Front()).(int)
|
||||
sq.sum = sq.sum - v
|
||||
return v
|
||||
}
|
||||
|
||||
// NewSumQueue creates a new SumQueue
|
||||
func NewSumQueue() *SumQueue {
|
||||
return &SumQueue{
|
||||
list.New(),
|
||||
0,
|
||||
}
|
||||
}
|
||||
|
||||
func part2(target int) {
|
||||
sq := NewSumQueue()
|
||||
found := false
|
||||
err := processLines("input.txt", func(line string) (stop bool, err error) {
|
||||
v, err := strconv.Atoi(line)
|
||||
// fmt.Println(v, sq.Len())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if v == target {
|
||||
return
|
||||
}
|
||||
sq.Push(v)
|
||||
if sq.Sum() == target {
|
||||
// Found it!
|
||||
stop = true
|
||||
found = true
|
||||
return
|
||||
}
|
||||
for sq.Sum() > target && sq.Sum() > 0 {
|
||||
// While too big, pop from the front
|
||||
_ = sq.Pop()
|
||||
}
|
||||
if sq.Sum() == target {
|
||||
// Found it!
|
||||
stop = true
|
||||
found = true
|
||||
return
|
||||
}
|
||||
return
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if found {
|
||||
min := -1
|
||||
max := -1
|
||||
for e := sq.Front(); e != nil; e = e.Next() {
|
||||
if min < 0 || e.Value.(int) < min {
|
||||
min = e.Value.(int)
|
||||
}
|
||||
if e.Value.(int) > max {
|
||||
max = e.Value.(int)
|
||||
}
|
||||
}
|
||||
fmt.Printf("Found %d numbers matching min %d max %d sum %d", sq.Len(), min, max, min+max)
|
||||
} else {
|
||||
fmt.Println("Didn't find anything")
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
result := part1()
|
||||
part2(result)
|
||||
}
|
20
d09/testinput.txt
Normal file
20
d09/testinput.txt
Normal file
@ -0,0 +1,20 @@
|
||||
35
|
||||
20
|
||||
15
|
||||
25
|
||||
47
|
||||
40
|
||||
62
|
||||
55
|
||||
65
|
||||
95
|
||||
102
|
||||
117
|
||||
150
|
||||
182
|
||||
127
|
||||
219
|
||||
299
|
||||
277
|
||||
309
|
||||
576
|
94
d10/input.txt
Normal file
94
d10/input.txt
Normal file
@ -0,0 +1,94 @@
|
||||
38
|
||||
23
|
||||
31
|
||||
16
|
||||
141
|
||||
2
|
||||
124
|
||||
25
|
||||
37
|
||||
147
|
||||
86
|
||||
150
|
||||
99
|
||||
75
|
||||
81
|
||||
121
|
||||
93
|
||||
120
|
||||
96
|
||||
55
|
||||
48
|
||||
58
|
||||
108
|
||||
22
|
||||
132
|
||||
62
|
||||
107
|
||||
54
|
||||
69
|
||||
51
|
||||
7
|
||||
134
|
||||
143
|
||||
122
|
||||
28
|
||||
60
|
||||
123
|
||||
82
|
||||
95
|
||||
14
|
||||
6
|
||||
106
|
||||
41
|
||||
131
|
||||
109
|
||||
90
|
||||
112
|
||||
1
|
||||
103
|
||||
44
|
||||
127
|
||||
9
|
||||
83
|
||||
59
|
||||
117
|
||||
8
|
||||
140
|
||||
151
|
||||
89
|
||||
35
|
||||
148
|
||||
76
|
||||
100
|
||||
114
|
||||
130
|
||||
19
|
||||
72
|
||||
36
|
||||
133
|
||||
12
|
||||
34
|
||||
46
|
||||
15
|
||||
45
|
||||
87
|
||||
144
|
||||
80
|
||||
13
|
||||
142
|
||||
149
|
||||
88
|
||||
94
|
||||
61
|
||||
154
|
||||
24
|
||||
66
|
||||
113
|
||||
5
|
||||
73
|
||||
79
|
||||
74
|
||||
65
|
||||
137
|
||||
47
|
217
d10/main.go
Normal file
217
d10/main.go
Normal file
@ -0,0 +1,217 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"log"
|
||||
"math"
|
||||
"os"
|
||||
"sort"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func processLines(path string, f func(string) (stop bool, err error)) error {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
scanner := bufio.NewScanner(file)
|
||||
for scanner.Scan() {
|
||||
stop, err := f(scanner.Text())
|
||||
if stop || err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func part1() {
|
||||
values := []int{}
|
||||
if err := processLines("input.txt", func(line string) (bool, error) {
|
||||
v, err := strconv.Atoi(line)
|
||||
values = append(values, v)
|
||||
return false, err
|
||||
}); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
sort.Ints(values)
|
||||
|
||||
lastVal := 0
|
||||
ones := 0
|
||||
threes := 0
|
||||
for _, v := range values {
|
||||
diff := v - lastVal
|
||||
switch diff {
|
||||
case 1:
|
||||
ones++
|
||||
case 2:
|
||||
case 3:
|
||||
threes++
|
||||
default:
|
||||
log.Fatalf("unsupported distance: %d-%d=%d", v, lastVal, diff)
|
||||
return
|
||||
}
|
||||
lastVal = v
|
||||
}
|
||||
// Final devices is a 3 jolt diff
|
||||
threes++
|
||||
|
||||
fmt.Printf("Total ones %d total threes %d. Product %d\n", ones, threes, ones*threes)
|
||||
}
|
||||
|
||||
var memoized = map[int][][]int{}
|
||||
|
||||
func searchSlice(s []int, start int) [][]int {
|
||||
// Check for memoized results
|
||||
if memResults, ok := memoized[start]; ok {
|
||||
fmt.Printf("Cached value for index %d", start)
|
||||
return memResults
|
||||
}
|
||||
// Check for a memoized result
|
||||
// If at the end, return an empty array
|
||||
lastVal := s[start]
|
||||
if start == len(s)-1 {
|
||||
// fmt.Println("At end! Yay!")
|
||||
return [][]int{[]int{lastVal}}
|
||||
}
|
||||
fmt.Printf("Checking index %d value %d\n", start, lastVal)
|
||||
results := [][]int{}
|
||||
for i := 1; i <= 3 && start+i < len(s); i++ {
|
||||
v := s[start+i]
|
||||
if v-lastVal > 3 {
|
||||
// Not valid, skip this
|
||||
continue
|
||||
}
|
||||
subResults := searchSlice(s, start+i)
|
||||
for _, subResult := range subResults {
|
||||
subResult = append([]int{lastVal}, subResult...)
|
||||
results = append(results, subResult)
|
||||
}
|
||||
}
|
||||
// memoize the results
|
||||
memoized[start] = results
|
||||
return results
|
||||
}
|
||||
|
||||
var memoizedC = map[int]int{}
|
||||
|
||||
func searchSliceC(s *[]int, start int) int {
|
||||
// Check for memoized results
|
||||
if memResultsC, ok := memoizedC[start]; ok {
|
||||
// fmt.Printf("Cached value for index %d", start)
|
||||
return memResultsC
|
||||
}
|
||||
// Check for a memoized result
|
||||
// If at the end, return an empty array
|
||||
lastVal := (*s)[start]
|
||||
if start == len(*s)-1 {
|
||||
// fmt.Println("At end! Yay!")
|
||||
return 1
|
||||
}
|
||||
fmt.Printf("Checking index %d value %d\n", start, lastVal)
|
||||
results := 0
|
||||
for i := 1; i <= 3 && start+i < len(*s); i++ {
|
||||
v := (*s)[start+i]
|
||||
if v-lastVal > 3 {
|
||||
// Not valid, skip this
|
||||
continue
|
||||
}
|
||||
results += searchSliceC(s, start+i)
|
||||
|
||||
}
|
||||
// memoize the results
|
||||
memoizedC[start] = results
|
||||
return results
|
||||
}
|
||||
|
||||
func part2() {
|
||||
values := []int{}
|
||||
if err := processLines("input.txt", func(line string) (bool, error) {
|
||||
v, err := strconv.Atoi(line)
|
||||
values = append(values, v)
|
||||
return false, err
|
||||
}); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
values = append([]int{0}, values...)
|
||||
sort.Ints(values)
|
||||
deviceJolts := values[len(values)-1] + 3
|
||||
values = append(values, deviceJolts)
|
||||
fmt.Println("Total values", len(values))
|
||||
|
||||
/*
|
||||
* paths := []int{}
|
||||
* i := 0
|
||||
* for i < len(values) {
|
||||
* // look ahead
|
||||
* for l := 3; l > 1; l-- {
|
||||
* if i+l < len(values) && values[i+l]-values[i] <= 3 {
|
||||
* // Look ahead is valid
|
||||
* paths = append([]int{l}, paths...)
|
||||
* // We only want max, so break out if we found it
|
||||
* i = i + l
|
||||
* break
|
||||
* }
|
||||
* }
|
||||
* i++
|
||||
* }
|
||||
* fmt.Println("Paths", paths)
|
||||
* powTotal := 1.0
|
||||
* for _, num := range paths {
|
||||
* if powTotal == 1.0 {
|
||||
* powTotal = float64(num)
|
||||
* } else {
|
||||
* powTotal = math.Pow(float64(powTotal), float64(num))
|
||||
* }
|
||||
* }
|
||||
* fmt.Println("Total pow paths", powTotal)
|
||||
* productTotal := 1
|
||||
* for _, num := range paths {
|
||||
* productTotal = productTotal * num
|
||||
* }
|
||||
* fmt.Println("Total product paths", productTotal)
|
||||
*
|
||||
* totalOptions := 0
|
||||
* i = 0
|
||||
* options := []int{}
|
||||
* for i < len(values) {
|
||||
* // look ahead
|
||||
* for l := 3; l >= 1; l-- {
|
||||
* if i+l < len(values) && values[i+l]-values[i] <= 3 {
|
||||
* // Look ahead is valid
|
||||
* totalOptions++
|
||||
* options = append(options, l)
|
||||
* break
|
||||
* }
|
||||
* }
|
||||
* i++
|
||||
* }
|
||||
* fmt.Println("Options", options)
|
||||
* fmt.Println("Total sum options *2=", totalOptions*2)
|
||||
* totalProdOptions := 1
|
||||
* for _, num := range options {
|
||||
* totalProdOptions = totalProdOptions * num
|
||||
* }
|
||||
* fmt.Println("Total prod options", totalProdOptions)
|
||||
*/
|
||||
|
||||
fmt.Printf("Looking for device jolts %d\n", deviceJolts)
|
||||
countResults := searchSliceC(&values, 0)
|
||||
fmt.Printf("Search found %d results\n", countResults)
|
||||
|
||||
/*
|
||||
* results := searchSlice(values, 0)
|
||||
* fmt.Printf("Search found %d results\n", len(results))
|
||||
*/
|
||||
}
|
||||
|
||||
func main() {
|
||||
part1()
|
||||
part2()
|
||||
}
|
10
d11/input-small.txt
Normal file
10
d11/input-small.txt
Normal file
@ -0,0 +1,10 @@
|
||||
L.LL.LL.LL
|
||||
LLLLLLL.LL
|
||||
L.L.L..L..
|
||||
LLLL.LL.LL
|
||||
L.LL.LL.LL
|
||||
L.LLLLL.LL
|
||||
..L.L.....
|
||||
LLLLLLLLLL
|
||||
L.LLLLLL.L
|
||||
L.LLLLL.LL
|
98
d11/input.txt
Normal file
98
d11/input.txt
Normal file
@ -0,0 +1,98 @@
|
||||
LLLLLL.LLLLLLLLLLLL.LLLLLL.LLLLLLLLLLLL.LLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLLLL
|
||||
LLLLLL.LLLLLLLLLLLL.LLLLLLL.LLLLL.LLLLL.LLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LL
|
||||
LLLLLLLLLLLLL.LLLLLLLLLLLLL.LLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLL.L.LLLLLL.LL.LLLLLL
|
||||
LLLLLLLLLLLLL.LLLLL.LLLLLLLLLLLLLLLLL.LLLLLLLLLL.LLLL.LLLLLLL.LLLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLLLL
|
||||
LLLLL..LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLL.LLLL.LLLLLLL.LLLLL.LL.LLLLLLLLLLLLLL.LL.LLLLLLLLL
|
||||
LLLLLL.LLLLL..LLLLL.LLLLLLL.LLLLL.LLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLLLLLL.L.LLLLL.L
|
||||
LLLLLL.LLLLLL.LLL.L.LLLLLLL.LLLLL.LLLLL.LLLLLLLL.LLLL.LLLLLL..LLLLLLLL.LLLLLLLL.LLLLLLLLLLLLLL.LLL
|
||||
.LLLLLLLLLLLL.LLL.L.LLLLLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLLLLLLL.LLLLLL.L.L.LLLLLLLLLLLLL.L.LLLLLLLLL
|
||||
LLLLLL.LLLLLL.LLLLL.LLLLLLL..LLLLLLLLLL..LLLLLLL.LLLLLLLLLLLL.LLLLLLLL.LLLLLLLL.LLL.LLLL..LLLLLLLL
|
||||
..........LL....L..LL..L.....L...L....L............L.LL...L.......L.L.LL...L.L...L....L.L....LLL..
|
||||
LLLLLL.LLLLLL.LLLLL.LLLLLLL.LLL.L.LLLLL.LLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLL.LL..LLLLLLL.LLLLLLLLLL
|
||||
LLLLLLLLLLLLL.LLLLL.LLLLLLL.LLL.L.LLLLLLLLLLLLLL.LLLL.LLLLLLL.LLLLLLLL.LLLLLLLL.LLLLLLLLLLLLLL.LLL
|
||||
.LLLLL..LL.LL..LLL.LLLLLLLL.LLLLL.LLLLL.LLLLLLLLLLLLL.LLLLLLL.LLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLL
|
||||
L.LLLL.LLL.LLLLLLLL.LLLLLLL.LLLLL.LLLLLLLLLLLLLLLLLLL.LLL.LLL.LLLLLLLL.LLLLLLLL.LLLLLLLLLLLLL.LLLL
|
||||
LLLLLL.LLLLLLLLLLLLLLLLLLLL.L.LLLLLLLLL.LLLLLLLLLLLLLLLLLLLLL.LLLLLL.L.LLLLLLLL.LLLLLLLL.LLLLLLLLL
|
||||
LLLLLL.LLLLLLLLLLLL.LLLLLLLLLLLLL.LLLLL.LLLLLLLL.LLLL.LLLLLLL.LLLLLL.L.LLLLLLLL.LLLLLLLL.LLLLLLLLL
|
||||
...LLLLL.......L.LL..L..LL...LL..L.....L...L...LLL.L.L.....L.L....L.L......LL..L.L.L..LL.L.....LL.
|
||||
LLLLLLLLLLL.L.LLL.LLLLLLLLL.LLLLLLLLLLL.LLLLLLLL.LLLL.LLLLLLLLLLLLLLLL.LLLLLL.L.LL.LLLLLLLLLLLLLLL
|
||||
LLLLLL.LLLLLL.LLLLL.LLLLLLL.LLLLL.LLLLL.LLLLLLLLLLLLL.LLL.LLL.LLLLLLLL.LLLLLLLL..LLLLLLLLLLLLLL.LL
|
||||
LLLLLL.LLLLLLLLLLLL.LLLLLLL.LLLLL.LLLLLLLLLLLLLLLLLLL.LLLLL.L.LLLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLLLL
|
||||
LLLLL..LL.L.LLLLLLL.LLLLLLL.LLLLL.LLLLLLL.LLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLL.L.LLLLLLLL.LLLLLLLLL
|
||||
LLLLLL.LLLLLL.LLLLL.LLLLLLL.LLLLLL.LLLL.LLLLLLLL.LLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.L.LLLLLLLLL
|
||||
L.LLLL.LLLLLL.LLLLL.LLLLLLL.LLLLL.LLLLL.LLLLLLLL.LLLL.LLLL.LL.LLLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLLLL
|
||||
.LLLLL.LLLLLL.LLLLL.LLLLLLL.LLLLL.L.LLL.LLLLLLLL.LLL..LLLLLLL.LL.LLLLL.LLLLLLLLLLLLLLLLL.LLLLLLLLL
|
||||
LLLLLL.LLLLLL.LLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLL.LLLLLLLLLLLLLLLL.L.LLLLLL.LLLLLLLLLLLLLLLLL.
|
||||
L.LL..LLL.L.........L.L....L...LL.L......L..LL.......L.....L.LL.....L..L.L.....L.....L.L...L.L....
|
||||
LLLLLL.LLLLLLLLLLLL.LLLLLLL.LLLLL..LLLL..LLLLLLLLLLLL.LLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLL
|
||||
LLL.L..LLLL.L.LLLLLLLLLLLLL.LLLLL.LLLLL.L.LLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL..LLLLLLLL
|
||||
LLLLLL.LLLLLL.LLLL.LLLLLLLL.LLLLLLLLLLLLLLLLLLLL.LLLL.LLLLLLL..LLLLLLL.LLLLLLLLLLLLLLLLL.LLLLLLLLL
|
||||
LL.LLLLLLLLLLLLLLL..LLLLLLLLLLLL..LLLLLLLLL.LLLLLLLLL.LLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLL.L.LLLLLLLLL
|
||||
LLLLLL..LLLLLLLLLLLLLLLLL.L.LLLLLLLLLLL.LLLLLLLL.LLLL.LLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLLL.LLLLLLLLL
|
||||
..L...L...L..L..LL...L..........L.....L......L....L.L..L.L.L..L.LL....L..L...L...L......L.....L..L
|
||||
LLLLLLLLLLLL..LLLLL.LLLLLLL.LLLLL.LLLLLLLLLLLLLLLLLLL.LL.LLLLLLLLLLLLL.L.LLLLLL.LLLLLLLL.LLLLLLLLL
|
||||
LLLLLLLLLLLLL.LLLLL.LLLLLLL.LLLLL.LLLLL.LLLLLLLL.LLLL.L.LLLLL.LLLLLLLLLLLLLLLLL..LLLLLLL.LLLLLLLLL
|
||||
LLLLLLLLLLLLL.LLLLLLLL.LLLL.LLLLL.LLLLLLLLLLLLLL.LLLL.LLLLLLLLL.LLLLLL.LLLLLL.LLLLLLLLLL.LLLLLLLLL
|
||||
LLLLLLLLLLLLL.LLLLL.LLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLL.LLL.LLLL.LLLLLLLL.LLLLL.LLLLLLLLLL.L
|
||||
LLLLLLLLLLLLL.L.LLL.LLLLLLL.LLLLL.LLLLL.LLLL.LLLLLLLL.LLLLLLLLLLLLLLLLLLLLL.LLL.LLLLLLLL.LLLLLLLLL
|
||||
LLLLLL.LLLLLLLLLLLL.LLLLLLL.LLLLL.LLLLL.LLLLLLLLLLLLL.LLLLLLL.LLLLLLLL.LLLLLLLL.LLLLLLL..LLLLLLLLL
|
||||
LLL..L..LLLL.LLL.L......L...LL.L..L.L...L...LL....L.L.L.L................L....L..L...L......LLL.L.
|
||||
LLLLLLLLLLLLL.LLLLLLLLLLLLL.LLLL..LLLLL.LLLLLLLL.LLLL.LLLLLLL.LLLLLLLL..LLLLLLL.LLLLLLLLLLLLLLLLLL
|
||||
LLLLLL.LLLLLL.LLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLLLLLLLLLLLLL.LL.LLLLLLLL.LLLLLL.LLLLLLLLLL.LLLLLLLLL
|
||||
.LLLLL.LLLLLL.LLLLL.LLLLLLLLLLLLL.LLLLLLLLLLLLLL.LLLL.LLLLLLL.LLLLLLLL.LLLLLLLL.LLLLLLLL.LLLL.LLLL
|
||||
LLLLLLLLLLLLL.LLLLLLLLLLLLL.LLLLLLLLLLL.LLLLLLLL.LLLLLLLLLLL..LLLLLLLL.LLLLLLLL.LLLLLLLL.L.LLLLLLL
|
||||
LLLLLLLLLLLLL.LLLLL.LLLLLLL.LLLLLLLLLLLLLLLLLLLL.LLLL.LLLLLLLLLLLLLLLL.LLLLL.LL.LLLLLLLLLLLLLLLLLL
|
||||
LLLLLL.LLLLLL.LLLLL.LLLL.LL.LLLLL.LLLLL.LLLLLLLL..LLL.LLLLL.L.LLLLLLLLLLLLLLLLL.LLL.LLLL.LLLLLLLLL
|
||||
LL.LLL.LLLLLL.LLLLL.LLLLLLLLLLLLL.LL.LLLLLLLLLLL.LLLLLLLLLLLL.LLLLLLLL.LLL.L.LL.LLLLLLLLLLL.LLLLLL
|
||||
LLLLLLLLLLLLL.LLLLL..LLLLLLLLLLLLLLLLLL.L.LLLLLL.LLLL.LLLLLLL.LLLLLLLLL.LLLLLLLLLLLLLLLL.LLLLLLLLL
|
||||
.LLLLL..L.L.L...L...L..LL.L.L.LL.L...L.L.L...................LL..L...L......L..L.........L.....LL.
|
||||
LLLL.LLLLLLLL.LLLLL.LLLLLLL.LLLLLL.LLLLLLLLLLLLL.LLLL.L.LLLLL.LLLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLLLL
|
||||
LLLLLL.LLLLLL.LLLLLL.L.LLLL.LLLLL.LLLLLLLLLLLLLL.LLLL.LLLLLLLLLLLLLLLL.LLLLLLLL.LLLL.LLL.LL..LLLL.
|
||||
.LLLLL.LLLLLLLLLLLL.LLLL.LLLLLLLL.LLLLLLLLLLLLLL.L.LLLL.LLLLLLLLLLLLLL.LLLLLLL..LLLLLLLL.LLLLLLLLL
|
||||
LLLLLL.LLLLLL.LLLLL.LLLLLLL.LLLL...LLLLL.LLLLLLL.LLLL.LLLLLL..LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
|
||||
LLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLL.LLL.LLLLLLLLL.LLLLLLL.LLLLLLLL..L.LLLLL.LLLLLLLL.LLLLLLLLL
|
||||
LLLLLLLLLLLLL.LLLLLLLLLLLLL.LLLLLLLLLLL.LLLLLLLLLLLLL.LLLLLLL.LLLLLLLL.LLLLLLLL.LL.LLLLLLLLLLLLLL.
|
||||
LLL.LL.LLLLLL.LLLLL.LLLLLLL.LLLLLLLLLLL.LLLLLLLL.LLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLL
|
||||
LLLLLL.LLLLLL.LLLLLLLLLLLLL.LLLLLLLL.LLLLLLLL.LL.LLLL.LLLLLLL.LLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLL
|
||||
LLLLLL.LLL..L.LLLLL.LLLLLLLLLLLLLLLLL.L.LLLLLLLLLLLLL.LLLLLLL.LLLLLLLL.LLLLLLLL.LLLLLLLL.LLLLLLLLL
|
||||
L.LL.L.L...L.LL.L.LLL...L.......LLL.L.LL..LLLL.L.L...L..LL.L..LL..L.L..LLLL.L.L..L.L....L....L...L
|
||||
LLLLLL.LLLLLLLLLLLL.LLLLLLL.LLLLL.LLLLL.LLLLLLLL.LLLL.LLLLLLL.LLLLLLLLLLLLLLLLL.LLL.LLLL.L.LLLLLLL
|
||||
LLLLLL.LLLLLLLLLLLLLLLLLLLL.LLLLL.LLLLLLLLLLLLLLLL.LL.LLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLL.LLLLLLLLL
|
||||
LLLLLL.L.LLLL.LLLLL.LLL.LLL.LLLLLLLLLLLLL.LLLLLLLLLLL.LLLLLL..LLLLLLLL.LLLLLLLL.LLLLLLLL.LLLLLLLLL
|
||||
LLLL.LLLLLLLL.LLLLL..LLLLLLLLLLLL.LL.LL.LLLLLLLLLLLLL.LLLLLLL.LLLLLLLL.L.LLLLLL.LLLLLLLLLLLLLLLLLL
|
||||
LLLLLL.LLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLL.LLLLLLLLLLLLL.LLLLLLL.LLLLLLLL.LLLLLLLL..LLLLLLL.LL.LLLLLL
|
||||
LLLLLL.LLLLLLLLLLLL.LLLLLLLLLLLLL.LLLL..LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLL.LLL.LLLLL
|
||||
L.L..L................L..LL.....LL...L............L....LL..LL.LLL.L.............L..L...L.....LLL..
|
||||
LLLLLLLLLLLLLLLL.LL.LLLLLLL.LLLLL.LLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLLLL
|
||||
LLLLLL.LLLLL.LLLLLL.LLLLLLL.LLLLL.LLL.LLLLLLLLLL.LLLL.LLLLLLL.LLLLLLLL.LLLLLLLL.LLLLLLLL.LLLLLLLL.
|
||||
LLLLLL.LLLLLLLLLLLLLL.LLLLL.LLLLL.LL.LL.LLLLLLLL.LLLL.LLLLLLL.LL.LLLLL.LLLLLLLLLLLLLLLLL.LLLLLLLLL
|
||||
LLLL.LL.LLLLL.LLLLL.LLLLLLL.LLLLL.LLLLL.LLLLLLLL.LLLL.LLLLLLL.LLLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLLLL
|
||||
LLLLLL.LLLLL..LLLLL.LLLLLLL.LLLLLLLLLLLLLLLLLLLL.LLLL.LLLLLLL.LLL.LLLL.LLLLLL.L.LLLLLLLL.LLLLLLLLL
|
||||
L.L..L...LL.L.....LL..LL.L.....L.L..L....L..L.L...L.LLLL....L...LL......L..L....LL..L..L........LL
|
||||
LLLLLLLLLLLLLLLLLLL.LLLL.LL.LLLLLLLLLLL.LLLLLLLLLLLLL.LLLLLLLLLLLLLLLL.LLL.LLLL.LLLLLLLL.LLLLL.LLL
|
||||
LLLLLLLLLLLLL.LLLLL.LLLLLLL.LLLLLLLL.LL.LLLLLL.LLLLLL.LLLLLLL.LLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLL
|
||||
LLLLLL.LLLLL.LLLLLL.LLLLLLL.LLLLLLLLLLL..LLLLLLL.L.LL.LLLLLLL.LLLLLLLL.LLLLLLLLLLLLLLLL..LLLLLLLLL
|
||||
LLLLLL.LLLLLLLLLLLL.LLLLLLL.LLLLL.LLLLL.LLLLLLLLLLLLLLLLLLLLL.LLLLLLLL.LLL.LLLL.LLLLLLLL.LLLLLLLLL
|
||||
LLLLLL.LLLLLLLLLLLLLLLLL.LL.LLLLL.LLLLLLLLLLLLLLLL.LLLLLLLLLL.LLLLLLLL.LLLLLLLL.LLLLLLLL.LLLLLLLLL
|
||||
LLLLLL.LLLL.L.LLLLLLLLLLLLL.LLLLLLLLL.L.LLLLLLLL.LLLL.LLLLLLL.LLLLLLLL.LLLLLLL..LLLLLLLL.LLLLLLLLL
|
||||
LLLLL..LLLL.L.LLLLL.LLLLLLLLLLLLL.LLLLL.LLLLLLLL.LLLLLLLLLLLL.LLLLLLLLLLLLLLLL..LLLLLLLL.LLLLLLLLL
|
||||
L.LLLLLLLLLLLLLLLLL.LLLLLLL.LL.LL.LLLLL.LLLLLLLLLLLLL.LL.LLLLLLLLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLLLL
|
||||
LL.L......L......L...L..LLL.....L.L..L.L...L......L..L..L.....L...LL.L.LL.L.LLL....L.LLL....L..L..
|
||||
LLLLLLLLLL.LLLLLLLLLL.LL.LL.LLLLLLLLLLL.L..LLLLL.LLLL.LLLLLLL.LLLLLLLL.LLLLLLLL.LLLLLLLL.LLLLLLLLL
|
||||
LLLLLL.LLLLLL.LLLLL.LLLLLLL.LLLLL.LLLLL.LLLLL.LL..LLL.LLLLLLL.LLLLLLLLL.LLLLLLL.LLLLLLLL.LLLLLLLLL
|
||||
LLLLLL..LL.LL.LLLLL.LLLLLLL.L.LLLLLLLLL.LLLLLLLL.LLLLLLLL.LLL.LLL.LLLL.LLLLLLLLLLLLLLLL..LLLLLLLLL
|
||||
LLLLLLLLLLL.LLLLLLL.LLL.LLLLLLLLL.LLLLL.LLLLLLLL.LLLLLL.LLLLLLLLLLLLLL.LLLLLLLL.LLLLLLLL.LLLLLLLLL
|
||||
LLLLLLLLLLL.L.LLLLL.LLLLLLL.LLLLL.LLLLL.LLLLLLLL.L.LLLLLLLLLLL.LLLLLLL.LLLLLLLL.LLLLLLLL.LLLLLLLLL
|
||||
LLLLLL.LLLLLL..LLLL.LLLLLLLLLLLLLLLL.LL.LLLL.LLL.LLLL.LLLLLLL.LLLLLLLL.LLLLLLLL.LLLLLLLL.LLLLLLLLL
|
||||
LLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLLLLLL.L.L.LLLLLL.LLLLLLLLLLLL.LLLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLLLL
|
||||
LLLLLL.LLLLLLLLLLLL.LLLLLLL.LLLLLLLLLLL.LLLLLLLLLL.LLLLLLLLLLLLLLLLLLL.LL.LLLLLLLLL.LLLLLLL.LLLLLL
|
||||
L..L.LL......LLL....LLLL.......L.L..L..L....LLLLL..LLLLL..L..L.L.L........LLL...LL.L......LLL.....
|
||||
LLLLLL.LLLLLLLLLLLLLLLLLLLL.LLLL..LLLLLLLLLLLLLLLLLLL.LLLLLLLLL.LL.LLL.LLLLLLLL.LLLLLLLL.LLLLLLLLL
|
||||
LLLLLL.LLLLLL.LLLLL.LLLLLLL.LLLLLLLLLLL.LLLLLLLL.LLLLLLLLLLLL.LLLLLLLL.LLLLLLLL.LLLLLLLL.LLLLLLLLL
|
||||
LLLLL.LLLL.LLLLLLLL..LLLLLL.LLLLL.LLLL...LLLLL.L.LLLL.LLLLLLL..LLLLLLLL.LLLLLLLLLLLLLLLL.LLLLLLLLL
|
||||
LLLLLLLLLLLLL.LLLLL.LLLLLLL.LLLLL.LLLLLL.LLLLLLLLLLLL.LLLLLLLLLLLLLLLLLL.LLLLLL.LLLLLLLL.LLLLL.LLL
|
||||
LLLLLLLLLLLLL.LLLLL.L.LLLLL.LLLLLLLLLLL.LLLLLLLLLL.LL.LLLLLLLLLL.LLLLL.LLLLLLLL.LLLLLLLLLLLLL.LLLL
|
||||
LLLLL.LLLLLLLLLLLLL.LLLLLLL.LLLLL.LLLLL.LLLLLLLL.LLLL.LLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLL
|
||||
LLLLLL.LLLLLL.LLLLL.LLLLLLL.LLLLL.LLLLL.LLLLLLLL.LLLL.LLLLLLL.LLLLLLLL.LLLLLLLL.LLLLLLLL.LLLLLLLLL
|
||||
LLLLLL.LLLLLL.LLLLL.LLLLLLL.LLLLL.LLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLLLLL.L.LLLLLL.LLLLLLLLLLLLLLLLL.
|
||||
LLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLL.LLLLLLLL.LLLL.LLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLL
|
463
d11/main.go
Normal file
463
d11/main.go
Normal file
@ -0,0 +1,463 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
)
|
||||
|
||||
func processLines(path string, f func(string) (stop bool, err error)) error {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
scanner := bufio.NewScanner(file)
|
||||
for scanner.Scan() {
|
||||
stop, err := f(scanner.Text())
|
||||
if stop || err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
emptySeatCode = 'L'
|
||||
occupiedSeatCode = '#'
|
||||
floorCode = '.'
|
||||
printMaps = false
|
||||
|
||||
// Variables for controlling part 1 and part 2.
|
||||
maxOccupied = 4
|
||||
lookVisible = false
|
||||
)
|
||||
|
||||
type point struct {
|
||||
x, y int
|
||||
}
|
||||
|
||||
type square struct {
|
||||
seat bool
|
||||
occupied bool
|
||||
loc point
|
||||
left *square
|
||||
right *square
|
||||
up *square
|
||||
down *square
|
||||
|
||||
tock func() error
|
||||
}
|
||||
|
||||
func (s square) isAvailable() bool {
|
||||
return s.seat && !s.occupied
|
||||
}
|
||||
|
||||
func (s square) hasPerson() bool {
|
||||
return s.seat && s.occupied
|
||||
}
|
||||
|
||||
func (s *square) sit() error {
|
||||
if !s.seat {
|
||||
return fmt.Errorf("cannot sit on the floor")
|
||||
}
|
||||
|
||||
if s.occupied {
|
||||
return fmt.Errorf("someone is already sitting here")
|
||||
}
|
||||
|
||||
s.occupied = true
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *square) leave() error {
|
||||
if !s.seat {
|
||||
return fmt.Errorf("cannot leave from the floor")
|
||||
}
|
||||
|
||||
if !s.occupied {
|
||||
return fmt.Errorf("nobody is here to leave")
|
||||
}
|
||||
|
||||
s.occupied = false
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *square) setLeft(l *square) {
|
||||
if l.right != nil {
|
||||
log.Fatalf(
|
||||
"cannot set square above %v to %v because %v already has %v below it",
|
||||
s.loc, l.loc, l.loc, l.right.loc,
|
||||
)
|
||||
}
|
||||
|
||||
s.left = l
|
||||
l.right = s
|
||||
}
|
||||
|
||||
func (s *square) setUp(u *square) {
|
||||
if u.down != nil {
|
||||
log.Fatalf(
|
||||
"cannot set square above %v to %v because %v already has %v below it",
|
||||
s.loc, u.loc, u.loc, u.down.loc,
|
||||
)
|
||||
}
|
||||
|
||||
s.up = u
|
||||
u.down = s
|
||||
}
|
||||
|
||||
func (s *square) leftUp() *square {
|
||||
if s.left != nil {
|
||||
if s.left.up != nil {
|
||||
return s.left.up
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *square) upRight() *square {
|
||||
if s.up != nil {
|
||||
if s.up.right != nil {
|
||||
return s.up.right
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *square) rightDown() *square {
|
||||
if s.right != nil {
|
||||
if s.right.down != nil {
|
||||
return s.right.down
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *square) downLeft() *square {
|
||||
if s.down != nil {
|
||||
if s.down.left != nil {
|
||||
return s.down.left
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *square) lookLeft() *square {
|
||||
n := s.left
|
||||
if n != nil && !n.seat {
|
||||
return n.lookLeft()
|
||||
}
|
||||
|
||||
return n
|
||||
}
|
||||
|
||||
func (s *square) lookRight() *square {
|
||||
n := s.right
|
||||
if n != nil && !n.seat {
|
||||
return n.lookRight()
|
||||
}
|
||||
|
||||
return n
|
||||
}
|
||||
|
||||
func (s *square) lookUp() *square {
|
||||
n := s.up
|
||||
if n != nil && !n.seat {
|
||||
return n.lookUp()
|
||||
}
|
||||
|
||||
return n
|
||||
}
|
||||
|
||||
func (s *square) lookDown() *square {
|
||||
n := s.down
|
||||
if n != nil && !n.seat {
|
||||
return n.lookDown()
|
||||
}
|
||||
|
||||
return n
|
||||
}
|
||||
|
||||
func (s *square) lookLeftUp() *square {
|
||||
n := s.leftUp()
|
||||
if n != nil && !n.seat {
|
||||
return n.lookLeftUp()
|
||||
}
|
||||
|
||||
return n
|
||||
}
|
||||
|
||||
func (s *square) lookUpRight() *square {
|
||||
n := s.upRight()
|
||||
if n != nil && !n.seat {
|
||||
return n.lookUpRight()
|
||||
}
|
||||
|
||||
return n
|
||||
}
|
||||
|
||||
func (s *square) lookRightDown() *square {
|
||||
n := s.rightDown()
|
||||
if n != nil && !n.seat {
|
||||
return n.lookRightDown()
|
||||
}
|
||||
|
||||
return n
|
||||
}
|
||||
|
||||
func (s *square) lookDownLeft() *square {
|
||||
n := s.downLeft()
|
||||
if n != nil && !n.seat {
|
||||
return n.lookDownLeft()
|
||||
}
|
||||
|
||||
return n
|
||||
}
|
||||
|
||||
func appendNonNil(s []*square, e *square) []*square {
|
||||
if e != nil {
|
||||
return append(s, e)
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *square) visibleSeats() []*square {
|
||||
result := []*square{}
|
||||
result = appendNonNil(result, s.lookLeft())
|
||||
result = appendNonNil(result, s.lookRight())
|
||||
result = appendNonNil(result, s.lookUp())
|
||||
result = appendNonNil(result, s.lookDown())
|
||||
result = appendNonNil(result, s.lookLeftUp())
|
||||
result = appendNonNil(result, s.lookUpRight())
|
||||
result = appendNonNil(result, s.lookRightDown())
|
||||
result = appendNonNil(result, s.lookDownLeft())
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func (s *square) adjacentSeats() []*square {
|
||||
result := []*square{}
|
||||
result = appendNonNil(result, s.left)
|
||||
result = appendNonNil(result, s.right)
|
||||
result = appendNonNil(result, s.up)
|
||||
result = appendNonNil(result, s.down)
|
||||
result = appendNonNil(result, s.leftUp())
|
||||
result = appendNonNil(result, s.upRight())
|
||||
result = appendNonNil(result, s.rightDown())
|
||||
result = appendNonNil(result, s.downLeft())
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func (s *square) tick() bool {
|
||||
// Noop tock function
|
||||
s.tock = func() error { return nil }
|
||||
|
||||
if !s.seat {
|
||||
return false
|
||||
}
|
||||
|
||||
var seats []*square
|
||||
|
||||
if lookVisible {
|
||||
seats = s.visibleSeats()
|
||||
} else {
|
||||
seats = s.adjacentSeats()
|
||||
}
|
||||
|
||||
if s.isAvailable() {
|
||||
// Check adjacent seats
|
||||
for _, adj := range seats {
|
||||
if adj.hasPerson() {
|
||||
// If any adjacent seat is occupied, do nothing
|
||||
return false
|
||||
}
|
||||
}
|
||||
// Nothing is occupied? Sit!
|
||||
s.tock = s.sit
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
if s.hasPerson() {
|
||||
numOccupied := 0
|
||||
|
||||
for _, adj := range seats {
|
||||
if adj.hasPerson() {
|
||||
numOccupied++
|
||||
}
|
||||
}
|
||||
|
||||
if numOccupied >= maxOccupied {
|
||||
s.tock = s.leave
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (s square) String() string {
|
||||
// return fmt.Sprintf("%v", s.loc)
|
||||
if !s.seat {
|
||||
return "."
|
||||
}
|
||||
|
||||
if s.occupied {
|
||||
return "#"
|
||||
}
|
||||
|
||||
return "L"
|
||||
}
|
||||
|
||||
func readMap() *[][]*square {
|
||||
worldMap := [][]*square{}
|
||||
rowIndex := 0
|
||||
|
||||
if err := processLines("input.txt", func(line string) (bool, error) {
|
||||
// fmt.Printf("New line! %d\n", rowIndex)
|
||||
row := []*square{}
|
||||
var leftSeat *square
|
||||
for i, c := range line {
|
||||
var s square
|
||||
switch c {
|
||||
case emptySeatCode:
|
||||
s = square{loc: point{i, rowIndex}, seat: true}
|
||||
case occupiedSeatCode:
|
||||
s = square{loc: point{i, rowIndex}, seat: true, occupied: true}
|
||||
case floorCode:
|
||||
s = square{loc: point{i, rowIndex}, seat: false}
|
||||
default:
|
||||
return false, fmt.Errorf("unknown square value %x", c)
|
||||
}
|
||||
// fmt.Printf("%v", s.loc)
|
||||
if leftSeat != nil {
|
||||
s.setLeft(leftSeat)
|
||||
}
|
||||
if rowIndex > 0 {
|
||||
up := worldMap[rowIndex-1][i]
|
||||
// fmt.Printf("\nTry set above %d,%d to %d,%d ", i, rowIndex, up.loc.x, up.loc.y)
|
||||
s.setUp(up)
|
||||
}
|
||||
|
||||
leftSeat = &s
|
||||
row = append(row, &s)
|
||||
}
|
||||
// fmt.Println(row)
|
||||
worldMap = append(worldMap, row)
|
||||
// fmt.Printf("\n")
|
||||
rowIndex++
|
||||
|
||||
return false, nil
|
||||
}); err != nil {
|
||||
log.Fatal("could not parse map", err)
|
||||
}
|
||||
|
||||
return &worldMap
|
||||
}
|
||||
|
||||
func printMap(worldMap *[][]*square) {
|
||||
for _, row := range *worldMap {
|
||||
for _, s := range row {
|
||||
fmt.Print(s.String())
|
||||
}
|
||||
|
||||
fmt.Print("\n")
|
||||
}
|
||||
}
|
||||
|
||||
func tickMap(worldMap *[][]*square) bool {
|
||||
worldChanged := false
|
||||
|
||||
for _, row := range *worldMap {
|
||||
for _, s := range row {
|
||||
worldChanged = s.tick() || worldChanged
|
||||
}
|
||||
}
|
||||
|
||||
return worldChanged
|
||||
}
|
||||
|
||||
func tockMap(worldMap *[][]*square) error {
|
||||
for _, row := range *worldMap {
|
||||
for _, s := range row {
|
||||
err := s.tock()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func countOccupied(worldMap *[][]*square) int {
|
||||
occupied := 0
|
||||
|
||||
for _, row := range *worldMap {
|
||||
for _, s := range row {
|
||||
if s.hasPerson() {
|
||||
occupied++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return occupied
|
||||
}
|
||||
|
||||
func run() {
|
||||
worldMap := readMap()
|
||||
|
||||
if printMaps {
|
||||
fmt.Println("Time 0")
|
||||
printMap(worldMap)
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
t := 1
|
||||
changed := true
|
||||
|
||||
for changed {
|
||||
changed = tickMap(worldMap)
|
||||
|
||||
err = tockMap(worldMap)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if printMaps {
|
||||
fmt.Printf("\nTime %d (%t)\n", t, changed)
|
||||
printMap(worldMap)
|
||||
}
|
||||
t++
|
||||
}
|
||||
fmt.Printf("\nTotal %d occupied seats after %d iterations\n", countOccupied(worldMap), t)
|
||||
}
|
||||
|
||||
func main() {
|
||||
// Part 1
|
||||
run()
|
||||
|
||||
// Part 2
|
||||
maxOccupied = 5
|
||||
lookVisible = true
|
||||
|
||||
run()
|
||||
}
|
779
d12/input.txt
Normal file
779
d12/input.txt
Normal file
@ -0,0 +1,779 @@
|
||||
S3
|
||||
W3
|
||||
F47
|
||||
L90
|
||||
W1
|
||||
F42
|
||||
N1
|
||||
R90
|
||||
F7
|
||||
R90
|
||||
E2
|
||||
S1
|
||||
W2
|
||||
F11
|
||||
E4
|
||||
N1
|
||||
F77
|
||||
W1
|
||||
S3
|
||||
W4
|
||||
F64
|
||||
W3
|
||||
R180
|
||||
N5
|
||||
E1
|
||||
F8
|
||||
N1
|
||||
F54
|
||||
N2
|
||||
L180
|
||||
N1
|
||||
F44
|
||||
E2
|
||||
N2
|
||||
L90
|
||||
W3
|
||||
F5
|
||||
W2
|
||||
L180
|
||||
F100
|
||||
N3
|
||||
E1
|
||||
W4
|
||||
N5
|
||||
F40
|
||||
R180
|
||||
W5
|
||||
R90
|
||||
N1
|
||||
W3
|
||||
R270
|
||||
N1
|
||||
R90
|
||||
S5
|
||||
F10
|
||||
E4
|
||||
N4
|
||||
F56
|
||||
E3
|
||||
N4
|
||||
W4
|
||||
R90
|
||||
N3
|
||||
F24
|
||||
F58
|
||||
R90
|
||||
N2
|
||||
R90
|
||||
W5
|
||||
S2
|
||||
R90
|
||||
W3
|
||||
R90
|
||||
W1
|
||||
N3
|
||||
R90
|
||||
N4
|
||||
E2
|
||||
F25
|
||||
N5
|
||||
N4
|
||||
L90
|
||||
E5
|
||||
N4
|
||||
R90
|
||||
N1
|
||||
R90
|
||||
F73
|
||||
W1
|
||||
S3
|
||||
W4
|
||||
W1
|
||||
F28
|
||||
W3
|
||||
E2
|
||||
S3
|
||||
F28
|
||||
S3
|
||||
R270
|
||||
E1
|
||||
S2
|
||||
W3
|
||||
S3
|
||||
L90
|
||||
F56
|
||||
E5
|
||||
L180
|
||||
R90
|
||||
F48
|
||||
N2
|
||||
F75
|
||||
S2
|
||||
E5
|
||||
F21
|
||||
F57
|
||||
N5
|
||||
L90
|
||||
E4
|
||||
N4
|
||||
F14
|
||||
S3
|
||||
F75
|
||||
W5
|
||||
L90
|
||||
E3
|
||||
R90
|
||||
N1
|
||||
W4
|
||||
F4
|
||||
W5
|
||||
S3
|
||||
E3
|
||||
F68
|
||||
N3
|
||||
R90
|
||||
W4
|
||||
N5
|
||||
S3
|
||||
F4
|
||||
R90
|
||||
F48
|
||||
R90
|
||||
F93
|
||||
R90
|
||||
S3
|
||||
F90
|
||||
R90
|
||||
F41
|
||||
N2
|
||||
S1
|
||||
E5
|
||||
F19
|
||||
E3
|
||||
F71
|
||||
R180
|
||||
F16
|
||||
W3
|
||||
N4
|
||||
W3
|
||||
F12
|
||||
L180
|
||||
L90
|
||||
R180
|
||||
W4
|
||||
R90
|
||||
F26
|
||||
W1
|
||||
E4
|
||||
F65
|
||||
L90
|
||||
F90
|
||||
W5
|
||||
S4
|
||||
W1
|
||||
E3
|
||||
L90
|
||||
W3
|
||||
N2
|
||||
F77
|
||||
W2
|
||||
L90
|
||||
E4
|
||||
S2
|
||||
W5
|
||||
F60
|
||||
R90
|
||||
F45
|
||||
R90
|
||||
S3
|
||||
F56
|
||||
W2
|
||||
S3
|
||||
W5
|
||||
F58
|
||||
L90
|
||||
N1
|
||||
F94
|
||||
S4
|
||||
F17
|
||||
W5
|
||||
R180
|
||||
S2
|
||||
R90
|
||||
N4
|
||||
W1
|
||||
S3
|
||||
R180
|
||||
F93
|
||||
R90
|
||||
F45
|
||||
E4
|
||||
R90
|
||||
S1
|
||||
F81
|
||||
E2
|
||||
L90
|
||||
S1
|
||||
F63
|
||||
E2
|
||||
R90
|
||||
E2
|
||||
N1
|
||||
W1
|
||||
L90
|
||||
F91
|
||||
S5
|
||||
L270
|
||||
E3
|
||||
S1
|
||||
F29
|
||||
N4
|
||||
R180
|
||||
F44
|
||||
L90
|
||||
E3
|
||||
L90
|
||||
F90
|
||||
R90
|
||||
F93
|
||||
N2
|
||||
S2
|
||||
F28
|
||||
E1
|
||||
F58
|
||||
N1
|
||||
F9
|
||||
L90
|
||||
S1
|
||||
F74
|
||||
N2
|
||||
F19
|
||||
L180
|
||||
S3
|
||||
E1
|
||||
R90
|
||||
F55
|
||||
S3
|
||||
L90
|
||||
F58
|
||||
S1
|
||||
R90
|
||||
E4
|
||||
F42
|
||||
S5
|
||||
R90
|
||||
S4
|
||||
L90
|
||||
S1
|
||||
E3
|
||||
F75
|
||||
L90
|
||||
F44
|
||||
E2
|
||||
F50
|
||||
S2
|
||||
N4
|
||||
W2
|
||||
F14
|
||||
W2
|
||||
N2
|
||||
F14
|
||||
S1
|
||||
W4
|
||||
F74
|
||||
L90
|
||||
F52
|
||||
W3
|
||||
S5
|
||||
L90
|
||||
W5
|
||||
N3
|
||||
L90
|
||||
F54
|
||||
S1
|
||||
R90
|
||||
E3
|
||||
R90
|
||||
F23
|
||||
S4
|
||||
F75
|
||||
N5
|
||||
R90
|
||||
F79
|
||||
R90
|
||||
F70
|
||||
N2
|
||||
F89
|
||||
W1
|
||||
S5
|
||||
E2
|
||||
F44
|
||||
L180
|
||||
W5
|
||||
R90
|
||||
F72
|
||||
R90
|
||||
N3
|
||||
W4
|
||||
N4
|
||||
F90
|
||||
R270
|
||||
E4
|
||||
F43
|
||||
W4
|
||||
F44
|
||||
N5
|
||||
F55
|
||||
S4
|
||||
F68
|
||||
S1
|
||||
E1
|
||||
F39
|
||||
W2
|
||||
N4
|
||||
F46
|
||||
W5
|
||||
F62
|
||||
E1
|
||||
R270
|
||||
F97
|
||||
W4
|
||||
L180
|
||||
F41
|
||||
R90
|
||||
W3
|
||||
R270
|
||||
S1
|
||||
E1
|
||||
R90
|
||||
E2
|
||||
F18
|
||||
E2
|
||||
F12
|
||||
R90
|
||||
W5
|
||||
L90
|
||||
E2
|
||||
F82
|
||||
N3
|
||||
E5
|
||||
F45
|
||||
N5
|
||||
F69
|
||||
N5
|
||||
W1
|
||||
R90
|
||||
F15
|
||||
W1
|
||||
S2
|
||||
R90
|
||||
F50
|
||||
S4
|
||||
S5
|
||||
W2
|
||||
S4
|
||||
F21
|
||||
E5
|
||||
L90
|
||||
F47
|
||||
E1
|
||||
F73
|
||||
L90
|
||||
F4
|
||||
R90
|
||||
F65
|
||||
E2
|
||||
S4
|
||||
F52
|
||||
E1
|
||||
N1
|
||||
L90
|
||||
S1
|
||||
F41
|
||||
R180
|
||||
S2
|
||||
F5
|
||||
E1
|
||||
R90
|
||||
N3
|
||||
F29
|
||||
L90
|
||||
F69
|
||||
E4
|
||||
F92
|
||||
R90
|
||||
N4
|
||||
L180
|
||||
W5
|
||||
N3
|
||||
R180
|
||||
W1
|
||||
N5
|
||||
E5
|
||||
F1
|
||||
N3
|
||||
F19
|
||||
W4
|
||||
F33
|
||||
N2
|
||||
R90
|
||||
E2
|
||||
N3
|
||||
F68
|
||||
E3
|
||||
S1
|
||||
R90
|
||||
N3
|
||||
R180
|
||||
E5
|
||||
R90
|
||||
W1
|
||||
R90
|
||||
S2
|
||||
L90
|
||||
F67
|
||||
W2
|
||||
S4
|
||||
R270
|
||||
W1
|
||||
R90
|
||||
F11
|
||||
L180
|
||||
F83
|
||||
R90
|
||||
N3
|
||||
L90
|
||||
W1
|
||||
N1
|
||||
L90
|
||||
F41
|
||||
N4
|
||||
F45
|
||||
S2
|
||||
W4
|
||||
S4
|
||||
F92
|
||||
E3
|
||||
F21
|
||||
R180
|
||||
W4
|
||||
S1
|
||||
N3
|
||||
R90
|
||||
N2
|
||||
L90
|
||||
F97
|
||||
N4
|
||||
F99
|
||||
F78
|
||||
E2
|
||||
S3
|
||||
W1
|
||||
N4
|
||||
N1
|
||||
E1
|
||||
L180
|
||||
F32
|
||||
S1
|
||||
F84
|
||||
L90
|
||||
S3
|
||||
L90
|
||||
E3
|
||||
R90
|
||||
F62
|
||||
N4
|
||||
L90
|
||||
E2
|
||||
R90
|
||||
F68
|
||||
S4
|
||||
F29
|
||||
E5
|
||||
S5
|
||||
R180
|
||||
S1
|
||||
F15
|
||||
W1
|
||||
S3
|
||||
F65
|
||||
L180
|
||||
F54
|
||||
L90
|
||||
W2
|
||||
S3
|
||||
W2
|
||||
F22
|
||||
L180
|
||||
W5
|
||||
R90
|
||||
E4
|
||||
L90
|
||||
F65
|
||||
W5
|
||||
F82
|
||||
S3
|
||||
W5
|
||||
L90
|
||||
F83
|
||||
W4
|
||||
L90
|
||||
E1
|
||||
F92
|
||||
W4
|
||||
N2
|
||||
F99
|
||||
L90
|
||||
E5
|
||||
R180
|
||||
N5
|
||||
W5
|
||||
R90
|
||||
N3
|
||||
F74
|
||||
R90
|
||||
N1
|
||||
F26
|
||||
S3
|
||||
W2
|
||||
N2
|
||||
E3
|
||||
L90
|
||||
F75
|
||||
R90
|
||||
F12
|
||||
W3
|
||||
S5
|
||||
L90
|
||||
N2
|
||||
E4
|
||||
F13
|
||||
E1
|
||||
F44
|
||||
N3
|
||||
R90
|
||||
E5
|
||||
R90
|
||||
W4
|
||||
F4
|
||||
W5
|
||||
N3
|
||||
W3
|
||||
F40
|
||||
L180
|
||||
W3
|
||||
N2
|
||||
E3
|
||||
F57
|
||||
W1
|
||||
F16
|
||||
S2
|
||||
W3
|
||||
R90
|
||||
W3
|
||||
F24
|
||||
R90
|
||||
F84
|
||||
R90
|
||||
W2
|
||||
R270
|
||||
S1
|
||||
L180
|
||||
F62
|
||||
W1
|
||||
R180
|
||||
F71
|
||||
E2
|
||||
S2
|
||||
R90
|
||||
F84
|
||||
E2
|
||||
F64
|
||||
R90
|
||||
S5
|
||||
F42
|
||||
S4
|
||||
F37
|
||||
E5
|
||||
R90
|
||||
S2
|
||||
R90
|
||||
S4
|
||||
W1
|
||||
R180
|
||||
F71
|
||||
W3
|
||||
F19
|
||||
W5
|
||||
R180
|
||||
F98
|
||||
S5
|
||||
R90
|
||||
N2
|
||||
W5
|
||||
N5
|
||||
F14
|
||||
L270
|
||||
F29
|
||||
L90
|
||||
F94
|
||||
W4
|
||||
F92
|
||||
W5
|
||||
N4
|
||||
F78
|
||||
N1
|
||||
S3
|
||||
F10
|
||||
L90
|
||||
F72
|
||||
R90
|
||||
S2
|
||||
L180
|
||||
N3
|
||||
R180
|
||||
W3
|
||||
F83
|
||||
N4
|
||||
E5
|
||||
N2
|
||||
E3
|
||||
L90
|
||||
E2
|
||||
F84
|
||||
S4
|
||||
R90
|
||||
E3
|
||||
S4
|
||||
F59
|
||||
R90
|
||||
W1
|
||||
R90
|
||||
F29
|
||||
S4
|
||||
W1
|
||||
S5
|
||||
L90
|
||||
F77
|
||||
R90
|
||||
N4
|
||||
F69
|
||||
L90
|
||||
W5
|
||||
F15
|
||||
N3
|
||||
N1
|
||||
L180
|
||||
N2
|
||||
N4
|
||||
W4
|
||||
N1
|
||||
L180
|
||||
W4
|
||||
F5
|
||||
R180
|
||||
E2
|
||||
R90
|
||||
S2
|
||||
R90
|
||||
N2
|
||||
F49
|
||||
L180
|
||||
F32
|
||||
N5
|
||||
R90
|
||||
W5
|
||||
L90
|
||||
E1
|
||||
F46
|
||||
E1
|
||||
L90
|
||||
W3
|
||||
F69
|
||||
N5
|
||||
E1
|
||||
S3
|
||||
L90
|
||||
F98
|
||||
W2
|
||||
L90
|
||||
F17
|
||||
W3
|
||||
N2
|
||||
F78
|
||||
E5
|
||||
W1
|
||||
S1
|
||||
F73
|
||||
S2
|
||||
F36
|
||||
N5
|
||||
E3
|
||||
F61
|
||||
R90
|
||||
E4
|
||||
F88
|
||||
L90
|
||||
E4
|
||||
R180
|
||||
W4
|
||||
S2
|
||||
R180
|
||||
N2
|
||||
F17
|
||||
E5
|
||||
S5
|
||||
E1
|
||||
R90
|
||||
S3
|
||||
L90
|
||||
R90
|
||||
S4
|
||||
F1
|
||||
W2
|
||||
N1
|
||||
W5
|
||||
F35
|
||||
S2
|
||||
F78
|
||||
S2
|
||||
L90
|
||||
W1
|
||||
L180
|
||||
N4
|
||||
F99
|
||||
F34
|
||||
L90
|
||||
N5
|
||||
R90
|
||||
S4
|
||||
L90
|
||||
N2
|
||||
F72
|
||||
E5
|
||||
S4
|
||||
R180
|
||||
S4
|
||||
F18
|
||||
W1
|
||||
L90
|
||||
E1
|
||||
S4
|
||||
E2
|
||||
R90
|
||||
F62
|
||||
L90
|
||||
F71
|
||||
S1
|
||||
F18
|
||||
F6
|
||||
N1
|
||||
F28
|
||||
L90
|
||||
N1
|
||||
F24
|
||||
E1
|
||||
R90
|
||||
S2
|
||||
F51
|
180
d12/main.go
Normal file
180
d12/main.go
Normal file
@ -0,0 +1,180 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"log"
|
||||
"math"
|
||||
"os"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func processLines(path string, f func(string) (stop bool, err error)) error {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
scanner := bufio.NewScanner(file)
|
||||
for scanner.Scan() {
|
||||
stop, err := f(scanner.Text())
|
||||
if stop || err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type ship struct {
|
||||
// Ship position and heading
|
||||
e, n, heading int
|
||||
// Waypoint positions
|
||||
pe, pn int
|
||||
}
|
||||
|
||||
func (s *ship) part2(inst string) error {
|
||||
fmt.Println("Read inst", inst)
|
||||
c := inst[0]
|
||||
|
||||
amt, err := strconv.Atoi(inst[1:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch c {
|
||||
case 'N':
|
||||
s.pn += amt
|
||||
case 'S':
|
||||
s.pn -= amt
|
||||
case 'W':
|
||||
s.pe -= amt
|
||||
case 'E':
|
||||
s.pe += amt
|
||||
case 'R':
|
||||
err = s.rotateWaypoint(amt)
|
||||
case 'L':
|
||||
err = s.rotateWaypoint(-amt)
|
||||
case 'F':
|
||||
err = s.moveToWaypoint(amt)
|
||||
default:
|
||||
err = fmt.Errorf("unknown instruction %s", inst)
|
||||
}
|
||||
|
||||
fmt.Printf("After move %+v\n", s)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *ship) moveToWaypoint(amt int) error {
|
||||
s.n += amt * s.pn
|
||||
s.e += amt * s.pe
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *ship) rotateWaypoint(amt int) error {
|
||||
if amt < 0 {
|
||||
amt = 360 + amt
|
||||
}
|
||||
|
||||
for i := 0; i < amt/90; i++ {
|
||||
s.pe, s.pn = s.pn, -s.pe
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *ship) forward(amt int) error {
|
||||
switch s.heading {
|
||||
case 0:
|
||||
s.n += amt
|
||||
case 90:
|
||||
s.e += amt
|
||||
case 180:
|
||||
s.n -= amt
|
||||
case 270:
|
||||
s.e -= amt
|
||||
default:
|
||||
return fmt.Errorf("unable to move in heading %d", s.heading)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *ship) changeHeading(amt int) error {
|
||||
// Add to heading
|
||||
for amt < 0 {
|
||||
amt = 360 + amt
|
||||
}
|
||||
|
||||
s.heading = (s.heading + amt) % 360
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *ship) move(inst string) error {
|
||||
c := inst[0]
|
||||
|
||||
amt, err := strconv.Atoi(inst[1:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch c {
|
||||
case 'N':
|
||||
s.n += amt
|
||||
case 'S':
|
||||
s.n -= amt
|
||||
case 'W':
|
||||
s.e -= amt
|
||||
case 'E':
|
||||
s.e += amt
|
||||
case 'R':
|
||||
return s.changeHeading(amt)
|
||||
case 'L':
|
||||
return s.changeHeading(-amt)
|
||||
case 'F':
|
||||
return s.forward(amt)
|
||||
default:
|
||||
return fmt.Errorf("unknown instruction %s", inst)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func part1() {
|
||||
s := ship{0, 0, 90, 0, 0}
|
||||
|
||||
if err := processLines("input.txt", func(line string) (bool, error) {
|
||||
return false, s.move(line)
|
||||
}); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
dist := int(math.Abs(float64(s.e)) + math.Abs(float64(s.n)))
|
||||
fmt.Printf("Resulting position %d,%d Distance: %d\n", s.e, s.n, dist)
|
||||
}
|
||||
|
||||
func part2() {
|
||||
s := ship{0, 0, 90, 10, 1}
|
||||
|
||||
if err := processLines("input.txt", func(line string) (bool, error) {
|
||||
return false, s.part2(line)
|
||||
}); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
dist := int(math.Abs(float64(s.e)) + math.Abs(float64(s.n)))
|
||||
fmt.Printf("Resulting position %d,%d Distance: %d\n", s.e, s.n, dist)
|
||||
}
|
||||
|
||||
func main() {
|
||||
part1()
|
||||
part2()
|
||||
}
|
2
d13/input.txt
Normal file
2
d13/input.txt
Normal file
@ -0,0 +1,2 @@
|
||||
1000066
|
||||
13,x,x,41,x,x,x,37,x,x,x,x,x,659,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,409,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,17
|
132
d13/main.py
Executable file
132
d13/main.py
Executable file
@ -0,0 +1,132 @@
|
||||
#! /usr/bin/env python3
|
||||
import sys
|
||||
import math
|
||||
from typing import List
|
||||
from typing import Tuple
|
||||
|
||||
|
||||
def read_file(filename: str) -> Tuple[int, List[int]]:
|
||||
with open(filename) as f:
|
||||
ts = int(next(f).strip())
|
||||
busses = [
|
||||
int(bus) if bus != "x" else -1
|
||||
for bus in next(f).strip().split(",")
|
||||
]
|
||||
|
||||
return ts, busses
|
||||
|
||||
|
||||
def read_cli(arg: str) -> List[int]:
|
||||
busses = [
|
||||
int(bus) if bus != "x" else -1
|
||||
for bus in arg.strip().split(",")
|
||||
]
|
||||
|
||||
return busses
|
||||
|
||||
|
||||
def wait_time(ts: int, bus_id: int) -> int:
|
||||
return (bus_id - (ts % bus_id) % bus_id)
|
||||
|
||||
|
||||
def part1():
|
||||
ts, busses = read_file("input.txt")
|
||||
|
||||
min_wait = -1
|
||||
min_bus_id = 0
|
||||
for bus_id in busses:
|
||||
if bus_id < 0:
|
||||
continue
|
||||
w = wait_time(ts, bus_id)
|
||||
if min_wait < 0 or w < min_wait:
|
||||
min_wait = w
|
||||
min_bus_id = bus_id
|
||||
|
||||
print(f"Wait {min_wait} for bus {min_bus_id}. Answer {min_wait * min_bus_id}")
|
||||
|
||||
|
||||
def part2(busses=None, start=0):
|
||||
if busses is None:
|
||||
_, busses = read_file("input.txt")
|
||||
# busses = [7, 13, -1, -1, 59, -1, 31, 19]
|
||||
|
||||
t = start
|
||||
# t = 100000000000000
|
||||
# t = t - (t%7)
|
||||
# if t%7 != 0:
|
||||
# print("Not starting with multiple of 7")
|
||||
# return
|
||||
while True:
|
||||
# print(f"Checking time {t}")
|
||||
for i, bus_id in enumerate(busses):
|
||||
if bus_id < 0:
|
||||
continue
|
||||
if i == 0:
|
||||
w = t % bus_id
|
||||
else:
|
||||
w = wait_time(t, bus_id)
|
||||
# print(f"Wait for bus {bus_id} is {w} expect {i}")
|
||||
if w != i:
|
||||
if i > 0:
|
||||
t += busses[0]
|
||||
else:
|
||||
t += 1
|
||||
break
|
||||
else:
|
||||
print(f"All busses match for time {t}")
|
||||
break
|
||||
|
||||
|
||||
def part2_calc(busses=None, start=0):
|
||||
if busses is None:
|
||||
_, busses = read_file("input.txt")
|
||||
# busses = [7, 13, -1, -1, 59, -1, 31, 19]
|
||||
|
||||
t = start
|
||||
last_index = 0
|
||||
product = -1
|
||||
while True:
|
||||
print(f"Checking time {t}")
|
||||
for i, bus_id in enumerate(busses[last_index:], last_index):
|
||||
if bus_id < 0:
|
||||
continue
|
||||
if i == 0:
|
||||
w = t % bus_id
|
||||
else:
|
||||
w = wait_time(t, bus_id)
|
||||
print(f"Wait for bus {bus_id} is {w} expect {i}")
|
||||
if w == i % bus_id:
|
||||
last_index = i+1
|
||||
if product < 0:
|
||||
product = bus_id
|
||||
else:
|
||||
product = product * bus_id
|
||||
print(f"New index {last_index}, new product {product}")
|
||||
else:
|
||||
if i > 0:
|
||||
t += product
|
||||
else:
|
||||
t += 1
|
||||
break
|
||||
else:
|
||||
print(f"All busses match for time {t}")
|
||||
break
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) == 1:
|
||||
part1()
|
||||
part2_calc()
|
||||
else:
|
||||
busses = read_cli(sys.argv[1])
|
||||
b1, b2 = busses[0], busses[1]
|
||||
t = b1 * math.floor(b2/b1)
|
||||
print(f"Maybe t = {t}")
|
||||
start = 0
|
||||
if len(sys.argv) > 2:
|
||||
start = int(sys.argv[2])
|
||||
print("brute")
|
||||
part2(busses, start)
|
||||
print("")
|
||||
print("calc")
|
||||
part2_calc(busses, start)
|
572
d14/input.txt
Normal file
572
d14/input.txt
Normal file
@ -0,0 +1,572 @@
|
||||
mask = 01X11X10X10110110X111X11010X1X101010
|
||||
mem[19409] = 3025
|
||||
mem[40104] = 798480382
|
||||
mem[25359] = 905
|
||||
mask = 01011X111100XX1100X1X10X110000000000
|
||||
mem[55479] = 930785
|
||||
mem[25548] = 130263864
|
||||
mem[60518] = 202648
|
||||
mem[11955] = 1138
|
||||
mem[45248] = 753
|
||||
mask = 00XX10001XXX00101X1XX1101000010X0010
|
||||
mem[2050] = 27965
|
||||
mem[5662] = 110507779
|
||||
mem[60807] = 1608
|
||||
mask = 000110101100XX10X01000X010X000010100
|
||||
mem[28713] = 1039
|
||||
mem[22733] = 182274602
|
||||
mem[21460] = 12248397
|
||||
mem[60257] = 103
|
||||
mem[13722] = 137279
|
||||
mem[2117] = 208446548
|
||||
mask = 100110111X011X1X10110X11010001X11XX0
|
||||
mem[29709] = 6606
|
||||
mem[27812] = 143567051
|
||||
mem[3595] = 478522065
|
||||
mem[13123] = 7445318
|
||||
mem[37070] = 32452
|
||||
mem[60140] = 47608
|
||||
mem[21316] = 69201021
|
||||
mask = X10X0010110000111111X0X11X10X1000111
|
||||
mem[29528] = 3980
|
||||
mem[41054] = 274606
|
||||
mem[34884] = 265241899
|
||||
mem[7496] = 228368
|
||||
mem[35014] = 109110
|
||||
mem[40696] = 172101503
|
||||
mask = 010X011010X0001X11101011X1X100010100
|
||||
mem[23210] = 3864280
|
||||
mem[53761] = 5046
|
||||
mem[6853] = 1214
|
||||
mem[45297] = 219
|
||||
mem[33797] = 1843462
|
||||
mask = 01011011110011110X0X01110110010XX000
|
||||
mem[15509] = 16472647
|
||||
mem[19332] = 526724681
|
||||
mask = 0101X0101100X01X111X1X11X000X1X1X110
|
||||
mem[16393] = 122368236
|
||||
mem[18852] = 4351408
|
||||
mem[56526] = 780
|
||||
mem[46701] = 31085562
|
||||
mem[53459] = 47134
|
||||
mem[19409] = 7629114
|
||||
mem[47891] = 76573711
|
||||
mask = 000110X0010010X0X010XX110000X0X1000X
|
||||
mem[35342] = 1095
|
||||
mem[56466] = 3462270
|
||||
mem[31124] = 204698678
|
||||
mem[104] = 2115
|
||||
mem[22733] = 154721
|
||||
mask = 00X100X01XX000101X1001110000010XX110
|
||||
mem[44047] = 6823624
|
||||
mem[11955] = 242152
|
||||
mem[41039] = 515174779
|
||||
mask = 0101101X110X10110X11101011X00110XXXX
|
||||
mem[46716] = 52535895
|
||||
mem[20578] = 851818
|
||||
mem[7307] = 1658
|
||||
mem[59777] = 7566837
|
||||
mem[38136] = 6
|
||||
mem[18835] = 95379
|
||||
mem[37574] = 28195477
|
||||
mask = 010XXX101X0X0011X1100X1001110X01X100
|
||||
mem[17831] = 4467
|
||||
mem[45439] = 61064
|
||||
mem[43070] = 291981105
|
||||
mem[9562] = 725
|
||||
mem[18574] = 82455219
|
||||
mem[53761] = 2223
|
||||
mask = 0001X010X1001010XX10011110000011000X
|
||||
mem[24954] = 229575
|
||||
mem[49643] = 118597
|
||||
mem[40891] = 218656479
|
||||
mem[6549] = 655
|
||||
mem[16413] = 105021
|
||||
mask = 01X0X01010010X111X1001X0X1X1X0000110
|
||||
mem[24722] = 3306225
|
||||
mem[18574] = 2046331
|
||||
mem[51991] = 2879
|
||||
mask = 010X10001X00XX10000000101100000X0000
|
||||
mem[64694] = 69415191
|
||||
mem[42979] = 1589
|
||||
mem[49282] = 199
|
||||
mem[3987] = 2386
|
||||
mem[64631] = 17661
|
||||
mask = 011XXX1010010111101X0000100100X10XX0
|
||||
mem[21201] = 341993
|
||||
mem[61134] = 328
|
||||
mem[19716] = 463044
|
||||
mem[53800] = 23668576
|
||||
mem[46317] = 368717
|
||||
mem[3978] = 2699
|
||||
mask = X10X01X011001011X111101010X0XX111111
|
||||
mem[5567] = 9644235
|
||||
mem[50029] = 4717
|
||||
mem[34043] = 119207
|
||||
mem[35949] = 665131137
|
||||
mem[58233] = 98752
|
||||
mask = 0X00001011X0001111X000100X0000XX0110
|
||||
mem[28818] = 809
|
||||
mem[20113] = 604
|
||||
mem[58178] = 11229
|
||||
mem[9389] = 38294680
|
||||
mem[34657] = 8016112
|
||||
mem[10161] = 1585984
|
||||
mem[8020] = 1403857
|
||||
mask = 01011011110XX0110111111101100X000X01
|
||||
mem[47451] = 201798
|
||||
mem[62498] = 61888
|
||||
mem[49564] = 16728
|
||||
mem[60513] = 23392513
|
||||
mem[36774] = 56575
|
||||
mem[22431] = 70709
|
||||
mask = 011X100011000X1X10X0101100X10X011111
|
||||
mem[41938] = 34906
|
||||
mem[62853] = 221817
|
||||
mem[50173] = 471027372
|
||||
mem[55286] = 4561108
|
||||
mask = 1X010X0011010000X1100X000101X101X000
|
||||
mem[22998] = 62382
|
||||
mem[18574] = 57889052
|
||||
mem[57700] = 1018
|
||||
mask = X1XX0X1011001011111X101X111001111111
|
||||
mem[34453] = 6483
|
||||
mem[49122] = 391290
|
||||
mask = 01010000000100110XX000011X00X01XX10X
|
||||
mem[23870] = 19517
|
||||
mem[24291] = 616878
|
||||
mem[12134] = 1990123
|
||||
mem[26637] = 55962054
|
||||
mem[47968] = 712481177
|
||||
mem[20878] = 242502
|
||||
mem[30722] = 1568
|
||||
mask = 11X11111X100XX1000100111100000000010
|
||||
mem[35335] = 59630
|
||||
mem[63185] = 11256526
|
||||
mem[30722] = 266092278
|
||||
mem[9776] = 63532545
|
||||
mask = 10010010010X1010111X11001000X110101X
|
||||
mem[12312] = 4029860
|
||||
mem[27593] = 42705942
|
||||
mem[46156] = 27895
|
||||
mem[64088] = 1408576
|
||||
mem[50342] = 15980145
|
||||
mem[46315] = 29427
|
||||
mem[47451] = 18865
|
||||
mask = 011111001X0XX01010100110X11000X01100
|
||||
mem[1293] = 837
|
||||
mem[29000] = 10697
|
||||
mask = XX0X0010X1001010XX11X01110X101101100
|
||||
mem[42918] = 1028
|
||||
mem[2608] = 3093
|
||||
mem[21904] = 6098595
|
||||
mem[41278] = 1039294
|
||||
mem[53102] = 858102784
|
||||
mask = 0X0110X01100X010X0X0001X10X00XX00000
|
||||
mem[20578] = 860568571
|
||||
mem[52466] = 143792
|
||||
mem[10261] = 182
|
||||
mask = 0X0110101100X011XX111X111110111X11XX
|
||||
mem[5752] = 37841428
|
||||
mem[31368] = 1094581
|
||||
mask = 000X11101X01001110100001000X0100100X
|
||||
mem[56372] = 1046359
|
||||
mem[19541] = 315663570
|
||||
mem[37436] = 437380
|
||||
mem[54334] = 241690746
|
||||
mem[16559] = 3127549
|
||||
mem[59609] = 176914004
|
||||
mask = 110101X01XX1000X0XX0100000X0000XX101
|
||||
mem[1033] = 8174
|
||||
mem[49587] = 107787
|
||||
mem[1572] = 430
|
||||
mem[49873] = 115828687
|
||||
mem[24389] = 2707208
|
||||
mem[30170] = 91827506
|
||||
mask = 01XX01001XX10010X0101001000000011101
|
||||
mem[26015] = 198698
|
||||
mem[50136] = 19382
|
||||
mem[16413] = 103882
|
||||
mem[8340] = 2066093
|
||||
mask = XX01101X1101101XX01111X01X1100X00100
|
||||
mem[42378] = 518494
|
||||
mem[13927] = 94055
|
||||
mem[48225] = 15652034
|
||||
mask = 000100X0110X101X0X1XXX1X10110011101X
|
||||
mem[65006] = 6769
|
||||
mem[46625] = 5473325
|
||||
mem[22440] = 617624684
|
||||
mem[24954] = 719974
|
||||
mem[53626] = 62067
|
||||
mask = 00011XX01101X01X1010X11X10000X00X0X0
|
||||
mem[43072] = 106139234
|
||||
mem[53459] = 26813614
|
||||
mem[31162] = 184146764
|
||||
mask = 0X01X0101X00001XXX10X11X000001000010
|
||||
mem[5467] = 121320
|
||||
mem[63724] = 11067492
|
||||
mem[57246] = 315
|
||||
mem[16413] = 2008242
|
||||
mem[10240] = 11073
|
||||
mem[24282] = 618660016
|
||||
mask = 1101111011000010101X1101X0X0001X1011
|
||||
mem[61598] = 627237127
|
||||
mem[16057] = 235475116
|
||||
mem[5662] = 6226
|
||||
mem[61721] = 26023344
|
||||
mem[58178] = 209547
|
||||
mem[59687] = 141941
|
||||
mem[9548] = 1392254
|
||||
mask = 00011X1000X01010011X01111X0110X10100
|
||||
mem[13185] = 300556
|
||||
mem[51203] = 17097
|
||||
mem[59687] = 8787507
|
||||
mem[12337] = 124607
|
||||
mem[46043] = 4378256
|
||||
mask = 1100X100110100100110X10X000X01111101
|
||||
mem[17458] = 420459
|
||||
mem[46315] = 142385
|
||||
mem[7273] = 58415
|
||||
mem[49604] = 57549
|
||||
mem[33375] = 12460422
|
||||
mem[61540] = 7752
|
||||
mask = X1X11XXX1100X010X0100100000000X00010
|
||||
mem[28889] = 13691764
|
||||
mem[27546] = 355436
|
||||
mem[45337] = 10614
|
||||
mem[64088] = 960
|
||||
mem[39291] = 3019
|
||||
mem[30722] = 1976602
|
||||
mem[18725] = 299
|
||||
mask = 0X111X1011000X101010X0X001X100XX1010
|
||||
mem[5532] = 413573
|
||||
mem[7707] = 78463710
|
||||
mem[46156] = 25164851
|
||||
mem[17354] = 15295191
|
||||
mask = 000110100X0X10100X100011XX0010010000
|
||||
mem[18725] = 7003
|
||||
mem[49536] = 49752
|
||||
mem[33519] = 116272721
|
||||
mem[46701] = 253380665
|
||||
mask = 000X001001001XXX101XX00X0101X1010000
|
||||
mem[57459] = 792510
|
||||
mem[10350] = 217210394
|
||||
mem[43612] = 178868
|
||||
mem[2374] = 42534899
|
||||
mem[40891] = 621
|
||||
mem[7270] = 1014999
|
||||
mem[49038] = 1657373
|
||||
mask = 00XX10100001100X01000110001001010X10
|
||||
mem[7270] = 1904
|
||||
mem[33267] = 171621958
|
||||
mem[42531] = 623
|
||||
mask = 011111001100001X00X0010X10010010001X
|
||||
mem[59756] = 19646
|
||||
mem[45248] = 182118
|
||||
mem[49395] = 186
|
||||
mem[46043] = 1875998
|
||||
mem[42378] = 2150393
|
||||
mem[16423] = 449813446
|
||||
mask = 00X10X1001001010111X0X11100XX0101X01
|
||||
mem[42378] = 11316
|
||||
mem[6217] = 448726
|
||||
mem[56349] = 105698
|
||||
mem[18523] = 6560236
|
||||
mask = 0X01101011000X101111X1110010X1110111
|
||||
mem[57685] = 1052364113
|
||||
mem[42200] = 1624
|
||||
mem[64281] = 162750
|
||||
mem[53459] = 900417618
|
||||
mem[44010] = 311326
|
||||
mem[38385] = 168338
|
||||
mem[64234] = 715
|
||||
mask = 0110001010X1001X111000XX01X110X1000X
|
||||
mem[46270] = 413222
|
||||
mem[20358] = 301418973
|
||||
mask = 0101X01010000X1X111001000X010000X100
|
||||
mem[25549] = 9478586
|
||||
mem[27938] = 186993583
|
||||
mem[10014] = 630139
|
||||
mem[50316] = 22183454
|
||||
mask = 00X10XX0110010100X10XX11X01000100010
|
||||
mem[51762] = 575
|
||||
mem[39895] = 33305
|
||||
mem[19768] = 31036515
|
||||
mem[30918] = 522221
|
||||
mem[26371] = 790132
|
||||
mem[43705] = 13814
|
||||
mask = 00XXX010X1100010100101110101X0001110
|
||||
mem[12495] = 2801000
|
||||
mem[43811] = 35764
|
||||
mem[59173] = 235362
|
||||
mem[50677] = 13747007
|
||||
mem[47458] = 49520
|
||||
mask = 00X1101X1100X010X010001010000000010X
|
||||
mem[19737] = 309
|
||||
mem[10289] = 1391
|
||||
mem[44222] = 202053013
|
||||
mem[32818] = 57015
|
||||
mask = XX111010X10XX0101010XX00000X00100X01
|
||||
mem[25062] = 92115406
|
||||
mem[40507] = 8539848
|
||||
mem[6853] = 1555113
|
||||
mem[59566] = 55734
|
||||
mem[29440] = 3860
|
||||
mem[2339] = 1687
|
||||
mask = X0X100100100X000X0011000100100110001
|
||||
mem[62983] = 496942
|
||||
mem[55239] = 31959819
|
||||
mem[23037] = 185
|
||||
mem[14426] = 11052660
|
||||
mem[59756] = 11483028
|
||||
mask = 0X1X101011X0101X0X100110100110X101XX
|
||||
mem[9761] = 26687118
|
||||
mem[152] = 1818
|
||||
mask = 01X110X01010001X1110XXX0000100X100X0
|
||||
mem[46327] = 780262
|
||||
mem[11424] = 1003003
|
||||
mask = 010011XX100X0011X1XX000X01X10X011110
|
||||
mem[40928] = 10697
|
||||
mem[989] = 22449916
|
||||
mem[9034] = 107225
|
||||
mask = 010100X0X001001101100XX110X0000X10X0
|
||||
mem[50403] = 60110
|
||||
mem[1465] = 9126
|
||||
mem[4598] = 348452
|
||||
mem[26661] = 17672110
|
||||
mask = 00X110101XX00010100X0010010011X10010
|
||||
mem[38295] = 20183
|
||||
mem[61069] = 22691
|
||||
mem[51394] = 7278100
|
||||
mem[18711] = 34474
|
||||
mem[52888] = 1962576
|
||||
mask = 1001001X0X001010101X0110XXX001XX100X
|
||||
mem[33226] = 3641501
|
||||
mem[2376] = 72068973
|
||||
mem[57257] = 11382653
|
||||
mem[22489] = 47282
|
||||
mem[45359] = 38362
|
||||
mask = 010X1X10010X101X01111010111110111011
|
||||
mem[26980] = 755824
|
||||
mem[47763] = 385
|
||||
mem[23332] = 30083831
|
||||
mem[32975] = 61896119
|
||||
mask = XX0110111101X011X011X0XXX10000011100
|
||||
mem[29709] = 711754376
|
||||
mem[36513] = 71516
|
||||
mem[7293] = 5061813
|
||||
mem[60256] = 419151
|
||||
mask = 0101101011000XX1111111X001100100XX00
|
||||
mem[19475] = 35852
|
||||
mem[57183] = 6494332
|
||||
mem[1327] = 872346
|
||||
mem[2543] = 943
|
||||
mem[2188] = 868813
|
||||
mem[29387] = 209125695
|
||||
mask = 00X1X0101X1000X01X010X1X01100X0X1101
|
||||
mem[51955] = 196066365
|
||||
mem[38207] = 15671526
|
||||
mem[26980] = 75520251
|
||||
mem[11077] = 161630247
|
||||
mem[26456] = 30666501
|
||||
mem[19737] = 9386
|
||||
mask = 1101011010110X0X01101XX001X0X001X001
|
||||
mem[49292] = 858273
|
||||
mem[11497] = 884831
|
||||
mem[49282] = 93065
|
||||
mem[54031] = 862594
|
||||
mask = 0X01011010X1X01111X0X0X00X11X1010100
|
||||
mem[58536] = 4031842
|
||||
mem[11621] = 155458283
|
||||
mem[8786] = 12859
|
||||
mask = 00010010XXX000X010010X1XX001X0X01100
|
||||
mem[45429] = 122467
|
||||
mem[57256] = 759
|
||||
mem[3687] = 384128816
|
||||
mem[56464] = 10758724
|
||||
mem[11869] = 652805159
|
||||
mem[50173] = 75914445
|
||||
mask = 0001001001001010111XX10X1X0XX0111101
|
||||
mem[5809] = 743780
|
||||
mem[52067] = 806
|
||||
mem[12750] = 22132
|
||||
mem[13019] = 654
|
||||
mask = 00X110X01100101X00100X1X00XX00100001
|
||||
mem[2117] = 4067660
|
||||
mem[2068] = 9851885
|
||||
mem[48662] = 52185630
|
||||
mem[24246] = 72048
|
||||
mem[25978] = 5182633
|
||||
mask = 010X1010X0X0001111100X001101X01X0XX0
|
||||
mem[10242] = 1118
|
||||
mem[57601] = 525
|
||||
mem[38099] = 930509
|
||||
mask = 10111101110X0X10001001X00001001000X1
|
||||
mem[50741] = 59787235
|
||||
mem[1588] = 218533
|
||||
mem[33080] = 182579
|
||||
mem[3978] = 1591079
|
||||
mem[62070] = 15472
|
||||
mask = 0101100X1100X0X10110X010000X000X00X1
|
||||
mem[3814] = 788124
|
||||
mem[63265] = 215577374
|
||||
mem[57364] = 1311024
|
||||
mem[36364] = 3985
|
||||
mem[18564] = 4526
|
||||
mem[23647] = 376609
|
||||
mask = 001XX00011010010111000101X100X0011X0
|
||||
mem[61429] = 6896
|
||||
mem[22094] = 1966698
|
||||
mask = X00110111101XX111011101X011010100X01
|
||||
mem[36214] = 310642
|
||||
mem[59733] = 1160
|
||||
mem[10909] = 1820
|
||||
mem[25225] = 51102962
|
||||
mem[35074] = 514484736
|
||||
mem[21460] = 3630
|
||||
mask = 1001001X01001010XX10111001XX1X1X1000
|
||||
mem[53608] = 6145
|
||||
mem[44618] = 302105
|
||||
mem[50955] = 12609449
|
||||
mem[48282] = 22035626
|
||||
mask = 01X1XX001XXX001XX0100111000000001100
|
||||
mem[47458] = 4534
|
||||
mem[26444] = 4150059
|
||||
mem[10366] = 1061
|
||||
mem[51657] = 2817023
|
||||
mem[35995] = 1064419
|
||||
mem[38295] = 148703436
|
||||
mask = 01X0001010010X1110X0000010111X001000
|
||||
mem[26046] = 2672378
|
||||
mem[1080] = 682
|
||||
mem[2151] = 737
|
||||
mask = 110X0100110100X001X0X1XXX100011101X0
|
||||
mem[56044] = 527135884
|
||||
mem[39296] = 107094645
|
||||
mem[61785] = 1261
|
||||
mask = 01001X00100X0011010000000101000XX101
|
||||
mem[54752] = 16579540
|
||||
mem[36330] = 1696582
|
||||
mem[1435] = 240113842
|
||||
mem[49758] = 7811
|
||||
mem[51729] = 2543212
|
||||
mem[10909] = 13139
|
||||
mask = 0X0XXX100001101X011010101000011001XX
|
||||
mem[58487] = 9986
|
||||
mem[7175] = 3371969
|
||||
mem[14294] = 10275
|
||||
mem[36225] = 13168
|
||||
mem[7934] = 48879
|
||||
mem[47891] = 1571293
|
||||
mem[18711] = 399
|
||||
mask = X1010XX01X01001X01101010X1X00001X010
|
||||
mem[62247] = 18380710
|
||||
mem[20715] = 15548870
|
||||
mem[61924] = 28821546
|
||||
mem[40119] = 181518508
|
||||
mem[50251] = 59934
|
||||
mask = XXX1011X11X100X1X110001011X001100001
|
||||
mem[13627] = 4734
|
||||
mem[36208] = 48295
|
||||
mem[37672] = 184327969
|
||||
mem[60518] = 9137
|
||||
mem[46168] = 105126453
|
||||
mask = 1X111101110X0010001000XX000100XXX011
|
||||
mem[4455] = 17333982
|
||||
mem[58592] = 931411
|
||||
mem[61752] = 198443
|
||||
mem[183] = 808
|
||||
mask = XX010010010XX0101011111111010011X100
|
||||
mem[6221] = 256009562
|
||||
mem[3528] = 422478
|
||||
mem[16002] = 6328770
|
||||
mask = 0X01X00011001010XX000010100000100010
|
||||
mem[31570] = 32237
|
||||
mem[14971] = 846258186
|
||||
mem[18978] = 1202
|
||||
mem[15368] = 120674
|
||||
mem[13185] = 22420
|
||||
mask = 010110111101101XX011X11XX11X00X00X00
|
||||
mem[59330] = 628
|
||||
mem[9283] = 58883
|
||||
mem[44010] = 387833048
|
||||
mask = 010010101001X1111010111X000X00X0X110
|
||||
mem[50633] = 751888
|
||||
mem[11056] = 31979
|
||||
mem[50741] = 4724
|
||||
mem[40028] = 7336181
|
||||
mem[42263] = 6863
|
||||
mask = 0001X010110000X00010010X10000XX10100
|
||||
mem[20546] = 8708
|
||||
mem[36908] = 234294
|
||||
mem[63185] = 1408
|
||||
mem[57531] = 1054
|
||||
mem[13722] = 1045167819
|
||||
mem[4617] = 3519205
|
||||
mask = 00111000X10010X10010X01010X00010010X
|
||||
mem[46693] = 4740
|
||||
mem[17824] = 884
|
||||
mem[54997] = 339096
|
||||
mem[2117] = 26803
|
||||
mem[20] = 84635057
|
||||
mask = 0101XXX01100X011011X010000000X00X100
|
||||
mem[40142] = 140297
|
||||
mem[53459] = 5575659
|
||||
mem[57435] = 69641959
|
||||
mem[28563] = 433881
|
||||
mem[59188] = 230341
|
||||
mem[26483] = 151116806
|
||||
mask = 110101X01XX100X10110001XX1X0X01000X1
|
||||
mem[37526] = 454911
|
||||
mem[35793] = 3340
|
||||
mem[54537] = 630806
|
||||
mem[58456] = 115228
|
||||
mem[59172] = 13363
|
||||
mask = 010110X0110000101010X001111X0X010010
|
||||
mem[45969] = 1736711
|
||||
mem[2487] = 610736260
|
||||
mem[54173] = 453
|
||||
mem[55144] = 2748104
|
||||
mem[52466] = 6109568
|
||||
mem[31890] = 3977366
|
||||
mask = 01011001110000X101100X00X00X10010000
|
||||
mem[64336] = 3971537
|
||||
mem[60265] = 85267
|
||||
mem[24597] = 7455656
|
||||
mem[34924] = 703390248
|
||||
mem[40391] = 328312
|
||||
mem[49255] = 1117186
|
||||
mask = 110X0100101100X1011010101X0X11X11010
|
||||
mem[31313] = 789405
|
||||
mem[7934] = 1803
|
||||
mem[36190] = 1836611
|
||||
mask = X0010010010010101X1X1X1010X111X010XX
|
||||
mem[4017] = 64210
|
||||
mem[40696] = 58930789
|
||||
mem[18166] = 195479433
|
||||
mem[41257] = 40207
|
||||
mem[40948] = 1058796
|
||||
mem[30803] = 486
|
||||
mem[29709] = 72337
|
||||
mask = 000X101000X110X001X00110X1X0011X0XX1
|
||||
mem[11077] = 1653
|
||||
mem[2376] = 77389
|
||||
mem[19561] = 4876923
|
||||
mem[32851] = 538156
|
||||
mem[38532] = 1110
|
||||
mask = X101101011X010111110X0111001X101010X
|
||||
mem[44618] = 13980
|
||||
mem[10366] = 711247
|
||||
mem[4942] = 74171
|
||||
mem[25306] = 350133
|
||||
mem[21409] = 27748
|
||||
mask = 00011010X1001010XXX0001110000001011X
|
||||
mem[5809] = 1082
|
||||
mem[36908] = 180
|
||||
mem[59172] = 196430412
|
||||
mem[60137] = 1388
|
||||
mem[49643] = 1887
|
||||
mask = 01011010X10000X1111111111XX00101111X
|
||||
mem[56344] = 1237
|
||||
mem[23638] = 37922654
|
||||
mem[20307] = 593227321
|
200
d14/main.go
Normal file
200
d14/main.go
Normal file
@ -0,0 +1,200 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"log"
|
||||
"math"
|
||||
"os"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func processLines(path string, f func(string) (stop bool, err error)) error {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
scanner := bufio.NewScanner(file)
|
||||
for scanner.Scan() {
|
||||
stop, err := f(scanner.Text())
|
||||
if stop || err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var memExtractor = regexp.MustCompile(`^mem\[([0-9]+)] = ([0-9]+)`)
|
||||
|
||||
func powInt(x, y int) int {
|
||||
return int(math.Pow(float64(x), float64(y)))
|
||||
}
|
||||
|
||||
func applyMask(mask string, v int) (int, error) {
|
||||
for i := 0; i < len(mask); i++ {
|
||||
m := mask[len(mask)-i-1]
|
||||
switch m {
|
||||
case 'X':
|
||||
case '1':
|
||||
v |= powInt(2, i)
|
||||
case '0':
|
||||
v &^= powInt(2, i)
|
||||
default:
|
||||
return 0, fmt.Errorf("could not apply mask %v in position %d", m, i)
|
||||
}
|
||||
}
|
||||
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func sprintBinArray(a []int, z int) string {
|
||||
r := " "
|
||||
|
||||
for _, v := range a {
|
||||
f := fmt.Sprintf("%%%db(%%d)", z)
|
||||
r += fmt.Sprintf(f, v, v)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("[%s]", r)
|
||||
}
|
||||
|
||||
func applyFloatingMask(mask string, v int) ([]int, error) {
|
||||
base2 := 2
|
||||
results := []int{v}
|
||||
|
||||
// fmt.Printf("Applying %s to %8b\n", mask, v)
|
||||
|
||||
for i := 0; i < len(mask); i++ {
|
||||
m := mask[len(mask)-i-1]
|
||||
// fmt.Printf("Apply %s at %d ", string(m), i)
|
||||
|
||||
resultLen := len(results)
|
||||
for j := 0; j < resultLen; j++ {
|
||||
switch m {
|
||||
case 'X':
|
||||
// Add a 0 mask to end of results
|
||||
results = append(results, results[j]|powInt(base2, i))
|
||||
// Apply a 1 mask in place
|
||||
results[j] &^= powInt(base2, i)
|
||||
case '1':
|
||||
results[j] |= powInt(base2, i)
|
||||
case '0':
|
||||
// results[j] &^= powInt(base2, i)
|
||||
default:
|
||||
return results, fmt.Errorf("could not apply mask %v in position %d", m, i)
|
||||
}
|
||||
}
|
||||
|
||||
// fmt.Printf("Result %s\n", sprintBinArray(results, 8))
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
func parseMemValues(line string) (loc int, val int, err error) {
|
||||
match := memExtractor.FindStringSubmatch(line)
|
||||
if match == nil {
|
||||
err = fmt.Errorf("could not extract mem val in %s", line)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
loc, err = strconv.Atoi(match[1])
|
||||
if err != nil {
|
||||
err = fmt.Errorf("error parsing int from %s: %w", line, err)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
val, err = strconv.Atoi(match[2])
|
||||
if err != nil {
|
||||
err = fmt.Errorf("error parsing int from %s: %w", line, err)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func part1() {
|
||||
var mask string
|
||||
|
||||
mem := map[int]int{}
|
||||
|
||||
if err := processLines("input.txt", func(line string) (bool, error) {
|
||||
if strings.HasPrefix(line, "mask") {
|
||||
mask = strings.TrimPrefix(line, "mask = ")
|
||||
} else {
|
||||
loc, val, err := parseMemValues(line)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
val, err = applyMask(mask, val)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("error applying mask to value on line %s: %w", line, err)
|
||||
}
|
||||
// fmt.Printf("mem[%d] = %d\n", loc, val)
|
||||
mem[loc] = val
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
sum := 0
|
||||
for _, v := range mem {
|
||||
sum += v
|
||||
}
|
||||
|
||||
fmt.Printf("Total value in memory %d\n", sum)
|
||||
}
|
||||
|
||||
func part2() {
|
||||
var mask string
|
||||
|
||||
mem := map[int]int{}
|
||||
|
||||
if err := processLines("input.txt", func(line string) (bool, error) {
|
||||
if strings.HasPrefix(line, "mask") {
|
||||
mask = strings.TrimPrefix(line, "mask = ")
|
||||
} else {
|
||||
loc, val, err := parseMemValues(line)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
locs, err := applyFloatingMask(mask, loc)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("error applying mask to value on line %s: %w", line, err)
|
||||
}
|
||||
for _, l := range locs {
|
||||
mem[l] = val
|
||||
}
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
sum := 0
|
||||
for _, v := range mem {
|
||||
sum += v
|
||||
}
|
||||
|
||||
fmt.Printf("Total value in memory %d\n", sum)
|
||||
}
|
||||
|
||||
func main() {
|
||||
part1()
|
||||
part2()
|
||||
}
|
94
d15/main.go
Normal file
94
d15/main.go
Normal file
@ -0,0 +1,94 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
type game struct {
|
||||
turn, lastNumber int
|
||||
history map[int]int
|
||||
}
|
||||
|
||||
func newGame(startingNumbers []int) *game {
|
||||
g := game{0, 0, map[int]int{}}
|
||||
for _, n := range startingNumbers {
|
||||
g.history[g.lastNumber] = g.turn
|
||||
g.turn++
|
||||
g.lastNumber = n
|
||||
}
|
||||
|
||||
return &g
|
||||
}
|
||||
|
||||
func (g *game) takeTurn() (int, int) {
|
||||
// fmt.Printf("> Starting turn %d. last: %d\n", g.turn+1, g.lastNumber)
|
||||
// fmt.Printf(">> state %+v\n", g)
|
||||
|
||||
var number int
|
||||
|
||||
// Get the new number
|
||||
if t, ok := g.history[g.lastNumber]; ok {
|
||||
// fmt.Printf(">> We've seen %d before!\n", g.lastNumber)
|
||||
// Last number was seen
|
||||
number = g.turn - t
|
||||
} else {
|
||||
// Otherwise the number is zero
|
||||
number = 0
|
||||
}
|
||||
|
||||
// Store the last turn in history
|
||||
g.history[g.lastNumber] = g.turn
|
||||
|
||||
// Go to the next turn
|
||||
g.turn++
|
||||
g.lastNumber = number
|
||||
|
||||
// fmt.Printf(">> Incrementing turn and updating state %+v\n", g)
|
||||
// fmt.Printf("Turn %d spoke \"%d\"\n", g.turn, g.lastNumber)
|
||||
|
||||
return g.turn, g.lastNumber
|
||||
}
|
||||
|
||||
func (g *game) turnTo(targetTurn int) int {
|
||||
var n int
|
||||
|
||||
for g.turn < targetTurn {
|
||||
_, n = g.takeTurn()
|
||||
}
|
||||
|
||||
return n
|
||||
}
|
||||
|
||||
func part1() {
|
||||
numbers := []int{16, 12, 1, 0, 15, 7, 11}
|
||||
// numbers := []int{0, 3, 6}
|
||||
g := newGame(numbers)
|
||||
fmt.Println(g)
|
||||
|
||||
t, n := g.takeTurn()
|
||||
for t < 2020 {
|
||||
t, n = g.takeTurn()
|
||||
}
|
||||
|
||||
fmt.Printf("Part 1: Number on turn %d is %d\n", t, n)
|
||||
}
|
||||
|
||||
func part2() {
|
||||
numbers := []int{16, 12, 1, 0, 15, 7, 11}
|
||||
// numbers := []int{0, 3, 6}
|
||||
g := newGame(numbers)
|
||||
fmt.Println(g)
|
||||
|
||||
t, n := g.takeTurn()
|
||||
for t < 30000000 {
|
||||
t, n = g.takeTurn()
|
||||
}
|
||||
|
||||
fmt.Printf("Part 2: Number on turn %d is %d\n", t, n)
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Println(newGame([]int{16, 12, 1, 0, 15, 7, 11}).turnTo(2020))
|
||||
fmt.Println(newGame([]int{16, 12, 1, 0, 15, 7, 11}).turnTo(30000000))
|
||||
part1()
|
||||
part2()
|
||||
|
||||
}
|
12
d16/input-small.txt
Normal file
12
d16/input-small.txt
Normal file
@ -0,0 +1,12 @@
|
||||
class: 1-3 or 5-7
|
||||
row: 6-11 or 33-44
|
||||
seat: 13-40 or 45-50
|
||||
|
||||
your ticket:
|
||||
7,1,14
|
||||
|
||||
nearby tickets:
|
||||
7,3,47
|
||||
40,4,50
|
||||
55,2,20
|
||||
38,6,12
|
11
d16/input-small2.txt
Normal file
11
d16/input-small2.txt
Normal file
@ -0,0 +1,11 @@
|
||||
class: 0-1 or 4-19
|
||||
row: 0-5 or 8-19
|
||||
seat: 0-13 or 16-19
|
||||
|
||||
your ticket:
|
||||
11,12,13
|
||||
|
||||
nearby tickets:
|
||||
3,9,18
|
||||
15,1,5
|
||||
5,14,9
|
261
d16/input.txt
Normal file
261
d16/input.txt
Normal file
@ -0,0 +1,261 @@
|
||||
departure location: 29-766 or 786-950
|
||||
departure station: 40-480 or 491-949
|
||||
departure platform: 46-373 or 397-957
|
||||
departure track: 33-657 or 673-970
|
||||
departure date: 31-433 or 445-961
|
||||
departure time: 33-231 or 250-966
|
||||
arrival location: 48-533 or 556-974
|
||||
arrival station: 42-597 or 620-957
|
||||
arrival platform: 32-119 or 140-967
|
||||
arrival track: 28-750 or 762-973
|
||||
class: 26-88 or 101-950
|
||||
duration: 30-271 or 293-974
|
||||
price: 33-712 or 718-966
|
||||
route: 49-153 or 159-953
|
||||
row: 36-842 or 851-972
|
||||
seat: 43-181 or 194-955
|
||||
train: 29-500 or 513-964
|
||||
type: 32-59 or 73-974
|
||||
wagon: 47-809 or 816-957
|
||||
zone: 44-451 or 464-955
|
||||
|
||||
your ticket:
|
||||
151,103,173,199,211,107,167,59,113,179,53,197,83,163,101,149,109,79,181,73
|
||||
|
||||
nearby tickets:
|
||||
339,870,872,222,255,276,706,890,583,718,924,118,201,141,59,581,931,143,221,919
|
||||
400,418,807,726,84,142,820,112,228,687,335,855,761,740,627,532,369,313,147,620
|
||||
474,926,741,424,632,982,876,926,738,936,300,726,400,321,348,160,421,464,78,258
|
||||
337,683,885,368,214,215,620,650,321,311,200,696,838,880,526,812,821,891,829,204
|
||||
678,69,480,939,219,736,628,948,178,296,204,890,199,526,736,210,170,923,228,726
|
||||
574,55,871,945,347,207,840,707,442,791,159,216,427,312,947,326,738,801,264,54
|
||||
811,259,417,932,870,634,945,408,706,766,303,402,942,50,415,150,839,674,904,836
|
||||
670,358,701,172,231,914,875,205,586,517,576,206,796,400,363,303,295,932,73,308
|
||||
319,949,312,803,217,6,719,870,202,883,111,532,467,801,83,202,331,637,930,412
|
||||
580,262,196,529,401,806,446,104,326,657,589,789,876,817,470,653,167,191,634,678
|
||||
720,217,118,422,190,115,684,827,317,228,524,569,531,471,322,408,896,566,875,302
|
||||
678,683,218,820,896,303,296,316,229,758,114,261,825,750,901,428,479,556,373,404
|
||||
502,259,577,77,260,588,340,199,626,575,171,422,372,83,111,902,300,863,800,886
|
||||
577,216,195,804,298,948,83,807,878,656,740,743,854,740,219,331,714,176,683,199
|
||||
492,187,259,528,853,80,808,887,149,723,324,922,170,323,884,825,710,562,416,471
|
||||
702,55,141,261,743,256,632,693,787,581,363,851,578,74,164,146,413,224,829,282
|
||||
370,161,470,207,876,57,564,103,195,216,468,632,161,734,487,150,570,251,311,196
|
||||
242,430,115,575,806,258,109,85,433,794,85,258,647,596,84,339,215,879,203,74
|
||||
912,449,174,371,857,556,743,537,521,643,903,745,764,207,295,896,431,901,592,332
|
||||
687,361,855,683,298,828,421,894,163,214,308,110,643,495,106,198,613,205,322,582
|
||||
318,578,83,318,150,182,298,740,424,306,411,895,50,265,887,465,912,262,294,428
|
||||
320,948,74,114,643,801,928,280,868,930,822,140,620,696,627,520,692,820,526,764
|
||||
622,477,314,253,419,73,333,924,750,432,705,894,114,827,364,946,577,269,789,463
|
||||
639,742,840,541,656,787,222,637,728,734,558,744,173,801,80,629,634,572,151,326
|
||||
830,468,597,75,259,762,331,315,151,369,308,419,447,207,523,268,118,719,501,839
|
||||
496,312,525,343,559,77,114,404,362,595,656,301,622,337,741,818,816,352,1,449
|
||||
432,512,627,739,729,627,218,829,595,471,641,447,639,350,220,718,573,319,859,363
|
||||
646,368,258,320,916,520,328,327,180,357,646,620,530,208,269,84,264,53,184,163
|
||||
904,657,329,897,327,339,674,803,110,327,308,78,883,353,150,446,296,645,539,932
|
||||
472,726,685,676,406,419,594,419,699,364,416,868,106,53,662,856,859,571,674,571
|
||||
301,741,900,869,259,727,557,975,334,913,496,948,929,79,165,680,838,465,591,902
|
||||
939,201,586,897,948,725,625,224,923,801,910,723,361,338,55,217,721,300,674,777
|
||||
362,211,592,573,711,831,170,949,171,408,647,578,228,349,629,780,582,567,84,349
|
||||
317,874,623,704,934,526,898,797,447,485,400,589,679,109,827,107,353,807,859,513
|
||||
519,108,304,162,888,88,742,637,789,923,749,404,171,175,708,432,559,200,557,444
|
||||
787,589,518,397,762,200,734,222,468,252,306,560,558,701,905,656,155,689,51,258
|
||||
354,159,938,734,932,636,478,162,562,718,315,712,933,862,530,877,118,535,366,797
|
||||
189,338,517,302,414,401,167,905,947,500,895,940,405,222,864,706,835,352,269,825
|
||||
757,404,212,426,628,113,945,480,398,271,353,364,225,804,643,84,416,728,936,223
|
||||
337,529,631,589,909,314,174,820,257,199,822,359,344,445,929,20,513,450,212,928
|
||||
254,927,865,202,851,733,897,329,433,224,319,674,857,722,837,207,419,84,728,375
|
||||
416,464,822,368,920,175,0,213,799,200,648,529,398,889,678,407,180,870,496,786
|
||||
712,335,80,824,826,416,261,400,904,630,255,691,259,723,344,354,786,857,774,195
|
||||
945,257,57,260,642,817,934,909,574,358,269,683,764,176,365,427,549,878,500,791
|
||||
807,140,308,885,866,623,80,111,648,848,572,643,853,854,560,934,699,52,580,164
|
||||
895,590,647,730,540,874,255,115,304,117,224,399,168,819,420,525,306,160,580,595
|
||||
594,265,401,920,855,62,352,706,908,835,925,908,829,620,476,51,251,73,875,696
|
||||
261,748,411,706,409,53,470,202,227,918,653,398,516,518,416,187,917,836,649,222
|
||||
288,690,877,468,620,451,147,919,251,408,836,584,319,729,640,445,673,87,650,856
|
||||
308,806,477,875,329,928,948,800,417,574,220,991,355,51,693,838,747,794,498,913
|
||||
706,582,499,834,887,109,677,857,280,407,651,517,468,407,403,303,515,881,656,523
|
||||
256,597,344,577,636,702,561,738,683,884,268,858,73,201,421,721,646,739,424,992
|
||||
903,211,920,623,160,152,567,786,852,423,179,258,690,493,110,505,823,303,721,373
|
||||
397,893,747,819,729,88,651,893,699,229,744,948,712,104,741,643,511,854,876,706
|
||||
929,880,820,532,259,621,307,480,900,59,915,188,863,624,119,252,928,935,451,885
|
||||
335,893,475,733,787,850,629,839,530,231,451,942,260,718,654,473,255,495,406,464
|
||||
451,822,629,745,226,595,295,862,408,592,498,474,77,110,845,354,906,424,913,936
|
||||
75,891,446,347,468,521,312,320,346,579,900,205,528,307,370,890,8,269,826,566
|
||||
566,353,58,360,629,793,649,567,259,736,261,531,118,880,244,145,581,172,885,471
|
||||
107,371,947,936,250,468,624,888,334,622,947,327,837,941,360,521,754,199,688,905
|
||||
313,163,370,367,8,174,341,792,153,736,725,581,313,203,872,225,590,720,841,475
|
||||
210,823,329,556,763,691,371,202,807,902,741,413,303,832,651,802,473,358,990,897
|
||||
718,652,891,367,702,640,645,883,817,231,590,842,350,820,291,681,422,859,691,338
|
||||
349,408,890,915,116,719,872,589,586,620,116,206,683,353,317,81,319,86,849,797
|
||||
84,520,856,641,254,206,209,356,178,476,728,114,559,802,579,377,298,112,941,853
|
||||
518,741,500,466,796,676,833,235,330,854,494,762,58,923,908,228,335,433,85,565
|
||||
418,697,943,513,854,907,824,872,479,81,372,324,688,216,299,407,621,492,63,685
|
||||
559,652,645,107,685,577,870,370,509,58,371,85,445,800,174,255,412,475,640,837
|
||||
85,366,789,597,625,701,275,166,632,82,854,422,628,863,855,213,448,213,517,263
|
||||
447,373,853,469,912,545,712,695,749,673,299,647,744,826,893,367,865,448,116,943
|
||||
570,520,859,919,742,221,577,316,946,358,82,910,892,595,584,559,644,593,665,879
|
||||
645,345,399,430,697,86,641,642,239,764,325,253,728,82,891,372,402,270,400,153
|
||||
144,533,735,296,806,648,521,747,115,194,405,764,188,861,838,584,872,373,738,744
|
||||
446,180,652,85,429,330,172,517,629,566,167,922,177,884,751,868,919,102,494,930
|
||||
306,946,257,637,886,231,836,566,108,210,357,720,791,819,826,489,346,159,420,883
|
||||
360,622,764,398,398,82,323,165,403,185,557,447,635,171,493,211,736,570,766,79
|
||||
840,174,102,911,424,821,878,311,498,785,798,572,211,268,59,177,732,853,475,165
|
||||
109,228,693,210,300,882,184,419,872,939,706,693,596,635,625,905,566,351,202,727
|
||||
686,414,806,638,869,737,407,506,912,465,448,738,913,118,514,321,363,180,905,345
|
||||
928,348,305,110,916,827,222,681,197,313,827,903,148,761,498,523,643,297,430,897
|
||||
317,816,623,799,152,518,491,801,934,762,694,708,583,257,818,400,931,358,899,755
|
||||
418,943,493,888,559,252,826,222,680,726,426,639,104,579,886,732,844,111,856,817
|
||||
478,728,865,930,591,340,734,401,900,399,116,839,78,106,315,111,667,631,302,478
|
||||
744,691,703,984,901,301,75,432,687,336,630,421,527,116,944,111,930,641,497,729
|
||||
529,930,589,712,588,59,817,76,566,704,319,253,935,423,692,753,626,217,299,142
|
||||
911,403,257,196,179,178,55,627,468,546,684,327,255,923,912,252,646,266,206,207
|
||||
889,638,475,473,866,227,789,148,72,57,50,366,269,743,878,901,627,227,586,199
|
||||
833,976,570,51,335,212,173,110,652,424,446,858,677,73,787,107,877,159,587,165
|
||||
333,831,361,52,165,59,145,528,935,57,262,366,884,198,354,223,985,808,170,521
|
||||
928,301,762,573,572,832,728,708,933,150,689,308,680,579,603,313,354,582,368,477
|
||||
437,686,400,937,162,594,878,414,170,209,259,886,432,208,348,228,399,519,708,574
|
||||
85,633,54,353,886,917,161,499,496,78,804,119,652,496,511,919,476,306,728,51
|
||||
451,718,399,578,639,651,293,940,364,75,450,364,799,341,851,295,465,335,754,266
|
||||
371,268,852,750,706,735,113,752,863,795,467,572,794,497,838,310,160,367,251,471
|
||||
883,269,624,268,268,557,68,197,590,330,678,316,429,266,877,414,896,733,899,746
|
||||
991,521,595,300,422,471,686,620,159,341,448,730,694,513,342,575,743,213,790,684
|
||||
178,252,643,595,697,59,703,328,424,76,567,173,254,880,805,728,519,798,332,157
|
||||
297,373,312,687,566,491,571,109,448,581,720,873,552,695,806,446,351,854,594,150
|
||||
260,216,58,789,676,180,708,785,115,252,331,344,498,334,570,935,200,105,208,687
|
||||
207,484,171,323,466,722,794,833,323,50,763,347,729,252,710,176,910,328,74,649
|
||||
938,293,838,840,341,429,702,483,259,852,900,112,143,180,881,526,519,58,466,750
|
||||
700,172,253,365,871,563,643,520,945,587,253,852,492,731,493,281,310,112,573,220
|
||||
425,941,103,586,871,801,807,918,843,898,522,251,799,177,763,144,195,228,408,84
|
||||
149,256,792,82,711,419,533,946,835,271,76,681,172,141,120,451,178,633,358,297
|
||||
595,79,203,762,856,988,556,562,791,528,635,678,865,205,449,870,823,341,260,817
|
||||
407,24,904,411,818,365,859,654,491,817,297,86,674,218,360,840,620,54,806,708
|
||||
466,210,258,641,199,766,76,256,651,267,824,343,940,405,198,701,431,259,205,536
|
||||
561,164,326,563,765,897,177,805,207,571,425,572,349,734,907,233,255,310,54,88
|
||||
934,866,361,699,709,861,140,680,217,699,172,647,572,923,56,319,164,475,136,255
|
||||
689,587,52,885,751,517,624,915,790,347,172,366,162,941,893,916,358,419,421,226
|
||||
562,516,58,626,940,802,840,212,473,230,887,875,180,893,332,942,274,896,718,170
|
||||
863,557,196,692,263,53,145,340,211,61,117,816,417,108,171,111,683,312,559,75
|
||||
250,808,732,474,174,261,312,587,349,167,573,934,790,334,819,643,784,212,564,500
|
||||
480,103,319,230,477,428,119,563,896,421,568,712,923,519,737,672,882,398,496,625
|
||||
424,787,54,256,917,880,415,466,309,410,59,836,230,189,594,927,620,730,561,168
|
||||
584,104,415,451,747,808,349,742,54,410,315,711,531,277,705,521,368,259,144,708
|
||||
365,467,337,75,993,147,223,519,150,206,864,946,763,51,596,105,736,310,695,146
|
||||
79,365,85,309,649,676,324,597,938,310,733,942,223,693,316,904,413,229,833,484
|
||||
946,921,52,450,229,180,700,268,16,701,919,885,730,682,494,836,786,852,171,220
|
||||
295,750,718,149,626,497,335,819,518,624,199,705,631,825,418,897,468,19,698,866
|
||||
556,584,807,269,721,213,420,721,870,812,88,359,180,829,738,789,295,877,151,360
|
||||
940,333,838,622,637,173,325,923,547,866,304,398,943,789,822,916,639,679,261,340
|
||||
480,266,711,197,322,112,362,169,705,828,84,862,719,17,593,864,142,561,916,356
|
||||
337,675,859,872,586,689,329,949,771,573,267,932,200,526,333,161,350,115,300,697
|
||||
562,362,942,150,924,215,330,162,753,565,498,321,307,709,641,697,863,578,205,868
|
||||
655,464,886,153,318,402,818,733,490,73,354,853,936,858,637,473,203,301,177,312
|
||||
705,429,402,348,882,471,644,193,427,687,804,841,414,270,332,720,228,633,787,880
|
||||
265,927,325,889,345,403,88,168,219,696,230,570,733,521,833,217,482,711,522,742
|
||||
335,702,271,178,592,569,845,913,176,649,299,916,788,253,205,860,146,113,710,168
|
||||
264,219,87,368,798,852,470,224,646,367,355,710,655,17,649,219,942,169,314,118
|
||||
54,710,880,343,270,468,269,850,167,50,675,303,688,750,419,870,324,674,728,914
|
||||
528,423,153,101,939,471,418,21,414,926,656,446,211,826,681,863,897,530,839,347
|
||||
909,298,338,890,335,216,693,171,584,480,228,987,198,252,582,657,641,218,824,791
|
||||
254,578,837,816,936,271,368,268,167,101,685,516,743,399,465,542,495,626,888,319
|
||||
268,140,857,844,79,763,115,322,735,159,409,519,857,699,317,917,520,910,75,728
|
||||
628,2,410,568,299,252,168,683,587,303,743,141,702,723,498,911,766,165,465,800
|
||||
431,583,212,933,253,358,981,114,766,764,942,361,524,586,203,730,562,627,449,926
|
||||
631,337,858,720,866,567,723,828,731,926,145,204,640,653,231,724,688,371,482,144
|
||||
83,571,836,361,797,349,834,809,704,293,839,301,271,219,797,743,803,637,719,811
|
||||
844,59,356,851,692,180,786,476,703,801,323,797,943,86,432,329,943,596,868,745
|
||||
230,922,302,180,118,241,231,867,469,639,161,207,807,325,825,74,338,526,722,855
|
||||
628,0,416,116,143,467,262,937,269,590,80,926,176,523,519,674,523,911,651,366
|
||||
873,934,81,406,163,945,905,216,359,795,819,554,314,583,722,568,597,317,204,880
|
||||
433,683,181,426,583,631,826,873,894,938,588,854,308,267,885,222,861,843,719,144
|
||||
905,825,294,143,203,465,794,674,346,364,180,88,865,168,905,947,897,943,252,717
|
||||
492,416,629,719,827,108,921,163,745,930,500,343,426,740,777,326,574,149,250,589
|
||||
940,340,584,722,251,520,880,532,151,398,795,886,869,253,185,304,468,311,852,877
|
||||
833,371,112,810,56,516,829,352,641,466,295,528,476,718,413,725,559,917,818,533
|
||||
677,355,203,373,356,398,573,831,750,410,697,809,53,597,435,946,173,890,905,152
|
||||
588,465,475,201,523,521,340,897,427,834,875,718,635,407,733,323,908,341,440,595
|
||||
478,496,748,82,890,210,623,809,315,273,58,681,655,101,640,325,621,337,494,299
|
||||
216,761,834,342,766,808,466,325,51,480,221,721,433,411,403,342,267,620,218,255
|
||||
301,58,310,355,891,149,474,681,76,677,518,734,532,745,908,333,519,418,278,446
|
||||
842,527,339,354,940,828,198,478,413,181,695,84,637,988,712,938,165,147,696,211
|
||||
795,712,522,698,402,310,813,465,910,630,263,331,731,706,936,686,226,829,199,828
|
||||
575,786,691,828,447,512,730,270,56,722,794,108,175,346,639,174,217,347,652,822
|
||||
530,732,51,688,74,696,416,309,264,521,209,727,710,259,361,401,559,909,260,510
|
||||
368,590,119,906,200,725,329,696,942,140,118,933,474,847,657,557,652,823,162,332
|
||||
107,940,194,558,335,798,926,366,528,918,880,867,695,491,268,226,70,765,150,732
|
||||
161,684,179,184,732,749,265,529,349,87,934,467,723,111,216,201,861,795,449,801
|
||||
649,141,914,636,468,196,656,703,813,897,852,472,347,56,337,809,736,901,707,747
|
||||
594,141,425,316,174,573,885,357,873,595,726,334,59,745,717,887,207,200,310,357
|
||||
732,368,862,346,795,657,531,464,721,356,732,422,114,735,328,421,741,332,394,164
|
||||
264,261,806,898,471,170,763,819,642,690,500,267,847,592,73,906,171,175,909,532
|
||||
77,852,267,578,219,913,795,839,85,920,645,560,303,871,404,804,595,206,727,138
|
||||
264,323,50,338,301,417,702,817,791,666,172,674,597,721,876,705,576,449,786,945
|
||||
880,633,356,366,197,692,209,426,261,940,643,634,926,160,269,590,191,293,928,529
|
||||
295,700,113,627,643,557,141,820,379,140,430,677,791,450,686,118,322,479,495,423
|
||||
467,749,178,367,520,566,938,114,176,226,894,470,908,824,806,373,436,596,497,575
|
||||
816,233,748,518,829,424,901,643,56,565,333,570,561,948,114,430,632,901,301,708
|
||||
208,268,409,297,571,838,722,62,889,885,256,725,166,869,168,150,647,406,498,762
|
||||
646,695,359,76,710,363,748,887,416,515,696,227,166,86,742,308,140,721,311,663
|
||||
635,479,734,830,338,224,563,359,88,587,676,370,582,871,840,476,247,790,856,584
|
||||
226,101,270,301,423,103,264,674,724,361,349,620,646,337,801,830,445,688,746,64
|
||||
821,112,882,887,295,764,760,789,623,198,655,922,109,809,922,88,399,419,925,305
|
||||
891,308,685,214,106,147,228,903,114,497,309,743,175,399,416,416,354,935,747,990
|
||||
642,449,852,913,621,752,318,255,331,478,229,680,630,871,865,922,253,422,151,201
|
||||
115,732,583,361,316,500,210,77,319,737,448,625,371,651,202,949,403,228,263,999
|
||||
711,280,169,354,364,255,176,633,560,225,194,214,252,229,168,117,329,348,344,681
|
||||
168,471,181,476,368,691,918,19,910,325,629,793,298,340,880,570,201,686,795,398
|
||||
763,206,648,686,679,163,250,167,178,917,301,205,69,372,175,201,802,629,258,513
|
||||
340,304,195,422,220,450,942,500,620,505,88,924,266,566,832,50,647,480,222,840
|
||||
643,560,923,526,880,942,411,945,184,527,630,725,258,118,908,868,205,422,416,523
|
||||
376,639,418,938,425,905,650,891,317,269,495,940,113,582,728,178,176,589,802,78
|
||||
775,312,631,797,931,103,109,588,109,464,680,293,655,149,167,821,415,816,260,881
|
||||
478,655,496,170,419,806,582,115,908,639,110,153,644,571,543,164,103,210,175,228
|
||||
206,211,889,225,703,901,857,530,648,144,81,934,110,923,305,846,433,745,529,646
|
||||
493,763,224,310,921,644,355,479,81,115,269,265,886,9,110,625,694,675,350,636
|
||||
836,518,345,917,78,445,478,892,945,476,417,107,862,744,380,327,872,935,884,691
|
||||
928,475,349,927,404,801,203,924,667,915,143,932,119,197,864,513,646,802,359,592
|
||||
194,369,582,115,422,531,675,373,166,640,311,268,703,710,826,699,722,114,795,847
|
||||
179,257,525,695,324,197,745,719,171,450,707,576,814,478,888,426,828,749,268,916
|
||||
654,520,898,640,929,586,425,828,862,861,861,266,743,297,0,689,884,116,414,366
|
||||
318,365,189,651,586,294,326,429,735,569,934,109,447,914,675,701,701,803,106,634
|
||||
145,229,170,364,581,722,918,875,866,410,566,982,635,321,750,164,741,335,403,918
|
||||
890,497,731,81,432,417,919,338,355,297,153,640,675,799,620,684,518,4,209,301
|
||||
197,733,109,834,889,207,898,400,140,525,424,583,416,448,902,201,902,688,472,14
|
||||
0,809,569,206,625,431,56,448,913,800,476,344,882,269,166,314,908,202,373,570
|
||||
206,201,414,688,166,718,677,696,978,431,594,263,628,449,868,360,807,305,346,499
|
||||
217,513,429,924,143,167,526,348,268,101,260,654,917,866,812,748,59,816,589,655
|
||||
788,52,203,270,361,796,895,466,596,149,864,929,895,325,351,702,883,316,892,239
|
||||
831,500,911,524,820,498,547,315,737,103,494,406,220,358,467,414,725,415,466,472
|
||||
577,821,171,9,863,807,398,354,266,268,339,724,932,691,334,679,450,264,228,654
|
||||
116,497,360,294,166,469,919,870,321,592,566,206,883,214,736,309,806,762,810,748
|
||||
839,525,166,295,269,203,892,578,740,645,305,583,874,634,681,499,998,912,365,638
|
||||
419,692,496,597,297,945,929,410,911,699,733,868,831,709,932,680,890,199,728,615
|
||||
944,820,324,693,736,874,637,872,528,249,681,149,339,151,464,591,225,314,315,313
|
||||
270,639,345,944,690,150,201,822,851,468,876,830,511,303,57,923,762,869,472,316
|
||||
641,793,104,944,23,870,307,788,877,591,860,328,492,899,472,328,419,361,903,820
|
||||
799,992,500,116,516,142,903,451,177,477,931,560,744,77,570,52,344,695,816,50
|
||||
691,227,707,202,302,813,149,623,261,116,575,564,704,824,653,890,937,101,174,256
|
||||
257,112,339,420,261,834,492,907,912,649,874,838,729,826,271,345,361,470,637,193
|
||||
339,812,319,906,401,575,867,586,207,351,697,497,855,740,407,347,945,736,152,896
|
||||
925,845,88,477,58,216,885,565,623,259,142,307,621,304,115,476,939,700,202,469
|
||||
808,786,83,651,174,623,579,224,224,789,208,161,7,722,116,350,698,733,883,199
|
||||
682,421,887,432,847,336,524,654,361,371,161,480,59,880,797,348,407,308,681,403
|
||||
686,571,408,941,788,705,480,365,678,728,631,591,152,555,119,725,595,936,143,142
|
||||
825,331,993,830,876,399,142,880,741,140,694,947,293,532,445,855,78,912,357,412
|
||||
898,315,491,897,927,807,165,596,695,563,877,700,56,307,480,253,139,77,117,762
|
||||
299,690,341,493,500,152,351,810,631,339,828,87,205,565,725,696,207,828,270,404
|
||||
484,260,809,639,52,620,910,223,499,706,465,348,85,698,116,622,579,707,826,571
|
||||
621,655,13,445,733,686,411,449,467,898,491,75,344,805,148,356,195,79,449,653
|
||||
988,891,824,632,229,909,571,176,928,586,708,117,471,560,864,805,725,161,114,934
|
||||
741,165,570,908,632,728,938,570,516,220,86,301,655,882,581,637,877,475,234,320
|
||||
67,801,766,731,254,827,916,572,449,621,628,596,478,175,166,696,323,533,416,701
|
||||
720,58,837,307,695,306,629,215,522,706,856,591,281,110,175,872,532,524,181,167
|
||||
525,841,651,174,940,530,165,869,423,250,920,705,724,742,112,144,378,259,467,360
|
||||
740,648,791,679,674,404,165,265,151,256,348,162,880,150,66,353,80,636,258,115
|
||||
886,575,150,754,365,562,362,522,498,571,639,364,834,169,55,562,470,446,466,366
|
||||
552,361,412,118,318,724,652,828,450,627,469,594,424,620,519,108,884,884,53,349
|
||||
519,587,585,341,892,56,175,316,312,472,874,496,267,358,946,874,812,218,943,228
|
||||
927,307,867,229,597,448,929,557,688,886,269,331,718,345,471,651,369,838,619,469
|
||||
203,796,199,515,424,212,572,529,220,786,170,889,198,359,596,65,626,569,933,687
|
||||
208,105,266,278,269,653,531,627,881,253,81,632,836,445,574,788,348,209,166,586
|
||||
425,543,702,474,424,673,918,747,628,762,175,931,832,863,79,213,109,557,881,494
|
||||
606,789,514,465,893,339,315,494,314,921,944,477,724,920,856,150,733,932,897,415
|
399
d16/main.go
Normal file
399
d16/main.go
Normal file
@ -0,0 +1,399 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func processLines(path string, f func(string) (stop bool, err error)) error {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
scanner := bufio.NewScanner(file)
|
||||
for scanner.Scan() {
|
||||
stop, err := f(scanner.Text())
|
||||
if stop || err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func processGroups(path string, f func([]string) (stop bool, err error)) error {
|
||||
group := []string{}
|
||||
|
||||
if err := processLines(path, func(line string) (stop bool, err error) {
|
||||
if line == "" {
|
||||
stop, err = f(group)
|
||||
if stop || err != nil {
|
||||
return
|
||||
}
|
||||
group = []string{}
|
||||
} else {
|
||||
group = append(group, line)
|
||||
}
|
||||
|
||||
return
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err := f(group)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// StringSet is a set of strings.
|
||||
type StringSet map[string]bool
|
||||
|
||||
// Add an item to a StringSet.
|
||||
func (s *StringSet) Add(v string) {
|
||||
(*s)[v] = true
|
||||
}
|
||||
|
||||
// AddAll adds all items in a list to the set.
|
||||
func (s *StringSet) AddAll(l []string) {
|
||||
for _, v := range l {
|
||||
s.Add(v)
|
||||
}
|
||||
}
|
||||
|
||||
// Values returns all values in the set as a list.
|
||||
func (s StringSet) Values() []string {
|
||||
values := []string{}
|
||||
for k := range s {
|
||||
values = append(values, k)
|
||||
}
|
||||
|
||||
return values
|
||||
}
|
||||
|
||||
// NewStringSet creates an empty string set.
|
||||
func NewStringSet() StringSet {
|
||||
return StringSet{}
|
||||
}
|
||||
|
||||
// Union returns the union of two SringSets.
|
||||
func Union(s1, s2 StringSet) StringSet {
|
||||
union := NewStringSet()
|
||||
|
||||
for v := range s1 {
|
||||
union.Add(v)
|
||||
}
|
||||
|
||||
for v := range s2 {
|
||||
union.Add(v)
|
||||
}
|
||||
|
||||
return union
|
||||
}
|
||||
|
||||
// Intersection returns the union of two SringSets.
|
||||
func Intersection(s1, s2 StringSet) StringSet {
|
||||
intersect := NewStringSet()
|
||||
|
||||
for v := range s1 {
|
||||
if _, ok := s2[v]; ok {
|
||||
intersect.Add(v)
|
||||
}
|
||||
}
|
||||
|
||||
return intersect
|
||||
}
|
||||
|
||||
// Difference returns the value of s1 with values of s2 removed.
|
||||
func Difference(s1, s2 StringSet) StringSet {
|
||||
difference := NewStringSet()
|
||||
|
||||
for v := range s1 {
|
||||
if _, ok := s2[v]; !ok {
|
||||
difference.Add(v)
|
||||
}
|
||||
}
|
||||
|
||||
return difference
|
||||
}
|
||||
|
||||
type numRange struct {
|
||||
lower, upper int
|
||||
}
|
||||
|
||||
func (r numRange) validate(n int) bool {
|
||||
return r.lower <= n && n <= r.upper
|
||||
}
|
||||
|
||||
type fieldRule struct {
|
||||
name string
|
||||
ranges []numRange
|
||||
}
|
||||
|
||||
func (f fieldRule) validate(n int) bool {
|
||||
for _, r := range f.ranges {
|
||||
if r.validate(n) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
var ruleMatcher = regexp.MustCompile(`([a-z ]+): ([0-9]+)-([0-9]+) or ([0-9]+)-([0-9]+)`)
|
||||
|
||||
func parseFieldRule(line string) (fieldRule, error) {
|
||||
res := ruleMatcher.FindStringSubmatch(line)
|
||||
if res == nil {
|
||||
return fieldRule{}, fmt.Errorf("failed parsing rule line: %s", line)
|
||||
}
|
||||
|
||||
name := res[1]
|
||||
|
||||
l1, err := strconv.Atoi(res[2])
|
||||
if err != nil {
|
||||
return fieldRule{}, fmt.Errorf("failed parsing int in rule %w", err)
|
||||
}
|
||||
|
||||
u1, err := strconv.Atoi(res[3])
|
||||
if err != nil {
|
||||
return fieldRule{}, fmt.Errorf("failed parsing int in rule %w", err)
|
||||
}
|
||||
|
||||
l2, err := strconv.Atoi(res[4])
|
||||
if err != nil {
|
||||
return fieldRule{}, fmt.Errorf("failed parsing int in rule %w", err)
|
||||
}
|
||||
|
||||
u2, err := strconv.Atoi(res[5])
|
||||
if err != nil {
|
||||
return fieldRule{}, fmt.Errorf("failed parsing int in rule %w", err)
|
||||
}
|
||||
|
||||
return fieldRule{
|
||||
name: name,
|
||||
ranges: []numRange{
|
||||
numRange{
|
||||
lower: l1,
|
||||
upper: u1,
|
||||
},
|
||||
numRange{
|
||||
lower: l2,
|
||||
upper: u2,
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
type fieldRules []fieldRule
|
||||
|
||||
func (f fieldRules) validFields(n int) []string {
|
||||
validFields := []string{}
|
||||
for _, r := range f {
|
||||
if r.validate(n) {
|
||||
validFields = append(validFields, r.name)
|
||||
}
|
||||
}
|
||||
|
||||
return validFields
|
||||
}
|
||||
|
||||
type ticket []int
|
||||
|
||||
func parseTicket(line string) (ticket, error) {
|
||||
t := ticket{}
|
||||
|
||||
for _, n := range strings.Split(line, ",") {
|
||||
i, err := strconv.Atoi(n)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
t = append(t, i)
|
||||
}
|
||||
|
||||
return t, nil
|
||||
}
|
||||
|
||||
func parseInput() (fieldRules, ticket, []ticket) {
|
||||
rules := fieldRules{}
|
||||
nearby := []ticket{}
|
||||
|
||||
var t ticket
|
||||
|
||||
if err := processGroups("input.txt", func(group []string) (bool, error) {
|
||||
if len(rules) == 0 {
|
||||
for _, line := range group {
|
||||
rule, err := parseFieldRule(line)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
rules = append(rules, rule)
|
||||
}
|
||||
} else if group[0] == "your ticket:" {
|
||||
var err error
|
||||
t, err = parseTicket(group[1])
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
} else if group[0] == "nearby tickets:" {
|
||||
for _, line := range group[1:] {
|
||||
nt, err := parseTicket(line)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
nearby = append(nearby, nt)
|
||||
}
|
||||
} else {
|
||||
log.Fatal(fmt.Errorf("unknown section %v", group))
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
return rules, t, nearby
|
||||
}
|
||||
|
||||
func part1() {
|
||||
rules, _, nearby := parseInput()
|
||||
|
||||
invalid := 0
|
||||
|
||||
for _, t := range nearby {
|
||||
for _, v := range t {
|
||||
if len(rules.validFields(v)) == 0 {
|
||||
invalid += v
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("Total scanning error rate is %d\n", invalid)
|
||||
}
|
||||
|
||||
func reduceFields(fieldOptions []StringSet) ([]string, error) {
|
||||
type fieldOption struct {
|
||||
options StringSet
|
||||
position int
|
||||
}
|
||||
|
||||
workingFields := []fieldOption{}
|
||||
for i, o := range fieldOptions {
|
||||
workingFields = append(
|
||||
workingFields,
|
||||
fieldOption{o, i},
|
||||
)
|
||||
}
|
||||
|
||||
// Sort slice by number of options
|
||||
sort.Slice(workingFields, func(i, j int) bool {
|
||||
return len(workingFields[i].options) < len(workingFields[j].options)
|
||||
})
|
||||
|
||||
for i, o1 := range workingFields {
|
||||
if len(o1.options) == 1 {
|
||||
// Remove this option from everywhere else
|
||||
for j, o2 := range workingFields {
|
||||
if i == j {
|
||||
// Skip current outer index
|
||||
continue
|
||||
}
|
||||
|
||||
workingFields[j].options = Difference(o2.options, o1.options)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fmt.Printf("All options? %+v", workingFields)
|
||||
|
||||
// Sort slice by number of options
|
||||
sort.Slice(workingFields, func(i, j int) bool {
|
||||
return workingFields[i].position < workingFields[j].position
|
||||
})
|
||||
|
||||
results := []string{}
|
||||
for _, o := range workingFields {
|
||||
if len(o.options) != 1 {
|
||||
return []string{}, fmt.Errorf("some options have multiple values")
|
||||
}
|
||||
|
||||
results = append(results, o.options.Values()[0])
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
func part2() {
|
||||
rules, myTicket, nearby := parseInput()
|
||||
fieldOptions := []StringSet{}
|
||||
|
||||
// Get all possible field names
|
||||
allFields := []string{}
|
||||
for _, rule := range rules {
|
||||
allFields = append(allFields, rule.name)
|
||||
}
|
||||
|
||||
// Add them to every field in ticket
|
||||
for range myTicket {
|
||||
s := StringSet{}
|
||||
s.AddAll(allFields)
|
||||
fieldOptions = append(fieldOptions, s)
|
||||
}
|
||||
|
||||
var ticketOptions []StringSet
|
||||
|
||||
for _, nearbyTicket := range nearby {
|
||||
ticketOptions = []StringSet{}
|
||||
for _, ticketValue := range nearbyTicket {
|
||||
validFields := StringSet{}
|
||||
validFields.AddAll(rules.validFields(ticketValue))
|
||||
if len(validFields) == 0 {
|
||||
// This ticket is invalid
|
||||
ticketOptions = nil
|
||||
break
|
||||
}
|
||||
ticketOptions = append(ticketOptions, validFields)
|
||||
}
|
||||
// Done checking ticket
|
||||
if ticketOptions != nil {
|
||||
// Ticket is valid
|
||||
for i := range fieldOptions {
|
||||
fieldOptions[i] = Intersection(fieldOptions[i], ticketOptions[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fmt.Printf("Final fieldOptions %+v\n", fieldOptions)
|
||||
|
||||
fieldLabels, err := reduceFields(fieldOptions)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// fmt.Println("Values: ", fieldLabels)
|
||||
product := 1
|
||||
for i, label := range fieldLabels {
|
||||
if strings.HasPrefix(label, "departure") {
|
||||
product *= myTicket[i]
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("Product of all departures %d\n", product)
|
||||
}
|
||||
|
||||
func main() {
|
||||
part1()
|
||||
part2()
|
||||
}
|
8
d17/input.txt
Normal file
8
d17/input.txt
Normal file
@ -0,0 +1,8 @@
|
||||
#...#.#.
|
||||
..#.#.##
|
||||
..#..#..
|
||||
.....###
|
||||
...#.#.#
|
||||
#.#.##..
|
||||
#####...
|
||||
.#.#.##.
|
113
d17/main.go
Normal file
113
d17/main.go
Normal file
@ -0,0 +1,113 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
var (
|
||||
activeRune = '#'
|
||||
inactiveRune = '.'
|
||||
)
|
||||
|
||||
type point3 [3]int
|
||||
|
||||
func addPoint(p1, p2 point3) point3 {
|
||||
p := point3{}
|
||||
for i := range p {
|
||||
p[i] = p1[i] + p2[i]
|
||||
}
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
type cube struct {
|
||||
loc point3
|
||||
active bool
|
||||
|
||||
tock func() error
|
||||
world *grid
|
||||
}
|
||||
|
||||
func (c cube) neighbors() []cube {
|
||||
directions := []point3{
|
||||
// 1 pt
|
||||
point3{0, 0, 1},
|
||||
point3{0, 0, -1},
|
||||
point3{0, 1, 0},
|
||||
point3{0, -1, 0},
|
||||
point3{1, 0, 0},
|
||||
point3{-1, 0, 0},
|
||||
// 2pt
|
||||
point3{0, 1, 1},
|
||||
point3{0, 1, -1},
|
||||
point3{0, -1, 1},
|
||||
point3{0, -1, -1},
|
||||
point3{1, 1, 0},
|
||||
point3{1, -1, 0},
|
||||
point3{-1, 1, 0},
|
||||
point3{-1, -1, 0},
|
||||
point3{1, 0, 1},
|
||||
point3{-1, 0, 1},
|
||||
point3{1, 0, -1},
|
||||
point3{-1, 0, -1},
|
||||
// 3pt
|
||||
point3{1, 1, 1},
|
||||
point3{-1, 1, 1},
|
||||
point3{1, -1, 1},
|
||||
point3{1, 1, -1},
|
||||
point3{-1, -1, 1},
|
||||
point3{1, -1, -1},
|
||||
point3{-1, 1, -1},
|
||||
point3{-1, -1, -1},
|
||||
}
|
||||
}
|
||||
|
||||
func (c *cube) tick() error {
|
||||
|
||||
}
|
||||
|
||||
type world [][][]*cube
|
||||
|
||||
func (w world) getCube(p point) *cube {
|
||||
x := point[0]
|
||||
y := point[1]
|
||||
z := point[2]
|
||||
|
||||
if z >= len(w) {
|
||||
return nil
|
||||
}
|
||||
|
||||
slice := world[z]
|
||||
|
||||
if y >= len(slice) {
|
||||
return nil
|
||||
}
|
||||
|
||||
row := slice[y]
|
||||
|
||||
if x >= len(row) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return row[x]
|
||||
}
|
||||
|
||||
func (w *world) tick() error {
|
||||
for z, slice := range w {
|
||||
for y, row := range slice {
|
||||
for x, cube := range row {
|
||||
err := cube.tick()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
p := point3{}
|
||||
p[0] = 1
|
||||
fmt.Println(p)
|
||||
|
||||
}
|
703
d17/main.py
Executable file
703
d17/main.py
Executable file
@ -0,0 +1,703 @@
|
||||
#! /usr/bin/env python3
|
||||
from collections import namedtuple
|
||||
from itertools import product
|
||||
from typing import Any
|
||||
from typing import Callable
|
||||
from typing import Iterable
|
||||
from typing import List
|
||||
from typing import Optional
|
||||
from typing import Tuple
|
||||
from typing import Set
|
||||
|
||||
|
||||
Point = namedtuple("Point", "x y z w", defaults=(0,))
|
||||
|
||||
|
||||
back_refs = {
|
||||
"left": "right",
|
||||
"right": "left",
|
||||
"up": "down",
|
||||
"down": "up",
|
||||
"front": "back",
|
||||
"back": "front",
|
||||
}
|
||||
|
||||
ACTIVE = "#"
|
||||
INACTIVE = "."
|
||||
|
||||
|
||||
def add_points(p1, p2) -> Point:
|
||||
return Point(
|
||||
p1.x + p2.x,
|
||||
p1.y + p2.y,
|
||||
p1.z + p2.z,
|
||||
p1.w + p2.w,
|
||||
)
|
||||
|
||||
|
||||
class Cube(object):
|
||||
|
||||
def __init__(self, loc: Point, world: "World", active=False):
|
||||
self._loc = loc
|
||||
self._world = world
|
||||
self.active = active
|
||||
|
||||
self._ticked = False
|
||||
|
||||
def _tock():
|
||||
# print("Default tock")
|
||||
pass
|
||||
|
||||
self.tock = _tock
|
||||
|
||||
# def __init__(self, left=None, up=None, right=None,
|
||||
# down=None, front=None, back=None):
|
||||
# # self.set_neighbor("left", left)
|
||||
# # self.set_neighbor("up", up)
|
||||
# # self.set_neighbor("right", right)
|
||||
# # self.set_neighbor("down", down)
|
||||
# # self.set_neighbor("front", front)
|
||||
# # self.set_neighbor("back", back)
|
||||
#
|
||||
# # tock func
|
||||
# self.tock = None
|
||||
|
||||
# def set_neighbor(self, direction: str, value: "Cube"):
|
||||
# backref = back_refs[direction]
|
||||
# setattr(self, direction, value)
|
||||
# if value is not None:
|
||||
# setattr(value, backref, self)
|
||||
|
||||
def neighbors(self, expand=False) -> Iterable["Cube"]:
|
||||
seen_points: Set[Point] = set()
|
||||
for diff in product((0, 1, -1), repeat=4):
|
||||
# from pdb import set_trace; set_trace()
|
||||
neighbor_point = add_points(
|
||||
self._loc,
|
||||
Point(
|
||||
diff[0],
|
||||
diff[1],
|
||||
diff[2],
|
||||
diff[3],
|
||||
),
|
||||
)
|
||||
if self._loc == neighbor_point:
|
||||
# skip self
|
||||
continue
|
||||
|
||||
if neighbor_point in seen_points:
|
||||
# skip points we've already visited
|
||||
# print("Already seen, skipping")
|
||||
continue
|
||||
|
||||
seen_points.add(neighbor_point)
|
||||
|
||||
# print(f"Getting point {neighbor_point}")
|
||||
neighbor = self._world.get_point(neighbor_point, expand=expand)
|
||||
if neighbor is not None:
|
||||
# print("FOUND!")
|
||||
yield neighbor
|
||||
|
||||
def tick(self):
|
||||
active_neighbors = 0
|
||||
for neighbor in self.neighbors():
|
||||
# print(f"Neighbor is active: {neighbor.active}")
|
||||
if neighbor.active:
|
||||
# print(f"Neighbor is active {neighbor}")
|
||||
active_neighbors += 1
|
||||
|
||||
# if self._loc == Point(1, 3, 0):
|
||||
# import pdb; pdb.set_trace()
|
||||
|
||||
if self.active and active_neighbors not in (2, 3):
|
||||
# print("Should go inactive")
|
||||
def _tock():
|
||||
# print("go inactive")
|
||||
self.active = False
|
||||
|
||||
self.tock = _tock
|
||||
elif not self.active and active_neighbors == 3:
|
||||
# print("Should go active")
|
||||
def _tock():
|
||||
# print("go active")
|
||||
self.active = True
|
||||
|
||||
self.tock = _tock
|
||||
|
||||
else:
|
||||
# print("Should do nothing")
|
||||
def _tock():
|
||||
# print("Empty tock")
|
||||
pass
|
||||
|
||||
self.tock = _tock
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"({self._loc.x}, {self._loc.y}, {self._loc.z})"
|
||||
|
||||
def to_str(self) -> str:
|
||||
return ACTIVE if self.active else INACTIVE
|
||||
|
||||
|
||||
class AutoExpanding(object):
|
||||
_l: List[Any]
|
||||
_zero: int
|
||||
_item_factory: Callable[[int], Any]
|
||||
|
||||
def __init__(self):
|
||||
self._l = [self._item_factory(0)]
|
||||
self._zero = 0
|
||||
|
||||
def get(self, i, expand=True):
|
||||
if not expand:
|
||||
if self._zero+i < 0:
|
||||
raise IndexError(f"index {i} is out of bounds")
|
||||
return self._l[self._zero+i]
|
||||
|
||||
if self._zero is None:
|
||||
self._l = [self._item_factory(0)]
|
||||
self._zero = 0
|
||||
|
||||
if i > 0 and i >= len(self._l) - self._zero - 1:
|
||||
# print(f"resize pos to {i} with {self._l} zero={self._zero}")
|
||||
self._l = self._l + [
|
||||
self._item_factory(j)
|
||||
for j in range(len(self._l)-self._zero, i+1)
|
||||
]
|
||||
# print(f"> done {self._l} zero={self._zero}")
|
||||
elif i < 0 and abs(i) > self._zero:
|
||||
# print(f"resize neg to {i} with {self._l} zero={self._zero}")
|
||||
self._l = [
|
||||
self._item_factory(j)
|
||||
for j in range(i, -1 * self._zero)
|
||||
] + self._l
|
||||
self._zero = abs(i)
|
||||
# print(f"> done {self._l} zero={self._zero}")
|
||||
|
||||
# print(f"Now getting item at index {i} from {self._l}")
|
||||
return self._l[self._zero+i]
|
||||
|
||||
def __getitem__(self, i):
|
||||
if isinstance(i, slice):
|
||||
return [
|
||||
self[j]
|
||||
for j in range(
|
||||
i.start if i.start is not None else self.min_index(),
|
||||
(i.stop if i.stop is not None else self.max_index()) + 1,
|
||||
i.step or 1,
|
||||
)
|
||||
]
|
||||
|
||||
return self.get(i, expand=False)
|
||||
|
||||
def __setitem__(self, i, value):
|
||||
self.get(i, expand=True)
|
||||
self._l[self._zero+i] = value
|
||||
|
||||
def __len__(self) -> int:
|
||||
return len(self._l)
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self._l)
|
||||
|
||||
def min_index(self) -> int:
|
||||
return -1 * self._zero
|
||||
|
||||
def max_index(self) -> int:
|
||||
return len(self._l) - self._zero - 1
|
||||
|
||||
def get_bounds(self) -> Tuple[int, int]:
|
||||
return self.min_index(), self.max_index()
|
||||
|
||||
def resize(self, min_index: int, max_index: int):
|
||||
if min_index < self.min_index():
|
||||
self.get(min_index, expand=True)
|
||||
else:
|
||||
if min_index > 0:
|
||||
raise IndexError("Cannot resize to exclude zero")
|
||||
self._l = self[min_index:]
|
||||
self._zero = abs(min_index)
|
||||
|
||||
if max_index > self.max_index():
|
||||
self.get(max_index, expand=True)
|
||||
else:
|
||||
if max_index < 0:
|
||||
raise IndexError("Cannot resize to exclude zero")
|
||||
self._l = self[:max_index]
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"<AutoExpanding {self._l}>"
|
||||
|
||||
|
||||
class World(AutoExpanding):
|
||||
|
||||
def iter_cubes(self) -> Iterable[Cube]:
|
||||
raise NotImplementedError()
|
||||
|
||||
def tick(self):
|
||||
for c in self.iter_cubes():
|
||||
c.tick()
|
||||
|
||||
def tock(self):
|
||||
for c in self.iter_cubes():
|
||||
c.tock()
|
||||
|
||||
def get_point(self, p: Point, expand=True) -> Optional[Cube]:
|
||||
raise NotImplementedError()
|
||||
|
||||
def trim(self):
|
||||
raise NotImplementedError()
|
||||
|
||||
def get_all_bounds(self) -> Tuple[Point, Point]:
|
||||
raise NotImplementedError()
|
||||
|
||||
def true_up(self):
|
||||
raise NotImplementedError()
|
||||
|
||||
def expand_all(self, i: int):
|
||||
raise NotImplementedError()
|
||||
|
||||
def count_active(self) -> int:
|
||||
total = 0
|
||||
|
||||
for c in self.iter_cubes():
|
||||
if c.active:
|
||||
total += 1
|
||||
|
||||
return total
|
||||
|
||||
|
||||
class GridRow(AutoExpanding):
|
||||
def __init__(self, y: int, z: int, world: World, w: Optional[int] = 0):
|
||||
self._y = y
|
||||
self._z = z
|
||||
self._w = w
|
||||
self._world = world
|
||||
super().__init__()
|
||||
|
||||
def _item_factory(self, x: int) -> Cube:
|
||||
return Cube(Point(x, self._y, self._z, self._w), self._world)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return "[" + " ".join((str(c) for c in self._l)) + "]"
|
||||
|
||||
def to_str(self) -> str:
|
||||
return "".join((c.to_str() for c in self._l))
|
||||
|
||||
|
||||
class GridSlice(AutoExpanding):
|
||||
def __init__(self, z: int, world: World, w: Optional[int] = 0):
|
||||
self._z = z
|
||||
self._w = w
|
||||
self._world = world
|
||||
super().__init__()
|
||||
|
||||
def _item_factory(self, y: int) -> GridRow:
|
||||
return GridRow(y, self._z, self._world, w=self._w)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"z={self._z}\n" + "\n".join((
|
||||
str(r) for r in self._l
|
||||
))
|
||||
|
||||
def to_str(self) -> str:
|
||||
return f"z={self._z}\n" + "\n".join([r.to_str() for r in self._l])
|
||||
|
||||
|
||||
class Grid(World):
|
||||
def __init__(self, world: Optional[World] = None, w: Optional[int] = 0):
|
||||
if world is not None:
|
||||
self._world = world
|
||||
else:
|
||||
self._world = self
|
||||
|
||||
self._w = w
|
||||
|
||||
super().__init__()
|
||||
|
||||
def _item_factory(self, z: int) -> GridSlice:
|
||||
return GridSlice(z, self._world, w=self._w)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return "\n\n".join((
|
||||
str(s) for s in self._l
|
||||
))
|
||||
|
||||
def to_str(self) -> str:
|
||||
return "\n\n".join((
|
||||
s.to_str() for s in self._l
|
||||
))
|
||||
|
||||
def iter_cubes(self) -> Iterable[Cube]:
|
||||
for s in self:
|
||||
for r in s:
|
||||
for c in r:
|
||||
yield c
|
||||
|
||||
def get_point(self, p: Point, expand=True) -> Optional[Cube]:
|
||||
try:
|
||||
# print(f"expand world z to {p.z}")
|
||||
c = self.get(
|
||||
p.z,
|
||||
expand=expand,
|
||||
).get(
|
||||
p.y,
|
||||
expand=expand,
|
||||
).get(
|
||||
p.x,
|
||||
expand=expand,
|
||||
)
|
||||
# from pdb import set_trace; set_trace()
|
||||
return c
|
||||
except IndexError:
|
||||
return None
|
||||
|
||||
def trim(self):
|
||||
for s in self:
|
||||
for r in s:
|
||||
first, last = None, None
|
||||
min_index, max_index = r.get_bounds()
|
||||
for i in range(min_index, max_index+1):
|
||||
if r[i].active:
|
||||
if first is None:
|
||||
first = i
|
||||
last = i
|
||||
if first is None or first > 0:
|
||||
first = 0
|
||||
if last is None or last < 0:
|
||||
last = 0
|
||||
r.resize(first, last)
|
||||
|
||||
first, last = None, None
|
||||
min_index, max_index = s.get_bounds()
|
||||
for i in range(min_index, max_index+1):
|
||||
if len(s[i]) > 1 or (len(s[i]) == 1 and s[i][0].active):
|
||||
if first is None:
|
||||
first = i
|
||||
last = i
|
||||
if first is None or first > 0:
|
||||
first = 0
|
||||
if last is None or last < 0:
|
||||
last = 0
|
||||
s.resize(first, last)
|
||||
|
||||
def get_all_bounds(self) -> Tuple[Point, Point]:
|
||||
min_z, max_z = self.get_bounds()
|
||||
min_y, max_y = 0, 0
|
||||
min_x, max_x = 0, 0
|
||||
|
||||
for s in self:
|
||||
if s.min_index() < min_y:
|
||||
min_y = s.min_index()
|
||||
|
||||
if s.max_index() > max_y:
|
||||
max_y = s.max_index()
|
||||
|
||||
for r in s:
|
||||
if r.min_index() < min_x:
|
||||
min_x = r.min_index()
|
||||
|
||||
if r.max_index() > max_x:
|
||||
max_x = r.max_index()
|
||||
|
||||
return Point(min_x, min_y, min_z), Point(max_x, max_y, max_z)
|
||||
|
||||
def true_up(self):
|
||||
min_point, max_point = self.get_all_bounds()
|
||||
|
||||
for s in self:
|
||||
s.resize(min_point.y, max_point.y)
|
||||
for r in s:
|
||||
r.resize(min_point.x, max_point.x)
|
||||
|
||||
def expand_all(self, i: int):
|
||||
min_point, max_point = self.get_all_bounds()
|
||||
# print(f"expand {i} cell")
|
||||
# print("expsting min, max:", min_point, max_point)
|
||||
min_point = add_points(min_point, Point(-i, -i, -i))
|
||||
max_point = add_points(max_point, Point(i, i, i))
|
||||
# print("new min, max:", min_point, max_point)
|
||||
self.get_point(min_point, expand=True)
|
||||
self.get_point(max_point, expand=True)
|
||||
|
||||
|
||||
class HyperGrid(World):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
def _item_factory(self, w: int) -> Grid:
|
||||
return Grid(world=self, w=w)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return "\n\n".join((
|
||||
str(s) for s in self._l
|
||||
))
|
||||
|
||||
def to_str(self) -> str:
|
||||
return "\n\n".join((
|
||||
f"w = {s._w}, " + s.to_str() for s in self._l
|
||||
))
|
||||
|
||||
def iter_cubes(self) -> Iterable[Cube]:
|
||||
for g in self:
|
||||
for s in g:
|
||||
for r in s:
|
||||
for c in r:
|
||||
yield c
|
||||
|
||||
def get_point(self, p: Point, expand=True) -> Optional[Cube]:
|
||||
try:
|
||||
# print(f"expand world z to {p.z}")
|
||||
c = self.get(
|
||||
p.w,
|
||||
expand=expand,
|
||||
).get(
|
||||
p.z,
|
||||
expand=expand,
|
||||
).get(
|
||||
p.y,
|
||||
expand=expand,
|
||||
).get(
|
||||
p.x,
|
||||
expand=expand,
|
||||
)
|
||||
# from pdb import set_trace; set_trace()
|
||||
return c
|
||||
except IndexError:
|
||||
return None
|
||||
|
||||
def get_all_bounds(self) -> Tuple[Point, Point]:
|
||||
min_w, max_w = self.get_bounds()
|
||||
min_z, max_z = 0, 0
|
||||
min_y, max_y = 0, 0
|
||||
min_x, max_x = 0, 0
|
||||
|
||||
for g in self:
|
||||
if g.min_index() < min_z:
|
||||
min_z = g.min_index()
|
||||
|
||||
if g.max_index() > max_z:
|
||||
max_z = g.max_index()
|
||||
|
||||
for s in g:
|
||||
if s.min_index() < min_y:
|
||||
min_y = s.min_index()
|
||||
|
||||
if s.max_index() > max_y:
|
||||
max_y = s.max_index()
|
||||
|
||||
for r in s:
|
||||
if r.min_index() < min_x:
|
||||
min_x = r.min_index()
|
||||
|
||||
if r.max_index() > max_x:
|
||||
max_x = r.max_index()
|
||||
|
||||
return (
|
||||
Point(min_x, min_y, min_z, min_w),
|
||||
Point(max_x, max_y, max_z, max_w),
|
||||
)
|
||||
|
||||
def true_up(self):
|
||||
min_point, max_point = self.get_all_bounds()
|
||||
for g in self:
|
||||
g.resize(min_point.z, max_point.z),
|
||||
for s in g:
|
||||
s.resize(min_point.y, max_point.y)
|
||||
for r in s:
|
||||
r.resize(min_point.x, max_point.x)
|
||||
|
||||
def expand_all(self, i: int):
|
||||
min_point, max_point = self.get_all_bounds()
|
||||
# print(f"expand {i} cell")
|
||||
# print("existing min, max:", min_point, max_point)
|
||||
min_point = add_points(min_point, Point(-i, -i, -i, -i))
|
||||
max_point = add_points(max_point, Point(i, i, i, i))
|
||||
# print("new min, max:", min_point, max_point)
|
||||
self.get_point(min_point, expand=True)
|
||||
self.get_point(max_point, expand=True)
|
||||
|
||||
|
||||
def part1():
|
||||
# Load world
|
||||
g = Grid()
|
||||
with open("input.txt") as f:
|
||||
for y, row in enumerate(f):
|
||||
row.strip()
|
||||
for x, c in enumerate(row):
|
||||
g.get(0).get(y).get(x).active = c == ACTIVE
|
||||
|
||||
g.true_up()
|
||||
|
||||
print("time = 0\n_____________")
|
||||
print(g.to_str())
|
||||
|
||||
for t in range(6):
|
||||
g.expand_all(1)
|
||||
g.true_up()
|
||||
|
||||
g.tick()
|
||||
g.tock()
|
||||
# g.trim()
|
||||
g.true_up()
|
||||
|
||||
print(f"time = {t+1}\n_____________")
|
||||
print(g.to_str())
|
||||
# print(g)
|
||||
|
||||
total = g.count_active()
|
||||
print(f"Total active: {total}")
|
||||
|
||||
|
||||
def part2():
|
||||
# Load world
|
||||
g = HyperGrid()
|
||||
with open("input.txt") as f:
|
||||
for y, row in enumerate(f):
|
||||
row.strip()
|
||||
for x, c in enumerate(row):
|
||||
g.get(0).get(0).get(y).get(x).active = c == ACTIVE
|
||||
|
||||
g.true_up()
|
||||
|
||||
print("time = 0\n_____________")
|
||||
print(g.to_str())
|
||||
|
||||
# g.expand_all(1)
|
||||
# g.true_up()
|
||||
# print("EXPANDED\ntime = 0\n_____________")
|
||||
# print(g.to_str())
|
||||
# return
|
||||
|
||||
for t in range(6):
|
||||
g.expand_all(1)
|
||||
g.true_up()
|
||||
|
||||
g.tick()
|
||||
g.tock()
|
||||
# g.trim()
|
||||
g.true_up()
|
||||
|
||||
# print(f"time = {t+1}\n_____________")
|
||||
# print(g.to_str())
|
||||
# print(g)
|
||||
|
||||
total = g.count_active()
|
||||
print(f"Total active: {total}")
|
||||
|
||||
|
||||
def test():
|
||||
g = Grid()
|
||||
|
||||
# print("test")
|
||||
# s = [
|
||||
# "...",
|
||||
# "###",
|
||||
# "...",
|
||||
# ]
|
||||
# for y, row in enumerate(s):
|
||||
# row.strip()
|
||||
# for x, c in enumerate(row):
|
||||
# g.get(0).get(y).get(x).active = c == ACTIVE
|
||||
#
|
||||
# g.true_up()
|
||||
#
|
||||
# print("time = 0")
|
||||
# print(g.to_str())
|
||||
# print(g)
|
||||
#
|
||||
# p = g.get(0).get(0).get(1)
|
||||
# from pdb import set_trace; set_trace()
|
||||
# p.tick()
|
||||
# p.tock()
|
||||
# print(g.to_str())
|
||||
#
|
||||
# p = g.get(0).get(2).get(1)
|
||||
# from pdb import set_trace; set_trace()
|
||||
# p.tick()
|
||||
# p.tock()
|
||||
# print(g.to_str())
|
||||
|
||||
# print(list(g[0][0][0].neighbors()))
|
||||
#
|
||||
# print(g.to_str())
|
||||
#
|
||||
#
|
||||
# return
|
||||
|
||||
# g.get(1).get(1).get(1)
|
||||
# g.get_point(Point(1, 1, 1))
|
||||
# g.expand_all(1)
|
||||
# g.true_up()
|
||||
# print(g)
|
||||
|
||||
# r = GridRow(0, 0, None)
|
||||
# print(r)
|
||||
# r.get(1)
|
||||
# print(r)
|
||||
# print(r[:3])
|
||||
# r.get(-3)
|
||||
# # print(r[0:3])
|
||||
# print(r[-2:])
|
||||
#
|
||||
# print("Resize")
|
||||
# print(r)
|
||||
# r.resize(0, 3)
|
||||
# print(r)
|
||||
|
||||
# return
|
||||
|
||||
# c = g.get(0).get(0).get(0)
|
||||
# print(g)
|
||||
# from pdb import set_trace; set_trace()
|
||||
# neigh = list(c.neighbors())
|
||||
# print(neigh)
|
||||
#
|
||||
# return
|
||||
|
||||
print("test")
|
||||
s = [
|
||||
".#.",
|
||||
"..#",
|
||||
"###",
|
||||
]
|
||||
for y, row in enumerate(s):
|
||||
row.strip()
|
||||
for x, c in enumerate(row):
|
||||
g.get(0).get(y).get(x).active = c == ACTIVE
|
||||
|
||||
g.true_up()
|
||||
|
||||
print("time = 0\n_____________")
|
||||
print(g.to_str())
|
||||
# print(g)
|
||||
|
||||
# g.expand_all(1)
|
||||
# g.true_up()
|
||||
# print(g.to_str())
|
||||
# print(g)
|
||||
# return
|
||||
|
||||
for t in range(6):
|
||||
g.expand_all(1)
|
||||
g.true_up()
|
||||
# print(g.to_str())
|
||||
# p = g.get(0).get(3).get(1)
|
||||
# from pdb import set_trace; set_trace()
|
||||
|
||||
g.tick()
|
||||
g.tock()
|
||||
# g.trim()
|
||||
g.true_up()
|
||||
|
||||
print(f"time = {t+1}\n_____________")
|
||||
print(g.to_str())
|
||||
# print(g)
|
||||
|
||||
total = g.count_active()
|
||||
print(f"Total active: {total}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# part1()
|
||||
part2()
|
300
d17/util.go
Normal file
300
d17/util.go
Normal file
@ -0,0 +1,300 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"os"
|
||||
)
|
||||
|
||||
var (
|
||||
errItemAlreadySet = errors.New("cannot set item in direction as one is already set")
|
||||
)
|
||||
|
||||
// ProcessLines maps a function on lines parsed from a file.
|
||||
func ProcessLines(path string, f func(string) (stop bool, err error)) error {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
scanner := bufio.NewScanner(file)
|
||||
for scanner.Scan() {
|
||||
stop, err := f(scanner.Text())
|
||||
if stop || err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ProcessGroups maps a function on groups of lines parsed from a file separated by some string.
|
||||
func ProcessGroups(path, separator string, f func([]string) (stop bool, err error)) error {
|
||||
group := []string{}
|
||||
|
||||
if err := ProcessLines(path, func(line string) (stop bool, err error) {
|
||||
if line == separator {
|
||||
stop, err = f(group)
|
||||
if stop || err != nil {
|
||||
return
|
||||
}
|
||||
group = []string{}
|
||||
} else {
|
||||
group = append(group, line)
|
||||
}
|
||||
|
||||
return
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err := f(group)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// StringSet is a set of strings..
|
||||
type StringSet map[string]bool
|
||||
|
||||
// Add an item to a StringSet.
|
||||
func (s *StringSet) Add(v string) {
|
||||
(*s)[v] = true
|
||||
}
|
||||
|
||||
// AddAll adds all items in a list to the set.
|
||||
func (s *StringSet) AddAll(l []string) {
|
||||
for _, v := range l {
|
||||
s.Add(v)
|
||||
}
|
||||
}
|
||||
|
||||
// Items returns all values in the set as a list.
|
||||
func (s StringSet) Items() []string {
|
||||
values := []string{}
|
||||
for k := range s {
|
||||
values = append(values, k)
|
||||
}
|
||||
|
||||
return values
|
||||
}
|
||||
|
||||
// NewStringSet creates an empty string set.
|
||||
func NewStringSet(values []string) StringSet {
|
||||
v := StringSet{}
|
||||
v.AddAll(values)
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
// Union returns the union of two SringSets.
|
||||
func Union(s1, s2 StringSet) StringSet {
|
||||
union := NewStringSet(s1.Items())
|
||||
union.AddAll(s2.Items())
|
||||
|
||||
return union
|
||||
}
|
||||
|
||||
// Intersection returns the union of two SringSets.
|
||||
func Intersection(s1, s2 StringSet) StringSet {
|
||||
intersect := StringSet{}
|
||||
|
||||
for v := range s1 {
|
||||
if _, ok := s2[v]; ok {
|
||||
intersect.Add(v)
|
||||
}
|
||||
}
|
||||
|
||||
return intersect
|
||||
}
|
||||
|
||||
// Difference returns the value of s1 with values of s2 removed.
|
||||
func Difference(s1, s2 StringSet) StringSet {
|
||||
difference := StringSet{}
|
||||
|
||||
for v := range s1 {
|
||||
if _, ok := s2[v]; !ok {
|
||||
difference.Add(v)
|
||||
}
|
||||
}
|
||||
|
||||
return difference
|
||||
}
|
||||
|
||||
// Point represents a point on a coordinate system.
|
||||
type Point struct {
|
||||
x, y int
|
||||
}
|
||||
|
||||
// AddPoints adds two points together.
|
||||
func AddPoints(p1, p2 Point) Point {
|
||||
return Point{
|
||||
p1.x + p2.x,
|
||||
p1.y + p2.y,
|
||||
}
|
||||
}
|
||||
|
||||
// PowInt is equivalent to math.Pow but for integers.
|
||||
func PowInt(x, y int) int {
|
||||
return int(math.Pow(float64(x), float64(y)))
|
||||
}
|
||||
|
||||
// LinkedGridItem is a single item in a linked grid.
|
||||
type LinkedGridItem struct {
|
||||
location Point
|
||||
left, right, up, down *LinkedGridItem
|
||||
grid *LinkedGrid
|
||||
}
|
||||
|
||||
func (item LinkedGridItem) String() string {
|
||||
return fmt.Sprintf("%v", item.location)
|
||||
}
|
||||
|
||||
// Location of the item.
|
||||
func (item LinkedGridItem) Location() Point {
|
||||
return item.location
|
||||
}
|
||||
|
||||
// Left gives a pointer to the item on the left.
|
||||
func (item LinkedGridItem) Left() *LinkedGridItem {
|
||||
return item.left
|
||||
}
|
||||
|
||||
// Up gives a pointer to the item above.
|
||||
func (item LinkedGridItem) Up() *LinkedGridItem {
|
||||
return item.up
|
||||
}
|
||||
|
||||
// Right gives a pointer to the item on the right.
|
||||
func (item LinkedGridItem) Right() *LinkedGridItem {
|
||||
return item.right
|
||||
}
|
||||
|
||||
// Down gives a pointer to the item below.
|
||||
func (item LinkedGridItem) Down() *LinkedGridItem {
|
||||
return item.down
|
||||
}
|
||||
|
||||
// SetLeft gives a pointer to the item on the left.
|
||||
func (item *LinkedGridItem) SetLeft(other *LinkedGridItem) error {
|
||||
if item.left != nil || other.right != nil {
|
||||
return errItemAlreadySet
|
||||
}
|
||||
|
||||
item.left = other
|
||||
other.right = item
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetUp gives a pointer to the item on the up.
|
||||
func (item *LinkedGridItem) SetUp(other *LinkedGridItem) error {
|
||||
if item.up != nil || other.down != nil {
|
||||
return errItemAlreadySet
|
||||
}
|
||||
|
||||
item.up = other
|
||||
other.down = item
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetRight gives a pointer to the item on the right.
|
||||
func (item *LinkedGridItem) SetRight(other *LinkedGridItem) error {
|
||||
if item.right != nil || other.left != nil {
|
||||
return errItemAlreadySet
|
||||
}
|
||||
|
||||
item.right = other
|
||||
other.left = item
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetDown gives a pointer to the item on the down.
|
||||
func (item *LinkedGridItem) SetDown(other *LinkedGridItem) error {
|
||||
if item.down != nil || other.up != nil {
|
||||
return errItemAlreadySet
|
||||
}
|
||||
|
||||
item.down = other
|
||||
other.up = item
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// LinkedGrid is a 2d array of grid square.
|
||||
type LinkedGrid [][]*LinkedGridItem
|
||||
|
||||
// Print a linked grid.
|
||||
func (grid LinkedGrid) Print() {
|
||||
for _, row := range grid {
|
||||
for _, item := range row {
|
||||
fmt.Print(item.String())
|
||||
}
|
||||
|
||||
fmt.Print("\n")
|
||||
}
|
||||
}
|
||||
|
||||
// NewLinkedGrid initializes a new linked grid of a given size.
|
||||
func NewLinkedGrid(width, height int) *LinkedGrid {
|
||||
|
||||
var w = make(LinkedGrid, height)
|
||||
|
||||
for y := 0; y < height; y++ {
|
||||
w[y] = make([]*LinkedGridItem, width)
|
||||
|
||||
for x := 0; x < height; x++ {
|
||||
item := LinkedGridItem{location: Point{x, y}}
|
||||
|
||||
if x != 0 {
|
||||
_ = item.SetLeft(w[y][x-1])
|
||||
}
|
||||
|
||||
if y != 0 {
|
||||
_ = item.SetUp(w[y-1][x])
|
||||
}
|
||||
|
||||
w[y][x] = &item
|
||||
}
|
||||
}
|
||||
|
||||
return &w
|
||||
}
|
||||
|
||||
// MapInt maps a function onto a list of ints.
|
||||
func MapInt(a []int, f func(int) (int, error)) error {
|
||||
var err error
|
||||
|
||||
for i, v := range a {
|
||||
a[i], err = f(v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ReduceInt maps a function onto a list of ints.
|
||||
func ReduceInt(a []int, start int, f func(int, int) (int, error)) (int, error) {
|
||||
var err error
|
||||
|
||||
result := start
|
||||
|
||||
for _, v := range a {
|
||||
result, err = f(result, v)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
4
d18/input-small.txt
Normal file
4
d18/input-small.txt
Normal file
@ -0,0 +1,4 @@
|
||||
2 * 3 + (4 * 5)
|
||||
5 + (8 * 3 + 9 + 3 * 4 * 3)
|
||||
5 * 9 * (7 * 3 * 3 + 9 * 3 + (8 + 6 * 4))
|
||||
((2 + 4 * 9) * (6 + 9 * 8 + 6) + 6) + 2 + 4 * 2
|
373
d18/input.txt
Normal file
373
d18/input.txt
Normal file
@ -0,0 +1,373 @@
|
||||
(4 + (2 * 7) * 4) + (6 * 9 + 8 * 4 + 7 * 3) * 3 * 5
|
||||
5 * 9 + (5 * 9) * (6 + 2) + 3 + 7
|
||||
8 + 5 * 9 * 9 + 9 + 5
|
||||
(7 + 9 * 8 + 4 * 6) + 6 * ((9 + 9 + 5 * 7 + 4) * 8 * 2 + 5 * 6 + 2) + 2 * 6
|
||||
(6 * (5 + 8 * 7 * 8 + 4) * (7 + 7 * 3 * 5)) + 5 * (8 + (8 + 3 + 5 + 5) + (3 + 2 + 7 * 2 * 9) + 6 * 5 + (2 * 6)) * ((4 * 3) + 3) + 9 * (3 + 6 * 2 + 3 * 8)
|
||||
2 * 9 + (6 * 2 + 6 + (9 + 6 + 8 + 5 + 5) + (8 + 7 * 4 + 3) + 8) * (4 + 4 * 2 + 6)
|
||||
5 + 4 + 5 + (7 + (9 + 7 + 4 + 4 + 4 + 5) + 2 * 4) + 4 * 9
|
||||
9 + (7 * 8 + (6 + 3 + 4)) + (5 * 9)
|
||||
2 * 4 + 8 + (5 + 8) * 9 * (9 + (5 + 3) + 3)
|
||||
8 * 6 * 5 + 8 + (8 * (2 + 8 * 7 * 5 + 3 + 5)) * 2
|
||||
6 * ((3 + 4 * 3 * 7 * 8) * 8 + (9 + 5 + 2 * 3) * 3 * 2) + 7 + 8 * 8 + 4
|
||||
9 + 3 + 7 * 8
|
||||
(9 + (4 + 9 + 3 + 5 * 5 + 5) * 5 + 9 * 6) * 3 * 2 * 6 * 5
|
||||
7 * 9 * 6
|
||||
(5 + 2 * 8) * 8 + 3 + 8
|
||||
9 * 5 * (5 + (5 * 4 + 8 + 6 * 5) * (9 * 7 + 5)) * 3 * 9
|
||||
(6 * (8 * 3 * 7 + 2) * (3 + 9 + 5 + 5) + 3) + 7 * 3
|
||||
7 + 9 + (4 + 9 * (4 * 6 + 3 * 8 * 5) + 8 + 9 + 3) + 6 * (6 + 8 + 7 * 9 * 6 + 6) + 7
|
||||
2 * (5 * 5 + 6 + (5 + 5 * 5 + 6)) * 4 + 5 + 2
|
||||
8 + 2 * (8 * 7 * 4 + 8) * 9
|
||||
9 + 5 * (4 * 8 + 9 * 6 + (3 * 3) + 2) + 5 + (4 * 5 + 2 * 2)
|
||||
(5 * 7 + 2) + 3 + 9
|
||||
7 * 9 + 8
|
||||
3 * 7 * (7 + 5 + 8 * 5 * 8)
|
||||
(7 + (3 * 6 + 6 * 9 + 2) * 8 * 6 + 6 + 2) * 6
|
||||
4 * (7 * 5 * (6 + 8) * 7 * (5 * 3 * 2 * 9 + 2 * 4) * 6) * 2 + 2 * 5
|
||||
((3 * 3 * 9 + 8) + 2 + 5 + 8) + 6 * (6 + 9 * 2) + 7 * 9 * ((9 + 4 + 4) * 4 + 4 + 9)
|
||||
7 * (4 * 2 + 3 + 7 + 5) * (8 + 2 + (5 * 9) * 2 + 3 * 5)
|
||||
7 + (8 + 3 + 8 * 4 * 2 * 2) + 7 * 2 + ((3 + 5 * 3 + 5) * 8 + 3) + 8
|
||||
7 + 2 + 9 * 9 + 5
|
||||
((6 + 4 + 2) * 2 + 9) + 3 * 6 * (6 + 4 + 9 + 2 + 6) * 9
|
||||
6 + 6 * (9 * 9 + 6 + 6) + 2 * 6
|
||||
2 + 5 * ((4 * 4) * 6) + (3 * 3 + 2) * 9 + 5
|
||||
9 * 4 + 8 * 5 * ((6 * 5 * 4) + (3 + 8 * 7 + 6 * 7) * (6 * 6 + 7) * 8 + 4 + 7)
|
||||
3 * 8 + (4 + (7 * 7 + 9 * 8 * 6 + 7) * (8 * 4 + 4 * 6 * 4 + 4) + 2 * 9)
|
||||
3 + 6 * 2 * 3 * (4 + 7 + (3 * 6 + 7 * 8) * 7 + 9 * 8)
|
||||
2 + 8 + (5 * 4 * 2 * 5 + 5) * 4 + 3 * 4
|
||||
6 + 4 + (5 + 5)
|
||||
6 * 3 + 8 + (8 + 2 + 9 * 3) * ((6 * 8 + 6) + 6 + (7 * 4 * 3) * 4 + 9 + 3)
|
||||
((9 + 7 + 9 + 2 * 7 * 7) + 8 * 6) + 2 + 7
|
||||
6 * (6 + 9 * 2 + 4 * 7 + 8) + 5 * 9
|
||||
((2 + 5 + 6 * 3) + 7 + (7 * 6 * 8 * 3 + 8 * 3)) + (8 * 6 * 8 * 9 * 5)
|
||||
6 * 7 * 5 + 5 * (2 * 9) * 4
|
||||
(8 * 7) * (2 * (7 + 3) + 3) + 8
|
||||
(7 * 9 + 7 + 7 + 7 + 7) + (7 * 5 * 8 + 4 * 5) + 6
|
||||
5 * (6 * 7 * 8 * 5) * 6
|
||||
5 * (2 + (6 * 7) * 8 * 3 + 6 * 2) + 2 * 4 + 8 + 3
|
||||
3 * 5 + 6 + 6
|
||||
((9 * 9) * 6) + (4 + 9 * 6 + 4 * 9 + 7)
|
||||
(3 + 9 + 2) * (3 * 7 * 7 * 7 * (8 * 8 * 4 + 3 + 8)) + 2
|
||||
6 * 6 + 8
|
||||
((9 + 5 + 8) + 9) + 7 + ((9 * 5) * 3 * (3 * 4 * 4 + 3) * 7) + ((5 + 6 + 2) * (7 * 2 * 9 * 8) * 5)
|
||||
6 + (8 * 7 * 6 + 5) + 9 * 7 * 7 * 7
|
||||
2 + (4 * 9 * 3 * 9 + 8) + 2 * 7 * 3 + 4
|
||||
7 + 3 + (5 + 7 * (4 + 4 * 8) + 2 + 8 * 6) * 2
|
||||
(2 * 5 * (4 * 7) * 9 * (3 + 7)) + 3 * 4 * (2 * 3 * 8 * 4) * ((6 + 2 * 2) + (6 * 5 * 7 * 6) + 9 * (8 + 4))
|
||||
((9 + 3 + 5) + 8) * 2
|
||||
2 + 4 + 7 + 5 * (6 * 7 + 8 * (4 * 3 + 6 * 4 + 7) * (7 + 3 + 7 + 3 * 2) + 8)
|
||||
5 + (9 * 8 + 5)
|
||||
(2 + (9 + 7 * 8) + (6 + 7) + 6) * 5 + 3 * 2
|
||||
7 + (9 + (8 * 7 * 9)) * 8 + 3
|
||||
9 * (9 + 4 * 2 * 3 + (6 + 7 * 8 + 9)) + 6 * ((7 * 4 + 7 * 4) + 2 * 6 * 5 + 6 * 6)
|
||||
((3 * 3 + 4 * 9) + 7 + 7 + 3) * 8
|
||||
9 + 8 * (2 + 6 + 8 * 6 + 3 + (8 * 6 * 6 * 4 * 6))
|
||||
3 * (9 + 2 * (9 + 2 * 8) + 3 + 8 * 5) + (9 + 8 + (6 * 9 + 2 + 8 * 5 + 7) * 7) * 2
|
||||
((2 + 9) + 3) * 6 * 2 * 2 * 4 + 7
|
||||
2 * 3 + 4 + (7 + (7 * 5 * 5 + 5) * 9 + (3 + 3 * 5) + 3 * 8)
|
||||
4 * (8 + 2 + (3 * 7 + 4 + 2 * 6 + 2) * 8 + 7)
|
||||
4 + (5 * 9 * (8 + 3 * 9 + 9 + 5) * (3 * 8 + 9 * 8)) * 8 + 9
|
||||
4 * 5 * (2 + 2 + 7 + (3 * 7 * 4 * 2) + 3) * 6
|
||||
((8 * 8 * 4 + 4 + 5) + 6) + 9 * (3 * 3) * 4
|
||||
9 * (8 + (6 + 2 * 7 + 3 + 8 * 8) * 3 * (9 + 3) * (3 + 7 * 3) + 5)
|
||||
9 * 3
|
||||
6 * (7 + 8 * 8 * 4) * 6 * 9 + (4 * 7) * 4
|
||||
4 * (3 * (4 * 9 * 6) + 5 + 5) * 4 * 6 * 6 * ((9 + 3 * 6 + 5 + 8) + 4)
|
||||
5 * 2 * (4 * 3 + (8 * 4 + 2 + 2) * 6 * (8 * 8 * 2 + 7 + 9) + 3) * 5 + (4 + 6)
|
||||
3 + (5 + 6 * 5 * 9) * 9 + 7
|
||||
((3 + 6 + 8) * 7 * 3 + 4 + 4 * 8) * 2 * 2
|
||||
2 + ((9 + 9 * 4 + 2 + 3) * 4 + 9 + 5 + (7 + 3 * 9)) + 8 + 7 * 3
|
||||
5 * 5 * (5 * 6 * 6 + (3 + 4 * 8 + 7) * 2) * 6 + 4 + 3
|
||||
4 + 3 * (5 + (6 * 5 + 6 * 2) * 4) + 9 + 7 * (5 * 5 + 9 * 5)
|
||||
2 + (6 * 7) + 7 + 3 * 7
|
||||
5 * 7 * (6 + (9 * 5)) * 4 + 2
|
||||
((7 * 7 * 3) + 2 + 2 + (9 + 8 + 3)) * (3 * 8 + 6) + ((6 + 2 * 6) * (2 * 4 + 3 + 8 + 2)) * 8
|
||||
((8 + 3 + 8 + 5 + 8 * 3) * 2 + 4 * (6 + 4)) * 8 * 2 * 5 + 9
|
||||
7 + 6 * 3 + 3 + (5 * 7 + 3 + 3 + 8) * 6
|
||||
8 + 7 + ((5 * 9 * 3 + 3 + 4 + 6) + (6 * 6 + 2 + 6) + 8)
|
||||
5 + 5
|
||||
6 + (6 * 5 * 7 + 8)
|
||||
(8 + (9 + 2 + 8 + 2 + 2) * 4 + 7 * 6) * 9 * 6 * (6 * 6 * 5 + 5 * 4) + 7 + 9
|
||||
3 + 8 + (3 + (6 * 9 + 9 * 2 * 3 * 4) * 3 + 9 * (4 * 2) + (3 * 2 * 9 + 2))
|
||||
(5 * 8 + 7 * 8 + (2 + 3 * 8) * (8 + 4 * 7)) * 3
|
||||
8 + 2 * (2 + (6 * 6 + 9 * 3 + 6) + (9 * 2 * 4) + 6 * 4 * (6 * 3 + 2 + 6 + 3 + 5)) + 8 + 4 * 9
|
||||
8 + 8 + (4 * 9 + 9)
|
||||
5 + 5 * (5 + 8 + (3 * 9 * 9 + 8 + 8 * 2) * 5) * (8 + 7 + 7 + 8 + (2 + 7 * 4 * 8))
|
||||
6 * 3 + 6 + ((9 * 5 * 4 + 6 + 5 + 5) * 6) * 2 + (6 * 5 + 5 * 7 * 8 * (3 + 7 * 7 * 9))
|
||||
4 + (3 + 4 + 5 * (4 * 2 + 7 * 9 + 6 + 6)) + (7 + 7)
|
||||
2 * (6 + 2 + 6 * 3 + 4) + (6 + 5 * 4 * 8 + 3 + 7) + 8 + 3 * 5
|
||||
((5 + 3 + 7 * 2 + 9 * 5) + 7 * 7 * (4 + 7 + 9) + 8 + 6) + 3
|
||||
((9 * 9 + 2 * 7 * 5 * 6) + 8 * 7 * 4 * 2 + 6) * 5 * 9
|
||||
((3 * 3 * 2 + 5 + 6) * 7 + (3 * 6 * 2) * 3 + 3) + 9 * 7 + 5
|
||||
(7 + (4 + 7 + 6 * 8 + 9 * 9) + 7 * 2 * 2) * 7
|
||||
(9 * 3 * 9) + ((2 * 6 * 6 + 9 * 7) * 3) + 3 + 8 + 8
|
||||
2 + (3 * 5) * (2 + 8 + 8 * 3 * 6 + 6) * 6 * 9
|
||||
(4 * 7 * 7 + 3 + 4) * 3 * 9 + 6 * (2 + 5 * 4)
|
||||
(8 * 4 + 3 * 8) * 4 * 5
|
||||
(7 + 5 + (4 + 2) + 4) + (2 * 5 * 9 * 2 * 6)
|
||||
9 * 4 + 3 + 8 * (2 * 4 + 7 * 2 * 2) * (2 + 6 + 5 + 9 + 5)
|
||||
8 + 3 * (6 * 8) + (2 * 4 + 7 * 8)
|
||||
(9 + 6 + 3) * 5 + (9 * 8) * 5 + 6 * 5
|
||||
((6 * 2 + 6 * 2) + 3 + 7 + 5 * 8) * 2 + 2
|
||||
2 + (9 * 3 * 9) * (4 + (6 + 4 + 7) + 5) + 9
|
||||
(3 + 4) + 5 + 7 + 7
|
||||
9 + 8 + 8 + 7 + 5 + ((2 + 7 * 9 * 7 * 6 * 9) * 8 * 8 + 7 * 3 + 9)
|
||||
(8 * 7 * (8 * 7)) * 9 + (4 * (4 + 9) * (7 * 9 + 9 + 6 * 5 + 5) + 7)
|
||||
(6 + 7 * 9 + 5 + 5) * 5 * (2 + 6 + (3 * 6) + (7 + 3 + 5 * 5) + 9)
|
||||
2 + ((7 + 8 * 2 + 8) * 4 + 2) * 9 * 9 + 8
|
||||
8 * 8 * 7 * 2 + 2
|
||||
7 * 2 + 9 + ((5 * 2 + 6 * 9 + 8 + 7) + 6 * 2 + 8 + 4 * (3 * 2 * 3 * 2))
|
||||
5 * (7 * 5 + (7 * 9) * 4 * 6 * (8 + 7 + 3 + 9 + 9)) * 4
|
||||
8 * ((3 + 7 + 5) + 7) + 5 + (6 + 4 + 6 + 4 * 4) + ((2 * 6) * 3) + 9
|
||||
3 * 3
|
||||
4 * (5 + 5 + 6 + 2 + 7) + 7 * 6
|
||||
(7 + 4 + 5 * 9 + 5 + 8) * 8 * (7 * 9 * 9) + 4
|
||||
3 + (9 * (7 * 7 + 3 * 4 + 8 + 5) * 7 * (2 * 4) + 9 + 5) * (4 + 7)
|
||||
6 * (5 * (6 * 2) + 6 + (4 * 8 + 9) + 3 * (2 * 4 + 4)) * 6 * 5 + 6 + 3
|
||||
(9 * 3 * 9) * 8 * 5 * (8 + 3 + 2 + 9)
|
||||
(8 + 8 * (8 * 9) + 2 + 7) + 8 * (5 * 7 + 6 + 2 * 4 * 2) + 6 * (3 * 8 + 6) * 2
|
||||
2 * (8 * 5 + 7) * 8 + 7 * 9
|
||||
4 * 4 * (5 + (5 * 4 + 2 * 9 + 5 + 7)) * 8 * ((4 * 9 + 4) + 6 * (7 + 2 + 4 * 8 * 9))
|
||||
4 * 6 + (4 * 8 * 3 * (9 + 8) * 7 * 9)
|
||||
(6 + 9 + 3 * 2 + 8 * 8) * 6
|
||||
(8 + (3 + 3 + 2 * 3) + (6 + 7 * 6) + 7 * 4 + (9 * 5 * 4 * 6 + 2)) * 2 + 5
|
||||
4 * 6 + 2 * 5 * 2 + (5 + 3 + 2 + (5 * 3 * 3 + 7 * 6 + 2) + 8)
|
||||
9 + 2 + (7 * 7 + 7 + 9)
|
||||
5 + 8 + (8 + (5 + 9 + 6 * 2 * 4 * 4)) * 9
|
||||
(2 + 4 + 8 + 7 * 8 * 5) + 3 + 3 + (9 + 9 + (9 * 2 + 6 + 4 + 4) + 6 * 2) + 2
|
||||
7 + (6 + 5 * 2 * 9 + 7 + (9 + 7)) * (3 + 6 + 2 * 5 * 3)
|
||||
8 + (9 + (4 * 3 * 7 * 7) * 7) + 9 * 6
|
||||
6 * 9 * ((8 + 5) + 9) * 7 * 8
|
||||
(2 * 9 + 2) + (6 * 3 * 3 + 6 * 7 + 9)
|
||||
7 * 5 * (4 * 4 + 7 * 4 + 8 + 3)
|
||||
3 * (6 + (5 + 3) + 5) * 3
|
||||
(7 * (9 * 5 * 9 + 2 + 4) + 3 * 8 + (9 + 7) + (2 * 9 + 5)) * (6 + 3 * 9 + 3 + (7 + 4 * 9 + 5) + 9) * (8 * 2 + (2 * 9 + 7 + 5 * 4) * 4)
|
||||
4 + 7 + 5 + 6 * 8
|
||||
5 + 4 + 3
|
||||
9 * (6 * 2 + 7 + 5) * 3 * 2 * 2
|
||||
7 * 4 + ((6 * 7 * 6 * 8 + 6 * 9) * 7 * 3) + 8
|
||||
9 * 5 + 4 + 8 + 8 * 8
|
||||
(3 + 6) * 2 * 7 * (2 * 7 + 2 + 6 + 3)
|
||||
5 * 2 + 8 * 7 + (4 + 8 + (3 * 6 + 7 * 2 + 4 + 7))
|
||||
6 + (8 + 6 * (9 * 7 + 2 + 2 + 3 + 4) * (4 * 7 + 2 + 4 * 3) * 3)
|
||||
(8 + 5 * 2) * (9 * 4) + 5
|
||||
3 * (4 * 5 * (4 + 3 + 4) + 5 * (3 + 6 + 3 * 7 * 7)) * 3
|
||||
2 + 7 + (8 + 3) + 8
|
||||
8 * (9 * 8 * 3) + 4
|
||||
(2 * 6) * 3
|
||||
((9 * 6 + 3 + 3 * 9 + 7) + 2 * (2 + 9 * 8 + 2 * 4) + 9 * 8 + 6) + (5 * 9 * (2 + 7) + 7 * 9) + 7
|
||||
4 + 7 * ((3 * 7 + 2) * 9 * 7 * 2 + 4 + 3) * 4 * (3 + 8 * 9) + 6
|
||||
9 * (9 + (9 * 6 + 2 * 7 + 6) + 7 * 2 + 2)
|
||||
(9 * 2 + 4 + 8 + 6 * 8) * (4 + 8 + 7) * 5 + (4 * 2 + 2) * ((4 * 5) * 8) * 2
|
||||
(5 * 9 + 9 + 2) * 3 + ((7 * 5 + 9 * 3) + 2 + 3 + 6 + 7) + 4 * 6 * 6
|
||||
9 * 8 + 3 * 4 * (9 + 5 + 7 + 5) * (6 * (7 + 4 * 6 * 7) + 6 * (6 * 5 * 3 + 9 + 4) + (2 * 3 + 3 + 6))
|
||||
7 * 6 * 2 + (8 * 9 + (6 * 7 * 8 + 6 + 9 * 8) * 3 + 6)
|
||||
5 + 7 * 8 + 2 + ((2 + 4) * 7)
|
||||
2 * 5 + 6 * 6 * (3 * 6)
|
||||
6 * 6 * 6 * (6 * (4 * 4 + 5) * 4 + 3 + 9) + 4
|
||||
((3 * 4 * 7) * 5 * 9 + 7 * 6 + 5) + 2 * 2 * 6 + 4 * 8
|
||||
7 * 2 * (3 + (6 * 9 * 9) * 4) * (5 * 8 * 7 * 6 + 2 * 9) * 7
|
||||
9 + (6 + 6 + (8 + 8 * 3 + 6 + 6))
|
||||
5 * 2 + 7 + 3 * (9 + 9 * 9 * 9 * (4 * 4)) * 2
|
||||
4 + 6 + 3 + (2 + 2 * 7 * 2) + 5 + 7
|
||||
7 * 9 * 9 * 2 * 4 + 7
|
||||
6 + (6 + 5 + 5) + 7 + 4
|
||||
9 + (9 * (7 * 3 + 9 + 7 + 8 * 8) * 6 * 5) + 2 * 5
|
||||
8 + 6 * 8
|
||||
8 * (9 * 6 + 4 + 8 + 8)
|
||||
((8 + 3) + 8 * 2) + (3 * 6 * 7 + 7 + 4 + 2) * 9 * 5
|
||||
6 * (4 * 5 + 6 * 7 * 4) + (2 * 8 + 4 + 7 + 7 + 6) + 9 + 5
|
||||
9 * 8 * (2 + 7 + 9 + 4 + 5) + (8 * (3 * 8 + 3 * 6)) + ((7 * 2) * 7) + 2
|
||||
9 + 4 + 9 * 2 * (5 * 2 + 6 + (9 * 5 + 8 + 2 * 5) + 6 + 6) + 7
|
||||
9 + 9 * ((3 * 6) + (5 + 5 + 7 * 9 * 4 + 9) + 2 * 6 * 6) * 5
|
||||
(9 * (3 * 2) + 8 * 2) * (6 * (8 + 3 * 8 + 5 * 5 * 9) + 4 + 9 * 6) * 5 + 9 * 6
|
||||
7 * 9 * (2 * 9 + 4 * (3 * 2 * 6 * 9 + 5 + 6) + 2) + 7 * 6 + 3
|
||||
9 + (5 * (3 * 9) + 4 * 6 + 6) + 9 + 8 * 5
|
||||
8 + 8 * 8 + (9 + 4 * (5 + 3 * 8 * 3 * 4 * 4) + 2 * 8 * (9 * 6 * 4 * 6 + 9))
|
||||
(6 + 6 * 3 + (5 + 8 * 4 + 4) + 3) * (3 + 7) * (6 + 5 * 4 * 6 + 6 + (5 * 7))
|
||||
(9 + 7 + 6 + (8 * 8) * 4 * 6) + 3 * 5
|
||||
5 * 2 * 3 + (3 + (6 + 9 * 2) * 3 * 3)
|
||||
2 + (8 * 7 * (4 * 8 * 2 + 6 * 7)) * 5 + 5 + (8 * 5)
|
||||
9 * 6 * 4 * 2 * ((6 * 3 + 9 * 8) * 5) * 3
|
||||
((8 + 6) + 6 * (8 * 5 * 5 * 7) + (2 + 9 + 6 * 7) * 7 * (2 + 9 * 7 * 3)) * ((7 * 5 + 2 * 5) + (8 * 7))
|
||||
(7 + 8) * 6 * 9 + 6 + 6 * 8
|
||||
7 * 8 + (8 * 2) * 7 * 8 * 9
|
||||
9 * ((8 + 6 * 9 + 2 + 3 * 2) * 2 + 4 + 3 + 7) * 2 * 6
|
||||
2 + (8 + (2 + 9) * 7 * 4 + (8 * 6 + 8 * 6 * 4 + 5) + 6) + 4 * (9 + (3 + 4) * (3 * 9 * 7 * 6 + 9 + 7) + 9 * 6 * 3)
|
||||
2 + (8 + (8 * 2 + 3 * 8 * 4 + 2)) + 3 * 6
|
||||
(5 * 5 + (3 + 5 * 6 * 9 + 4 * 4)) * 8 * (7 * 7 + 3 * 7)
|
||||
9 + 6 * (9 * 2 + 2 * (9 + 6 * 8 + 5 + 3))
|
||||
5 * 5 + 5 * (7 * 3 * 3 * 5) + 6
|
||||
7 * 5 * 7 * ((6 * 3 + 5 * 8 * 6) * 7 + 4 * 5) + 7
|
||||
(5 * 4 + 8) * 3 + 6 + 9 + 6
|
||||
(7 + 7 + 4 + 8) * (2 * 7 + 9) * 2 * 4
|
||||
2 + ((7 + 2 + 9 * 4 + 2) * 6 + 9)
|
||||
9 + 2 + (7 + 6 + 4) * 3 * 8
|
||||
5 + 7 * 2 + 2 * (3 * 4 + 4 * 6) + 2
|
||||
2 + (7 + 2 + (9 * 3 * 5 + 7 + 7) + 5 * (7 + 7 * 2 * 4 * 7 * 4) + 5) * (6 + 2 * 5 + (4 * 6 + 4 * 8 * 4) + 7) * 2 * 5
|
||||
((5 * 9) * 9) * 2 + 4 + ((3 + 6) + (9 + 3 + 6 + 3) * 3 * 5 + (9 + 9 + 6 * 7) + 7) * 2 + 9
|
||||
4 + (4 + 4 + 6) + 6 + 5 * 9 + 8
|
||||
(3 * 8 * (7 * 5 * 7 * 5 * 7 + 2)) * 7 * 4 + 3 + 2 + 4
|
||||
(4 * 8 + 7 + 8 * 5 * 9) + 2 * (5 * 2 * 3 * 9) + 7 + 7 * 2
|
||||
6 * 3 * (4 + 6) + 7 + 2
|
||||
(5 + 4 + 4 * 8 + (4 * 6 * 5 + 7 * 4 * 2)) * 9 * 6 * 6 * (3 + 5 + 9 * 7)
|
||||
4 * (5 * 2 + 8 * 9 * 3) + 3
|
||||
7 * 3 + 7 + 5 + ((6 * 8 * 8 + 8 + 2 * 4) * 8 * 2 * 9)
|
||||
4 * 2 + 6 + 2
|
||||
(2 * 2 + 2 * 9 * 6) + (5 + 9) * 3 * 9 * 5
|
||||
(5 + 5 * (3 + 3 + 7) * (3 * 7 * 7)) + 4
|
||||
9 + 7 + 9 + 5 * 6
|
||||
(6 + 9 + (4 + 7 * 7 * 4) + (9 * 2 + 9 + 5 + 6)) + 7 * 8
|
||||
5 + (5 * (6 * 5 + 8 + 2) + (4 * 7 * 4 * 7 * 7 * 8) * 8)
|
||||
4 + (6 + 6 * 2 + 9) + 7 * ((3 + 8) * (3 * 5 + 5 * 3 * 3 * 6) + (4 + 9 * 3 + 3 * 2 + 9))
|
||||
(7 * (7 + 7 + 5) * 8 * 2 * 8 + 3) + (2 * 4 + 8 * 7 + 3 + 2) + 7 * (7 + 2 + 2)
|
||||
(3 * 7 * 4) * 5 + 4 * 7 * 8 * 4
|
||||
7 * 3 * (2 * 7 * 9 * 7 * (8 + 4 + 2) * 3) + 7
|
||||
7 * (9 + 2 + 5 + 5 + 7 * 5)
|
||||
5 + 2 * 9 * (8 * 6 * 8 + 2 * 7)
|
||||
4 + (2 + (2 * 5 * 7 * 5) + 3 + 6) + 8 * ((3 + 4 * 4 + 5 * 3 + 6) + 2 + (5 * 8)) + 8 + 3
|
||||
2 * (9 * 7 * 3) + (8 + 7 + 8 + 2 * 3 + 9) + 8 + 9
|
||||
8 * (7 + 5 * 3 + (2 * 6 * 6 * 4) + 9) + 3 * 4
|
||||
3 + 4 * 8 * 9 + (6 + (5 + 7 * 7 * 4)) + 7
|
||||
(5 + 6 + 8 + 5 * 7) * 2 + 5 * (9 * (9 * 9 + 8 + 5) + 7 * 4)
|
||||
8 + (8 * 2 * 4 * 2 + 3 * 2) * (3 * 3) * 6 + 8
|
||||
(6 * 2 * (6 + 5 * 9 * 3) * 6 * 2 + 7) + 7 * 8 + 2 * 4
|
||||
5 + (2 + 4 + 5 * 4 + 6) + 9 * (5 * (5 + 9) * 9 * 9 * 2 + 8) * 5
|
||||
7 * 4 + 9 * (9 + (5 * 7 + 8 * 7 * 5) + 9 + 2 + 2 + (2 * 4 * 7 + 5))
|
||||
7 + 2 + (4 + (8 + 8 + 5 * 9)) + 9
|
||||
(8 * 3 * 9 + 6) * 8 + 8 + 7
|
||||
(2 + 3 * 9 * 4) * 7 + (8 * 6 * 9) * (8 + 6 + 9 + 4)
|
||||
((7 * 6 + 4) + 6 + 6) + 5 * 4 + 3 * 4
|
||||
5 * (2 + (3 * 9 + 9 * 6) + (7 + 3 + 2 * 4 + 9)) + 7 + 8 * 5 * 5
|
||||
7 * 9 * (5 + 6 + (7 * 6) + 4 + 4 + 3) * 2 + 9
|
||||
(3 * 2 + 5) * 8 * (2 + 4 + 2 + 8 + 7 * (8 * 9))
|
||||
((2 + 7 * 8 * 9) * 4 * 3 + 6 * 7) + 9 * 8 + 5 + 9
|
||||
5 + 4 + 9 + 8
|
||||
7 + 7 + 9 + 2 + 5 + ((6 * 3 + 3 + 6) * 4 * (4 + 4))
|
||||
(9 * 4) + 8 * 4
|
||||
3 * 9 * (9 + 5 * 4) + 8 + 9 * 3
|
||||
3 + (9 * 8 * (6 + 4 + 6 + 5 * 2) + 9 + (4 * 7 * 7) + (3 + 4 + 6 * 8 + 9)) * (2 + 8) + 7 * 5 * 6
|
||||
9 + 6
|
||||
6 * 8 * 8 + 6 * 6 * ((9 + 3) + (4 + 2 * 8 + 8 * 2 + 5) * 2)
|
||||
4 + (4 * (2 + 2)) + 7 + 4 + (4 * (8 + 8 + 4 + 4 + 2) + (3 + 2) * 9 + 8) + (4 + 9 * 9)
|
||||
(2 * (3 * 7 + 6 + 2)) + (4 * 6) + 6 + (6 + 9 + (2 * 2 * 2 + 6 + 4) * 4) * 5 + (4 + 2 * 5 * 8 + 6 * 2)
|
||||
4 * ((5 + 5 + 9 + 3 * 5) * 7 * (7 + 9 * 5 * 7 + 2) + 5 * (4 + 7)) + 7 * 9 * 6 * 4
|
||||
4 * 7 + 4 + ((4 + 8 * 6 * 3 + 2) + 3 + 8 * (6 * 7 * 2 * 8) * 7) * 9 + 6
|
||||
4 * 6 * ((3 * 6) + 4 + (2 * 2 * 2 * 7) + 9 + 8) * (3 + 8 * 2 * 4 * 2 * 3) + (4 + 3 * (7 + 5) + 6 + 9) + 5
|
||||
(7 + 2 + (8 + 6 * 4)) + 8 + (7 + 5 + (2 * 5 + 9) * 5)
|
||||
(7 * 8 + 5 + 8 + 8 * 2) * 6 + (5 + (8 + 3 + 4 * 5) * 9)
|
||||
8 * (4 + 5 * 9 + 6 + 8 * 7) * 3 * 6 + 4 * 5
|
||||
6 + ((6 * 3 * 4) + (8 * 8 * 2 * 5 * 8 + 2)) + 3
|
||||
9 * 3 + 6 + 5 + ((5 * 2 + 9 * 5 + 6) + (4 * 9)) + (4 * 2 * 3 + 7)
|
||||
6 + 8 + (6 + 2 + 8 + 2) * (5 + 8 + 5 * 5 + (4 + 9 + 3))
|
||||
(2 * 7) + (6 + 4 + (8 + 6 + 5 + 9 * 4 + 7))
|
||||
8 * 3 + 3 * (3 * 5) * 6 + 2
|
||||
9 + 4 + ((5 * 4 + 2 + 6) + 5) * 5 + 6 + 4
|
||||
(9 * 9 * 3 + 5 * 3 * 4) * 3 + (2 + 3 * 5 + (3 + 6 * 6 + 2) * 8 + 3)
|
||||
(6 + 9 * 9 + 7 * 6) + 7
|
||||
4 + 6 * (3 * 3 * 7 * 7 * 5 + 2) * (7 + 7 * 2 * 5 + 4 + 9) + (8 * 2 + (8 + 8 * 4 + 7 + 3 + 5) * 7) + 9
|
||||
4 + 8 + 6 * 7 * 7 + (2 * 8 + 3 + 5)
|
||||
4 * 8 * 4 * (9 * 9 * 5) + 9
|
||||
8 * 5 + (2 + 3 + 2 + 8 * (3 + 5 + 8 + 7 * 9))
|
||||
3 * ((8 * 6 + 9 * 8 * 5) + 9 * 6 + 6) * 6
|
||||
5 * 8 + 6 * (5 * 2 * 8)
|
||||
8 + (6 + 7 + 7 * (6 + 7 + 3) * (5 + 2 * 7) + 7) + (2 * 8)
|
||||
6 + 5 + 4 + 2 + ((3 + 8) * (5 + 4 * 9) * (4 + 9 + 3 + 9 + 9 * 7) + (5 + 2 + 9 + 3) + (6 + 6) + 3)
|
||||
3 * (2 + 5 * (5 * 6 * 5 + 9) + 9 * 5) * 8 * 5 + 4
|
||||
2 * 4 + 6 + (9 * 4 * 3 * 4)
|
||||
(4 * 6 * (3 + 9) + (3 * 5 + 8 * 5 * 9) + 6) + 9 + 8
|
||||
(3 * 5 + 8) + 8 * 8 * 7 + 8 * (9 + 6)
|
||||
(5 * 4 * 6 + 3 + 3) * (3 * 8 * (7 + 2 * 9 * 6)) + ((9 * 9 * 4 + 8 * 7 * 7) + 4 * 4) + 8 * 6
|
||||
3 + 5 * 5 * 6 * ((3 + 3) * 8 + (6 + 9 + 2 + 6 * 7)) * 4
|
||||
9 + ((4 * 7 + 2 + 2 * 6) + 8 * (4 * 6 + 7 * 5) * 7 + 4) + 6 + 6
|
||||
(9 + 9 * (8 * 2 + 9 + 5) * 3 * 4 * 4) + 5 * ((3 + 6 * 3 * 7) + 6 * 4) * (3 + 8 * 9 + 6 + (4 + 3 * 4 + 2) + 6)
|
||||
5 * 5 * (9 + 8 * 3 * 3 + 3) * 4 + 8
|
||||
3 + (6 * 9 * 8) + 9 + (3 + 3 + 2 + 5 + 2)
|
||||
3 + 4 * (4 * 8 + 2 * (3 + 3 + 4 + 9 * 7) + 4 + (6 + 9 + 4 * 6 + 9))
|
||||
6 * 5 * 9 * ((6 + 9 * 6 + 7) + (6 * 4 + 2 * 4 * 6 * 6) + 9 + 6 + 8)
|
||||
7 + 7 * 2 * 4 + 7 * 2
|
||||
2 + 8 * (7 + 3 * 3 + 2) + 6 + 3 * 7
|
||||
2 * 2 * 9 + 8 + 8
|
||||
9 + 5 + 4 * (6 * 7 * 5 * 7 * 4 * 3) * 3
|
||||
7 * 5 * 7 * 6 + 4 * 9
|
||||
((9 + 7 + 9 + 7 * 7 * 4) * 6 * 5) + 5 + (8 + (2 + 6 * 9 * 7 * 9 + 9) * (9 * 3 * 8 + 9 * 6 * 2) + 6 * 7) * (2 + 6 + (3 * 4 + 4) * 6 * 5) * 9 * 5
|
||||
(7 * 5 * (3 + 2 + 6 * 5 + 9) + 5 + (2 + 9) + 2) + 2 * 6 + (5 * (7 * 2 + 3 + 8 * 9) * 7 + 6 + 6 * (5 + 3 + 9)) * (4 * 6 + (9 + 7 + 4))
|
||||
((3 + 5) + 7 + 3) + 6
|
||||
3 * 4 + 4 * 6 + (5 + 8 * 2)
|
||||
7 + (7 * (4 + 4)) * 3 + 7 * 4
|
||||
(5 + 4 * 6 + 3 * 9 + 7) * (7 * 3 * 5) + 6
|
||||
3 + 4 * (8 + 2) + ((6 * 7) + 8 + 8 * (9 * 3 + 2) * 9)
|
||||
7 + (7 + 9 * 2 * 9 * 2 * (2 + 5 + 9 * 6)) * 4
|
||||
(7 + 6 + 3 + 5 * 2) + 2 * 3 + 4 * (3 + 4 * 5 * (3 + 7) + (7 + 2 * 7 * 6) + 8) * 8
|
||||
4 + (9 * 2 * 6 * (6 + 6 * 7 * 7 + 5) * 9) * 9 + (4 + 8 * 7) * 4 + 4
|
||||
6 * 6 * 2 + (4 * 2 + 7 + 4 + (2 + 2 * 5)) + 2
|
||||
8 + 2 + 3 + 3 + 8 + (6 + 4)
|
||||
8 + 9 + 2 + ((3 * 9 * 3 * 5) * 3 + (2 + 2 + 8 + 6 + 9 + 7)) + 9
|
||||
6 * (3 * (5 * 4 + 4 * 4 * 4 + 4)) * 8 * (5 + (5 + 2 * 7 + 8) * 3)
|
||||
3 + ((3 + 7) + 2 + (5 * 3 + 4 * 9))
|
||||
4 + 5 * 6 * (7 * 5 + 6 * 5 * 5 + (4 * 6 * 9 * 6)) + 7 + 3
|
||||
7 * 4 * 7 * 5 * (3 + (5 + 6 + 9 * 9 * 3 * 7) * 2 * 8 + 2 + 6)
|
||||
5 * 4 + (4 * 7 * (3 + 8 + 9)) + 4
|
||||
(7 + (3 * 5 * 7 + 5 * 8) * (6 + 9 * 6 * 7) * (3 + 9 * 8 + 4) + 8 + 7) * 2 + 4
|
||||
8 + 7 + (9 + 6 + 7 + 9 + 6 + 4) + (7 * 8 * 6 * 5 * 3) + (3 * 4 * 3 * 8)
|
||||
7 * ((4 + 4 + 9 + 3 * 3) + (9 * 6 * 8 * 7 * 3 + 6) * 7 + (7 + 2 * 3 + 6 * 2)) + 3 + (5 * 8) + (4 + 9 * 6 * (2 * 5 + 7 * 3 * 5) * 3 * 8)
|
||||
8 + (3 + (8 + 3 * 4 + 4)) * 2 * 4 * (3 + 4)
|
||||
(4 + 9 + 4 + (4 + 7 * 3 * 2 * 5 + 7)) * 2
|
||||
2 * 8
|
||||
6 * (7 * 5 + (4 * 5 * 2))
|
||||
(3 + 3 * 4 * 3 + 7 + 4) + 8 + 2 + 4 * 4 * 5
|
||||
7 * 2 * 5 + (2 * (9 + 6) * (3 * 8 + 4) + 3) * 9
|
||||
(6 * 9 * (6 + 6 + 7 + 7) * (5 * 7 + 8 * 5 + 2 * 8) + 5 + 8) * 9 * 9 + 3 * 2 + 7
|
||||
(2 * 3 + 8 + (4 * 2 + 7 * 2 + 7 + 7) + 3 + 6) * 3 * (6 + (9 + 7 * 2 + 2) + 6) + (4 + 3) * 3
|
||||
4 * (6 * (8 * 8 + 7) + 7) * 6 * 9 * (4 * (6 * 4 * 3 * 2 + 6) + (8 * 9) + (9 + 3) * 4)
|
||||
5 * 7 * 2 * (2 * 2 * 5 * (8 + 6))
|
||||
(8 * (7 + 7 + 8)) + 2 + 9 * 9 + 9 * 4
|
||||
6 + 6 + 5 + (2 * (8 * 7 + 3 * 6) + 9) * 7 + 6
|
||||
8 + 6 + (8 * 4 * 8 * 2 + (6 * 6 + 9 * 3 + 6)) + 3
|
||||
9 * 5 * 4 * (5 + (3 + 7) + (4 + 4 * 5 + 5 * 8 * 9) * 5)
|
||||
5 + 4 * 9 * ((2 * 4 + 8 * 2 * 7 + 2) + 4) * 9 * 3
|
||||
3 + 6 * (6 + 2 + 3 * 2) + (3 + 5) + ((3 * 6 + 5 + 7 + 8 * 8) * 9 + (5 + 8 * 7 + 6 * 8 + 7) + 7 + 8 + 5)
|
||||
7 * ((7 + 5 * 3 * 5 + 4) + 7 + (6 * 3 * 6 * 6 * 7 * 7))
|
||||
((5 + 7 * 9 * 2 + 3) * 2 + 9 * 3) * (4 + 6) * (4 * 7 * (9 + 6 * 8 + 5) * (3 + 8 + 9) + 9 * (8 + 6 * 9 + 6)) * 6 + 4
|
||||
2 * (6 * 3 + 4 + 4 * 2) + 6 + 7 + 5
|
||||
2 + 7 + 5 + 5 * ((7 * 6 + 2) * 8 * 8) + (2 * 5 * 4 * 5)
|
||||
3 + (7 * 8 * 5) + 5 + (5 + (4 * 4 + 7 + 2) + 6 + (8 + 3) * 9 + 4)
|
||||
6 * (9 + 5 + 6) * 5 + 5 * (7 * (3 * 5 + 6 + 2 * 5) * 2)
|
||||
(9 + 6 + (9 + 7 * 5 + 6 * 7) * 7 * 3) + 3 + 4 + 6
|
||||
7 * ((5 + 4 + 6) + 7) + 2 * 3 + (6 + 9 * (6 * 4 * 8 * 3 + 4 * 2) + 7) + 3
|
||||
7 * (8 + 9 + 5 * (9 * 7 * 9) + 2) + (7 + 7 + (7 + 3 + 2 * 2) + 4 * 2)
|
||||
3 * (2 * (4 + 6) * 8)
|
||||
8 + ((6 * 4 * 8 + 4) + 7) * 7
|
||||
(7 + (2 + 8 * 8 * 6 * 2)) + 7 * 2
|
||||
(4 * 2 + 4 * 8 + 4) + (3 * 9 + (2 * 4 + 2 * 7) * 9 + 7) * (5 + 9) * (7 + (3 * 4 * 4 * 6) + 8 * 7) + 8 + 8
|
||||
8 + (2 + 2 * 8 * 7 + 7) + 2 + 4 * 3 + (8 + 9 * 9)
|
||||
3 + 2 + 8 + (9 + 3 * (3 + 2 + 9 + 7) + 4 * 4 * 7) * 3
|
||||
5 * 4 * 7 * 3 + (9 * (6 * 6 + 2 * 4) * 8 + 2 * 9)
|
||||
4 * 7 * (3 + 6 * 6 + 4 + 8) + 5
|
||||
(8 + (8 + 2 * 9 + 3 * 3) * 8 * 8 * (9 * 6 + 2 * 6)) * 9 + 5 * 2 + 5
|
||||
5 + 6 + 3 + 4 * 9 + (4 + (4 + 3 + 9 * 2) + 4)
|
||||
3 * (5 + 3) * 7 + 6
|
||||
((3 * 2 + 2 * 6 + 5 + 3) + 4) + (4 * (8 + 2 + 9 * 2) * 8 + (8 * 3 + 6 + 2 + 6) * 2) + 7 + 2 * 9
|
||||
6 * 8 * ((8 * 8 + 3 * 7 + 8 * 4) * 4 + 9) + (8 * 7 * (6 * 8 * 3 * 2) * 3) * 2 * 8
|
||||
(2 * 7 + 4) * 2 * (5 * 4 + 2 + 5 + (7 + 5) * (4 * 3 + 6 * 8 * 5 + 9)) * 5
|
||||
(6 * 8) * (7 * 7 + 8 * 3 * 3) * (5 * 8 + 2)
|
||||
(6 + 6 * 2) * 5 + ((7 * 6 * 8) * 8 * 9 * 4)
|
||||
(8 * 4 * 9) + ((5 * 3 + 6 * 3) + (9 + 9 + 9 * 2 * 2) * (4 + 9 * 7 + 2 * 2 + 3) + 6) * 7 * 6 * 6
|
||||
((4 + 3) * (2 * 5 + 8 * 2 * 4) * 9) + 6 + (6 + (5 * 4 * 5 * 3 + 3) * 6 * (5 * 3 + 7 * 2 + 4 + 8)) + 4 + 7
|
||||
(6 * 9 + 9 + 7) * (6 * 2 * (4 * 7 * 4 + 4 * 5 + 7) + (7 + 5 * 8 * 4 + 9 + 6)) * 7 + 8 * 5 + (9 * 5 * 2 + 7)
|
||||
6 * 6 + ((2 + 9) * 5 + 2 * 3 + 3 * 3) + 9 * ((4 * 7) + 5 + 8 + 4)
|
||||
5 + (4 * 5 + 5 * 3 + 7) * 6 * 5 + (2 + (9 + 7 + 8 + 4))
|
||||
(2 * 4 + 5 + 8 + 6 * 9) + 3 + 6
|
||||
9 + (9 + 8 * 3) * (3 + 8 + 6 + 5) * 5
|
||||
(3 + 9 * 5 + 7) + 2
|
||||
((9 + 5 * 2) * 5 + (4 + 2 * 7) + 9) * 8
|
||||
(4 + 4) * 9 + 3 + 2 * 8
|
||||
(3 + 4 * 8 + 9 * 6 + 6) * 5 + 8 + 9
|
||||
3 * 8 + 9 * (3 * 4)
|
||||
6 + 7 * 6 * 7
|
||||
3 * 3 + (8 * 8 * 9 + 3 * 8 + 2) * 3 + 8 * 2
|
||||
5 + ((6 + 2 * 6) * 8 + 6 * 5) + ((7 + 3) + 2 * 5 + 7 + 6 + 5) + (8 + 2 * 7 + 4 + 2 * 3) * 2 * 5
|
||||
(6 * (6 * 7) * 7 + 3) * 9 + 6 * 3
|
||||
(5 * 9 + 7) + 8
|
||||
(3 + 9 * 3 * 9 * 2) * 9 * 5
|
||||
5 + (6 * 3)
|
88
d18/main.py
Executable file
88
d18/main.py
Executable file
@ -0,0 +1,88 @@
|
||||
#! /usr/bin/env python3
|
||||
|
||||
operators = {
|
||||
"+": lambda x, y: x + y,
|
||||
"-": lambda x, y: x - y,
|
||||
"*": lambda x, y: x * y,
|
||||
"/": lambda x, y: x / y,
|
||||
}
|
||||
|
||||
|
||||
def evaluate(s):
|
||||
num_s = ""
|
||||
num = None
|
||||
left_num = None
|
||||
op = None
|
||||
s = s+" "
|
||||
inner = None
|
||||
level = 0
|
||||
for c in s:
|
||||
# print(f"reading {c} level {level} left: {left_num} inner: {inner}")
|
||||
if c == ")":
|
||||
# print("close paren")
|
||||
level -= 1
|
||||
if level == 0:
|
||||
# print("eval inner", inner)
|
||||
num = evaluate(inner)
|
||||
# print(f"finished evaluating {inner}, Result was: {num}")
|
||||
inner = None
|
||||
else:
|
||||
inner += c
|
||||
elif c == "(":
|
||||
# Start to read innner
|
||||
# print("start reading inner paren")
|
||||
if inner is None:
|
||||
inner = ""
|
||||
else:
|
||||
inner += c
|
||||
level += 1
|
||||
pass
|
||||
elif inner is not None:
|
||||
inner += c
|
||||
# print("append to inner paren", inner)
|
||||
elif c.isnumeric():
|
||||
num_s += c
|
||||
elif c == " " and num_s:
|
||||
# print("got number")
|
||||
num = int(num_s)
|
||||
num_s = ""
|
||||
elif c in operators:
|
||||
op = operators[c]
|
||||
|
||||
if num is not None and left_num is None:
|
||||
# print(f"putting {num} on left")
|
||||
left_num = num
|
||||
num = None
|
||||
|
||||
# Evaluate
|
||||
if left_num is not None and num is not None:
|
||||
# print(f"evaluating {left_num} {op} {num}")
|
||||
left_num = op(left_num, num)
|
||||
# print(f"new left is {left_num}")
|
||||
num = None
|
||||
op = None
|
||||
|
||||
return left_num or 0
|
||||
|
||||
|
||||
def part1():
|
||||
# r = evaluate("1 + (2 * 3)")
|
||||
# r = evaluate("1 + (2 * 3) + (4 * (5 + 6))")
|
||||
# r = evaluate("1 + 2 * 3 + 4 * 5 + 6")
|
||||
# r = evaluate("((2 + 4 * 9) * (6 + 9 * 8 + 6) + 6) + 2 + 4 * 2")
|
||||
# print(r)
|
||||
# return
|
||||
|
||||
total = 0
|
||||
with open("input.txt") as f:
|
||||
for line in f:
|
||||
line.strip()
|
||||
v = evaluate(line)
|
||||
print(v)
|
||||
total += v
|
||||
|
||||
print("sum: ", total)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
part1()
|
96
d18/main2.py
Executable file
96
d18/main2.py
Executable file
@ -0,0 +1,96 @@
|
||||
#! /usr/bin/env python3
|
||||
from typing import List
|
||||
|
||||
|
||||
operators = {
|
||||
"+": lambda x, y: x + y,
|
||||
"-": lambda x, y: x - y,
|
||||
"*": lambda x, y: x * y,
|
||||
"/": lambda x, y: x / y,
|
||||
}
|
||||
|
||||
|
||||
class SynNode(object):
|
||||
def __init__(self, nodes, ops):
|
||||
self.nodes = nodes
|
||||
self.ops = ops
|
||||
|
||||
def evaluate(self) -> int:
|
||||
assert len(self.nodes) == len(self.ops) + 1
|
||||
# Eval sub nodes
|
||||
node_values = [node.evaluate() for node in self.nodes]
|
||||
total_value = node_values[0]
|
||||
|
||||
for i, op in enumerate(self.ops, 1):
|
||||
total_value = operators[op](total_value, node_values[i])
|
||||
|
||||
return total_value
|
||||
|
||||
|
||||
class ValueNode(SynNode):
|
||||
def __init__(self, val: int):
|
||||
self.value = val
|
||||
|
||||
def evaluate(self) -> int:
|
||||
return self.value
|
||||
|
||||
|
||||
def find_high_level_ops(s: str):
|
||||
balance = 0
|
||||
indicies = []
|
||||
for i, ch in enumerate(s):
|
||||
if ch == ')':
|
||||
balance += 1
|
||||
elif ch == '(':
|
||||
balance -= 1
|
||||
elif ch in operators and balance == 0:
|
||||
indicies.append(i)
|
||||
|
||||
return indicies
|
||||
|
||||
|
||||
def parse(s: str) -> SynNode:
|
||||
s = s.strip()
|
||||
if s.isnumeric():
|
||||
return ValueNode(int(s))
|
||||
|
||||
hl_op_indicies = find_high_level_ops(s)
|
||||
if not hl_op_indicies:
|
||||
# Must be like "(1 + 2)", remove parent and try parse sub operation
|
||||
return parse(s[1:-1])
|
||||
|
||||
ops = [s[i] for i in hl_op_indicies]
|
||||
nodes: List[SynNode] = []
|
||||
|
||||
start = 0
|
||||
for i in hl_op_indicies:
|
||||
nodes.append(parse(s[start:i]))
|
||||
start = i + 1
|
||||
|
||||
# Parse remaining
|
||||
nodes.append(parse(s[start:]))
|
||||
|
||||
while '+' in ops:
|
||||
add_index = ops.index('+')
|
||||
# Remove op and neighbor nodes and replace with a syn node instead
|
||||
op = ops.pop(add_index)
|
||||
right = nodes.pop(add_index+1)
|
||||
left = nodes.pop(add_index)
|
||||
nodes.insert(add_index, SynNode([left, right], [op]))
|
||||
|
||||
return SynNode(nodes, ops)
|
||||
|
||||
|
||||
def part2():
|
||||
# print(parse("1 + (2 * 3) + (4 * (5 + 6))").evaluate())
|
||||
# print(parse("5 + (8 * 3 + 9 + 3 * 4 * 3)").evaluate())
|
||||
total = 0
|
||||
with open("input.txt") as f:
|
||||
for line in f:
|
||||
r = parse(line).evaluate()
|
||||
total += r
|
||||
|
||||
print(f"Total: {total}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
part2()
|
538
d19/input.txt
Normal file
538
d19/input.txt
Normal file
@ -0,0 +1,538 @@
|
||||
2: 12 16 | 41 26
|
||||
55: 92 16 | 84 26
|
||||
107: 48 26 | 29 16
|
||||
91: 16 86 | 26 120
|
||||
56: 19 16 | 30 26
|
||||
33: 69 16 | 127 26
|
||||
65: 112 16 | 76 26
|
||||
23: 16 16 | 44 26
|
||||
102: 16 116 | 26 132
|
||||
39: 16 26 | 26 26
|
||||
40: 23 26 | 76 16
|
||||
108: 16 53 | 26 51
|
||||
22: 110 26 | 55 16
|
||||
42: 1 16 | 47 26
|
||||
14: 112 26 | 46 16
|
||||
117: 115 26 | 76 16
|
||||
120: 26 6 | 16 59
|
||||
72: 26 130 | 16 66
|
||||
131: 102 26 | 20 16
|
||||
93: 16 16 | 26 16
|
||||
58: 97 26 | 104 16
|
||||
69: 26 88 | 16 46
|
||||
54: 76 16 | 116 26
|
||||
1: 26 64 | 16 28
|
||||
48: 13 26 | 61 16
|
||||
92: 85 26 | 117 16
|
||||
49: 124 26 | 98 16
|
||||
6: 44 44
|
||||
24: 112 26
|
||||
17: 112 16 | 116 26
|
||||
115: 44 16 | 16 26
|
||||
113: 16 128 | 26 89
|
||||
106: 26 132 | 16 6
|
||||
16: "b"
|
||||
67: 44 16 | 26 26
|
||||
104: 44 88
|
||||
41: 26 132 | 16 76
|
||||
38: 16 59 | 26 46
|
||||
89: 16 24 | 26 62
|
||||
80: 18 26 | 35 16
|
||||
98: 46 26
|
||||
101: 16 132 | 26 46
|
||||
85: 16 59
|
||||
126: 16 67 | 26 59
|
||||
9: 26 49 | 16 80
|
||||
10: 26 67 | 16 59
|
||||
34: 26 93 | 16 23
|
||||
4: 70 26 | 107 16
|
||||
100: 123 26 | 63 16
|
||||
109: 118 16 | 54 26
|
||||
77: 16 50 | 26 99
|
||||
88: 26 26 | 16 16
|
||||
81: 67 26
|
||||
18: 16 115 | 26 88
|
||||
123: 57 16 | 103 26
|
||||
60: 26 18 | 16 43
|
||||
94: 26 23 | 16 59
|
||||
0: 8 11
|
||||
57: 46 16 | 125 26
|
||||
110: 26 58 | 16 60
|
||||
20: 44 76
|
||||
15: 56 26 | 33 16
|
||||
114: 26 132 | 16 23
|
||||
7: 16 6 | 26 115
|
||||
28: 16 3 | 26 25
|
||||
51: 112 16 | 23 26
|
||||
43: 88 16 | 116 26
|
||||
111: 26 6 | 16 93
|
||||
62: 26 132 | 16 112
|
||||
76: 16 26 | 26 16
|
||||
27: 96 26 | 45 16
|
||||
50: 26 93 | 16 76
|
||||
132: 16 26
|
||||
35: 16 115 | 26 132
|
||||
53: 16 46 | 26 116
|
||||
75: 104 26 | 81 16
|
||||
82: 26 9 | 16 100
|
||||
78: 26 116 | 16 125
|
||||
19: 16 39 | 26 132
|
||||
37: 26 41 | 16 127
|
||||
45: 91 16 | 108 26
|
||||
59: 26 26 | 26 16
|
||||
116: 26 16
|
||||
84: 7 16 | 94 26
|
||||
86: 16 6 | 26 88
|
||||
63: 94 26 | 17 16
|
||||
103: 115 26 | 59 16
|
||||
130: 16 34 | 26 20
|
||||
99: 39 26 | 6 16
|
||||
26: "a"
|
||||
64: 16 15 | 26 21
|
||||
97: 67 16 | 23 26
|
||||
83: 105 26 | 27 16
|
||||
21: 75 16 | 52 26
|
||||
30: 26 125 | 16 112
|
||||
3: 16 121 | 26 74
|
||||
105: 26 73 | 16 113
|
||||
125: 16 16
|
||||
13: 16 88 | 26 39
|
||||
32: 72 26 | 122 16
|
||||
122: 16 77 | 26 2
|
||||
90: 4 26 | 32 16
|
||||
12: 26 6 | 16 39
|
||||
29: 68 26 | 101 16
|
||||
79: 106 26 | 111 16
|
||||
61: 132 16 | 46 26
|
||||
31: 83 26 | 90 16
|
||||
96: 16 87 | 26 5
|
||||
118: 26 93 | 16 116
|
||||
44: 26 | 16
|
||||
25: 37 16 | 71 26
|
||||
52: 10 26 | 7 16
|
||||
124: 125 16 | 6 26
|
||||
66: 26 36 | 16 14
|
||||
127: 16 116 | 26 39
|
||||
68: 26 46 | 16 6
|
||||
70: 79 26 | 109 16
|
||||
128: 126 16 | 40 26
|
||||
8: 42
|
||||
71: 26 114 | 16 78
|
||||
73: 129 16 | 131 26
|
||||
5: 16 65 | 26 118
|
||||
11: 42 31
|
||||
119: 16 112 | 26 6
|
||||
95: 16 88 | 26 59
|
||||
87: 119 16 | 14 26
|
||||
121: 35 26 | 95 16
|
||||
47: 22 26 | 82 16
|
||||
46: 16 16 | 16 26
|
||||
129: 12 16 | 17 26
|
||||
112: 26 26
|
||||
36: 67 26 | 125 16
|
||||
74: 16 10 | 26 38
|
||||
|
||||
aaaaaababbaaababaaaabbbb
|
||||
aabbabbabbbbbaaaababbbbbaaabbaabababbaaabababbab
|
||||
baabaabaaabbaaaaaaabaabb
|
||||
aabaaababababbbaabababaaaaaaabba
|
||||
babbaabaaaabbabbabbaabba
|
||||
aabbabbbaaaaaaabaabaabaa
|
||||
aaabaabbaaabaabbaaaaababaabaabbabbabaaababaabaabbaabaabbaabaaaabbabababa
|
||||
abbabaabbbaabbbbaabaababaabbaabbbabbbabbaabbabbaabaabbbbbaaabaababbabbba
|
||||
abaaabaababaaabbbaaabbbb
|
||||
baabbabbaaababbbabaabaab
|
||||
abababbabbabbbaabaaaaaab
|
||||
bbabbaababbbbbbbbaababba
|
||||
abaaaaaaabbaaaaabbaabbba
|
||||
abbbbaabbabbbaabbabbbbbbaaababbaabaaaababaaabbbabaaaaabbbababaabbbaababb
|
||||
aabaaabbaaabbbaababbbaaaaabbaaababbbababbbabaabbabbaabbbbbabbbbbaaaababbabbabaaa
|
||||
aaabbbababbbabababbaabba
|
||||
babbbbabbbaabaabbbbaabba
|
||||
ababbbbbbbbaaabababbaaaabbaabaaabbbabbab
|
||||
bbabaaaaabababaababaabaaabababbb
|
||||
bbabbabbabbaaaabbbaababbbaaaabaabbaaaaaa
|
||||
baaaabaabbabbabbabbbbbbaabbbbbbbbbaababbbbabbaabaabababb
|
||||
babbaaaabaababaabaababab
|
||||
bbbababaababaabbbabaabbb
|
||||
baaababbbbbbbababbabbabaaaaabbaa
|
||||
baababaababbabbbabbababaabbaaabababbaaab
|
||||
bbbaaabbbabbbaaaaaabaabaabbbbaabbaaabbba
|
||||
aabbabaaaaaabaabababaabbbbbaabbaaababbbb
|
||||
aaababbbaabaabbababaababbbaaabbabaaaabab
|
||||
bbbbbbbbabbbaaaabbbbaaaa
|
||||
abbbbaaaaabaababbbbaabba
|
||||
abbbbaaaaabbbabbbbbaabbbaaabbabbabbababaababbaaa
|
||||
bababbabaaabbaaaaabaabaababababa
|
||||
aabaabbabbabaabaaaabbaaabbbbbbbabbbbbabbabbbbabb
|
||||
abbaaabaaaaaaaaabaaabbbaabbbaaabbaaaaabaaaabbbbaaaabbaab
|
||||
aabaaababbaaabbbaabbbaaabaabbbbabbbaaabaabbaababababaaba
|
||||
aaaaaabaabbaaaababbaabba
|
||||
aaaaaaaabaaabbaabaabaaabbbababaaabbabbab
|
||||
bbabbabaaabbababaabababb
|
||||
aabbbbabbaaabbbabaababaaaaabbbba
|
||||
baaaaaaabbbababbabbaaabaaabababbaababaaaababaaabaababaaa
|
||||
bbbaabbbabaaaabaaaabbbaa
|
||||
baaaabaabbababaabaabaaaa
|
||||
bbbbbaabbaaaaaaabbaaabaa
|
||||
aabbbbabbbbaaabbabbbbaab
|
||||
babaababbabbabbabbababbbaaabbbbb
|
||||
babbbbabbbaabaaabbbaabaa
|
||||
abbbbaaaabbaaaaabbabbbaaabbbaababaababbbaaaababbaaabbbbbaabaaaaa
|
||||
baabbbbabbbbbaabbbaabbba
|
||||
aabbabbbaaabaaaabbaabbbb
|
||||
babaabaabaaaabbaabababbb
|
||||
aabbabbbbabbaababbaaaaaa
|
||||
bbaababbababbbbbbbbbaaab
|
||||
bbbbbbabaaabbabbabaababbbbbbbbaa
|
||||
baabbaaabbabaabbbbbababb
|
||||
abbbbbbaaabaaabbaababbbb
|
||||
bababbbabbabaabbbabbaabaaabbbabaababbababbababab
|
||||
aababbababbbbbaabaababab
|
||||
babbbaaaaaaaaaabbbabaaba
|
||||
abbbaaabbaaaabaaababaabbaabaaaaaabbaabbaabaabababbabaaaa
|
||||
aababaabaabbaaaabababaab
|
||||
babababbaaaaaabaabababababbbabbbbbababaabaababba
|
||||
bbbbbabbbbaababaabaabbbbbababababaabbaba
|
||||
baabbbbabbabaabbbaababbb
|
||||
abbbbbabbababbbbbbaaabbabababbabaabbaabbabaaabbaaaaabababaabbaababbbabbaaaabaaaa
|
||||
aababababaaaabbbaaaabbbaaaaabbbb
|
||||
ababbaabbbaaaabaaaabaaab
|
||||
abbbbbbaaababaabbabbabbababbbaaabbaababa
|
||||
bbaabaabbbbaabbbbbaaabbbabbababbbbbbaabb
|
||||
abbababbabababbbaabaaaaa
|
||||
abbbaaaaaaaaabaabababbab
|
||||
bbaababbabababbaababaabbabbbbbabbbabbbbb
|
||||
babbabbabaabbaabaababbbb
|
||||
bbbbbaaaaabbabbabbaaaaab
|
||||
aaababababbbabaababbabab
|
||||
baababbbaaabbaababaaaabbabbaabbb
|
||||
aababaabaabaaaabbbbabaabbbbbbbabaabbbbaa
|
||||
aaaaaaaabbbbaabbbbbababaabbaabbbaaababba
|
||||
bbbababbbbaabbabbbababbaabababababbaaabaababaaab
|
||||
baababaaaabbbabbabbbabbababbababbabbaaab
|
||||
baabbbbaaabbbababbaaaabb
|
||||
bbababbbabbbbaaaabbabbab
|
||||
babbabbbabbbabaabaabbbbb
|
||||
aabaabbabbababaabbbbaaaa
|
||||
aabbbabbbbababaabaaaaaab
|
||||
aaabaaaabbbabaabaabbabaabbbabbbb
|
||||
aababaabbbbbabaaaaaaabba
|
||||
babaabbabbababbbbaabbbaabbbbbaababbbbabbbbabbbab
|
||||
abaaabbbbbababbbbabbbbba
|
||||
abbbbaaaaabbbabaaababbaa
|
||||
ababbbaaabbbabbbbabbaabb
|
||||
aaaaaaabaaaaabaababbbbabbabbbbababaabbaa
|
||||
aaaabbabbaaababbbbbabababbabaabaaabbbabbbbbbbabbaaabbbbbbabbabab
|
||||
bbbaaabbbbbbaabbaaabbbba
|
||||
bbbaaababbabbabbbaabaabb
|
||||
abbbbbbbaababbbbbbbbabbaabaabbaababbbaba
|
||||
aaaaaabbbbbbbababbaababbbaabbbba
|
||||
baaaabaaabbababaabaabaaaababbbbbbababaaabbbbbabb
|
||||
bbabbbaabbbaabbbbabaaabbbabaaabaabbbbbbbaaaaabba
|
||||
aaaaaabaabababbabbbbabba
|
||||
ababbaababababbaaaaabbba
|
||||
aabaababbabbbbabbbbaabbbabaaaaaaaabaaababaabbbbb
|
||||
baabbabbbbaaabbabababbaaaaaababb
|
||||
aaabbaabababbabaababaaab
|
||||
abbaaaabaaaaaabbaaabbbaa
|
||||
ababbababbabbabababbaaaababbabbabbbabaabbababaabbbabbbbaabbbbabbabbabbbb
|
||||
baaaaaaabbababbababaabbabaaaabbaaabababaabaaaaabaabbbbaa
|
||||
aabbaaaabbaaababbbaaabbaabbbababababaaaa
|
||||
aaaaabbbaaabababbaabbaabbaaaaaba
|
||||
bbababaabaaabaabbbbbabbb
|
||||
aababaabaaaaabbbabaaabaaabababbb
|
||||
bbbabababbaaaabbabaaabbabbabaaba
|
||||
bababbaaabaaaaaababbaabb
|
||||
aaaaaabbaaabaaaabaababab
|
||||
baaabaabbabaababaabbbbabaabaabbbbbbabbbabbaabbaa
|
||||
aaaaabaaaaabbabbbbbbbabb
|
||||
babbabaaaaabaaaaabbbbabb
|
||||
bbbbbaababbbbbbabbbaaabbabbbabbbbabbaabbbababbbb
|
||||
aaabababbbabbabbaaaabaababbaabbbaabababb
|
||||
bbaaababaaaaabaabaabbbbabbabbabbbabbbbbabaaabbba
|
||||
aabaaabbababbbbbbbbbaaaa
|
||||
aababbabbbaabaaabbabbaabaabbababbabbbbbb
|
||||
bababaaabbbbbaabbbbabaabbaabaaba
|
||||
aaaabaaaaaaaaababbaaaaabbbbababbbabbbaab
|
||||
aabaaaabbaaabaabaababbaa
|
||||
aabaababbbbabaabbaaabbba
|
||||
bbbbababbbabaaabbabbaabbababaaabbbbbabba
|
||||
aabbaaaaabbaaaababbbaabb
|
||||
aaabaaaaaaaaaaaabaaababaabbbabbbaababaabbaabaabbbbaabbabbbbabbaa
|
||||
abaaaaaaabbbabbbababbbaabaabaabb
|
||||
abbaaaaaaabbaaaababbbaab
|
||||
bbabaabbaaaaaabbabaabbba
|
||||
bbabaabbabbbabaababbbbba
|
||||
baabbbbaaaabaabaaabaabaa
|
||||
bbabbbbbbbaabbbaaabbaabbbbaabbabbabbbabbbbabbbab
|
||||
aaabababbbabbaababababababbbbabaabababaaaaaaabba
|
||||
aabbbaaaaababbabbbaaabbabbaaaabaabbbbaaaabbaabba
|
||||
ababaabbaabbbabaabaaaabbbbabbbbbbaaabbbb
|
||||
baababbbabbbabbbaababaaa
|
||||
bbbbbaaaabababababbabaab
|
||||
bbbbbaabbbabbaabbaaaaaba
|
||||
abaaabbbbabaababbabaaababbaababa
|
||||
aabbbbabbabaaabbbbababaaabaaaabbbabaabaa
|
||||
babbabbbababbbbbbaabbbbaabbabbab
|
||||
abababababbaaaaaaaabbbba
|
||||
aabbbabbbbabaaabbabbbbabaabaaaabbbbabaaaaaabbbba
|
||||
aabbbabbbbaababbbbbbbaab
|
||||
bbaaaababbbababaaaabbbbaabbbaaabbababbbb
|
||||
abbabbaabaaaabababaabababaaabbaaababbbbaababbabbaaabbabaababbaab
|
||||
aaabababaaaabaabaaaaaaabbbababbababbabbababbaaab
|
||||
babaabbabaabbabbbbbaabaa
|
||||
babbabbbbbaabaaabbbbbabaabbbabbabbaaaabbabbbabaabbbaaaaa
|
||||
bbbababaaabaaabbabababaabaaababbbabaaaaaabbaabba
|
||||
baabbabbababbbaaaaaabbaa
|
||||
aabaabababbbbbaabaababba
|
||||
ababbbaaababbbaaaaabbbaa
|
||||
abbabbbabbaababbaababbbb
|
||||
aababaababaabaaabbabaaababaabababbabbbab
|
||||
aaaabaaaaabbbbabaabbbabbbbaababbbbbbaaab
|
||||
bbbbababbbbbababaaaabbaa
|
||||
abbbaaaabbbaaabaabbbaaab
|
||||
bbabaaabbbbbabaababbaaaabbbaaabbbaaaaabaabbbabbbbbabbbbbbaaaaabbaaabbbabbbbaabababaaabaa
|
||||
aaabbaabaabbababaaaaabba
|
||||
bbabaaaaabbbaabaaabbabaaaabbabbbaaabaabbbbaabbab
|
||||
bbaabaaaaabbbaaababaabaaabbabaab
|
||||
bbbbababababaabbbaaababa
|
||||
baabaaaaabbababaaababaabaabbbabaabbabababbababbaabaaaabaabbbbaaaabaabbbbbaabbbbb
|
||||
bbababaaababababbababaaabbbabbbaaaaababa
|
||||
bbaabaaaabbbbbbbaaaabbbb
|
||||
aabaabbaababbbbbbaaababb
|
||||
abbbaaaaaabbabbababaaabaabbabaabababaaaabababbbb
|
||||
abbbbbaaaaaabbabbbabaaabbaaaaaaabbbabbab
|
||||
bbabbabbbbabbabbaabbaabb
|
||||
aabbabbababbaababbbabbba
|
||||
abababbabaababaababbbbaababbabab
|
||||
bbababbabbaabbbbbbbaaaaabababaabaaaaabba
|
||||
abaaaabbbaabbaabbaabaabb
|
||||
ababbaababbabbbaabaababa
|
||||
abaaaabaaabbbabbbaabbaaaababaaaabbbabbbabbaaaaaa
|
||||
aabbababbbabbbaaabaabbba
|
||||
abbabbbaaaaaabbbaabbabaabbaaabbbababbabbabaaabba
|
||||
aabbbabaaaabbbabbabbbbbabbabaabbabaababa
|
||||
babaabbaabaabaaababbabbaababababaabababa
|
||||
abbaaaaaaaabbbabbbaaabbbbaaaaaba
|
||||
bbaaabbbbbaaabbabababbab
|
||||
aabbababbbbaabbbaababbba
|
||||
abaaabbaaabaabbbbaaaabab
|
||||
babbaabaaabbbbabbaaabbaabbaaaabb
|
||||
bbabbabbababbbaabbaababa
|
||||
babbbababbabbbbabbbaabbbbbaaaabaabbbababaabbabbabbabbaaababbbbaaaabaaaabbbaabaabaaabbabb
|
||||
bbabbabbbbbbbbabbabbbbbb
|
||||
bbbaaabbabaaabaaabbababbbabababbbbabaaabaaaababb
|
||||
babaaababbaababbababbababbbabaabbbbbbabbabbaaababbabaabaaababbaa
|
||||
aabbbbabbaaaabbaaabaabbabaabbabbabbbaaabaaaababa
|
||||
abbaaaaaabbababbbbbbbabb
|
||||
baabbbaaabbaababbbbabbaa
|
||||
ababbabababbbaabbbaabbbb
|
||||
abababbabaabbbabbaababaaababaabbbbbabbaabbaabbababbabbababbbbabbaabbbaaaaabbaababaabbaba
|
||||
aabaababababbbaabbaabbab
|
||||
babaabbabbbbaabbaababbaa
|
||||
baabbaabbbbbbababaabbaaaabababaabaabbbabbbbbabaa
|
||||
abbabababbaabaabbbaababa
|
||||
baababbbaabaaabaabaaabbbaabababa
|
||||
bbabaabbbbbbbaabbabaabbb
|
||||
babaabbaabaabbbaaabaabbbbabbabaababbabbb
|
||||
babaababbbaababbbbaabaaaabbbbabaabbabbbbaaaabbba
|
||||
ababaabaababbbbaaaaabbba
|
||||
aabbbabbaabbbbabaabbabbbabbbaababaaaaaaaabbabbbb
|
||||
aaabaaaaaabaabbaaabaaaaa
|
||||
abbababbabbbaababbbaabba
|
||||
abababbababbbbabbaaaaaab
|
||||
aaaabaabaaabbbabbbaabbab
|
||||
abbbbbbbbaababbbbabbabab
|
||||
ababaabbbbbbbbababbbbaab
|
||||
aaaaaaabaabbabababaaaaaaaaabababbabbbbaa
|
||||
bbaabaaaaabbbabbbaaabbba
|
||||
baabbaaababbabaabbbbaaba
|
||||
bbbaabbbabbabbbabaaaaaab
|
||||
aaaaababbbbabbaababbabababaabbab
|
||||
aaabbbababbbabbaabaabbbb
|
||||
abababaaabababababbaabba
|
||||
ababbbaaabbaabaaabbabbbb
|
||||
bbabaabbbaabbbbabaaabaaa
|
||||
ababbaabaaaabaabbbbbbbab
|
||||
baabaaabbbaabaaaaabaaaabbaabbbabbbbabbbbaabababb
|
||||
abbaabbbabaababaabaabaaaabbbaaaababbaabbbabaabaa
|
||||
aababbabbababaaaababbbba
|
||||
bbabbabaabaaaaaaabaaaaaabbaababbaaaabbaababbbbaabbabbbbaaabbabaa
|
||||
aaaaaaabbbaababbababbbaabbabbabaaababbaabbabbbbbaabababa
|
||||
aaabaaaabaaabaababaabbab
|
||||
baaaaaaabaabaaababaaaabaaabbaabb
|
||||
bbaabaabaabaaaabbbbbaaab
|
||||
abaabbbaaaabaaaaabbbababaaabaaaaaaaabaaaababbbabbbababbaaabbabbb
|
||||
abaaabbbabbbbbabbabaaaaa
|
||||
ababbababbbabaababbbbabb
|
||||
babaababaaaaaaaaaaabbbabaaaababa
|
||||
aabaaabbaaaaabbbaaabbaba
|
||||
baaabbaaaabaaababaababaaaabaaabaaaabaaaaabbbaaba
|
||||
aaaaabbbbabbaabaaaabbaabbbbbbabb
|
||||
aabbbbababbbaaaabbaaaaab
|
||||
bbbabaabaabaaaabbabaaaaa
|
||||
abbbbaaaabbbaabaabaabbbb
|
||||
abbaaaaababbaaaaabbbabbabaaaaaba
|
||||
abbbaabaabbbaababbababab
|
||||
bbbaaabbbaabaababaaabbab
|
||||
aabaabababbbaaaabbbbaaba
|
||||
baababbbbaababbbbabbbbabbbbababbabbbbaab
|
||||
bbbbababaababaabbbbbbaaabbaaaabaabbbbaaabbbabbba
|
||||
baaabbaabaabbbabaaaaabaaaabbaabb
|
||||
aabaaababbbabababbbabbbb
|
||||
aabbaababaabbbbabaaaaaba
|
||||
aaaabbababbaababbabbbabb
|
||||
ababababaaaabbababaaabab
|
||||
aaabaabababbbbababbabbbbaabbaaabaabaaabbbbbababbabbabbabaaabbbba
|
||||
aabaaabbaabaaabbbbbaaabbbbbabaaa
|
||||
bbbaabbbbabaaababbbbbbabababbbbbaaabbabbabbabbaa
|
||||
abbaaaabbaabaababbbaaaab
|
||||
baaaabaaabaaaabbbbabbbab
|
||||
bbabbababbbbbbbbbabaabbb
|
||||
babaaabaaabbabbabbababab
|
||||
bbabbabaabbbababbbbabbba
|
||||
abaaaabababbbaaabbabbabaaabaaabb
|
||||
aaaabbabaaaaaaabbabbbaba
|
||||
abaaaaaabaabbaaababbbbabaabbabbabbbaaaaaaaabbbba
|
||||
ababbabaabbbbbaaaabaabaa
|
||||
abbbaababaaababbaabaaaaa
|
||||
bbbabaabbbaabbbbbaaabaaa
|
||||
bbabbabbbaaabbaabaaabbba
|
||||
babbabaabbabbaababaabbba
|
||||
abbababaababababaabbbbaa
|
||||
baabbbabaaaaabbbbabbbbbb
|
||||
aabbabaaaabbabbaabbbaaab
|
||||
abbbbbaaaabaaaabbbbabbbb
|
||||
bbbaabbbbbbbabaaababaaaa
|
||||
ababbaabbbaababbbbaaababbaaabaabbbaababbbbbbbbaa
|
||||
bbbabbababbbbbaaaabbbabbbbbaabbabbaaaaabbaabbaaaabbbbabaaababaaa
|
||||
aababaaababbbaababaabbbaaababbbabbbbbbaa
|
||||
babbabbbaaaabbabaaabaaab
|
||||
aabbbaaaaaabaabaababaaab
|
||||
babaaabaaabbbaaaabaabbba
|
||||
aabaaaababbbabbaabaababa
|
||||
bbbbbbaaabbabbaaabaabaabaaabbabaaaababbbabbbabbb
|
||||
aababaababbaaaabbabbaabb
|
||||
abbbaaaabaaabbaabbabababbaabaabb
|
||||
aaaaaabbabbaaaaababababa
|
||||
bbbbabaabbbaaabaaababbbb
|
||||
babaabababbbabbabbbabaaa
|
||||
bbbaaabbbaabbbbaaaabbbaa
|
||||
abbabbbababbbaaabaabbabbababbabbababbbbaaaabbabababbbbabaabbaaba
|
||||
abababbabbbaaababaabbaba
|
||||
aabbababaaabbbbbbbaaaabbbbbbbbababbbabaabbabbbbb
|
||||
abaabaaabbababbbbaaaabababaabbaaaaaabbbbbbbbaaaabbbbbbaabbaababa
|
||||
aabbabbaababbbbbbbbbaaaa
|
||||
aaaaaabbaabbababbbaaaaaa
|
||||
bbbaaababbbbbbabaaabbaabbbbaabba
|
||||
bbabbabbabbbabbabbabbbab
|
||||
bbaabaaabbaabbbbabbbaabb
|
||||
babbbaaaaababaabbbbbbabb
|
||||
abaaabaaabaaaabaaabbbbbb
|
||||
bbababaaabbbabbaabbbabbbbabbbbbaababaaba
|
||||
abababaabbabaabbbbaaabbabaabbbababbaabbb
|
||||
babbaabaabbbabbaabaabbbb
|
||||
baabbbbabbababbabaababba
|
||||
bbaaabbbaabbaaaabaaababbbabbabaabaabbbbb
|
||||
aaaabbabbbbbbbbbaaaabbabbaaaabbb
|
||||
bbbbabaaabbaababbbaabbab
|
||||
baaaabbaabaaaaaababbabaabaaababa
|
||||
aabaabbabbaaaababababbaababbabab
|
||||
abaaaaaabaaababbabbaaabb
|
||||
abbbabbabbbbabaabbbbaaba
|
||||
babababbbbabbbaaaabbbabbaaaaaabbbabbabbbaabaaaabababaaaa
|
||||
aaaabaababbbbbbaabaabbaa
|
||||
ababbbaaababababababbaaa
|
||||
ababbbaabababaaabbbbbabb
|
||||
abbababbaabaaabbbbbaabab
|
||||
babaababbababbbabbbbabbb
|
||||
abbbbabbabbbaabbabaaaaabbaaabbbbbabbaaababaababa
|
||||
baabbbbaaaabbabbbbbababb
|
||||
aaaaabaaabbabbbababbbbaabaaabbaabbbabbba
|
||||
baabaaabaabbbaaaabaaabba
|
||||
aabaabbabbbbbababaababbb
|
||||
aabbbabaabaaaaaaabaabbaa
|
||||
abaabababaabaababbbbbbaabbabaabbaabaabbb
|
||||
aabaaabbbbabbabaabaaaababbaababaaabbbaab
|
||||
abaaaaaabababbbaabbbaabb
|
||||
bbabaabbaaabaaaababbbabaabbaabba
|
||||
bbbbabababbbabababaababb
|
||||
babbaaabababbabaabbabababaaababbbbabbbbbbbabbabbbaaaabaaabbbbbba
|
||||
abbbbbbbbbbbabababbabbaaabbaaaababbbbabaaabbaaaaaababbbbbbaababbbbaabaabababaabbababaabbbbbbbbba
|
||||
bbbaaababaaaabbabaaababbababbaabbbbbbbba
|
||||
babbabbaaaabbbabababbabb
|
||||
ababaabbabbabbbabbabbbba
|
||||
aaabbaabababbbaaababaaab
|
||||
ababbbabaababbaaababbaaa
|
||||
baaaabaaaabbaaaaabaababa
|
||||
baaababbababababbbabbaaa
|
||||
ababbabababaabababaabaabaaaabbbbbbaaaaababaabbaabbaaaabb
|
||||
abbbbbaaaaaaabbbabbabaab
|
||||
aaaaaaabbbaaababbbbaaababaababaaababbaaa
|
||||
aaabbbabbabaabaaaabbbaab
|
||||
abbbabbabbababaaaaabbbbb
|
||||
abbbbabaaaaabbbaabbabaab
|
||||
bbabaabbaabbbaaabaabbbbb
|
||||
ababbaababbabbbabbabbaabbbaaaaabbbbbbbba
|
||||
aabaaabababbbbaabaabaabb
|
||||
aabbbaaabaabaaabbbbabbaa
|
||||
babbbaaababbaabaabbbabbbababbaabababaaba
|
||||
aababaabbabbabbababbbbabaabbbbabbbbbaaaaaabaabaa
|
||||
aabaaaabbbaabbbabaabaaababaaabababbbabbbabbaaababbaabaababbabbbbabbabaaa
|
||||
abbbabbbbabbbbaaaabbbabbaabaaabaabaababbbbbabaaa
|
||||
babababbaababbababbabaaa
|
||||
aaaaabbbabbbabbabbbaabba
|
||||
bbaabaaaabaabbabababaaab
|
||||
babbabaaaaaaaababaaababbbaabbbaaabaabaab
|
||||
abbbbbbbabbaabaabbbbbbaa
|
||||
aabaaaaabaaaaaabaaaaabbaaabababa
|
||||
abababbabbabbabbaabaabbb
|
||||
aabbbaaaabababbaabbaaaabbbababab
|
||||
baababaababbabaaaabaaabaaabbbababbbbabbabbabbaaababbbbba
|
||||
bbababaabaaaabbaababbababbabaaaaabbabbab
|
||||
abbbbbbbabbbbbaaaaaabbba
|
||||
bababbbabbbaaabaaabbbabbabaaabaaaabbabbbababbbbbababbbab
|
||||
abababaaaaaaaababbbaabaa
|
||||
babbabbbaabbabbbaababaaa
|
||||
abbaabaababaaaabbbbbabbaaaabbabbbbbababaabbbbbabbaaaaabbbbaaaabaaabbaaab
|
||||
aaababababbaaaabbaaaabbb
|
||||
aaaaaabaaaaabaabaaaabbaa
|
||||
bbaaabbbabbbbbbaaabbaaaaababbabbbaaabbba
|
||||
bbbaabbbbbabbbaaabbbbbab
|
||||
aabbaabaabbbababbaaabbbb
|
||||
bbabbbabbbaabbaaabbbbbbababaaabaabbababbaabbaabbbaabaaaabaababbb
|
||||
aaaabaaaabbbabaababbbbaabaaaaaba
|
||||
abbbabbaabaaabbbabbababaaaaabbabbaabbaaaababbbab
|
||||
baaabaabaabbaaaabbababbbabbaaaababbbbbab
|
||||
bbbbbbababaaabaabbaaaaaa
|
||||
baaabbaaaabaaabaaaabaaab
|
||||
bbbaaabaaabbabbaabbabaab
|
||||
babaabababbbbbbaaaaabbba
|
||||
aaabbbabaaaaaaaabababbab
|
||||
bbbbababaabbabbababbbbbb
|
||||
aaaaabaaaaaaaababaaaaabb
|
||||
aaaaaaaababbbbababbbabbaabababbb
|
||||
abbbbbbaaababaababbbbaab
|
||||
aaaaaabababaababaaaaabba
|
||||
aabbaaaabababbabaabaababbbaabbbbabbbaaaaaabbabaaabaabbbb
|
||||
ababbbbaabbabbbabbbbbaaababababbaababaaabaaaaaab
|
||||
bbabbabbbabaaabaaabbbbaa
|
||||
baaaabbaaabbbabaabaabaaabbabbababbbbbbbbaaabaaaababbbbbabaaabbabbabbbbbaaaababaa
|
||||
abbababaaaabababbbabbaaa
|
||||
babaabbabbbaabbbaaaabbaa
|
||||
abbbbbaaaabaabbaaabbabbaabbabaaaabbabaaa
|
||||
abababbababaaabaabbababaaaaabbababaaaaaaabababbaabaabbbabbaaaabb
|
||||
bbbaabbbababaabbabaaaaab
|
||||
aabaabaaabbabaabbbaaabaa
|
||||
abababaabaabbaababbabbbb
|
||||
babaabbaaaaaaaabaaaaabba
|
||||
bbaabbbaababaaaaaaaababa
|
||||
bbabaaaaabaaaaaaaaabaaaabbbabababaabbbababaaabba
|
||||
abaaabaaabaaaabbbaaaabab
|
||||
aabbabaaaaaaabbbababbbba
|
||||
abababaabbbbaabbaabbaaabbbbbaaaabababababababaaaabbbbaaaaaaaabbbbabbbaaa
|
||||
abbbabbabababbaaabaabbaa
|
||||
aaabaaaaaabbaaaabbaabbba
|
||||
aabaabbababbabbaaabbabbbababbaab
|
||||
bbbbbaabaaabaaabaabbaabbbbaababa
|
381
d19/main.py
Executable file
381
d19/main.py
Executable file
@ -0,0 +1,381 @@
|
||||
#! /usr/bin/env python3
|
||||
from itertools import product
|
||||
from typing import Dict
|
||||
from typing import List
|
||||
from typing import Optional
|
||||
from typing import Tuple
|
||||
|
||||
MAX_DEPTH = 10
|
||||
|
||||
|
||||
class Rule(object):
|
||||
_rule_body: str
|
||||
key: int
|
||||
_values: List[str]
|
||||
_depth: int
|
||||
|
||||
def __init__(self, key: int, rule_body: str):
|
||||
self.key = key
|
||||
self._rule_body = rule_body
|
||||
self._values = []
|
||||
self._depth = 0
|
||||
|
||||
def validate(self, s: str) -> bool:
|
||||
return s in self.values()
|
||||
|
||||
def values(self) -> List[str]:
|
||||
if not self._values:
|
||||
if self._depth >= MAX_DEPTH:
|
||||
# Break out of recursion
|
||||
return []
|
||||
|
||||
self._depth += 1
|
||||
|
||||
values: List[str] = []
|
||||
for sub_rule in self._rule_body.split(" | "):
|
||||
rule_combo: "Rule" = ValueRule(-1, [""])
|
||||
for rule_key in sub_rule.split(" "):
|
||||
rule_combo += RULE_INDEX[int(rule_key)]
|
||||
|
||||
values += rule_combo.values()
|
||||
|
||||
self._values = values
|
||||
|
||||
return self._values
|
||||
|
||||
def __add__(self, other) -> "Rule":
|
||||
values = [
|
||||
"".join(v)
|
||||
for v in product(self.values(), other.values())
|
||||
]
|
||||
return ValueRule(
|
||||
-1,
|
||||
values,
|
||||
)
|
||||
|
||||
def __mul__(self, other) -> List[str]:
|
||||
raise NotImplementedError()
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"<Rule key={self.key} rule={self._rule_body}>"
|
||||
|
||||
|
||||
class ValueRule(Rule):
|
||||
key: int
|
||||
|
||||
def __init__(self, key: int, values: List[str]):
|
||||
self.key = key
|
||||
self._values = values
|
||||
|
||||
def values(self) -> List[str]:
|
||||
return self._values
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"<ValueRule key={self.key} values={self.values()}>"
|
||||
|
||||
|
||||
def parse_rule(line) -> Tuple[int, Rule]:
|
||||
rule_index = line.find(":")
|
||||
if rule_index <= 0:
|
||||
raise ValueError(f"Could not find rule number in {line}")
|
||||
rule_key = int(line[:rule_index])
|
||||
rule_body = line[rule_index+2:]
|
||||
rule: Optional[Rule] = None
|
||||
if rule_body[0] == '"':
|
||||
rule = ValueRule(rule_key, [rule_body[1:-1]])
|
||||
else:
|
||||
rule = Rule(rule_key, rule_body)
|
||||
|
||||
return rule_key, rule
|
||||
|
||||
|
||||
RULE_INDEX: Dict[int, Rule] = {}
|
||||
|
||||
|
||||
def test():
|
||||
test_input = (
|
||||
"0: 4 1 5",
|
||||
"1: 2 3 | 3 2",
|
||||
"2: 4 4 | 5 5",
|
||||
"3: 4 5 | 5 4",
|
||||
'4: "a"',
|
||||
'5: "b"',
|
||||
)
|
||||
RULE_INDEX.update({
|
||||
parse_rule(line)
|
||||
for line in test_input
|
||||
})
|
||||
|
||||
print(RULE_INDEX)
|
||||
|
||||
for rule in RULE_INDEX.values():
|
||||
print(rule.key, rule.values())
|
||||
|
||||
test_eval = (
|
||||
"ababbb",
|
||||
"bababa",
|
||||
"abbbab",
|
||||
"aaabbb",
|
||||
"aaaabbb",
|
||||
)
|
||||
|
||||
rule_0 = RULE_INDEX[0]
|
||||
matched = 0
|
||||
|
||||
for t in test_eval:
|
||||
if rule_0.validate(t):
|
||||
matched += 1
|
||||
|
||||
print(f"Total matched is {matched}")
|
||||
|
||||
|
||||
def part1():
|
||||
rules_parsed = False
|
||||
matched = 0
|
||||
|
||||
with open("input.txt") as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
print(line, end="")
|
||||
if line == "":
|
||||
rules_parsed = True
|
||||
print("DONE PARSING RULES")
|
||||
elif not rules_parsed:
|
||||
key, rule = parse_rule(line)
|
||||
RULE_INDEX[key] = rule
|
||||
print(" Parsed")
|
||||
elif RULE_INDEX[0].validate(line):
|
||||
matched += 1
|
||||
print(" OK")
|
||||
else:
|
||||
print(" Not OK")
|
||||
|
||||
print(f"Total matched is {matched}")
|
||||
|
||||
|
||||
def chunk(a, n):
|
||||
return (a[i:i+n] for i in range(0, len(a), n))
|
||||
|
||||
|
||||
def count_prefix(value: str, prefix: str) -> int:
|
||||
count = 0
|
||||
for c in chunk(value, len(prefix)):
|
||||
if c == prefix:
|
||||
count += 1
|
||||
else:
|
||||
break
|
||||
|
||||
return count
|
||||
|
||||
|
||||
class Rule0(Rule):
|
||||
def __init__(self):
|
||||
super().__init__(0, "")
|
||||
|
||||
def validate(self, value: str) -> bool:
|
||||
r42 = RULE_INDEX[42]
|
||||
r31 = RULE_INDEX[31]
|
||||
|
||||
# print(42, "\n".join(r42.values()))
|
||||
# print(31, "\n".join(r31.values()))
|
||||
|
||||
size = None
|
||||
for v in r42.values():
|
||||
if size is None:
|
||||
size = len(v)
|
||||
assert len(v) == size
|
||||
for v in r31.values():
|
||||
assert len(v) == size
|
||||
|
||||
match42, match31 = 0, 0
|
||||
for c in chunk(value, size):
|
||||
if match31 == 0 and r42.validate(c):
|
||||
match42 += 1
|
||||
elif match42 != 0 and r31.validate(c):
|
||||
match31 += 1
|
||||
else:
|
||||
return False
|
||||
|
||||
# if value == "abbbbbabbbaaaababbaabbbbabababbbabbbbbbabaaaa":
|
||||
# from pdb import set_trace; set_trace()
|
||||
|
||||
if match42 > match31 and match31 > 0:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
# if RULE_INDEX[0].validate(value):
|
||||
# from pdb import set_trace; set_trace()
|
||||
|
||||
# Check beginning starts with "8"
|
||||
for prefix1 in r42.values():
|
||||
prefix_count = count_prefix(value, prefix1)
|
||||
|
||||
if prefix_count == 0:
|
||||
# Not even one chunk was matched, this is a bust
|
||||
continue
|
||||
|
||||
# Trim first prefix out
|
||||
back_half = value[len(prefix1) * prefix_count:]
|
||||
|
||||
# Check following "11" match
|
||||
for prefix2, suffix in product(r42.values(), r31.values()):
|
||||
remain = back_half
|
||||
|
||||
if RULE_INDEX[0].validate(value) and prefix1 == "bbabb" and prefix2 == "bbaab" and suffix == "aabba":
|
||||
from pdb import set_trace; set_trace()
|
||||
|
||||
# If prefixes aren't the same, look for the new one
|
||||
if prefix1 != prefix2:
|
||||
prefix_count = count_prefix(remain, prefix2)
|
||||
# Trim the new prefix
|
||||
remain = remain[len(prefix2) * prefix_count:]
|
||||
|
||||
if prefix_count == 0:
|
||||
# No valid prefix
|
||||
continue
|
||||
|
||||
suffix_count = count_prefix(remain, suffix)
|
||||
|
||||
if suffix_count == 0:
|
||||
# No valid suffix
|
||||
continue
|
||||
|
||||
# Trim the suffix
|
||||
remain = remain[len(suffix) * suffix_count:]
|
||||
if len(remain) > 0:
|
||||
# There is something after the suffix
|
||||
continue
|
||||
|
||||
# Make sure we've seen at least the same number of prefixes
|
||||
if prefix_count >= suffix_count:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def part2():
|
||||
# Update two changed rules
|
||||
# 0: 8 11
|
||||
|
||||
# Test short circuits
|
||||
# RULE_INDEX[42] = parse_rule('42: "a"')[1]
|
||||
# RULE_INDEX[31] = parse_rule('31: "b"')[1]
|
||||
|
||||
# rule8 = parse_rule("8: 42 | 42 8")[1]
|
||||
# rule11 = parse_rule("11: 42 31 | 42 11 31")[1]
|
||||
|
||||
# print(RULE_INDEX[8].values())
|
||||
# print(RULE_INDEX[11].values())
|
||||
|
||||
rules_parsed = False
|
||||
matched = 0
|
||||
|
||||
# Empty rules
|
||||
RULE_INDEX.clear()
|
||||
|
||||
with open("input.txt") as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
print(line, end="")
|
||||
if line == "":
|
||||
rules_parsed = True
|
||||
# All rules parsed, replace values
|
||||
# RULE_INDEX[8] = rule8
|
||||
# RULE_INDEX[11] = rule11
|
||||
print("DONE PARSING RULES")
|
||||
r42 = RULE_INDEX[42]
|
||||
print("prefixes", r42.values())
|
||||
r31 = RULE_INDEX[31]
|
||||
print("suffixes", r31.values())
|
||||
elif not rules_parsed:
|
||||
key, rule = parse_rule(line)
|
||||
RULE_INDEX[key] = rule
|
||||
print(" Parsed")
|
||||
elif Rule0().validate(line):
|
||||
matched += 1
|
||||
print(" OK")
|
||||
else:
|
||||
print(" Not OK")
|
||||
|
||||
print(f"Total matched is {matched}")
|
||||
|
||||
|
||||
def test2():
|
||||
r0 = Rule0()
|
||||
# RULE_INDEX[42] = ValueRule(42, ["prefixa", "prefixb"])
|
||||
# RULE_INDEX[31] = ValueRule(31, ["sa", "sb"])
|
||||
|
||||
test_input = (
|
||||
"42: 9 14 | 10 1",
|
||||
"9: 14 27 | 1 26",
|
||||
"10: 23 14 | 28 1",
|
||||
'1: "a"',
|
||||
"11: 42 31",
|
||||
"5: 1 14 | 15 1",
|
||||
"19: 14 1 | 14 14",
|
||||
"12: 24 14 | 19 1",
|
||||
"16: 15 1 | 14 14",
|
||||
"31: 14 17 | 1 13",
|
||||
"6: 14 14 | 1 14",
|
||||
"2: 1 24 | 14 4",
|
||||
"0: 8 11",
|
||||
"13: 14 3 | 1 12",
|
||||
"15: 1 | 14",
|
||||
"17: 14 2 | 1 7",
|
||||
"23: 25 1 | 22 14",
|
||||
"28: 16 1",
|
||||
"4: 1 1",
|
||||
"20: 14 14 | 1 15",
|
||||
"3: 5 14 | 16 1",
|
||||
"27: 1 6 | 14 18",
|
||||
'14: "b"',
|
||||
"21: 14 1 | 1 14",
|
||||
"25: 1 1 | 1 14",
|
||||
"22: 14 14",
|
||||
"8: 42",
|
||||
"26: 14 22 | 1 20",
|
||||
"18: 15 15",
|
||||
"7: 14 5 | 1 21",
|
||||
"24: 14 1",
|
||||
)
|
||||
RULE_INDEX.update({
|
||||
parse_rule(line)
|
||||
for line in test_input
|
||||
})
|
||||
|
||||
og_valid = 0
|
||||
new_valid = 0
|
||||
|
||||
for v in (
|
||||
"abbbbbabbbaaaababbaabbbbabababbbabbbbbbabaaaa",
|
||||
"bbabbbbaabaabba",
|
||||
"babbbbaabbbbbabbbbbbaabaaabaaa",
|
||||
"aaabbbbbbaaaabaababaabababbabaaabbababababaaa",
|
||||
"bbbbbbbaaaabbbbaaabbabaaa",
|
||||
"bbbababbbbaaaaaaaabbababaaababaabab",
|
||||
"ababaaaaaabaaab",
|
||||
"ababaaaaabbbaba",
|
||||
"baabbaaaabbaaaababbaababb",
|
||||
"abbbbabbbbaaaababbbbbbaaaababb",
|
||||
"aaaaabbaabaaaaababaa",
|
||||
"aaaabbaaaabbaaa",
|
||||
"aaaabbaabbaaaaaaabbbabbbaaabbaabaaa",
|
||||
"babaaabbbaaabaababbaabababaaab",
|
||||
"aabbbbbaabbbaaaaaabbbbbababaaaaabbaaabba",
|
||||
):
|
||||
og = RULE_INDEX[0].validate(v)
|
||||
n = r0.validate(v)
|
||||
print(v, "og", og, "new", n)
|
||||
if og:
|
||||
og_valid += 1
|
||||
if n:
|
||||
new_valid += 1
|
||||
|
||||
print("og valid:", og_valid, "new valid:", new_valid)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# part1()
|
||||
part2()
|
||||
# test2()
|
1727
d20/input.txt
Normal file
1727
d20/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
400
d20/main.py
Executable file
400
d20/main.py
Executable file
@ -0,0 +1,400 @@
|
||||
#! /usr/bin/env python3
|
||||
from itertools import chain
|
||||
from functools import reduce
|
||||
from typing import List
|
||||
from typing import Optional
|
||||
from typing import Set
|
||||
from typing import Tuple
|
||||
|
||||
|
||||
class Tile(object):
|
||||
def __init__(self, tile_num: int, content: List[List[str]]):
|
||||
self.num = tile_num
|
||||
self.content = content
|
||||
|
||||
# Neighboring tiles
|
||||
self.top: Optional["Tile"] = None
|
||||
self.bottom: Optional["Tile"] = None
|
||||
self.left: Optional["Tile"] = None
|
||||
self.right: Optional["Tile"] = None
|
||||
|
||||
# All edges for quick match
|
||||
self.edges: Set[str] = set()
|
||||
self.edges.add(self.top_edge)
|
||||
self.edges.add(self.top_edge[::-1])
|
||||
self.edges.add(self.bottom_edge)
|
||||
self.edges.add(self.bottom_edge[::-1])
|
||||
self.edges.add(self.left_edge)
|
||||
self.edges.add(self.left_edge[::-1])
|
||||
self.edges.add(self.right_edge)
|
||||
self.edges.add(self.right_edge[::-1])
|
||||
|
||||
@property
|
||||
def left_edge(self) -> str:
|
||||
return "".join(
|
||||
[self.content[y][0] for y in range(0, len(self.content))]
|
||||
)
|
||||
|
||||
@property
|
||||
def right_edge(self) -> str:
|
||||
return "".join(
|
||||
[self.content[y][-1] for y in range(0, len(self.content))]
|
||||
)
|
||||
|
||||
@property
|
||||
def top_edge(self) -> str:
|
||||
return "".join(self.content[0])
|
||||
|
||||
@property
|
||||
def bottom_edge(self) -> str:
|
||||
return "".join(self.content[-1])
|
||||
|
||||
def flip_lr(self):
|
||||
for i, row in enumerate(self.content):
|
||||
self.content[i] = row[::-1]
|
||||
|
||||
def flip_tb(self):
|
||||
self.content = self.content[::-1]
|
||||
|
||||
def rotate_cw(self):
|
||||
self.content = [
|
||||
[self.content[j][i] for j in range(len(self.content)-1, -1, -1)]
|
||||
for i in range(len(self.content[0]))
|
||||
]
|
||||
|
||||
def rotate_ccw(self):
|
||||
self.content = [
|
||||
[self.content[j][i] for j in range(len(self.content))]
|
||||
for i in range(len(self.content[0])-1, -1, -1)
|
||||
]
|
||||
|
||||
def align_edge(self, edge: str, direction: str):
|
||||
assert edge in self.edges
|
||||
|
||||
if direction in ("top", "bottom"):
|
||||
while getattr(self, direction+"_edge") != edge:
|
||||
if getattr(self, direction+"_edge")[::-1] == edge:
|
||||
self.flip_lr()
|
||||
return
|
||||
|
||||
self.rotate_cw()
|
||||
elif direction in ("left", "right"):
|
||||
while getattr(self, direction+"_edge") != edge:
|
||||
if getattr(self, direction+"_edge")[::-1] == edge:
|
||||
self.flip_tb()
|
||||
return
|
||||
self.rotate_cw()
|
||||
else:
|
||||
raise ValueError(f"Unknown direction {direction}")
|
||||
|
||||
def count_neighbors(self, other_tiles: List["Tile"]) -> int:
|
||||
num_neighbors = 0
|
||||
for tile in other_tiles:
|
||||
if self.num == tile.num:
|
||||
continue
|
||||
if self.edges & tile.edges:
|
||||
num_neighbors += 1
|
||||
|
||||
return num_neighbors
|
||||
|
||||
def find_bottom(
|
||||
self,
|
||||
other_tiles: List["Tile"],
|
||||
assign: Optional[bool] = True,
|
||||
) -> Optional["Tile"]:
|
||||
bottom_tile: Optional[Tile] = None
|
||||
for tile in other_tiles:
|
||||
if self.num == tile.num:
|
||||
continue
|
||||
if self.bottom_edge in tile.edges:
|
||||
tile.align_edge(self.bottom_edge, "top")
|
||||
if bottom_tile is None:
|
||||
bottom_tile = tile
|
||||
else:
|
||||
raise ValueError("Multiple match error")
|
||||
if assign:
|
||||
self.bottom = tile
|
||||
tile.top = self
|
||||
|
||||
return bottom_tile
|
||||
|
||||
def find_right(
|
||||
self,
|
||||
other_tiles: List["Tile"],
|
||||
assign: Optional[bool] = True,
|
||||
) -> Optional["Tile"]:
|
||||
right_tile: Optional[Tile] = None
|
||||
for tile in other_tiles:
|
||||
if self.num == tile.num:
|
||||
continue
|
||||
if self.right_edge in tile.edges:
|
||||
tile.align_edge(self.right_edge, "left")
|
||||
if right_tile is None:
|
||||
right_tile = tile
|
||||
else:
|
||||
raise ValueError("Multiple match error")
|
||||
if assign:
|
||||
self.right = tile
|
||||
tile.left = self
|
||||
|
||||
return right_tile
|
||||
|
||||
def remove_edges(self):
|
||||
self.content = [
|
||||
row[1:-1]
|
||||
for row in self.content[1:-1]
|
||||
]
|
||||
|
||||
def __add__(self, other) -> "Tile":
|
||||
new_content = [
|
||||
s + o
|
||||
for s, o in zip(self.content, other.content)
|
||||
]
|
||||
|
||||
return Tile(self.num * other.num, new_content)
|
||||
|
||||
def __truediv__(self, other) -> "Tile":
|
||||
new_content = [
|
||||
row for row in chain(self.content, other.content)
|
||||
]
|
||||
|
||||
return Tile(self.num * other.num, new_content)
|
||||
|
||||
def __eq__(self, other) -> bool:
|
||||
return self.num == other.num
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return self.num
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"<Tile no={self.num}>"
|
||||
|
||||
def to_str(self) -> str:
|
||||
return "\n".join(
|
||||
"".join(row)
|
||||
for row in self.content
|
||||
)
|
||||
|
||||
def total_turbulance(self) -> int:
|
||||
total = 0
|
||||
for row in self.content:
|
||||
for c in row:
|
||||
if c == "#":
|
||||
total += 1
|
||||
|
||||
return total
|
||||
|
||||
|
||||
SEAMONSTER = [
|
||||
" # ",
|
||||
"# ## ## ###",
|
||||
" # # # # # # ",
|
||||
]
|
||||
|
||||
IN_THE_SEA: Set[Tuple[int, int]] = set()
|
||||
|
||||
|
||||
def search_seamonster(
|
||||
content: List[List[str]],
|
||||
x: int,
|
||||
y: int,
|
||||
) -> Tuple[bool, int]:
|
||||
found = True
|
||||
turbulance = 0
|
||||
|
||||
in_the_sea: Set[Tuple[int, int]] = set()
|
||||
for yi in range(len(SEAMONSTER)):
|
||||
if y+yi >= len(content):
|
||||
return False, 0
|
||||
row = content[y+yi]
|
||||
for xi in range(len(SEAMONSTER[yi])):
|
||||
p = (x+xi, y+yi)
|
||||
if p in IN_THE_SEA:
|
||||
return False, 0
|
||||
|
||||
if x+xi >= len(row):
|
||||
return False, 0
|
||||
|
||||
c = row[x+xi]
|
||||
sea = SEAMONSTER[yi][xi]
|
||||
|
||||
if sea == "#" and c == "#":
|
||||
in_the_sea.add(p)
|
||||
# Not a seamonster match
|
||||
elif sea == "#" and c != "#":
|
||||
return False, 0
|
||||
elif sea == " " and c == "#":
|
||||
turbulance += 1
|
||||
elif sea == " " and c == ".":
|
||||
continue
|
||||
else:
|
||||
raise ValueError(f"Uncharted waters: {sea}, {c}")
|
||||
|
||||
if found:
|
||||
for p in in_the_sea:
|
||||
IN_THE_SEA.add(p)
|
||||
|
||||
return found, turbulance
|
||||
|
||||
|
||||
def read_tiles(filename: str) -> List[Tile]:
|
||||
results: List[Tile] = []
|
||||
with open(filename) as f:
|
||||
tile_num = -1
|
||||
content: List[List[str]] = []
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if line.startswith("Tile "):
|
||||
tile_num = int(line[5:line.index(":")])
|
||||
elif line == "":
|
||||
results.append(Tile(tile_num, content))
|
||||
tile_num = -1
|
||||
content = []
|
||||
else:
|
||||
content.append([c for c in line])
|
||||
|
||||
results.append(Tile(tile_num, content))
|
||||
|
||||
return results
|
||||
|
||||
|
||||
def test():
|
||||
tiles = read_tiles("test-input.txt")
|
||||
corners: List[Tile] = []
|
||||
for tile in tiles:
|
||||
num_neighbors = tile.count_neighbors(tiles)
|
||||
print(f"Tile: {tile.num}: {num_neighbors}")
|
||||
if num_neighbors == 2:
|
||||
corners.append(tile)
|
||||
|
||||
product = 1
|
||||
for t in corners:
|
||||
product *= t.num
|
||||
|
||||
print("Corner product:", product)
|
||||
|
||||
|
||||
def part1():
|
||||
tiles = read_tiles("input.txt")
|
||||
corners: List[Tile] = []
|
||||
for tile in tiles:
|
||||
num_neighbors = tile.count_neighbors(tiles)
|
||||
print(f"Tile: {tile.num}: {num_neighbors}")
|
||||
if num_neighbors == 2:
|
||||
corners.append(tile)
|
||||
|
||||
product = 1
|
||||
for t in corners:
|
||||
product *= t.num
|
||||
|
||||
print("Corner product:", product)
|
||||
|
||||
|
||||
def part2():
|
||||
tiles = set(read_tiles("input.txt"))
|
||||
corners: List[Tile] = []
|
||||
for tile in tiles:
|
||||
num_neighbors = tile.count_neighbors(tiles)
|
||||
print(f"Tile: {tile.num}: {num_neighbors}")
|
||||
if num_neighbors == 2:
|
||||
corners.append(tile)
|
||||
|
||||
product = 1
|
||||
for t in corners:
|
||||
product *= t.num
|
||||
|
||||
top_left: Optional[Tile] = None
|
||||
|
||||
print("Corner product:", product)
|
||||
for corner in corners:
|
||||
right = corner.find_right(tiles, False)
|
||||
if not right:
|
||||
continue
|
||||
bottom = corner.find_bottom(tiles, False)
|
||||
if not bottom:
|
||||
continue
|
||||
|
||||
top_left = corner
|
||||
# print(corner.to_str(), corner.right.to_str())
|
||||
# print(corner.bottom.to_str())
|
||||
break
|
||||
else:
|
||||
print("no perfect corner")
|
||||
|
||||
# Init grid
|
||||
g = [[top_left]]
|
||||
print("removing", top_left)
|
||||
tiles.remove(top_left)
|
||||
|
||||
tile = top_left
|
||||
tile.find_bottom(tiles)
|
||||
|
||||
# Build rows
|
||||
while tile.bottom:
|
||||
tile = tile.bottom
|
||||
g.append([tile])
|
||||
print("removing bottom", tile)
|
||||
tiles.remove(tile)
|
||||
tile.find_bottom(tiles)
|
||||
|
||||
for row in g:
|
||||
tile = row[0]
|
||||
tile.find_right(tiles)
|
||||
while tile.right:
|
||||
print(f"removing right {tile}->{tile.right}")
|
||||
tile = tile.right
|
||||
row.append(tile)
|
||||
tiles.remove(tile)
|
||||
tile.find_right(tiles)
|
||||
|
||||
v_split = Tile(0, [[" "] for _ in range(len(top_left.content))])
|
||||
h_split = Tile(0, [[" " for _ in range(len(top_left.content[0]))]])
|
||||
m = reduce(lambda x, y: x/h_split/y, (
|
||||
reduce(lambda x, y: x+v_split+y, (tile for tile in row))
|
||||
for row in g
|
||||
))
|
||||
|
||||
m.flip_tb()
|
||||
print(m.to_str())
|
||||
|
||||
# Trim all edges
|
||||
for row in g:
|
||||
for t in row:
|
||||
t.remove_edges()
|
||||
|
||||
m = reduce(lambda x, y: x/y, (
|
||||
reduce(lambda x, y: x+y, (tile for tile in row))
|
||||
for row in g
|
||||
))
|
||||
|
||||
turbulance = m.total_turbulance()
|
||||
seamonsters = 0
|
||||
|
||||
while seamonsters == 0:
|
||||
m.rotate_cw()
|
||||
content = m.content
|
||||
for y in range(len(content)):
|
||||
for x in range(len(content[y])):
|
||||
found, _ = search_seamonster(content, x, y)
|
||||
if found:
|
||||
print("found a seamonster at", x, y)
|
||||
seamonsters += 1
|
||||
|
||||
sea_turb = 0
|
||||
for row in SEAMONSTER:
|
||||
for c in row:
|
||||
if c == "#":
|
||||
sea_turb += 1
|
||||
|
||||
turbulance -= sea_turb * seamonsters
|
||||
|
||||
for p in IN_THE_SEA:
|
||||
m.content[p[1]][p[0]] = "O"
|
||||
|
||||
print(m.to_str())
|
||||
print(f"Found {seamonsters} seamonsters with {turbulance} turbulance")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# part1()
|
||||
part2()
|
142
d20/output.txt
Normal file
142
d20/output.txt
Normal file
@ -0,0 +1,142 @@
|
||||
...###...##...#...#..###
|
||||
.#.###..##..##..####.##.
|
||||
#.##..#..#...#..####...#
|
||||
#####..#####...###....##
|
||||
#..####...#.#.#.###.###.
|
||||
..#.#..#..#.#.#.####.###
|
||||
.####.###.#...###.#..#.#
|
||||
.#.#.###.##.##.#..#.##..
|
||||
###.#...#..#.##.######..
|
||||
.#.#....#.##.#...###.##.
|
||||
...#..#..#.#.##..###.###
|
||||
##..##.#...#...#.#.#.#..
|
||||
#.####....##..########.#
|
||||
###.#.#...#.######.#..##
|
||||
#.####..#.####.#.#.###..
|
||||
#..#.##..#..###.#.##....
|
||||
.####...#..#....#..#####
|
||||
....#..#...##..#.#......
|
||||
...########.#...#####...
|
||||
##.#....#.##.######.#..#
|
||||
###.#####...#.###...#.##
|
||||
##.##.###.#.#..#.#####.#
|
||||
###....#.#....#..#.###..
|
||||
.#.#..#.##...#.#.#......
|
||||
|
||||
.####...#####..#...###..
|
||||
#####..#..#.#.####..#.#.
|
||||
.#.#...#.###...#.##.O#..
|
||||
#.O.##.OO#.#.OO.##.OOO##
|
||||
..#O.#O#.O##O..O.#O##.##
|
||||
...#.#..##.##...#..#..##
|
||||
#.##.#..#.#..#..##.#.#..
|
||||
.###.##.....#...###.#...
|
||||
#.####.#.#....##.#..#.#.
|
||||
##...#..#....#..#...####
|
||||
..#.##...###..#.#####..#
|
||||
....#.##.#.#####....#...
|
||||
..##.##.###.....#.##..#.
|
||||
#...#...###..####....##.
|
||||
.#.##...#.##.#.#.###...#
|
||||
#.###.#..####...##..#...
|
||||
...###.##.##...#.######.
|
||||
###.###..#######..#####.
|
||||
..#.##..#..#.#######.###
|
||||
.##..#.#########..#..##.
|
||||
.#####.#.#.#...##..#....
|
||||
.##....#.#.#########..##
|
||||
...#...#..#..##...###.##
|
||||
..###..#..##.#...##.##.#
|
||||
|
||||
.####...#####..#...###..
|
||||
#####..#..#.#.####..#.#.
|
||||
.#.#...#.###...#.##.O#..
|
||||
#.O.##.OO#.#.OO.##.OOO##
|
||||
..#O.#O#.O##O..O.#O##.##
|
||||
...#.#..##.##...#..#..##
|
||||
#.##.#..#.#..#..##.#.#..
|
||||
.###.##.....#...###.#...
|
||||
#.####.#.#....##.#..#.#.
|
||||
##...#..#....#..#...####
|
||||
..#.##...###..#.#####..#
|
||||
....#.##.#.#####....#...
|
||||
..##.##.###.....#.##..#.
|
||||
#...#...###..####....##.
|
||||
.#.##...#.##.#.#.###...#
|
||||
#.###.#..####...##..#...
|
||||
#.###...#.##...#.##O###.
|
||||
.O##.#OO.###OO##..OOO##.
|
||||
..O#.O..O..O.#O##O##.###
|
||||
#.#..##.########..#..##.
|
||||
#.#####..#.#...##..#....
|
||||
#....##..#.#########..##
|
||||
#...#.....#..##...###.##
|
||||
#..###....##.#...##.##.#
|
||||
|
||||
|
||||
..#.#....# ##.#.#.... ...##.....
|
||||
#...###... ..##...#.. ...#..####
|
||||
#.#.###... .##..##... .####.##.#
|
||||
##.##..#.. ..#...#... .####...#.
|
||||
.#####..## #####...#. .##....##.
|
||||
.#..####.# #..#.#.#.# ####.###..
|
||||
#..#.#..#. ...#.#.#.. .####.###.
|
||||
..####.### ##.#...##. .#.#..#.##
|
||||
..#.#.###. ..##.##.## #..#.##..#
|
||||
...#.#.#.# ###.##.#.. .##...####
|
||||
|
||||
...#.#.#.# ###.##.#.. .##...####
|
||||
####.#.... .#..#.##.. .######...
|
||||
..#.#..... .#.##.#..# #.###.##..
|
||||
....#..#.# #.#.#.##.# #.###.###.
|
||||
.##..##.#. ....#...## #.#.#.#...
|
||||
.#.####... ...##..##. .######.##
|
||||
####.#.#.. ...#.##### ###.#..###
|
||||
##.####... .#.####.#. ..#.###..#
|
||||
##..#.##.. ..#..###.# ##.##....#
|
||||
#.##...##. ..##.#..#. ..#.###...
|
||||
|
||||
#.##...##. ..##.#..#. #.#.#####.
|
||||
#.####...# ##..#..... .#..######
|
||||
.....#..## #...##..#. ..#.......
|
||||
#...###### ####.#...# ######....
|
||||
.##.#....# ##.##.###. ####.#..#.
|
||||
.###.##### ##...#.### .#...#.##.
|
||||
###.##.##. .#.#.#..## #.#####.##
|
||||
.###....#. ..#....#.. ..#.###...
|
||||
..#.#..#.# ###...#.#. ..#.......
|
||||
#...##.#.. ..###..### ..#.###...
|
||||
|
||||
|
||||
#...##.#.. ..###..### #.#.#####.
|
||||
..#.#..#.# ###...#.#. .#..######
|
||||
.###....#. ..#....#.. ..#.......
|
||||
###.##.##. .#.#.#..## ######....
|
||||
.###.##### ##...#.### ####.#..#.
|
||||
.##.#....# ##.##.###. .#...#.##.
|
||||
#...###### ####.#...# #.#####.##
|
||||
.....#..## #...##..#. ..#.###...
|
||||
#.####...# ##..#..... ..#.......
|
||||
#.##...##. ..##.#..#. ..#.###...
|
||||
|
||||
#.##...##. ..##.#..#. ..#.###...
|
||||
##..#.##.. ..#..###.# ##.##....#
|
||||
##.####... .#.####.#. ..#.###..#
|
||||
####.#.#.. ...#.##### ###.#..###
|
||||
.#.####... ...##..##. .######.##
|
||||
.##..##.#. ....#...## #.#.#.#...
|
||||
....#..#.# #.#.#.##.# #.###.###.
|
||||
..#.#..... .#.##.#..# #.###.##..
|
||||
####.#.... .#..#.##.. .######...
|
||||
...#.#.#.# ###.##.#.. .##...####
|
||||
|
||||
...#.#.#.# ###.##.#.. .##...####
|
||||
..#.#.###. ..##.##.## #..#.##..#
|
||||
..####.### ##.#...##. .#.#..#.##
|
||||
#..#.#..#. ...#.#.#.. .####.###.
|
||||
.#..####.# #..#.#.#.# ####.###..
|
||||
.#####..## #####...#. .##....##.
|
||||
##.##..#.. ..#...#... .####...#.
|
||||
#.#.###... .##..##... .####.##.#
|
||||
#...###... ..##...#.. ...#..####
|
||||
..#.#....# ##.#.#.... ...##.....
|
107
d20/test-input.txt
Normal file
107
d20/test-input.txt
Normal file
@ -0,0 +1,107 @@
|
||||
Tile 2311:
|
||||
..##.#..#.
|
||||
##..#.....
|
||||
#...##..#.
|
||||
####.#...#
|
||||
##.##.###.
|
||||
##...#.###
|
||||
.#.#.#..##
|
||||
..#....#..
|
||||
###...#.#.
|
||||
..###..###
|
||||
|
||||
Tile 1951:
|
||||
#.##...##.
|
||||
#.####...#
|
||||
.....#..##
|
||||
#...######
|
||||
.##.#....#
|
||||
.###.#####
|
||||
###.##.##.
|
||||
.###....#.
|
||||
..#.#..#.#
|
||||
#...##.#..
|
||||
|
||||
Tile 1171:
|
||||
####...##.
|
||||
#..##.#..#
|
||||
##.#..#.#.
|
||||
.###.####.
|
||||
..###.####
|
||||
.##....##.
|
||||
.#...####.
|
||||
#.##.####.
|
||||
####..#...
|
||||
.....##...
|
||||
|
||||
Tile 1427:
|
||||
###.##.#..
|
||||
.#..#.##..
|
||||
.#.##.#..#
|
||||
#.#.#.##.#
|
||||
....#...##
|
||||
...##..##.
|
||||
...#.#####
|
||||
.#.####.#.
|
||||
..#..###.#
|
||||
..##.#..#.
|
||||
|
||||
Tile 1489:
|
||||
##.#.#....
|
||||
..##...#..
|
||||
.##..##...
|
||||
..#...#...
|
||||
#####...#.
|
||||
#..#.#.#.#
|
||||
...#.#.#..
|
||||
##.#...##.
|
||||
..##.##.##
|
||||
###.##.#..
|
||||
|
||||
Tile 2473:
|
||||
#....####.
|
||||
#..#.##...
|
||||
#.##..#...
|
||||
######.#.#
|
||||
.#...#.#.#
|
||||
.#########
|
||||
.###.#..#.
|
||||
########.#
|
||||
##...##.#.
|
||||
..###.#.#.
|
||||
|
||||
Tile 2971:
|
||||
..#.#....#
|
||||
#...###...
|
||||
#.#.###...
|
||||
##.##..#..
|
||||
.#####..##
|
||||
.#..####.#
|
||||
#..#.#..#.
|
||||
..####.###
|
||||
..#.#.###.
|
||||
...#.#.#.#
|
||||
|
||||
Tile 2729:
|
||||
...#.#.#.#
|
||||
####.#....
|
||||
..#.#.....
|
||||
....#..#.#
|
||||
.##..##.#.
|
||||
.#.####...
|
||||
####.#.#..
|
||||
##.####...
|
||||
##..#.##..
|
||||
#.##...##.
|
||||
|
||||
Tile 3079:
|
||||
#.#.#####.
|
||||
.#..######
|
||||
..#.......
|
||||
######....
|
||||
####.#..#.
|
||||
.#...#.##.
|
||||
#.#####.##
|
||||
..#.###...
|
||||
..#.......
|
||||
..#.###...
|
46
d21/input.txt
Normal file
46
d21/input.txt
Normal file
@ -0,0 +1,46 @@
|
||||
pnglkx nfnzx tjsdp jkbqk rpmqq gzgvdh rgdx szsbj xjdhk zfml ddbmq thvm mvnqdh gsgmdn dtlhh rqqfnlc bxv nthhxn hnmjfl ckqq qrsczjv fkh hkxcb rpcdfph flhfddq qspfqb zmb rpmmv zrgzf jfqqgtl xxfgvz kltcm xjrpr vnfmc xhmmt zkzdrn jmdg xgbvk ngqh hlmvqh djpsmd bnzq rbvdt tfmgl pjln (contains sesame, nuts)
|
||||
qchnn dnpgcd zfml thvm gsgmdn frld nfnzx nqfc xbpb kltcm ljmvpp mrfxh zntrfp gzgvdh rrbndl pptgt rknm qsgb mstc ckqq zzldmh nggcjr bkd zfsks hlmvqh cxzkmr zmb tzjnvp npbnj lh pfqxsxd clqk rpmmv szsbj mnvq cnghsg jdtzr kfsfn jxjqp knqzf lvjpp qdpbx qrsczjv xxfgvz ngqh zrgzf jvvmcq zmcj dsmc xhmmt (contains sesame)
|
||||
hlmvqh klmjmz clqk qrsczjv pjln lvjpp tbm thvm rqqfnlc gzgvdh klx sfk bnzq mhrm vht pjqdmpm tfmgl cxzkmr ghr rxrgtvs rfh rhrc vnfmc ljhn fbcds rkzhxmh htllnq zrgzf xhmmt rcr dgrrm xlzqfb xlnn ckqq vpgvm zntrfp jmdg pgqxp xjrpr vnmfg vqrjn thcs mnvq rczbvg bkd zqsc ngqh rpmqq zmcj cbbkfx rpcdfph mrfxh jfqqgtl mszc tzjnvp sdccxkt rcvd pcf xzcdnr jgtrnm zfcvnj dsmc gjqfj gtgrcf nthhxn jngghk hnmjfl qspfqb bxv (contains eggs)
|
||||
nthhxn htllnq pbn qsgb mrfxh zrgzf dvcfx mstc jngghk xddkbd dpfphd zhghprj rfh ljmvpp vtljml pmtfmv zmb xxfgvz crnfzr xbpb jmdg tshn nqfc kmsh rknm hkqp pjqdmpm pjln ddbmq bjvcg zntrfp vnfmc qszmzsh fhtsl tjsdp kfsfn jkbqk thvm mnvq dnpgcd xzcdnr xjrpr rbvdt vht jxjqp zzldmh cnghsg pzxj jfqqgtl ckqq kqzcj lxr glrc dgrrm cxzkmr clqk xjdhk hlmvqh vpvj lbfgp klmjmz (contains dairy, peanuts, eggs)
|
||||
rqqfnlc vgp tbm tjsdp tshn zzldmh zrgzf vgjbgj pptgt xnfhq pbn rpmmv dnpgcd qszmzsh rbvdt nzlks xddkbd thvm npbnj lxr szsbj dtlhh mrfxh ljmvpp xjzc zmb pjqdmpm rknm rrbndl xhmmt hlmvqh jmdg pjln pfqxsxd jdtzr jnr jkbqk vht vhcnpg ckqq ddgdhg pzxj ljhn xgbvk qfkjsq zhghprj gzgvdh xzcdnr ddbmq rcvd lbfgp mvnqdh rfh nggcjr gjqfj hrfmdk (contains dairy)
|
||||
cmnb cnghsg cxzkmr vfkpj pgb xddkbd qfvfzg gzgvdh bxv zfml clqk pbn nthhxn jmdg ckqq rvchbn xbpb sfk dtlhh rqqfnlc rhrc djpsmd qrftr gjqfj bjvcg zntrfp qrsczjv thvm zlgztsbd lbfgp vnmfg jkbqk lvjpp pfqxsxd ljmvpp mrfxh mnvq ljhn fkh ddrd hlmvqh qmmt rcr vht xgbvk ddbmq tbm vhcnpg srgnx zrgzf ngqh mhrm pptgt glrc rpmmv kx htllnq (contains soy, shellfish)
|
||||
fdf tshn zhghprj xjzc xxfgvz nggcjr hkqp vgjbgj ckqq hnmjfl mstc dmxhhd rpmmv jdtzr klx ngqh gtgrcf bjvcg vgp jgtrnm ttxx bcvmz pgqxp nfnzx sjgx zfcvnj tzjnvp qmmt jmdg qdpbx zmb rhrc gmc zfsks ljmvpp gjqfj fjgxv zttx lbskg vnfmc vfkpj lxr hkxcb dln xbpb sfk vpgvm thvm ljhn rknm rfh mgxzl thcs jfqqgtl bkd sdccxkt zzldmh mrfxh rcvd qchnn xhmmt rkzhxmh xgbvk csfmx zrgzf qrsczjv gzgvdh ncqdr rxr vtljml lbfgp pzxj djpsmd dpfphd rczbvg knnmm xmjlsn (contains nuts, dairy, sesame)
|
||||
klx hkqp lqmfgp mstc mgxzl cxfzhj xxfgvz qrsczjv jxjqp ljhn pcf mrxg jmdg bjvcg vht lbskg tphtz nldzpc tjsdp mszc hlmvqh sfk dln ghr mppf lbfgp zkzdrn qdpbx bnzq qsgb rrbndl nggcjr zttx qjsbk llgsg srgnx dbx stcsp rcr zfml jvvmcq pptgt gmc fkh xjdhk pzxj zntrfp flhfddq knqzf ddrd jmgt fdf thcs lh mrfxh xmjlsn kglr pjqdmpm kx dpfphd vqrjn vhcnpg rxrgtvs pfqxsxd nqfc ckqq cbbkfx dtlhh thvm zmb qmmt xlzqfb rpmmv jfqqgtl gsgmdn bcvmz mnvq fbcds xjzc gtgrcf (contains nuts, sesame)
|
||||
gzgvdh vbqbkt fjgxv nggcjr jvvmcq pptgt fmvvb zqsc hlmvqh rbvdt llgsg xddkbd rfh pjln tzjnvp glrc zmb rqqfnlc zttx qrsczjv rrbndl qfkjsq mppf rxrgtvs lvjpp dtlhh zfml stcsp zkzdrn vtljml qdpbx zrgzf fstgc xlnn sdccxkt hkxcb kltcm xlzqfb jfqqgtl npbnj bcvmz rknm ngqh xbpb rcr thvm kglr dbx xxfgvz bjvcg rpmmv srgnx ckqq gjqfj tshn gmc vgp dgrrm ljhn knnmm qkgqv mstc pnglkx flhfddq tjsdp jmdg zntrfp vgjbgj bkd (contains soy)
|
||||
qjsbk fkh xddkbd fjgxv lbfgp rxr ckqq tphtz vhcnpg klmjmz pmtfmv jmdg hrfmdk dbx fbcds jnr xxfgvz pfqxsxd qfvfzg bxv flhfddq rknm rpmqq pjln sdccxkt pgb klx jdtzr zmb thvm hlmvqh lxr zrgzf nthhxn vnmfg jgtrnm nfnzx zzldmh ddbmq nldzpc tvqbhv dznd dnpgcd cmnb vpvj sjgx xjzc hkxcb szsbj dcbk pmvl pjqdmpm mhrm rgdx jfqqgtl zttx vtljml mrfxh cbbkfx knqzf mszc jkbqk xbpb vgjbgj pptgt vfkpj vqrjn zhghprj xnfhq tshn rcvd xjdhk djpsmd rfh glrc rkzhxmh (contains wheat, dairy)
|
||||
mvnqdh nqfc bjvcg ckqq zfcvnj jmdg ljhn hkqp srgnx zfsks bxv xbpb rkzhxmh cxfzhj rpmqq zdntns dnpgcd thcs lvjpp klx jngghk flhfddq gmc pjln dcbk cbbkfx vbqbkt qchnn tshn fhtsl qmthj jvvmcq ncqdr jmgt csfmx qrsczjv tzjnvp rczbvg rcr hlmvqh rbvdt gtgrcf thvm cnghsg zrgzf rxrgtvs zmb (contains peanuts, soy)
|
||||
ckqq frld mvnqdh tphtz bjvcg xzcdnr djpsmd ttxx dcbk qdpbx tshn rczbvg vpvj qmmt ddrd dln bxv zrgzf jxjqp lh mgxzl qrsczjv ltvr pbn nggcjr dsmc llgsg knnmm pzxj cnghsg thvm vnmfg mhrm xlnn gjqfj pptgt jkbqk htllnq jmdg xnfhq klx jmgt mrfxh rxr hnmjfl lqmfgp qrftr mppf sjgx rvchbn lvjpp mstc zqsc gmc kmsh rpmmv crnfzr hrfmdk kglr hlmvqh cxzkmr dvcfx (contains shellfish, eggs, dairy)
|
||||
xjrpr mjpt cbbkfx rpmqq ljhn jmdg vht sdccxkt ngqh bnzq jgtrnm fmvvb mrfxh xxfgvz jfqqgtl tfmgl bcvmz pgqxp thvm crnfzr xddkbd zfsks qrsczjv pzxj tshn fbcds lbfgp thcs hkqp gsgmdn dvcfx zmb cnghsg csfmx vhqfz rxr bxv xjdhk zhghprj dtlhh ckqq qmthj jxjqp rczbvg gmc sfk ttxx ltvr pnglkx dnpgcd qsgb clqk klmjmz lh rvchbn pjln knqzf vnfmc qspfqb nthhxn zqsc mhrm gzgvdh ncqdr zrgzf ddrd vqrjn (contains nuts, shellfish)
|
||||
rvchbn vhcnpg mstc zrgzf hkqp bnzq xbpb qrsczjv fhtsl fjgxv ddgdhg jfqqgtl rpmqq dpfphd pcf qrftr ngqh vht dvcfx dfrg tphtz mnvq qjsbk mvnqdh zntrfp xjzc jmgt xzcdnr vnfmc xddkbd fkh kmsh xmjlsn ckqq zfsks bcvmz ljhn gmc rrbndl fmvvb cxzkmr lh zdntns pgb thvm xxfgvz hrfmdk dln mrfxh tvqbhv cnghsg vpgvm hlmvqh mjpt jdtzr dgrrm kglr pgqxp kqzcj hkxcb xgbvk djpsmd tshn klmjmz rfh xlnn bjvcg qfkjsq rkzhxmh glrc clqk gjqfj jmdg knqzf ljmvpp csfmx rbvdt zfcvnj dsmc fstgc (contains dairy)
|
||||
nthhxn vnfmc dsmc vpvj rhrc zfcvnj zdntns qmthj knnmm rpmmv dtlhh qdpbx zhghprj xddkbd mrfxh rqqfnlc dpfphd xhmmt dgrrm pgqxp zmb gmc flhfddq zkzdrn hlmvqh qrsczjv vhcnpg mjpt fbcds thvm ncqdr pjln zttx hrfmdk xlnn dvcfx fkh mszc klx cmnb zfml zrgzf mnvq rcr bjvcg csfmx xlzqfb ckqq (contains sesame, shellfish)
|
||||
xnfhq hlmvqh lh qdpbx rpcdfph qsgb rpmqq tjsdp ljhn gsgmdn vfkpj jmdg xlzqfb ckqq qmmt jmgt dvcfx zrgzf bkd pmvl ngqh sjgx dpfphd kfsfn mrfxh bjvcg jkbqk qrftr mjpt vnmfg nldzpc ncqdr jvvmcq pptgt pjqdmpm thvm pjln ddrd csfmx kglr xgbvk tzjnvp bxv htllnq fstgc zfcvnj jxjqp pbn dsmc kbtx vqrjn rqqfnlc rxrgtvs hnmjfl qrsczjv (contains eggs)
|
||||
mvnqdh klx rbvdt kx qmthj hrfmdk bcvmz fhtsl zrgzf xxfgvz pmvl csfmx hkxcb rpmqq vpvj jmgt vbqbkt lxr hlmvqh zhghprj kglr dpfphd xzcdnr mszc vgp dvcfx gzgvdh ncqdr mppf nldzpc djpsmd pnglkx mrfxh lqmfgp sjgx jfqqgtl dln vhcnpg npbnj cmnb hnmjfl kfsfn vtljml qspfqb xlzqfb dcbk jngghk lh jxjqp rxr jdtzr qrftr fbcds thvm mrxg zzldmh qfvfzg dtlhh hkqp dsmc qdpbx cxzkmr tfmgl xjrpr pjqdmpm rczbvg rcvd lbfgp jmdg qszmzsh glrc qkgqv tvqbhv qrsczjv fkh rknm ckqq zntrfp cbbkfx (contains shellfish, dairy)
|
||||
zqsc zmb sfk thvm lvjpp ddgdhg qrsczjv qspfqb dmxhhd zzldmh xzcdnr xjdhk dznd qfvfzg ljhn ghr zrgzf bcvmz frld pnglkx fhtsl srgnx jfqqgtl fdf vhqfz qsgb jkbqk ckqq xxfgvz pjqdmpm rpmqq jmdg fkh crnfzr mjpt cnghsg qrftr xddkbd rkzhxmh pfqxsxd mhrm gtgrcf hlmvqh fmvvb tvqbhv dgrrm xbpb qmthj gjqfj kqzcj tshn qkgqv vfkpj kmsh pgqxp ddrd glrc xgbvk hrfmdk rgdx bnzq knnmm qchnn vnmfg ncqdr qfkjsq pmtfmv xnfhq sjgx cbbkfx stcsp rbvdt mstc gzgvdh kglr dsmc rrbndl xjzc rpcdfph (contains nuts)
|
||||
rbvdt jmdg zkzdrn zmb hnmjfl gmc pgqxp lqmfgp knqzf xbpb fmvvb bkd dgrrm vgjbgj dcbk ttxx dtlhh vpgvm xlnn hlmvqh jgtrnm dpfphd qrsczjv xzcdnr jngghk qmmt thvm flhfddq gzgvdh crnfzr qszmzsh xlzqfb dfrg qspfqb qmthj rpcdfph frld zqsc xjdhk dmxhhd ljhn qchnn bnzq kltcm gtgrcf mszc zhghprj rhrc csfmx mrxg klmjmz lbskg ckqq pzxj nggcjr nthhxn nldzpc rpmqq dbx mhrm zrgzf xjzc (contains dairy, wheat, eggs)
|
||||
lh sfk jvvmcq szsbj fmvvb xxfgvz sjgx jnr vqrjn gmc cnghsg qsgb jmdg mppf jfqqgtl fjgxv vbqbkt zqsc xgbvk pgqxp nqfc jmgt rfh xlnn rhrc nfnzx rpcdfph qszmzsh kglr zmb xnfhq thvm tbm zzldmh rcvd pmvl kqzcj hnmjfl nggcjr qrsczjv qchnn zmcj rvchbn fdf xmjlsn mnvq mgxzl rkzhxmh bxv ngqh xlzqfb gjqfj sdccxkt clqk cmnb rbvdt jkbqk dpfphd mrfxh hlmvqh kltcm ckqq jngghk mszc (contains sesame)
|
||||
zfcvnj mvnqdh gjqfj htllnq nggcjr vtljml qrftr fstgc xjrpr dvcfx klmjmz thvm qjsbk rcvd hrfmdk rczbvg mjpt ncqdr kbtx nqfc xxfgvz xlzqfb mrfxh zmb jkbqk jmgt rxrgtvs qspfqb rhrc qmthj mszc ghr fmvvb cxfzhj lqmfgp ckqq zrgzf vfkpj tzjnvp mhrm vpvj pgqxp ngqh xlnn hlmvqh xnfhq tbm zqsc jvvmcq rvchbn lxr qrsczjv vgp cmnb pjqdmpm (contains dairy)
|
||||
qfvfzg ngqh rhrc nthhxn mvnqdh rcr knnmm zmcj nfnzx stcsp nzlks qdpbx kfsfn nldzpc mrfxh cxzkmr fkh vpvj llgsg pgb cmnb ncqdr qchnn zrgzf rknm xjzc zntrfp mstc clqk gsgmdn jnr ljhn mppf hkqp jmdg xlnn xgbvk csfmx rpmmv fmvvb mjpt thvm zlgztsbd dtlhh dln bnzq klmjmz tfmgl vgp qmmt kglr dbx gzgvdh rcvd kmsh rgdx kqzcj ttxx tzjnvp qmthj hlmvqh zfsks qrsczjv lh vhcnpg pgqxp zmb zhghprj vht rxr vbqbkt pcf gtgrcf zzldmh dvcfx (contains wheat)
|
||||
vfkpj kbtx qkgqv bkd srgnx rcr zdntns tjsdp kfsfn rhrc mstc vtljml zlgztsbd rbvdt zrgzf glrc qfvfzg rkzhxmh ddbmq pbn flhfddq dfrg kglr clqk rxrgtvs cxzkmr mrfxh ddgdhg cmnb hlmvqh rpmmv dln zttx pjln zmb pjqdmpm jmgt ckqq qdpbx rcvd thvm rrbndl vbqbkt xmjlsn lh xhmmt qmthj nzlks pgb xzcdnr mrxg xgbvk fkh vgp rqqfnlc gjqfj gsgmdn tbm szsbj bxv lxr cnghsg jfqqgtl dbx pmtfmv lvjpp xjzc xlnn dtlhh dsmc vnfmc qrsczjv zkzdrn ghr fhtsl (contains dairy, wheat, peanuts)
|
||||
nldzpc pbn rxr vgp zmb pgqxp zfsks vfkpj tvqbhv qmmt pjln jmdg qfkjsq hnmjfl mrxg hlmvqh dln nqfc lbfgp rcr kfsfn vtljml rxrgtvs tbm dsmc hkqp lh jngghk vbqbkt thvm fbcds clqk pjqdmpm ckqq mppf tzjnvp xhmmt csfmx rpcdfph sdccxkt kbtx knqzf rkzhxmh qrsczjv mszc ttxx klx mrfxh mnvq (contains dairy, sesame)
|
||||
rgdx tfmgl gmc fstgc ltvr ckqq pnglkx kglr hkqp ddgdhg qfkjsq xzcdnr jnr xxfgvz hlmvqh zhghprj ghr pfqxsxd ljmvpp zmb cmnb nldzpc dznd xlnn zrgzf lh zfcvnj dcbk kmsh xjrpr qjsbk nzlks gtgrcf kfsfn dpfphd rqqfnlc mppf zzldmh thcs cbbkfx jmgt rcr pjln mrfxh jxjqp fmvvb pmvl mgxzl knqzf rbvdt gzgvdh jmdg qrsczjv nqfc vnmfg qszmzsh tjsdp ljhn qrftr ddbmq bkd fbcds (contains wheat, peanuts)
|
||||
clqk rpmmv rkzhxmh pbn mrfxh pmvl hkxcb mvnqdh kbtx tzjnvp ncqdr kmsh dcbk zrgzf qchnn bkd kqzcj hlmvqh thvm cmnb mjpt knnmm pzxj frld gsgmdn pfqxsxd ltvr lqmfgp fkh rbvdt vgjbgj nldzpc jgtrnm dbx qrftr zdntns lbskg rpcdfph djpsmd vbqbkt dsmc jdtzr qmthj zmb hnmjfl sfk mppf fmvvb rcr xmjlsn qrsczjv csfmx dln vqrjn xbpb stcsp fdf rxrgtvs mstc jmdg ljhn npbnj thcs ddbmq knqzf dgrrm rqqfnlc mszc jnr lbfgp qsgb dtlhh pgb bcvmz qszmzsh rfh gjqfj xlzqfb rxr (contains peanuts)
|
||||
clqk csfmx lvjpp kqzcj thvm zntrfp dcbk ghr vtljml pfqxsxd pjqdmpm jgtrnm flhfddq zzldmh llgsg nthhxn mjpt zrgzf pjln dznd mnvq bjvcg nfnzx tzjnvp vgp dtlhh qmmt rpmmv jmdg zfcvnj xzcdnr zmb tbm dbx bxv cxzkmr tfmgl mszc ttxx qkgqv qjsbk ckqq pgqxp zfml mhrm vpvj jdtzr mgxzl tvqbhv qfvfzg vhcnpg lbskg lqmfgp cnghsg rcvd hnmjfl zhghprj hlmvqh xjrpr xxfgvz dln gtgrcf sdccxkt kx qspfqb jfqqgtl pptgt dmxhhd rpcdfph fstgc rcr fmvvb ljmvpp mrxg gmc pgb mrfxh kmsh cmnb (contains soy, wheat, eggs)
|
||||
klx nggcjr xjrpr zdntns kltcm vhcnpg xlnn kqzcj hlmvqh dnpgcd vht rpmmv bnzq hnmjfl lbskg fdf bkd dgrrm rvchbn mgxzl pgb jdtzr dcbk qszmzsh rpmqq hrfmdk qrftr dpfphd lxr ngqh xddkbd qrsczjv tbm vqrjn qchnn vpvj mstc ckqq pbn zrgzf jxjqp jgtrnm tfmgl zmb rqqfnlc xmjlsn rxr pmtfmv zmcj zfsks zqsc crnfzr jmdg fbcds mrfxh xgbvk hkxcb gmc nldzpc nfnzx xnfhq (contains peanuts, eggs, nuts)
|
||||
csfmx zzldmh dcbk fdf rhrc fjgxv qchnn cxzkmr qmthj crnfzr nqfc zmcj mhrm ltvr sdccxkt flhfddq cbbkfx cmnb qdpbx thvm xmjlsn fhtsl knqzf bxv nggcjr vnmfg zmb cxfzhj jdtzr pnglkx jmdg lxr kmsh vgjbgj mrfxh dln mppf gzgvdh rpmmv zntrfp zrgzf pgqxp ckqq zfml vnfmc vht pmvl xlzqfb rxrgtvs kltcm pzxj dsmc dtlhh hrfmdk qmmt dnpgcd bjvcg gsgmdn cnghsg xhmmt gmc ttxx qjsbk hlmvqh fkh vhqfz xxfgvz (contains dairy, sesame, eggs)
|
||||
jmgt mppf ttxx dsmc xnfhq bxv kglr bcvmz ckqq jmdg dfrg jnr mnvq ngqh sfk fdf xhmmt fjgxv zfcvnj rczbvg cmnb xjrpr szsbj dvcfx gtgrcf knqzf pjln mrfxh lbfgp vnmfg jdtzr mhrm fstgc tbm djpsmd pnglkx qkgqv zmb vfkpj hkxcb qfkjsq pgqxp xzcdnr nfnzx npbnj rbvdt jfqqgtl hlmvqh qfvfzg jvvmcq hnmjfl thvm rgdx gjqfj zhghprj kqzcj rcr zrgzf tvqbhv tshn (contains peanuts)
|
||||
rknm lvjpp cnghsg qrsczjv sdccxkt zrgzf rcvd rxrgtvs stcsp thvm fstgc ttxx pmvl rpcdfph dznd ckqq pptgt mstc rpmmv fdf knnmm jnr bjvcg mnvq qdpbx zfml rqqfnlc zqsc zhghprj mgxzl qmmt fkh rxr dsmc lbskg sfk xhmmt kqzcj vfkpj mhrm hlmvqh mrfxh pcf zmb jmgt ljmvpp jfqqgtl szsbj xjrpr vnfmc qszmzsh dbx mszc xlnn qrftr qchnn mjpt zttx ddgdhg gmc djpsmd zfcvnj dln qkgqv rcr dnpgcd tzjnvp hkxcb zmcj lxr bcvmz fhtsl vnmfg vpgvm (contains dairy, sesame)
|
||||
rgdx jmdg cmnb thvm fstgc pfqxsxd ncqdr dmxhhd glrc xjrpr rkzhxmh fhtsl mrfxh hkxcb pmtfmv zfsks knnmm pgb vnmfg thcs dfrg ddbmq clqk zntrfp nthhxn xjzc dgrrm lvjpp rpmmv vht lh jfqqgtl vgp mszc rczbvg jnr jngghk xhmmt vhqfz bcvmz zmb ckqq tjsdp bkd xlzqfb xddkbd pmvl qrsczjv ddgdhg djpsmd ttxx zfcvnj mjpt nldzpc qrftr kx xnfhq fjgxv jmgt ljhn mrxg pbn sdccxkt rxrgtvs dln dpfphd zrgzf tbm rfh tvqbhv (contains sesame, dairy, shellfish)
|
||||
rczbvg cxfzhj lxr mgxzl hkxcb kbtx zmb jvvmcq pmtfmv jfqqgtl jxjqp mszc thvm rknm jmdg vfkpj qmmt hlmvqh ltvr cnghsg pjln mrfxh gzgvdh szsbj pgb dcbk lvjpp qchnn bcvmz sdccxkt llgsg xgbvk mrxg ghr zhghprj hkqp thcs zrgzf zzldmh ckqq frld gtgrcf pnglkx clqk kglr xhmmt hnmjfl qjsbk qfvfzg dnpgcd dbx djpsmd qrftr rgdx tvqbhv ncqdr (contains eggs)
|
||||
pmvl zmb zrgzf rxrgtvs mvnqdh dznd srgnx qmmt pgb jmdg hlmvqh dgrrm xjdhk klx rcvd qrsczjv cnghsg ttxx hrfmdk qspfqb pfqxsxd fmvvb pzxj sfk rbvdt nggcjr zqsc npbnj kglr xddkbd lbskg lqmfgp mrxg mrfxh zfml rkzhxmh jfqqgtl vgjbgj rpmmv tphtz mszc dln zfcvnj vpgvm tzjnvp rhrc nldzpc rknm tshn jgtrnm mppf fjgxv ckqq ddgdhg vpvj fbcds (contains shellfish)
|
||||
xlzqfb nthhxn dln rczbvg jmdg vgp cbbkfx gsgmdn jvvmcq glrc klmjmz stcsp bcvmz dbx vpvj cmnb sjgx rfh rrbndl mgxzl jnr rhrc thvm xlnn mhrm mrfxh bxv qrftr lvjpp fjgxv kglr cxfzhj zmb pptgt ghr kbtx pnglkx qjsbk ckqq jfqqgtl fstgc dznd qszmzsh jgtrnm zrgzf tjsdp klx pjln vgjbgj vbqbkt zkzdrn sfk qrsczjv vhqfz hrfmdk kltcm vnfmc zqsc xhmmt knnmm qfvfzg xjrpr nqfc jkbqk (contains nuts, sesame)
|
||||
jgtrnm bxv fbcds dznd bkd ttxx rpmqq ckqq pmvl dtlhh xjdhk zdntns knnmm vqrjn dsmc lqmfgp ltvr jfqqgtl mszc xhmmt szsbj crnfzr fkh rbvdt pjqdmpm nggcjr qrftr bcvmz qmmt srgnx xddkbd rvchbn zmb cmnb pptgt xjzc llgsg rxr bnzq gsgmdn thvm zzldmh rcvd mrfxh dgrrm zfsks qsgb tvqbhv zkzdrn nzlks lh klmjmz rxrgtvs kqzcj mnvq ngqh rczbvg tshn tjsdp hlmvqh pcf fdf rfh pnglkx hkqp zrgzf jkbqk sdccxkt fstgc vpvj ddbmq zttx xlzqfb qfvfzg frld qrsczjv zlgztsbd xnfhq pfqxsxd cxfzhj cxzkmr tphtz clqk (contains shellfish, peanuts)
|
||||
hrfmdk nthhxn lh zrgzf thvm rbvdt qdpbx mhrm vhqfz lqmfgp qjsbk vgp qfvfzg szsbj nldzpc vpgvm sdccxkt dgrrm tfmgl zdntns ddgdhg zfsks hlmvqh zmcj pnglkx ncqdr qrsczjv sfk mrfxh rqqfnlc vht mstc pmvl cmnb gmc ckqq jmdg thcs bjvcg nzlks klx jfqqgtl fkh ghr ddbmq htllnq xlnn kglr (contains nuts)
|
||||
fkh knqzf tvqbhv mrfxh hkqp nqfc mvnqdh xxfgvz gzgvdh vnfmc qrftr qrsczjv ngqh cxzkmr mjpt dvcfx zmcj xddkbd clqk rvchbn dsmc xjzc pfqxsxd dfrg qmmt mhrm flhfddq rrbndl xnfhq hlmvqh jmdg dznd frld jnr djpsmd thvm qjsbk ddbmq qchnn pnglkx dtlhh zhghprj fhtsl vtljml nzlks qszmzsh lqmfgp pbn cmnb rpcdfph kx qkgqv zrgzf tshn zmb zlgztsbd xlnn (contains eggs, nuts, dairy)
|
||||
gsgmdn zqsc cxzkmr xlnn htllnq vbqbkt pgb pnglkx tphtz jmgt mrfxh qkgqv pjqdmpm glrc sdccxkt rbvdt vht pzxj fstgc bcvmz mjpt dvcfx vpvj ljmvpp pfqxsxd tshn zmcj zrgzf qmmt pcf dpfphd xxfgvz jxjqp rczbvg mgxzl thvm fjgxv hnmjfl rkzhxmh qrsczjv jmdg cnghsg zfml gjqfj tbm lh mppf dcbk zntrfp dbx jvvmcq szsbj pjln xhmmt rcr nthhxn kx fmvvb xzcdnr klx rpcdfph zmb djpsmd jdtzr mnvq hlmvqh bjvcg mrxg (contains eggs)
|
||||
vqrjn rhrc pzxj pjqdmpm tshn pjln nggcjr ljhn fkh qchnn kfsfn vgjbgj jmgt qkgqv stcsp knnmm dznd pgb csfmx fmvvb ltvr rknm rpcdfph thvm mrfxh qfvfzg zfcvnj zmb clqk kx ghr rpmmv vbqbkt tfmgl dfrg lxr hrfmdk vpgvm zlgztsbd rczbvg tvqbhv jnr qjsbk qfkjsq xxfgvz hlmvqh klx dnpgcd kbtx flhfddq jfqqgtl jmdg ddrd xgbvk rqqfnlc ckqq bnzq mnvq ncqdr dln qdpbx kltcm mppf zttx dbx pmtfmv klmjmz vnmfg pgqxp nthhxn crnfzr dmxhhd xhmmt rgdx mvnqdh gsgmdn nzlks xzcdnr fbcds djpsmd zfsks dpfphd lh ddbmq vfkpj vgp qrsczjv (contains peanuts, eggs, soy)
|
||||
dsmc hlmvqh rqqfnlc dgrrm lbskg xxfgvz klmjmz jmgt jnr dznd npbnj rrbndl fkh vfkpj dvcfx hnmjfl qrftr pmtfmv kltcm xzcdnr gtgrcf lbfgp bcvmz xddkbd vgjbgj gjqfj kglr qchnn zlgztsbd rcvd xmjlsn bnzq kbtx vnfmc zmb srgnx pptgt llgsg thvm ckqq qrsczjv cbbkfx cnghsg xjzc rbvdt mnvq mrfxh mppf rknm jmdg tzjnvp rfh vgp vpvj nfnzx hkxcb zqsc lqmfgp kmsh dnpgcd sjgx sfk gmc jfqqgtl ltvr vpgvm pmvl qmthj klx tbm rvchbn pfqxsxd xjdhk glrc rczbvg knqzf (contains shellfish, dairy, nuts)
|
||||
ngqh lxr qrftr nldzpc cbbkfx zdntns xxfgvz srgnx qspfqb zfsks tzjnvp tphtz qrsczjv lbfgp gjqfj xjrpr qfkjsq rfh xgbvk dtlhh mrfxh xjdhk qkgqv hkqp dsmc rczbvg klmjmz ckqq xlzqfb ddgdhg kltcm vhqfz kglr jxjqp xddkbd htllnq gtgrcf zrgzf lbskg gmc szsbj thvm zmb zfcvnj hlmvqh pjqdmpm (contains peanuts, shellfish)
|
||||
xlzqfb vpgvm flhfddq kbtx zmcj jmdg vhqfz tphtz vqrjn stcsp ckqq rgdx nfnzx nggcjr qrsczjv xmjlsn pgb ngqh pjqdmpm qsgb nldzpc hkxcb klmjmz rpmmv xjrpr zlgztsbd ncqdr zmb rpcdfph qjsbk gzgvdh xnfhq hlmvqh cbbkfx knnmm qfkjsq xddkbd vgp pmtfmv qdpbx cnghsg hrfmdk fjgxv xlnn xjzc mszc ljmvpp zntrfp fdf pcf mnvq thvm bkd fbcds dbx fstgc dln pfqxsxd zrgzf mhrm pbn zttx zhghprj (contains peanuts, eggs, dairy)
|
||||
nldzpc gmc mjpt knqzf rbvdt zntrfp nthhxn jmdg rxr xzcdnr kx ljmvpp kltcm jmgt gjqfj pgqxp xjrpr zmb qrsczjv hlmvqh dbx dmxhhd pnglkx gsgmdn vhcnpg zrgzf xjzc pjqdmpm rpcdfph lbfgp xgbvk jvvmcq qdpbx nqfc dvcfx thvm rknm kbtx npbnj mrxg klmjmz rrbndl xbpb ncqdr fdf vpvj kglr pptgt mrfxh (contains sesame)
|
||||
tshn dmxhhd qmthj kqzcj rqqfnlc pcf dgrrm hkqp ckqq flhfddq qmmt thcs vqrjn vht tbm lqmfgp bcvmz fbcds jmdg rbvdt xzcdnr xlzqfb vfkpj mrfxh sdccxkt fstgc fhtsl qfvfzg kmsh dznd zrgzf bxv glrc thvm pmtfmv rkzhxmh zqsc xjzc fmvvb ddbmq qspfqb tjsdp rcvd xgbvk gzgvdh cmnb pptgt ngqh xlnn sjgx mrxg qdpbx rknm hnmjfl szsbj zntrfp gtgrcf fdf kltcm vhcnpg zmb pjln mppf dnpgcd ttxx qrsczjv srgnx qszmzsh (contains shellfish, nuts)
|
||||
|
105
d21/main.py
Executable file
105
d21/main.py
Executable file
@ -0,0 +1,105 @@
|
||||
#! /usr/bin/env python3
|
||||
import re
|
||||
from functools import reduce
|
||||
from dataclasses import dataclass
|
||||
from typing import Any
|
||||
from typing import Dict
|
||||
from typing import Iterable
|
||||
from typing import Set
|
||||
|
||||
|
||||
food_parser = re.compile(r"([a-z ]+) \(contains ([a-z, ]+)\)")
|
||||
|
||||
|
||||
@dataclass
|
||||
class Food:
|
||||
items: Set[str]
|
||||
alergens: Set[str]
|
||||
|
||||
|
||||
def read_input(filename: str) -> Iterable[Food]:
|
||||
with open(filename) as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if line == "":
|
||||
continue
|
||||
match = food_parser.match(line)
|
||||
if not match:
|
||||
raise ValueError(f"cannot parse line {line}")
|
||||
items = match.group(1).split(" ")
|
||||
alergens = match.group(2).split(", ")
|
||||
yield Food(set(items), set(alergens))
|
||||
|
||||
|
||||
def extract_alergen_info(foods: Iterable[Food]) -> Dict[str, Set[str]]:
|
||||
alergen_defs: Dict[str, Set[str]] = {}
|
||||
|
||||
for food in foods:
|
||||
for alergen in food.alergens:
|
||||
if alergen not in alergen_defs:
|
||||
alergen_defs[alergen] = food.items.copy()
|
||||
else:
|
||||
alergen_defs[alergen] &= food.items
|
||||
|
||||
return alergen_defs
|
||||
|
||||
|
||||
def reduce_union(items: Iterable[Set[Any]]) -> Set[Any]:
|
||||
return reduce(lambda x, y: x | y, items)
|
||||
|
||||
|
||||
def reduce_intersecion(items: Iterable[Set[Any]]) -> Set[Any]:
|
||||
return reduce(lambda x, y: x & y, items)
|
||||
|
||||
|
||||
def narrow_results(alergen_defs: Dict[str, Set[str]]):
|
||||
sorted_alergens = sorted(alergen_defs.items(), key=lambda x: len(x[1]))
|
||||
for i, alergen_info in enumerate(sorted_alergens):
|
||||
if len(alergen_info[1]) == 1:
|
||||
# Remove from others
|
||||
if i+1 < len(sorted_alergens):
|
||||
for other_info in sorted_alergens[i+1:]:
|
||||
other_info[1].difference_update(alergen_info[1])
|
||||
|
||||
|
||||
def part1():
|
||||
all_foods = list(read_input("input.txt"))
|
||||
alergen_defs = extract_alergen_info(all_foods)
|
||||
|
||||
print("Alergen defs", alergen_defs)
|
||||
|
||||
safe_items = reduce_union((food.items for food in all_foods))
|
||||
all_possible_alergens = reduce_union(alergen_defs.values())
|
||||
|
||||
print("All possible alergens", all_possible_alergens)
|
||||
|
||||
safe_items -= all_possible_alergens
|
||||
|
||||
print("All safe items", safe_items)
|
||||
|
||||
count_safe = sum(
|
||||
map(
|
||||
lambda food: len(food.items & safe_items),
|
||||
(food for food in all_foods),
|
||||
),
|
||||
)
|
||||
|
||||
print("Count of safe items appeared is", count_safe)
|
||||
|
||||
print("Part 2")
|
||||
|
||||
narrow_results(alergen_defs)
|
||||
narrow_results(alergen_defs)
|
||||
narrow_results(alergen_defs)
|
||||
|
||||
print("Narrowed alergen list", alergen_defs)
|
||||
|
||||
canon_list = ",".join((
|
||||
a[1].pop() for a in sorted(alergen_defs.items(), key=lambda x: x[0])
|
||||
))
|
||||
|
||||
print("Canon list of ingredients", canon_list)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
part1()
|
4
d21/sample-input.txt
Normal file
4
d21/sample-input.txt
Normal file
@ -0,0 +1,4 @@
|
||||
mxmxvkd kfcds sqjhc nhms (contains dairy, fish)
|
||||
trh fvjkl sbzzf mxmxvkd (contains dairy)
|
||||
sqjhc fvjkl (contains soy)
|
||||
sqjhc mxmxvkd sbzzf (contains fish)
|
54
d22/input.txt
Normal file
54
d22/input.txt
Normal file
@ -0,0 +1,54 @@
|
||||
Player 1:
|
||||
14
|
||||
6
|
||||
21
|
||||
10
|
||||
1
|
||||
33
|
||||
7
|
||||
13
|
||||
25
|
||||
8
|
||||
17
|
||||
11
|
||||
28
|
||||
27
|
||||
50
|
||||
2
|
||||
35
|
||||
49
|
||||
19
|
||||
46
|
||||
3
|
||||
38
|
||||
23
|
||||
5
|
||||
43
|
||||
|
||||
Player 2:
|
||||
18
|
||||
9
|
||||
12
|
||||
39
|
||||
48
|
||||
24
|
||||
32
|
||||
45
|
||||
47
|
||||
41
|
||||
40
|
||||
15
|
||||
22
|
||||
36
|
||||
30
|
||||
26
|
||||
42
|
||||
34
|
||||
20
|
||||
16
|
||||
4
|
||||
31
|
||||
37
|
||||
44
|
||||
29
|
||||
|
8
d22/loop-input.txt
Normal file
8
d22/loop-input.txt
Normal file
@ -0,0 +1,8 @@
|
||||
Player 1:
|
||||
43
|
||||
19
|
||||
|
||||
Player 2:
|
||||
2
|
||||
29
|
||||
14
|
174
d22/main.py
Executable file
174
d22/main.py
Executable file
@ -0,0 +1,174 @@
|
||||
#! /usr/bin/env python3
|
||||
from copy import copy
|
||||
from enum import Enum
|
||||
from typing import Set, Tuple, List, Optional
|
||||
|
||||
|
||||
class Player(Enum):
|
||||
UNKNOWN = 0
|
||||
ONE = 1
|
||||
TWO = 2
|
||||
|
||||
|
||||
def read_decks(filename: str):
|
||||
deck1, deck2 = None, None
|
||||
cur_deck: List[int] = []
|
||||
with open(filename) as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if line.startswith("Player 1"):
|
||||
continue
|
||||
if line == "":
|
||||
continue
|
||||
if line.startswith("Player 2"):
|
||||
deck1 = cur_deck
|
||||
cur_deck = []
|
||||
continue
|
||||
cur_deck.append(int(line))
|
||||
|
||||
deck2 = cur_deck
|
||||
|
||||
return deck1, deck2
|
||||
|
||||
|
||||
def play_round(deck1, deck2):
|
||||
c1 = deck1.pop(0)
|
||||
c2 = deck2.pop(0)
|
||||
|
||||
print(f"{c1} vs {c2} ", end="", flush=True)
|
||||
|
||||
if c1 > c2:
|
||||
print("Player 1 wins!")
|
||||
deck1 += [c1, c2]
|
||||
elif c2 > c1:
|
||||
print("Player 2 wins!")
|
||||
deck2 += [c2, c1]
|
||||
else:
|
||||
print("Nobody wins?")
|
||||
# raise ValueError("Nobody wins")
|
||||
|
||||
|
||||
RoundHistory = Set[Tuple[Tuple[int, ...], Tuple[int, ...]]]
|
||||
|
||||
|
||||
def recursive_combat(
|
||||
deck1: List[int],
|
||||
deck2: List[int],
|
||||
game: int = 1,
|
||||
past_games: Optional[RoundHistory] = None
|
||||
) -> Player:
|
||||
if past_games is None:
|
||||
past_games = set()
|
||||
|
||||
print(f"{game}: Starting p2 {deck1} p2 {deck2}")
|
||||
|
||||
# Play until there is an empty deck
|
||||
game_round = 0
|
||||
winner = Player.UNKNOWN
|
||||
while deck1 and deck2:
|
||||
game_round += 1
|
||||
|
||||
# Check for looping...
|
||||
this_round = (tuple(deck1), tuple(deck2))
|
||||
if this_round in past_games:
|
||||
print(
|
||||
f"{game}:{game_round} Loop detected. Player 1 wins the game!",
|
||||
)
|
||||
return Player.ONE
|
||||
|
||||
past_games.add(this_round)
|
||||
|
||||
print(f"{game}:{game_round} p1 {deck1} p2 {deck2} ")
|
||||
|
||||
# Draw
|
||||
c1 = deck1.pop(0)
|
||||
c2 = deck2.pop(0)
|
||||
|
||||
print(f"{game}:{game_round} {c1} vs {c2} ", end="", flush=True)
|
||||
|
||||
winner = Player.UNKNOWN
|
||||
if c1 <= len(deck1) and c2 <= len(deck2):
|
||||
print("RECURSIVE COMBAT!!!!")
|
||||
winner = recursive_combat(
|
||||
copy(deck1[:c1]),
|
||||
copy(deck2[:c2]),
|
||||
game=game+1,
|
||||
past_games=past_games.copy(),
|
||||
)
|
||||
else:
|
||||
if c1 > c2:
|
||||
winner = Player.ONE
|
||||
elif c2 > c1:
|
||||
winner = Player.TWO
|
||||
else:
|
||||
raise ValueError("cards are equal? No way!")
|
||||
|
||||
if winner == Player.ONE:
|
||||
print("Player 1 wins!")
|
||||
deck1 += [c1, c2]
|
||||
elif winner == Player.TWO:
|
||||
print("Player 2 wins!")
|
||||
deck2 += [c2, c1]
|
||||
else:
|
||||
print("Nobody wins?")
|
||||
raise ValueError("Nobody wins")
|
||||
|
||||
print(f"{game}: Game finished p1 {deck1} p2 {deck2}")
|
||||
|
||||
# Deck is empty!
|
||||
if deck1:
|
||||
winner = Player.ONE
|
||||
elif deck2:
|
||||
winner = Player.TWO
|
||||
else:
|
||||
raise ValueError("unknown winner")
|
||||
|
||||
return winner
|
||||
|
||||
|
||||
def part1():
|
||||
deck1, deck2 = read_decks("input.txt")
|
||||
|
||||
print("Initial decks")
|
||||
print("Player 1", deck1)
|
||||
print("Player 2", deck2)
|
||||
|
||||
while deck1 and deck2:
|
||||
play_round(deck1, deck2)
|
||||
|
||||
winning_deck: List[int] = None
|
||||
if deck1:
|
||||
winning_deck = deck1
|
||||
print("Winner! Player 1!")
|
||||
elif deck2:
|
||||
winning_deck = deck2
|
||||
print("Winner! Player 2!")
|
||||
|
||||
score = sum((i*v for i, v in enumerate(reversed(winning_deck), 1)))
|
||||
print("Score:", score)
|
||||
|
||||
|
||||
def part2():
|
||||
deck1, deck2 = read_decks("input.txt")
|
||||
|
||||
print("Initial decks")
|
||||
print("Player 1", deck1)
|
||||
print("Player 2", deck2)
|
||||
|
||||
_ = recursive_combat(deck1, deck2)
|
||||
|
||||
winning_deck: List[int] = None
|
||||
if deck1:
|
||||
winning_deck = deck1
|
||||
print("Winner! Player 1!")
|
||||
elif deck2:
|
||||
winning_deck = deck2
|
||||
print("Winner! Player 2!")
|
||||
|
||||
score = sum((i*v for i, v in enumerate(reversed(winning_deck), 1)))
|
||||
print("Score:", score)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
part1()
|
||||
part2()
|
13
d22/sample-input.txt
Normal file
13
d22/sample-input.txt
Normal file
@ -0,0 +1,13 @@
|
||||
Player 1:
|
||||
9
|
||||
2
|
||||
6
|
||||
3
|
||||
1
|
||||
|
||||
Player 2:
|
||||
5
|
||||
8
|
||||
4
|
||||
7
|
||||
10
|
171
d23/main.py
Executable file
171
d23/main.py
Executable file
@ -0,0 +1,171 @@
|
||||
#! /usr/bin/env python3
|
||||
from typing import List
|
||||
from typing import Tuple
|
||||
|
||||
|
||||
def cups_str(cups: List[int], current: int) -> str:
|
||||
return " ".join(
|
||||
("(" if c == current else "") + str(c) + (")" if c == current else "")
|
||||
for c in cups
|
||||
)
|
||||
|
||||
|
||||
def get_result(cups: List[int], part2: bool = False) -> str:
|
||||
# Rotate 1 to the front
|
||||
index_1 = cups.index(1)
|
||||
|
||||
if not part2:
|
||||
result = cups[index_1:] + cups[:index_1]
|
||||
# Remove 1 from the front
|
||||
result = result[1:]
|
||||
return "".join((str(c) for c in result))
|
||||
else:
|
||||
cup1 = cups[index_1+1 % len(cups)]
|
||||
cup2 = cups[index_1+2 % len(cups)]
|
||||
print(f"cup1: {cup1} cup2: {cup2}")
|
||||
return str(cup1 * cup2)
|
||||
|
||||
|
||||
def str_to_cups(opening: str, part2: bool = False) -> List[int]:
|
||||
cups = [int(c) for c in opening]
|
||||
|
||||
if part2:
|
||||
max_cup = max(cups)
|
||||
cup_limit = 1000000
|
||||
cups += [c for c in range(max_cup+1, cup_limit+1)]
|
||||
|
||||
return cups
|
||||
|
||||
|
||||
def play_round(
|
||||
cups: List[int],
|
||||
current: int,
|
||||
debug: bool = True,
|
||||
) -> Tuple[List[int], int]:
|
||||
if debug:
|
||||
print(f"cups: {cups_str(cups, current)}")
|
||||
|
||||
cur_i = cups.index(current)
|
||||
|
||||
# Pick up cups
|
||||
picked_up: List[int] = []
|
||||
|
||||
while len(picked_up) < 3:
|
||||
if cur_i+1 < len(cups):
|
||||
picked_up.append(cups.pop(cur_i+1))
|
||||
else:
|
||||
picked_up.append(cups.pop(0))
|
||||
cur_i -= 1
|
||||
|
||||
if debug:
|
||||
print(f"pick up: {', '.join((str(c) for c in picked_up))}")
|
||||
|
||||
# Find destination
|
||||
dest = 0
|
||||
max_cup = 0
|
||||
for c in cups:
|
||||
if c < current and c > dest:
|
||||
dest = c
|
||||
if dest == current-1:
|
||||
break
|
||||
if c > max_cup:
|
||||
max_cup = c
|
||||
|
||||
if dest <= 0:
|
||||
dest = max_cup
|
||||
|
||||
dest_i = cups.index(dest)
|
||||
# Other guy
|
||||
# dest = max((c for c in cups if c < current), default=max(cups))
|
||||
# dest_i = cups.index(dest)
|
||||
# My attempt 1
|
||||
# dest = current - 1
|
||||
# dest_i = None
|
||||
# while dest_i is None:
|
||||
# if dest <= 0:
|
||||
# # Wrap around to the highest value instead
|
||||
# dest = max(cups)
|
||||
# try:
|
||||
# dest_i = cups.index(dest)
|
||||
# except ValueError:
|
||||
# # Try the next cup down
|
||||
# dest -= 1
|
||||
|
||||
if debug:
|
||||
print(f"destination: {dest}")
|
||||
|
||||
# Add cups back
|
||||
# cups[dest_i+1:dest_i+1] = picked_up
|
||||
if dest_i+1 >= len(cups):
|
||||
cups += picked_up
|
||||
else:
|
||||
for cup in reversed(picked_up):
|
||||
cups.insert(dest_i+1, cup)
|
||||
|
||||
# If inserted before the current, move that index up
|
||||
if dest_i < cur_i:
|
||||
cur_i += 3
|
||||
|
||||
# Get the new current to the right of old
|
||||
cur_i += 1
|
||||
cur_i = cur_i % len(cups)
|
||||
current = cups[cur_i]
|
||||
|
||||
return cups, current
|
||||
|
||||
|
||||
def play_game(cups: List[int], rounds: int, debug: bool = True) -> List[int]:
|
||||
current = cups[0]
|
||||
if debug:
|
||||
print(f"game: {cups_str(cups, current)} {rounds} rounds")
|
||||
|
||||
ten_percent = int(rounds / 10)
|
||||
|
||||
for move in range(rounds):
|
||||
if move % ten_percent == 0:
|
||||
print(f"{move/ten_percent*10}%")
|
||||
if debug:
|
||||
print(f"-- move {move+1} --")
|
||||
cups, current = play_round(cups, current, debug=debug)
|
||||
if debug:
|
||||
print("")
|
||||
|
||||
if debug:
|
||||
print("-- final --")
|
||||
print(f"cups: {cups_str(cups, current)}")
|
||||
|
||||
print(f"result {get_result(cups)}")
|
||||
|
||||
return cups
|
||||
|
||||
|
||||
def sample():
|
||||
# cups = str_to_cups("389125467")
|
||||
# cups = play_game(cups, 10, debug=False)
|
||||
# print(f"result {get_result(cups)}")
|
||||
#
|
||||
cups = str_to_cups("389125467")
|
||||
cups = play_game(cups, 100, debug=False)
|
||||
print(f"result {get_result(cups)}")
|
||||
|
||||
# cups = str_to_cups("389125467", part2=True)
|
||||
# cups = play_game(cups, 10000000, debug=False)
|
||||
# print(f"result {get_result(cups, part2=True)}")
|
||||
|
||||
|
||||
def part1():
|
||||
cups = str_to_cups("853192647")
|
||||
cups = play_game(cups, 100, debug=False)
|
||||
print(f"result {get_result(cups)}")
|
||||
|
||||
|
||||
def part2():
|
||||
cups = str_to_cups("853192647", part2=True)
|
||||
cups = play_game(cups, 10000000, debug=False)
|
||||
print(f"result {get_result(cups, part2=True)}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# sample()
|
||||
# part1()
|
||||
part2()
|
157
d23/main2.py
Executable file
157
d23/main2.py
Executable file
@ -0,0 +1,157 @@
|
||||
#! /usr/bin/env python3
|
||||
from typing import List
|
||||
from typing import Iterable
|
||||
from typing import Dict
|
||||
from typing import Tuple
|
||||
|
||||
|
||||
def listify(cups: Dict[int, int]) -> Iterable[int]:
|
||||
yield 1
|
||||
next_cup = cups[1]
|
||||
while next_cup != 1:
|
||||
yield next_cup
|
||||
next_cup = cups[next_cup]
|
||||
|
||||
|
||||
def cups_str(cups: Dict[int, int], current: int) -> str:
|
||||
return " ".join(
|
||||
("(" if c == current else "") + str(c) + (")" if c == current else "")
|
||||
for c in listify(cups)
|
||||
)
|
||||
|
||||
|
||||
def get_result(cups: Dict[int, int]) -> str:
|
||||
# Rotate 1 to the front
|
||||
cup1 = cups[1]
|
||||
cup2 = cups[cup1]
|
||||
print(f"cup1: {cup1} cup2: {cup2}")
|
||||
return str(cup1 * cup2)
|
||||
|
||||
|
||||
def str_to_cups(opening: str, max_cups: int = 0) -> Dict[int, int]:
|
||||
cups_list = [int(c) for c in opening]
|
||||
max_cup = max(cups_list)
|
||||
|
||||
if max_cups:
|
||||
cup_limit = max_cups
|
||||
cups_list += [c for c in range(max_cup+1, cup_limit+1)]
|
||||
|
||||
cups = dict(zip(cups_list, cups_list[1:]+cups_list[0:1]))
|
||||
|
||||
return cups
|
||||
|
||||
|
||||
def play_round(
|
||||
cups: Dict[int, int],
|
||||
current: int,
|
||||
max_cup: int,
|
||||
debug: bool = False,
|
||||
) -> Tuple[Dict[int, int], int]:
|
||||
if debug:
|
||||
print(f"cups: {cups_str(cups, current)}")
|
||||
|
||||
# Pick up cups
|
||||
first_cup = cups[current]
|
||||
second_cup = cups[first_cup]
|
||||
third_cup = cups[second_cup]
|
||||
following_cup = cups[third_cup]
|
||||
|
||||
# Seal
|
||||
cups[current] = following_cup
|
||||
|
||||
if debug:
|
||||
print(f"pick up: {first_cup}, {second_cup}, {third_cup}")
|
||||
|
||||
# Find destination
|
||||
dest = current - 1
|
||||
if dest < 1:
|
||||
dest = max_cup
|
||||
|
||||
while dest in (first_cup, second_cup, third_cup):
|
||||
dest -= 1
|
||||
if dest < 1:
|
||||
dest = max_cup
|
||||
|
||||
if debug:
|
||||
print(f"destination: {dest}")
|
||||
|
||||
# Add cups back
|
||||
following_cup = cups[dest]
|
||||
cups[dest] = first_cup
|
||||
cups[third_cup] = following_cup
|
||||
|
||||
# Get the new current to the right of old
|
||||
current = cups[current]
|
||||
|
||||
return cups, current
|
||||
|
||||
|
||||
def play_game(
|
||||
cups: Dict[int, int],
|
||||
start: int,
|
||||
max_cup: int,
|
||||
rounds: int,
|
||||
debug: bool = False,
|
||||
) -> Dict[int, int]:
|
||||
current = start
|
||||
if debug:
|
||||
print(f"game: {cups_str(cups, current)} {rounds} rounds")
|
||||
|
||||
ten_percent = int(rounds / 10)
|
||||
|
||||
for move in range(rounds):
|
||||
if move % ten_percent == 0:
|
||||
print(f"{move/ten_percent*10}%")
|
||||
if debug:
|
||||
print(f"-- move {move+1} --")
|
||||
cups, current = play_round(cups, current, max_cup, debug)
|
||||
if debug:
|
||||
print("")
|
||||
|
||||
if debug:
|
||||
print("-- final --")
|
||||
print(f"cups: {cups_str(cups, current)}")
|
||||
|
||||
# print(f"result {get_result(cups)}")
|
||||
|
||||
return cups
|
||||
|
||||
|
||||
def sample():
|
||||
# cups = str_to_cups("389125467")
|
||||
# cups = play_game(cups, 10, debug=False)
|
||||
# print(f"result {get_result(cups)}")
|
||||
|
||||
# cups = str_to_cups("389125467")
|
||||
# start = 3
|
||||
# max_cups = 9
|
||||
# cups = play_game(cups, start, max_cups, 100, debug=True)
|
||||
# print(f"result {get_result(cups)}")
|
||||
|
||||
start = 3
|
||||
rounds = 10000000
|
||||
max_cups = 1000000
|
||||
cups = str_to_cups("389125467", max_cups=max_cups)
|
||||
cups = play_game(cups, start, max_cups, rounds, debug=False)
|
||||
print(f"result {get_result(cups)}")
|
||||
|
||||
|
||||
def part1():
|
||||
cups = str_to_cups("853192647")
|
||||
cups = play_game(cups, 100, debug=False)
|
||||
print(f"result {get_result(cups)}")
|
||||
|
||||
|
||||
def part2():
|
||||
start = 8
|
||||
rounds = 10000000
|
||||
max_cups = 1000000
|
||||
cups = str_to_cups("853192647", max_cups=max_cups)
|
||||
cups = play_game(cups, start, max_cups, rounds, debug=False)
|
||||
print(f"result {get_result(cups)}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# sample()
|
||||
# part1()
|
||||
part2()
|
0
d24/__init__.py
Normal file
0
d24/__init__.py
Normal file
662
d24/expanding.py
Normal file
662
d24/expanding.py
Normal file
@ -0,0 +1,662 @@
|
||||
#! /usr/bin/env python3
|
||||
from collections import namedtuple
|
||||
from itertools import product
|
||||
from typing import Any
|
||||
from typing import Callable
|
||||
from typing import Iterable
|
||||
from typing import List
|
||||
from typing import Optional
|
||||
from typing import Tuple
|
||||
from typing import Set
|
||||
|
||||
|
||||
Point = namedtuple("Point", "x y z w", defaults=(0, 0))
|
||||
|
||||
|
||||
def add_points(p1, p2) -> Point:
|
||||
return Point(
|
||||
p1.x + p2.x,
|
||||
p1.y + p2.y,
|
||||
p1.z + p2.z,
|
||||
p1.w + p2.w,
|
||||
)
|
||||
|
||||
|
||||
class GridItem(object):
|
||||
|
||||
def __init__(self, loc: Point, world: "World"):
|
||||
self._loc = loc
|
||||
self._world = world
|
||||
|
||||
self._ticked = False
|
||||
|
||||
def _tock():
|
||||
# print("Default tock")
|
||||
pass
|
||||
|
||||
self.tock = _tock
|
||||
|
||||
def neighbors(self, expand=False) -> Iterable["GridItem"]:
|
||||
seen_points: Set[Point] = set()
|
||||
for diff in product((0, 1, -1), repeat=4):
|
||||
# from pdb import set_trace; set_trace()
|
||||
neighbor_point = add_points(
|
||||
self._loc,
|
||||
Point(
|
||||
diff[0],
|
||||
diff[1],
|
||||
diff[2],
|
||||
diff[3],
|
||||
),
|
||||
)
|
||||
if self._loc == neighbor_point:
|
||||
# skip self
|
||||
continue
|
||||
|
||||
if neighbor_point in seen_points:
|
||||
# skip points we've already visited
|
||||
# print("Already seen, skipping")
|
||||
continue
|
||||
|
||||
seen_points.add(neighbor_point)
|
||||
|
||||
# print(f"Getting point {neighbor_point}")
|
||||
neighbor = self._world.get_point(neighbor_point, expand=expand)
|
||||
if neighbor is not None:
|
||||
# print("FOUND!")
|
||||
yield neighbor
|
||||
|
||||
def tick(self):
|
||||
active_neighbors = 0
|
||||
for neighbor in self.neighbors():
|
||||
# print(f"Neighbor is active: {neighbor.active}")
|
||||
if neighbor.active:
|
||||
# print(f"Neighbor is active {neighbor}")
|
||||
active_neighbors += 1
|
||||
|
||||
if self.active and active_neighbors not in (2, 3):
|
||||
# print("Should go inactive")
|
||||
def _tock():
|
||||
# print("go inactive")
|
||||
self.active = False
|
||||
|
||||
self.tock = _tock
|
||||
elif not self.active and active_neighbors == 3:
|
||||
# print("Should go active")
|
||||
def _tock():
|
||||
# print("go active")
|
||||
self.active = True
|
||||
|
||||
self.tock = _tock
|
||||
|
||||
else:
|
||||
# print("Should do nothing")
|
||||
def _tock():
|
||||
# print("Empty tock")
|
||||
pass
|
||||
|
||||
self.tock = _tock
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"({self._loc.x}, {self._loc.y}, {self._loc.z})"
|
||||
|
||||
def to_str(self) -> str:
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
class AutoExpanding(object):
|
||||
_l: List[Any]
|
||||
_zero: int
|
||||
_item_factory: Callable[[int], Any]
|
||||
|
||||
def __init__(self):
|
||||
self._l = [self._item_factory(0)]
|
||||
self._zero = 0
|
||||
|
||||
def get(self, i, expand=True):
|
||||
if not expand:
|
||||
if self._zero+i < 0:
|
||||
raise IndexError(f"index {i} is out of bounds")
|
||||
return self._l[self._zero+i]
|
||||
|
||||
if self._zero is None:
|
||||
self._l = [self._item_factory(0)]
|
||||
self._zero = 0
|
||||
|
||||
if i > 0 and i >= len(self._l) - self._zero - 1:
|
||||
# print(f"resize pos to {i} with {self._l} zero={self._zero}")
|
||||
self._l = self._l + [
|
||||
self._item_factory(j)
|
||||
for j in range(len(self._l)-self._zero, i+1)
|
||||
]
|
||||
# print(f"> done {self._l} zero={self._zero}")
|
||||
elif i < 0 and abs(i) > self._zero:
|
||||
# print(f"resize neg to {i} with {self._l} zero={self._zero}")
|
||||
self._l = [
|
||||
self._item_factory(j)
|
||||
for j in range(i, -1 * self._zero)
|
||||
] + self._l
|
||||
self._zero = abs(i)
|
||||
# print(f"> done {self._l} zero={self._zero}")
|
||||
|
||||
# print(f"Now getting item at index {i} from {self._l}")
|
||||
return self._l[self._zero+i]
|
||||
|
||||
def __getitem__(self, i):
|
||||
if isinstance(i, slice):
|
||||
return [
|
||||
self[j]
|
||||
for j in range(
|
||||
i.start if i.start is not None else self.min_index(),
|
||||
(i.stop if i.stop is not None else self.max_index()) + 1,
|
||||
i.step or 1,
|
||||
)
|
||||
]
|
||||
|
||||
return self.get(i, expand=False)
|
||||
|
||||
def __setitem__(self, i, value):
|
||||
self.get(i, expand=True)
|
||||
self._l[self._zero+i] = value
|
||||
|
||||
def __len__(self) -> int:
|
||||
return len(self._l)
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self._l)
|
||||
|
||||
def min_index(self) -> int:
|
||||
return -1 * self._zero
|
||||
|
||||
def max_index(self) -> int:
|
||||
return len(self._l) - self._zero - 1
|
||||
|
||||
def get_bounds(self) -> Tuple[int, int]:
|
||||
return self.min_index(), self.max_index()
|
||||
|
||||
def resize(self, min_index: int, max_index: int):
|
||||
if min_index < self.min_index():
|
||||
self.get(min_index, expand=True)
|
||||
else:
|
||||
if min_index > 0:
|
||||
raise IndexError("Cannot resize to exclude zero")
|
||||
self._l = self[min_index:]
|
||||
self._zero = abs(min_index)
|
||||
|
||||
if max_index > self.max_index():
|
||||
self.get(max_index, expand=True)
|
||||
else:
|
||||
if max_index < 0:
|
||||
raise IndexError("Cannot resize to exclude zero")
|
||||
self._l = self[:max_index]
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"<AutoExpanding {self._l}>"
|
||||
|
||||
|
||||
class World(AutoExpanding):
|
||||
|
||||
def iter_items(self) -> Iterable[GridItem]:
|
||||
raise NotImplementedError()
|
||||
|
||||
def tick(self):
|
||||
for c in self.iter_items():
|
||||
c.tick()
|
||||
|
||||
def tock(self):
|
||||
for c in self.iter_items():
|
||||
c.tock()
|
||||
|
||||
def get_point(self, p: Point, expand=True) -> Optional[GridItem]:
|
||||
raise NotImplementedError()
|
||||
|
||||
def trim(self):
|
||||
raise NotImplementedError()
|
||||
|
||||
def get_all_bounds(self) -> Tuple[Point, Point]:
|
||||
raise NotImplementedError()
|
||||
|
||||
def true_up(self):
|
||||
raise NotImplementedError()
|
||||
|
||||
def expand_all(self, i: int):
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
class GridRow(AutoExpanding):
|
||||
def __init__(self, y: int, z: int, world: World, w: Optional[int] = 0):
|
||||
self._y = y
|
||||
self._z = z
|
||||
self._w = w
|
||||
self._world = world
|
||||
super().__init__()
|
||||
|
||||
def _item_factory(self, x: int) -> GridItem:
|
||||
return GridItem(Point(x, self._y, self._z, self._w), self._world)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return "[" + " ".join((str(c) for c in self._l)) + "]"
|
||||
|
||||
def to_str(self) -> str:
|
||||
return "".join((c.to_str() for c in self._l))
|
||||
|
||||
|
||||
class GridSlice(AutoExpanding):
|
||||
def __init__(self, z: int, world: World, w: Optional[int] = 0):
|
||||
self._z = z
|
||||
self._w = w
|
||||
self._world = world
|
||||
super().__init__()
|
||||
|
||||
def _item_factory(self, y: int) -> GridRow:
|
||||
return GridRow(y, self._z, self._world, w=self._w)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"z={self._z}\n" + "\n".join((
|
||||
str(r) for r in self._l
|
||||
))
|
||||
|
||||
def to_str(self) -> str:
|
||||
return f"z={self._z}\n" + "\n".join([r.to_str() for r in self._l])
|
||||
|
||||
|
||||
class Grid(World):
|
||||
def __init__(self, world: Optional[World] = None, w: Optional[int] = 0):
|
||||
if world is not None:
|
||||
self._world = world
|
||||
else:
|
||||
self._world = self
|
||||
|
||||
self._w = w
|
||||
|
||||
super().__init__()
|
||||
|
||||
def _item_factory(self, z: int) -> GridSlice:
|
||||
return GridSlice(z, self._world, w=self._w)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return "\n\n".join((
|
||||
str(s) for s in self._l
|
||||
))
|
||||
|
||||
def to_str(self) -> str:
|
||||
return "\n\n".join((
|
||||
s.to_str() for s in self._l
|
||||
))
|
||||
|
||||
def iter_cubes(self) -> Iterable[GridItem]:
|
||||
for s in self:
|
||||
for r in s:
|
||||
for c in r:
|
||||
yield c
|
||||
|
||||
def get_point(self, p: Point, expand=True) -> Optional[GridItem]:
|
||||
try:
|
||||
# print(f"expand world z to {p.z}")
|
||||
c = self.get(
|
||||
p.z,
|
||||
expand=expand,
|
||||
).get(
|
||||
p.y,
|
||||
expand=expand,
|
||||
).get(
|
||||
p.x,
|
||||
expand=expand,
|
||||
)
|
||||
# from pdb import set_trace; set_trace()
|
||||
return c
|
||||
except IndexError:
|
||||
return None
|
||||
|
||||
def trim(self):
|
||||
for s in self:
|
||||
for r in s:
|
||||
first, last = None, None
|
||||
min_index, max_index = r.get_bounds()
|
||||
for i in range(min_index, max_index+1):
|
||||
if r[i].active:
|
||||
if first is None:
|
||||
first = i
|
||||
last = i
|
||||
if first is None or first > 0:
|
||||
first = 0
|
||||
if last is None or last < 0:
|
||||
last = 0
|
||||
r.resize(first, last)
|
||||
|
||||
first, last = None, None
|
||||
min_index, max_index = s.get_bounds()
|
||||
for i in range(min_index, max_index+1):
|
||||
if len(s[i]) > 1 or (len(s[i]) == 1 and s[i][0].active):
|
||||
if first is None:
|
||||
first = i
|
||||
last = i
|
||||
if first is None or first > 0:
|
||||
first = 0
|
||||
if last is None or last < 0:
|
||||
last = 0
|
||||
s.resize(first, last)
|
||||
|
||||
def get_all_bounds(self) -> Tuple[Point, Point]:
|
||||
min_z, max_z = self.get_bounds()
|
||||
min_y, max_y = 0, 0
|
||||
min_x, max_x = 0, 0
|
||||
|
||||
for s in self:
|
||||
if s.min_index() < min_y:
|
||||
min_y = s.min_index()
|
||||
|
||||
if s.max_index() > max_y:
|
||||
max_y = s.max_index()
|
||||
|
||||
for r in s:
|
||||
if r.min_index() < min_x:
|
||||
min_x = r.min_index()
|
||||
|
||||
if r.max_index() > max_x:
|
||||
max_x = r.max_index()
|
||||
|
||||
return Point(min_x, min_y, min_z), Point(max_x, max_y, max_z)
|
||||
|
||||
def true_up(self):
|
||||
min_point, max_point = self.get_all_bounds()
|
||||
|
||||
for s in self:
|
||||
s.resize(min_point.y, max_point.y)
|
||||
for r in s:
|
||||
r.resize(min_point.x, max_point.x)
|
||||
|
||||
def expand_all(self, i: int):
|
||||
min_point, max_point = self.get_all_bounds()
|
||||
# print(f"expand {i} cell")
|
||||
# print("expsting min, max:", min_point, max_point)
|
||||
min_point = add_points(min_point, Point(-i, -i, -i))
|
||||
max_point = add_points(max_point, Point(i, i, i))
|
||||
# print("new min, max:", min_point, max_point)
|
||||
self.get_point(min_point, expand=True)
|
||||
self.get_point(max_point, expand=True)
|
||||
|
||||
|
||||
class HyperGrid(World):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
def _item_factory(self, w: int) -> Grid:
|
||||
return Grid(world=self, w=w)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return "\n\n".join((
|
||||
str(s) for s in self._l
|
||||
))
|
||||
|
||||
def to_str(self) -> str:
|
||||
return "\n\n".join((
|
||||
f"w = {s._w}, " + s.to_str() for s in self._l
|
||||
))
|
||||
|
||||
def iter_cubes(self) -> Iterable[GridItem]:
|
||||
for g in self:
|
||||
for s in g:
|
||||
for r in s:
|
||||
for c in r:
|
||||
yield c
|
||||
|
||||
def get_point(self, p: Point, expand=True) -> Optional[GridItem]:
|
||||
try:
|
||||
# print(f"expand world z to {p.z}")
|
||||
c = self.get(
|
||||
p.w,
|
||||
expand=expand,
|
||||
).get(
|
||||
p.z,
|
||||
expand=expand,
|
||||
).get(
|
||||
p.y,
|
||||
expand=expand,
|
||||
).get(
|
||||
p.x,
|
||||
expand=expand,
|
||||
)
|
||||
# from pdb import set_trace; set_trace()
|
||||
return c
|
||||
except IndexError:
|
||||
return None
|
||||
|
||||
def get_all_bounds(self) -> Tuple[Point, Point]:
|
||||
min_w, max_w = self.get_bounds()
|
||||
min_z, max_z = 0, 0
|
||||
min_y, max_y = 0, 0
|
||||
min_x, max_x = 0, 0
|
||||
|
||||
for g in self:
|
||||
if g.min_index() < min_z:
|
||||
min_z = g.min_index()
|
||||
|
||||
if g.max_index() > max_z:
|
||||
max_z = g.max_index()
|
||||
|
||||
for s in g:
|
||||
if s.min_index() < min_y:
|
||||
min_y = s.min_index()
|
||||
|
||||
if s.max_index() > max_y:
|
||||
max_y = s.max_index()
|
||||
|
||||
for r in s:
|
||||
if r.min_index() < min_x:
|
||||
min_x = r.min_index()
|
||||
|
||||
if r.max_index() > max_x:
|
||||
max_x = r.max_index()
|
||||
|
||||
return (
|
||||
Point(min_x, min_y, min_z, min_w),
|
||||
Point(max_x, max_y, max_z, max_w),
|
||||
)
|
||||
|
||||
def true_up(self):
|
||||
min_point, max_point = self.get_all_bounds()
|
||||
for g in self:
|
||||
g.resize(min_point.z, max_point.z),
|
||||
for s in g:
|
||||
s.resize(min_point.y, max_point.y)
|
||||
for r in s:
|
||||
r.resize(min_point.x, max_point.x)
|
||||
|
||||
def expand_all(self, i: int):
|
||||
min_point, max_point = self.get_all_bounds()
|
||||
# print(f"expand {i} cell")
|
||||
# print("existing min, max:", min_point, max_point)
|
||||
min_point = add_points(min_point, Point(-i, -i, -i, -i))
|
||||
max_point = add_points(max_point, Point(i, i, i, i))
|
||||
# print("new min, max:", min_point, max_point)
|
||||
self.get_point(min_point, expand=True)
|
||||
self.get_point(max_point, expand=True)
|
||||
|
||||
|
||||
def part1():
|
||||
# Load world
|
||||
g = Grid()
|
||||
with open("input.txt") as f:
|
||||
for y, row in enumerate(f):
|
||||
row.strip()
|
||||
for x, c in enumerate(row):
|
||||
# g.get(0).get(y).get(x).active = c == ACTIVE
|
||||
pass
|
||||
|
||||
g.true_up()
|
||||
|
||||
print("time = 0\n_____________")
|
||||
print(g.to_str())
|
||||
|
||||
for t in range(6):
|
||||
g.expand_all(1)
|
||||
g.true_up()
|
||||
|
||||
g.tick()
|
||||
g.tock()
|
||||
# g.trim()
|
||||
g.true_up()
|
||||
|
||||
print(f"time = {t+1}\n_____________")
|
||||
print(g.to_str())
|
||||
# print(g)
|
||||
|
||||
total = g.count_active()
|
||||
print(f"Total active: {total}")
|
||||
|
||||
|
||||
def part2():
|
||||
# Load world
|
||||
g = HyperGrid()
|
||||
with open("input.txt") as f:
|
||||
for y, row in enumerate(f):
|
||||
row.strip()
|
||||
for x, c in enumerate(row):
|
||||
# g.get(0).get(0).get(y).get(x).active = c == ACTIVE
|
||||
pass
|
||||
|
||||
g.true_up()
|
||||
|
||||
print("time = 0\n_____________")
|
||||
print(g.to_str())
|
||||
|
||||
# g.expand_all(1)
|
||||
# g.true_up()
|
||||
# print("EXPANDED\ntime = 0\n_____________")
|
||||
# print(g.to_str())
|
||||
# return
|
||||
|
||||
for t in range(6):
|
||||
g.expand_all(1)
|
||||
g.true_up()
|
||||
|
||||
g.tick()
|
||||
g.tock()
|
||||
# g.trim()
|
||||
g.true_up()
|
||||
|
||||
# print(f"time = {t+1}\n_____________")
|
||||
# print(g.to_str())
|
||||
# print(g)
|
||||
|
||||
total = g.count_active()
|
||||
print(f"Total active: {total}")
|
||||
|
||||
|
||||
def test():
|
||||
g = Grid()
|
||||
|
||||
# print("test")
|
||||
# s = [
|
||||
# "...",
|
||||
# "###",
|
||||
# "...",
|
||||
# ]
|
||||
# for y, row in enumerate(s):
|
||||
# row.strip()
|
||||
# for x, c in enumerate(row):
|
||||
# g.get(0).get(y).get(x).active = c == ACTIVE
|
||||
#
|
||||
# g.true_up()
|
||||
#
|
||||
# print("time = 0")
|
||||
# print(g.to_str())
|
||||
# print(g)
|
||||
#
|
||||
# p = g.get(0).get(0).get(1)
|
||||
# from pdb import set_trace; set_trace()
|
||||
# p.tick()
|
||||
# p.tock()
|
||||
# print(g.to_str())
|
||||
#
|
||||
# p = g.get(0).get(2).get(1)
|
||||
# from pdb import set_trace; set_trace()
|
||||
# p.tick()
|
||||
# p.tock()
|
||||
# print(g.to_str())
|
||||
|
||||
# print(list(g[0][0][0].neighbors()))
|
||||
#
|
||||
# print(g.to_str())
|
||||
#
|
||||
#
|
||||
# return
|
||||
|
||||
# g.get(1).get(1).get(1)
|
||||
# g.get_point(Point(1, 1, 1))
|
||||
# g.expand_all(1)
|
||||
# g.true_up()
|
||||
# print(g)
|
||||
|
||||
# r = GridRow(0, 0, None)
|
||||
# print(r)
|
||||
# r.get(1)
|
||||
# print(r)
|
||||
# print(r[:3])
|
||||
# r.get(-3)
|
||||
# # print(r[0:3])
|
||||
# print(r[-2:])
|
||||
#
|
||||
# print("Resize")
|
||||
# print(r)
|
||||
# r.resize(0, 3)
|
||||
# print(r)
|
||||
|
||||
# return
|
||||
|
||||
# c = g.get(0).get(0).get(0)
|
||||
# print(g)
|
||||
# from pdb import set_trace; set_trace()
|
||||
# neigh = list(c.neighbors())
|
||||
# print(neigh)
|
||||
#
|
||||
# return
|
||||
|
||||
print("test")
|
||||
s = [
|
||||
".#.",
|
||||
"..#",
|
||||
"###",
|
||||
]
|
||||
for y, row in enumerate(s):
|
||||
row.strip()
|
||||
for x, c in enumerate(row):
|
||||
# g.get(0).get(y).get(x).active = c == ACTIVE
|
||||
pass
|
||||
|
||||
g.true_up()
|
||||
|
||||
print("time = 0\n_____________")
|
||||
print(g.to_str())
|
||||
# print(g)
|
||||
|
||||
# g.expand_all(1)
|
||||
# g.true_up()
|
||||
# print(g.to_str())
|
||||
# print(g)
|
||||
# return
|
||||
|
||||
for t in range(6):
|
||||
g.expand_all(1)
|
||||
g.true_up()
|
||||
# print(g.to_str())
|
||||
# p = g.get(0).get(3).get(1)
|
||||
# from pdb import set_trace; set_trace()
|
||||
|
||||
g.tick()
|
||||
g.tock()
|
||||
# g.trim()
|
||||
g.true_up()
|
||||
|
||||
print(f"time = {t+1}\n_____________")
|
||||
print(g.to_str())
|
||||
# print(g)
|
||||
|
||||
total = g.count_active()
|
||||
print(f"Total active: {total}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# part1()
|
||||
part2()
|
547
d24/input.txt
Normal file
547
d24/input.txt
Normal file
@ -0,0 +1,547 @@
|
||||
neeneneneswneneee
|
||||
eeeswneseseeseeeseeeeesesee
|
||||
swswsweswwswswswnw
|
||||
neseewwswwneswnewnewwswswwswwse
|
||||
wswsweenweesenweeeeeenweeee
|
||||
neswwwswwwnewwwwwwwwsewwswsww
|
||||
neseeeswesweenweeeeeeeeee
|
||||
neeeneneeneeswneeneneneene
|
||||
ewwsenwwenwnwswnwswwnewwwsewne
|
||||
sesesesesesewseseweeeeneweseeww
|
||||
neeeswnwneswneneneweeneeneswnwnesw
|
||||
neseswnwnenenewneneesenenenenenenenenenene
|
||||
eneeeeseseeseesewseseseeeseee
|
||||
enenewseeenewnweseewnwneseweesw
|
||||
sesesesesenwseseseseseseseswseseee
|
||||
nenenenenwneeesweseneeeeeenenenwe
|
||||
neeenenwseswsenewseswenwewsww
|
||||
neeenesweswwneeneeeeeeeeenwe
|
||||
swseneswewwsewsweeeseeswwsesww
|
||||
nenwwnwnwswwnwwnwnwnwnwnweswswnenww
|
||||
swswseseswnwswswswseswseeswswswswnwswsesenw
|
||||
nwnewwswnwesewnwwwsenwwnewewe
|
||||
newwsewwsenwswwswswswswseswwnwwwsw
|
||||
swswsweswseswswwswswnwseswswswswswswswsw
|
||||
nenwnwnwnenwnwnwnenenwnenwneswnesenwenw
|
||||
nwswnwwnwnwwnwnenwwse
|
||||
neesweeeesewewneese
|
||||
nwneweswwwswswwswwswswsewsw
|
||||
wwwwsenwwnwneswsewsewnenewnwwseswne
|
||||
eeeeeneneneneweneeeeeweswnene
|
||||
enenwneneeneswnewnweewseswneswnew
|
||||
swsesesesesenweswseseseswswseswswsesese
|
||||
nweeeneweewsw
|
||||
nwswswneswswswneswsewswswswswsesw
|
||||
swenwwnenwnwnwswnwsesenenw
|
||||
swswswnwneswswswseswswswswswswswseswse
|
||||
sweseseseeseseweenese
|
||||
wnwnwnwnwnenwnwswnwnwenwsenwenwnwnene
|
||||
eeenweeeeeeeeeeesweeee
|
||||
nesenwswnwseswneewnenwenwsenwenwewnw
|
||||
eeeeeewesenweeseeeeswe
|
||||
swwwswneswsewwswsw
|
||||
nwnenwnenwnenwnenesenenwnwnwnwnwnwwnw
|
||||
newnesewnwnenwneneenwnenenwnenenenenesw
|
||||
eeeeeeeeeeenweeeseeeesw
|
||||
swnwnwwnwwwnwwewnwwsewwwwnwnew
|
||||
nwnwnwenenwswnwnwnwnwwnwnenwswewnwnw
|
||||
swseenwnwswnwnenesenenwnwneeswneenwwnw
|
||||
enwwseeswwenwswswesw
|
||||
enwseseeeeeeenweeeseeseswseee
|
||||
eseswseseswseneenwwneeswwwse
|
||||
swswswwesenwswswswswswswswswswsenesesw
|
||||
neswenwswswswnwnwsweswnweswswsweswsw
|
||||
newsenenwswesewenesewwseeesenwesew
|
||||
seswswswswswswneseseswweswseswsewseswnw
|
||||
wnwwwwnwnwnwwnenwwewnwnwswnwnww
|
||||
newwwwwwsenwwwewwwnwwwww
|
||||
seseseeeswseseswseswswwsewseseswswse
|
||||
eenenwswnenwneswnesenwnenenenwnwnenenewsw
|
||||
swnwewswwewnwnwswwwnwnwewwwse
|
||||
nwenewneneneewnene
|
||||
wwwwwswwswenwwsewwwwwwswsww
|
||||
enenewswnwneneneneseneneneeneneeneene
|
||||
wnwswswnewwwswnewwwsewwseswnew
|
||||
nenenwwsenweswnwswswnwswnwnenwnwne
|
||||
seeenwesesesewseseeseseeesesesese
|
||||
eeneeeeeeeneenwenweswsweeene
|
||||
wneneneswseneneneneneneeneenenwsenwnene
|
||||
seseseswsenewesesesenwneseseeseseesese
|
||||
wsesenesenwsesweseswnwsesweseseesenwsese
|
||||
wwwwnwwnewewwswsenwseseewnwnenwnw
|
||||
wnenenenenenenenenwnenenwnenenesenenene
|
||||
neeewnwwneneesweneeweseswnwneswsw
|
||||
neesewwneenwnwwwwseswwnwwwwswww
|
||||
esweeeeeeneneenwe
|
||||
eseeseeeeenwswseeseneeseseseswee
|
||||
neneenewnweneseswnenenwneneenwwseswne
|
||||
senwwnesenwswnwneeewswnenwnwwnwnwsene
|
||||
eeeeseeeeeneewwneeweneeenene
|
||||
nwnenesenwwwseswseswnwwesesenwwnene
|
||||
swseneswswswswswsewswnwneseswseneeswsesw
|
||||
nwnwwnwswnwnwwnwnwenenwswwnwnwnwnwenw
|
||||
seswswseeesesenwnweeseeeneeenewese
|
||||
nwsenenesenwwnenenwnwneswnenenenenenene
|
||||
swsewnwwwseswwwsewneneswneenene
|
||||
nwenenwnwnenwsenwnenwnwswnwnenenenwnenwnw
|
||||
swwneneneneneenweeeneenesweenesenesw
|
||||
swnwnwswnwwwswsenewsewswsewswswseswsww
|
||||
enenenenesenenenenenenenenenenwswnenewne
|
||||
newewesesewseseseseeeseseeesesese
|
||||
nenwwwnwsewswwwwewsewwwwwsew
|
||||
enwewnwwwwnwwnwnwnwnwnwnwwwnwnwswnw
|
||||
neweeswesweeswewneseewnw
|
||||
swswswswsewesewswswswswneseswswswseswse
|
||||
swneeewseneeeeeswneewwneseenwe
|
||||
wwwwwwwwwneewwsewwwwweww
|
||||
eeeesweneenweeeneneeweeenee
|
||||
wnenwneseeenwseeneneewneseswwnene
|
||||
wwwnwewnwnwnwnwnwewneenwnwnwswswswnw
|
||||
enenenenwesesewnwneeeswneneeneenenene
|
||||
nwnewseneseenwwwseswneswseneeeswnew
|
||||
swsewwsweseswneseseeseswneseneswswse
|
||||
swswswwswswnewsesesweswswswswseneswnesww
|
||||
enwwnwwnwwnewnwswswseeswnenwwnwwnwse
|
||||
sesenwnenwnwnenwnwnwswnwnenwnwnenenwnwnwsw
|
||||
seeneswswwswwswswwwwswwwswnenesw
|
||||
swwwwswneseswwwwswwnwswswswswwswsew
|
||||
swseeenenwnwswenwneneenwnwnenwnwsewsw
|
||||
wswswswwwswwwswswswneswswswseswswsw
|
||||
neswnewnenenwnenewenenwneneeenenenw
|
||||
eswneneneneneenenwneneeeneenenewe
|
||||
enenenenenenwneneeneeeeeeenese
|
||||
seeseewswwseseneesenwneseseswsewswsw
|
||||
ewwewswwswwswswwewwnwswwsww
|
||||
swwswswswswswswswswswne
|
||||
nwnenwnenenenwnwnwswnwne
|
||||
nwnenwnwswnwwewnwnwswnwsenwwnwnwnwnw
|
||||
nwnwnenwnwnwnwwnwnwnwswnwswnwnwewnwnw
|
||||
eseneseeswenwneeneneneneewnenwnenene
|
||||
swwnwwswwswswwswwswswswsewwwwswne
|
||||
swsewsenenweseesweee
|
||||
nwnwnwnwsenwnwnwnenenwnewnwnwnenwnwnwnw
|
||||
nwsweeeseseeeeseeeeseneeswene
|
||||
neenwneneswnwnesewewswneswnwnwneneswe
|
||||
esenenwnwnewseneswnwsewswwnwsenwsewswse
|
||||
nwwwweneeewwwesesenwneneswswswnw
|
||||
nwnwsenwnewseswnwesenewnenenwnenenenwe
|
||||
wnwwnwnenwnwsenwnewwnwwsewwnwwwwe
|
||||
wwwewwswwswwwswwwwswsw
|
||||
swswwswswseswswswswseswswswswnesw
|
||||
wwwwwwwwwwswwewwnwwwww
|
||||
nwnenwnwnwnwnwsenenwnwnwnwnwnw
|
||||
swnwswswswswwseeeswswswswswswsewnwnwsw
|
||||
nenwnenwnenewnwnenwnwnenwnwseenenwnenwne
|
||||
seewseeseeeeseseeeweneseseseese
|
||||
seenesesesesesesesewseseseseesesesese
|
||||
nenenenenwneneneenweneneneesenenenesene
|
||||
swswneneeseswwswnwseswswwswswseswsesw
|
||||
nwswsenwneenwnwnwnwsenwnwwsenwenewnwsw
|
||||
nweseseseswswswswswswswswswsw
|
||||
seseswseseseswsenwseseseseesesesesesese
|
||||
wwwwwwsenwwnewewnwwsewswnesww
|
||||
nwseswswnwseswswsewseseeseswswesesesesw
|
||||
seswseseenwswseseseenwswseswseesewswse
|
||||
nwwnwnwswnwwnwnwnwnwesenwnwnwwwwnww
|
||||
neneswseneneneswwnenweneeneneenesenww
|
||||
swswswswneseswswseswswswwswswsesweswswse
|
||||
swneswseswswswswswswswswswseswswseseswsene
|
||||
swswneneswswwneswwwswswswwswnweswsene
|
||||
nenwnwnwwnwnwnwnwnwnwnwnwnwenwnwnwswnwnw
|
||||
wwneswwwwwwwwewwwnwwwsewww
|
||||
neneeswnwneneeneeee
|
||||
swesweswswnesweswsesewwnenwnwnewnwnee
|
||||
nwwwwewwwwwwwnwwseswwwswwe
|
||||
sweenwseeseneweseseeewnwseeseenenw
|
||||
eeeeeenweseeneeeeeeeenesw
|
||||
nwnwnwswnwnwnwswnwnwnwnweeenwnwswnenw
|
||||
eneeneeeeweeeeeneeeeneewsee
|
||||
swnenwnweneneenwnwnwnwswnwnenenenwnwnwnw
|
||||
nenwnenwnwnenwnenesenenwnwnwnenw
|
||||
neeswnweswswseewwnwwweswwwwwne
|
||||
nwseeeeeeweseeeeseeeeeeee
|
||||
sweseneneseeseeseeneeeeeewsweew
|
||||
wnwwnewswwwswwwwewwwwnwww
|
||||
wswnwsweswwneseswnwswswwseswsweswnwwsw
|
||||
nweswneeweeeeswsenwew
|
||||
neeswneneenenweeneneneeneseenesenwe
|
||||
nwnwnwnwnwnwnwnwnwnwnenenwnwnwnwsenwnwse
|
||||
seswseseswseseswseseseseswsesenw
|
||||
nwnenwewnesenwnwnwnwnewnenwnenwne
|
||||
swswswswesweswswswwswswswswswswwswsw
|
||||
nwnweeeeeeeeeseeeeeeeese
|
||||
wswnwnwswswswwwwswswswswswwwseswswse
|
||||
seneswwseswsesewsenwsenenesenwseseese
|
||||
neneneswneswenenweeneenenenenwnwswnene
|
||||
newwwnwwwwnwsewwwwseswwwwse
|
||||
swsenwenwnwnwnwnewnwswenwwesw
|
||||
newwnwnwnewsewwswwwwnwnwnwswww
|
||||
eseswsenenesesenwwseswseseseeseesese
|
||||
nwwenwenwsenwnewnenenwnwwnweneswnwne
|
||||
neswneneseswseeseseswswsenesenwswswsww
|
||||
neneeeswseneswnwnwwenenenwseswwwe
|
||||
nwswseseseeeseseseseesesesesese
|
||||
wswwnwswswnenwneswnweswseenwewwwse
|
||||
swseseswseneswswseswswseseswswnwswseswswsw
|
||||
sesesenwseswseseseseseeesesesesesesese
|
||||
nenenenenenenewwneeeneneseneeneneene
|
||||
wnwswwewswnwnwsenenwesesweeswsene
|
||||
enenenwneneneeneeeneeseswneenenenene
|
||||
seenwseseeneeswwneseeeseswwesenww
|
||||
seseswnwwsewnewswnwseswneswswswesweenw
|
||||
nenenenenwnwnenenwwnwenwnenw
|
||||
nwwwwnwneeeeneneneseswsenewesenw
|
||||
swswswneneseswwwwswswswswswnwswswswsw
|
||||
nesesenwswswseswnenwsewswseseseseswnese
|
||||
neeeenenweswenweneneeneeneeeeese
|
||||
seeweneseeneseseseswseewsenenwe
|
||||
seseseseseseseseseseseseseseswsenwsw
|
||||
wswswswswsweswwwwseweswwwswswne
|
||||
nwseeswneswneswwnenwseswenewseswwsw
|
||||
neeweenweeeeneeeeeesweeeee
|
||||
swwswwswwneweswwswswwwswsewwsw
|
||||
sesweswwswenwweswswesenwnwnwnweswse
|
||||
nwneenenwnewenesw
|
||||
wnwseewwenwwwwesewwwnwewwnw
|
||||
eeeneesenenenweswene
|
||||
seenwseseseeseseewsweesesesewsese
|
||||
wswsweswswseseseseseseseseswswsesesenwse
|
||||
wweeeeeneeseeeeeeeeesese
|
||||
swseswseseseeswsenenwseswseseseseseswsw
|
||||
wwwewwwwwnwswwwnwnwnwwwewnw
|
||||
wwnwnenwseneeswswswewewswswswwenw
|
||||
neswswswswswseseswseseseseswseesenwswsw
|
||||
neeswnewnwwswsenwnwnenwnwsenesewene
|
||||
nenwseeswwswseswsesesweseswswswswseswsw
|
||||
nwwwwseneneswseseneeseswswnwnwseene
|
||||
seesesesesenwseweseeseseeseseswseese
|
||||
ewwwswswwsewnwwwwswnewneeswsw
|
||||
eeneneneneneneeneenenewnenenenesewne
|
||||
enweeswnwsweseneeneenwsenewnwswswne
|
||||
sesenwseewsesenweseeeseseeeseeenee
|
||||
nwnwnwnenwnwnwswnwnwnwnenwnwenwnenwswnwnwnw
|
||||
seswnwsenwnenwnwnenwnenwnwnenw
|
||||
nenwnwnwsenwnwnwnwnwnwnwnesenwswnwnwnwnwne
|
||||
swnwnenwnenenwnwnwnwnenwweenwwenwnwnwnw
|
||||
senwnwnwwnwwwwnwwnwnwnwswnenwnwnwnewnw
|
||||
neswnenwswsesewnwnewsewwnewnesenewnwnw
|
||||
wwwsenwnewwwwewwnwwwwwsww
|
||||
enwneeneneswswnesw
|
||||
enweesesewsenesesw
|
||||
eeswewneesenenweneneneneneeseee
|
||||
nwnwseneswnwnwwewwwwsenwwwnwww
|
||||
swwneswneswwwswsweeswswswwswswseswnw
|
||||
ewwwwwsewswwwwwwenwwwneww
|
||||
swneswseeswswswwswnwsewwswswswswwswwsw
|
||||
sweswwswseneseeewswwnenwnwneewwsw
|
||||
swwswswseswswswwswswswswswswswwswswne
|
||||
nwwwswwwwwwswwweweswneswwew
|
||||
neneneswsenenenwnenenwneswnweweenwsww
|
||||
senwswnewwseseeseenewseseneeeswene
|
||||
nenwsewwsenewswseenesewsenenewnwe
|
||||
swswswswwwwwewswwnewwswwwwww
|
||||
swsweswsenwnweenenwe
|
||||
wnwsesesesewseswnesenesenwswsesesesesesese
|
||||
eeewseeeseeweeeseeewwenee
|
||||
eeeeeneeeeeeeweseeewwe
|
||||
neneneneenenwneneneneneneneneneneneswne
|
||||
seeseeseesesesenweseeeswneenwnwee
|
||||
seeeseenwswneeeewswewneseeew
|
||||
nwseenwnwnwnwnwswnwnewwseenwnwnwsenw
|
||||
esweeeweweneeseeneseee
|
||||
ewswnwswswwnewswwsweseswweswswww
|
||||
sweseeneswwwwnwnenwsenwwsweseswe
|
||||
eweeseseeswnwneneeeneew
|
||||
swnweseeeeeneweeeeeeweene
|
||||
wwnwwweswwnenwwnwnwswwwewwsw
|
||||
neneeeweenewneneeeeneeeneswe
|
||||
swwwesewnwsenenwnewnwneseenwwswnew
|
||||
senwnwnenwnwnewnwneneswwneeneneenewse
|
||||
nwwwnwwwwwnwwwwnwsewnwwwsew
|
||||
wwwswwswwwswwwwseneneeswwwww
|
||||
neswswseswswnwseswseseswswwseswsesesesese
|
||||
nwsewnwnwwnewnwnwnenwneenwnwseneenw
|
||||
seseseseseseseesenewsesesesenesewsese
|
||||
newwnwnwnwwnwwwnwsenwnwnwwwsenww
|
||||
swswenwnewswswswneweweswswswswnwsesese
|
||||
seeseswseseseseesesesesesewseseswnwse
|
||||
nenewneneneswnenwsenenenenewneenenenee
|
||||
sewseneseswneseneseeewswnwswsewswwsw
|
||||
eeswwswswswswswswswswswsenwswswnwwswsw
|
||||
seneenwswseseeeneeeeeswswsenewe
|
||||
nenenwnwnenwenenenwnewnwwsenenenwnwne
|
||||
nenwenwswenwnenwnwsenwwnwenwnwswnwnw
|
||||
wwwsenwwswnwwwewenewwwwwnwnw
|
||||
nwnwnwnesenwnwnwsenwnwnwswnwnwnwnwnwnwnw
|
||||
swswswswseswsweswswnwswwswseswneswswswwsw
|
||||
eswnenwneenwewnwnwnww
|
||||
seseseseeseneseseseseseseweeseseseswnw
|
||||
enwwnwnwswnwnwnwnwwwnwnwnwwnw
|
||||
swsewseneswneewwwwnwnwnwnwwseswsesww
|
||||
nenesenwnenenenenenenenenenewneneswnee
|
||||
nwweswwsweswswswneswswnwswswswswww
|
||||
neeneeneneneeneenenenenenenewsenene
|
||||
nwswswswsweswwswswswwswewwwswswsw
|
||||
swwswwwwwswwseswswswnwweneswswsw
|
||||
wswnwneeneswnwwswwnwwsenenewwnwww
|
||||
nenenenenwwenwnwnenwenenww
|
||||
seseneseseswwneseeseewseseesesenwse
|
||||
nwenwsenwnewneswnwnenwnwnwneenwnwnwnenw
|
||||
nwnwnenwnwnwnwnweswnenwsenenwnwnwnenwnwwne
|
||||
nwnenwenwswnwenwwswnenwnenwnwnwnwewnee
|
||||
wwnwenwnwwnwwwnenwnwwnwnwnwesww
|
||||
neseeneeeneeeeewneneneneeenee
|
||||
swseseswnwneeseseneswswwswswnwswse
|
||||
swnwswseswswwswswswneswsw
|
||||
swwweeeeswnwneneeewnweeeeee
|
||||
enenwnenwsenwswnwnwnenenwnewnesenwnwsenwnw
|
||||
swewswwneneseeeenwneenenwnenwseee
|
||||
seseseseseenwseneseseeseswseeseswnwse
|
||||
seneeeseseeeseswnwswsesesenwwwseenw
|
||||
wwnewwwwwwwsenewwwwwwswwnww
|
||||
nwswwwswswwnwsweswswsweswswsesweswsw
|
||||
swswnwnwnwnwwenwnwnwenenwnenw
|
||||
seeseseseseweseseeeseseesee
|
||||
wnwnwnwsewnwnwnwnw
|
||||
nwnenenwnwneswnwnwnwnwnwnwnwneenwnwwnw
|
||||
sweeseneweseneswenwsesenweswsenwnee
|
||||
wswnwnweseseewenenenwenenesweene
|
||||
nwnesenwnwseesewneswwnesweswnwnwsenww
|
||||
sewneswwwnwewnenwnwnwwwswnwwnwswe
|
||||
eeesweseneeweenweeswenweneewe
|
||||
neneneeneeeeneneeesweeenwenene
|
||||
eeneneeeneeeenwneeswweneenenee
|
||||
sesweeneeseeeweeeenweeeese
|
||||
swnwswneewwwnwwsewwnwnwwnwnwwenwnw
|
||||
eeeeesweseeeseswenwnwenwnwee
|
||||
sewwnewwswwwwswnesewswsw
|
||||
nesewseewseswsesewwswweseseneswswe
|
||||
newneenwsewnenenenenenwne
|
||||
sewsenwseeseesewneswwwnwsenweswnene
|
||||
swswswwwwwswwwswneww
|
||||
wnewwwwwwwwwwwwwwwswsw
|
||||
swwwnewwwwswsenwnwwwnenwseenww
|
||||
neeenenwweneeneeneneneneneeneneswse
|
||||
nwsenwnwnwnwnwswwnenenwsewnwswnwenwse
|
||||
nwesenwnewwnwwwnwwwwnwwswnwnww
|
||||
neswwsenwswnwwwswswseswswwsw
|
||||
neneeneswneneneenewnewseenenenenene
|
||||
seswseswsesesenesesesesesese
|
||||
wwwnwwwwweswewswnw
|
||||
seneseswsesewseseneesewwseswwswsenese
|
||||
enenwnwnwwnwswnwnwnwswnwenwnwswenwnw
|
||||
neswwsenwswsweneswswnwswseswnesenwnesw
|
||||
senwwnweswseswneswneewneseesesesesene
|
||||
nwenwwnesenwnwwswenwnenwswnenwnenwse
|
||||
weneeseeneeswweswnweswenwewswnw
|
||||
eswnwewwnwnwswwswwswene
|
||||
swwnwneseseseneneseswewswwsenewseee
|
||||
seswwnwwwswseeswwswnwwsewwenene
|
||||
neeneneneneneenenenenewsenenenwswnene
|
||||
eesesweeeeeeeneenweeweseww
|
||||
seswswswnwswswsweswswnwswswswseswswswsesw
|
||||
nenwnwnwnenenwnwnwnwwnwsenesenwnenwnew
|
||||
neneswneneneenesenwnenenwnenwwnewnesene
|
||||
wnwnwewnwwswsenewenenwnwswwwwwwnw
|
||||
weneswnenwnenwnenenenenwnenesewnwnene
|
||||
eneneewswneenenwswnenweeeeneesee
|
||||
neswseseswseswwseseseseswnwnwnwswnwsesw
|
||||
nenenenenenwenenewnwnwwsenwnenenenene
|
||||
weseswnewnenwwenwnwnwewnenenwsenw
|
||||
swenwnewewwwnwneswewwsewnwsewnw
|
||||
seseseseneswseseswseswseseseseswnesewsesese
|
||||
nwnwnwnenwnwnwnwnenwnwenwnwnwnwnwnwnwsww
|
||||
nwesweeeneeeeseeeeeneeeeee
|
||||
esweseswnenwsenwnw
|
||||
swneswwswswswewswwnwnewswsenenenwsw
|
||||
enenwnwswnwnwnwsenenwnwnenenwnwnenwnwsenw
|
||||
neswneswswswsenwseseneswseseneswseswswse
|
||||
ewneneenwnenwneneswnwnw
|
||||
swsenwsenesweswwnwsenesewswswwseswswsesw
|
||||
swwswwswwwswwswswwswnwswswswe
|
||||
nwwnewwewwwwswneswwswswseswswsw
|
||||
seeseswwnesesenwsenwswweseswenwnese
|
||||
nwnenwneneswswwnenesenenwnenenwnwnenenene
|
||||
nenwnenwnwswnwnenwnewneneneneneneneenwne
|
||||
eeeenenenenwneneeeeeeneewsese
|
||||
neseswsesesesewsenewsesenwseneswnesesw
|
||||
eswnwswsweeswnwnwnwwswwwswwesesesw
|
||||
wnwwsenwwwenwswswswsewwenewnwwnw
|
||||
seweeeeeeeneeeeseenwswnenwee
|
||||
nwsenwwwwwwwwwwwwnwwwneww
|
||||
swneswswswswwswsweswwwswnenwwswseswsw
|
||||
swneeeeeeesweenwneneeeeeee
|
||||
neewsewswseswswsenwswswneswwswenesw
|
||||
wnwnwsewwswnwwwwnwnwnwnenw
|
||||
neseseeseswsesesewswsenwswseseswseswswnw
|
||||
nwenenwnwnwnwnwnwnwwswnwnwnwnwnwsenwe
|
||||
neneeewnewnweseenenwswwnesewsee
|
||||
sesewseswneswswseseswnwswswneswneswswe
|
||||
seseseswseswsesesesesesesesenesesewsesenwse
|
||||
enwwwswswwwnwsesewwewwwnwew
|
||||
nwsenwnweseswnwnenwnwnwnwnwnwwwswnwnw
|
||||
nwseseeneseesweseseseseseseseeswnwsese
|
||||
seswswseswneseswswneswswswseswswswswswswnw
|
||||
swswsenwseswswseswswswseseneseseseswneswsw
|
||||
seseeseswswswswswseswnwswswnwsweswsesw
|
||||
wneseswseseneseesenenwwnesewseswswese
|
||||
neneswnenwnenenenenwneesenwnenenenwnwnene
|
||||
sweneseweseeeeeseeeeeenweeee
|
||||
enwnwnwnwnwnewenwsenenenwnenenwnwswne
|
||||
weeeeneeeseseeeeseseesewewee
|
||||
wsenwnwsewwwwwwwnwwnwnewnwww
|
||||
nwnwewnwnewnwsewnwwnwnwnwnwwwwwse
|
||||
swswswwwwswwswswsewnewwwswwneww
|
||||
nenwswewwswneswwswswwweswswwww
|
||||
neneneswenenenwneneweewnwnenenenene
|
||||
swswseneseseseseswseswsese
|
||||
nwnesenwnenenewneseswwwnwenenwseene
|
||||
wsesewseseseseseseesesesesesenesesese
|
||||
seseweswsesesesesesesese
|
||||
nwnwnwnenwsenwnwnwneswnenwnenwenwnenwnw
|
||||
seseswewseneseseseseseseswswsesewnese
|
||||
seswseswsesenesesesesesenwswseseseswsese
|
||||
sweenwseeeeeeeeenweeeeeeswe
|
||||
eenwwnewswsesewewswswseneswnewww
|
||||
wwwwwwwwwnwwsewww
|
||||
wnwnenwswenwnwnwnwse
|
||||
swneseneneswneneesewwnenene
|
||||
wwswewwwwwwwwnwwnwwwswwswwse
|
||||
sesesewseeseswsewseswnesesesesesesene
|
||||
swwwwwwwwwswwwwnewwwsenesw
|
||||
swswseswswnwswswswseseeswsw
|
||||
newwswsenwnewwsewseseswenwneeswwnw
|
||||
nwsweswswswswswswnwswswswseswswswswsesw
|
||||
nwswneseswseswsenewenewwneseewsenw
|
||||
sewseneseneseseseseesewseseneswsesesese
|
||||
wnwnwenwnwnwnwnwnwnwnwsenwnwneswnwnwne
|
||||
sewneewwsesenwnwnewwswwwwneswwsw
|
||||
wwwnwsewwwwswwwwwnwwwwwe
|
||||
ewneenwseneneewswneswneenenwenee
|
||||
swwswswswswswswneswswseswswweswswswswswsw
|
||||
nwswnwswnenenwswneneneneeneene
|
||||
esenenenwneneneswenenewneneneenenenenene
|
||||
swswsweseewweswwsesw
|
||||
enwewwnwnwsenwneseswwesewnewenew
|
||||
eeeseseseeneesweeeeeee
|
||||
ewenwwwswwseswnwswnwwswsweswwww
|
||||
wnwweeneenewnenenwnewswneeesew
|
||||
nenwnenwnenenwswnenwnewnwnenwenwnwnene
|
||||
neneneseneeeneneesewneneeew
|
||||
neneneneneneneenenwneneneneswneenesenene
|
||||
nenwnenenwnwnwenenwnwneneneenewswnenenw
|
||||
swwwswwwwewswswswwwswnwseneswswww
|
||||
neenenewneneseneneesenewenenenenwnwnese
|
||||
wnwwweswswswwswweswswwswwswwwwnw
|
||||
wswwwewwswwswwwwwwnwwwsw
|
||||
senwesewenwseseswesesesenwswnwsesee
|
||||
nwnwnwnwnwneneswnwsenenwnenwsenenwnwnw
|
||||
seewwwwwnwnwwwwnwneswwwnwswnww
|
||||
seeweseeeseeeeseneeswseeseene
|
||||
enesweeweeeneesweneseeeeneee
|
||||
senwseweswneeesweeneseweeesenesew
|
||||
swswseswseswswsweneswswswwenwwneswsw
|
||||
swswswwewnwswswswswewwswswswswswswsw
|
||||
swswswseswsesewseswseenwseswseswnwnesese
|
||||
ewswswswswswneswswnwwenwsesenwswwsee
|
||||
swnenwweesenwswnewneneneswnwnwnwswnenw
|
||||
nwnwnwnwnenwswnenwnenwenwnwwnwnenenwnwne
|
||||
neneseenewnenenenewnenenenesenenenenenee
|
||||
nwnwnwswnenwnwenwsenenwnwnenwnwnenenwnwnene
|
||||
nenenenenewnenewsenenenenesenenenenene
|
||||
swswswswseseesesesenwswswsesenwseseseese
|
||||
neneneweeeenesesewneweneeeneene
|
||||
wwnwewswsewwnewwnewwwww
|
||||
seseeeeseeeeeesewseee
|
||||
senesesesweseswenwnesesweseneeseswe
|
||||
wweeswswnwswwsesesewesenwseewee
|
||||
nwwnwwnwnwnwnwwwnwnwswenwwnwnw
|
||||
wwswnewwwwwwwwwwsewwwww
|
||||
neneeneneneneneneeneenenesenenenewne
|
||||
neweseeeeseeeeeeeswseeseesee
|
||||
nweneneswnwnwnwnenesenesewnwnwneenwnwnw
|
||||
neneseswnenenwnwswwnwnenwnewseneseneneenw
|
||||
nenenewesewseweeeswswneswneseee
|
||||
swswseseeseseeeseesesesenwsesesesenwsese
|
||||
seneeneenweeneneenesweeewneee
|
||||
wwwewsenewwswneeneeswseswswenw
|
||||
nwnwwnewsenewswnesenwwwnwenwwsenwnw
|
||||
seeenwneewnweswnweewseewseese
|
||||
sewnwswwwwnewwnewnwwwsewwww
|
||||
swsenwnwewnwnwnwnwnwnwwnwnw
|
||||
enwesweeseeneswneeseewsewwnee
|
||||
wnwweneswswwsenwwwnwwwwnwnwww
|
||||
wwwswwwwwwnewswwwweswwww
|
||||
swswnewswswsweswswwwswseswswwwsw
|
||||
wwwnwwewnwwwwnwwwwnwwwnwsew
|
||||
nwnwnwnwnwsenwwnwsewnwnwnwnwnwnenwnwnw
|
||||
nesenweswnenenesenenenwneneeeneenwne
|
||||
sweeeseeeeesenweseeseseeese
|
||||
eseswwswseswseswneseseseseseswswseswwswsw
|
||||
nwenwnwsenwnwnenwnwnwnwnwnwsenwnwnwwne
|
||||
wewwwwwnewwwwewwnwwswww
|
||||
wnwwwswswneeswswswswswseseseesenwesw
|
||||
seweeeenweeeeesweeeeee
|
||||
nenenenenwsewnenenwneneswnenenenenenenene
|
||||
neesewneswneeeneneneneeenwwwneene
|
||||
swseswneswseswwesesweswswswnwseswnwswswe
|
||||
newnwwwseswswwswwswnwswwwsewswwne
|
||||
swswswwswswswswswsenwseswnenewswwswsw
|
||||
neeneenenewneeweeeswneseeeeee
|
||||
newsewnenwnewsenesewnwee
|
||||
nwnwswswseseneswswnweseswsenwneseweswsw
|
||||
seswswwwwwswwneswswwenewswne
|
||||
eneeenwwnwwwwwswnwnwswnwnwwww
|
||||
nwnwnwnwnwnwnwwewnwsww
|
||||
seeswneseseseeseesesesewenwseenwwse
|
||||
nwnwwswnwwwwewnwnwwwnwnwwewnwew
|
||||
eeseseseeeseneseeeseseeneseseswwsese
|
||||
swwswswweswwwnwswneswwswswswwww
|
||||
wnwswwwwwnwnwwwsenenwewswwwnenw
|
||||
sewswseseswnwnwsweenweswwseswswswnenwne
|
||||
wwnwwwnwnwwwwwnenwwnewswnwwnwwse
|
||||
seweswwneeswsenwswnwwswswswnwseswwsw
|
||||
nwnenenwnwnwneswnenenenenwenwnenwnenwneswne
|
||||
sewsenwnenwnwwwnenwnewwsenwwnwwnwse
|
||||
seseeseseenweneseweseswswswnesesenw
|
||||
swwneswwwwswwnewwswwseswswwsww
|
||||
seesweswnwseseseswnwnwswswnwse
|
||||
eesesweseeeseeeeeeenwsweene
|
||||
swseswswswseswswswswswswswwswswenwswsesw
|
||||
swwswswsweswwwnwswswswnwswwsewswsw
|
||||
nwnwwwnwwnwnwwnwwneenwwwwnwsesee
|
||||
weeenwseseseseeseenesesee
|
||||
nwnwwseenwwwwnwwnwwnwnenwsenwnww
|
||||
eeeeseseeeeswseeseseswneseeseeenw
|
||||
eeeeeneesweeeesweeenenweeee
|
||||
eweeseneeseesesenesweeseewsewne
|
||||
neneneswswenenwwnenewsweneswenwswsenw
|
||||
wwswnwsewneseswswneesenewswwwsenwsw
|
||||
seswswsweswnweswesweswswwnwnwsesese
|
||||
weneeeneeeeewseeeeeeeneee
|
||||
nwwnewwswwswswswwwswswwewswwwe
|
||||
seseesewseneeseesesweswsenwwsenwsese
|
||||
wenwseeswwnwewwneswnwenwwnwnwse
|
||||
wwwewswwwwwwwewnwwwwwnww
|
||||
seseswsesweweeesenweeseeeeseesenw
|
||||
swseneswneseswwswswswswseneseswswswswsesww
|
||||
esenwseseeeseseseesesesesenwwnwseene
|
||||
neeneneneeneeenenenwwswe
|
||||
wnewwswswswwwswswswswsewswwswwsw
|
||||
eswnwesenesweeeneesweeneseeesw
|
||||
nenwneneneeswneneneswnwnenene
|
||||
swswswswswswswneseswswenwwnweswswswsw
|
||||
eeeeneeeneeewneneeeeeeenwesw
|
||||
neneeesweseneneenwseenwnee
|
||||
nwnenenenwswewnwnwnwnwnwnweswseswnenw
|
||||
wneseseseseseseswseneswseseswsesesesese
|
||||
wswsweseseswswneswwswneswneswswnwswsw
|
||||
swnwnweneneswsewnenwnw
|
||||
nwnwnwnwnewnwnenwnenwnwnwnwnwnesenenesene
|
||||
nenenenenenwnenenwneenwswnenwsenenenenw
|
||||
swnwswnweesenwswswswsenwswseseeswswsesw
|
||||
ewswnwseswsenweenwsenesesewsee
|
||||
nwnewseewsewnwnwnesewwnwsesenwwswnw
|
||||
nwnwnenwnenwneneneenwwnenenenwswnwenenw
|
||||
nwwwswwwwwwnwwwswwenwnwwwe
|
||||
wnwsenesenwswsewswneswswnwsewswwwwsw
|
231
d24/main.py
Executable file
231
d24/main.py
Executable file
@ -0,0 +1,231 @@
|
||||
#! /usr/bin/env python3
|
||||
from typing import Iterable
|
||||
from typing import Tuple
|
||||
from typing import Optional
|
||||
|
||||
from expanding import AutoExpanding
|
||||
from expanding import GridItem
|
||||
from expanding import Point
|
||||
from expanding import World
|
||||
from expanding import add_points
|
||||
|
||||
|
||||
D2P = {
|
||||
"se": Point(1, -1),
|
||||
"sw": Point(-1, -1),
|
||||
"ne": Point(1, 1),
|
||||
"nw": Point(-1, 1),
|
||||
"w": Point(-2, 0),
|
||||
"e": Point(2, 0),
|
||||
}
|
||||
|
||||
|
||||
def directions_to_point(s: str) -> Point:
|
||||
point = Point(0, 0)
|
||||
direction = ""
|
||||
for c in s:
|
||||
direction += c
|
||||
if direction in D2P:
|
||||
point = add_points(point, D2P[direction])
|
||||
direction = ""
|
||||
|
||||
if direction != "":
|
||||
raise ValueError("Something left over unexpectedly")
|
||||
|
||||
return point
|
||||
|
||||
|
||||
class Tile(GridItem):
|
||||
|
||||
def __init__(self, loc: Point, world: World, is_black: bool = False):
|
||||
# Give this tile a unique id for tracking later
|
||||
self.is_black = is_black
|
||||
|
||||
def _tock():
|
||||
# print("Default tock")
|
||||
pass
|
||||
|
||||
self.tock = _tock
|
||||
|
||||
super().__init__(loc, world)
|
||||
|
||||
def flip(self):
|
||||
self.is_black = not self.is_black
|
||||
|
||||
def neighbors(self, expand=False) -> Iterable["Tile"]:
|
||||
for diff in D2P.values():
|
||||
neighbor_point = add_points(self._loc, diff)
|
||||
neighbor = self._world.get_point(neighbor_point, expand=expand)
|
||||
if neighbor:
|
||||
yield neighbor
|
||||
|
||||
def tick(self):
|
||||
num_black = count_black(self.neighbors(expand=True))
|
||||
if self.is_black and (num_black == 0 or num_black > 2):
|
||||
self.tock = self.flip
|
||||
if not self.is_black and num_black == 2:
|
||||
self.tock = self.flip
|
||||
|
||||
|
||||
def count_black(tiles: Iterable[Tile]) -> int:
|
||||
return sum(map(lambda x: 1 if x.is_black else 0, tiles))
|
||||
|
||||
|
||||
class TileRow(AutoExpanding):
|
||||
def __init__(self, y: int, world: World):
|
||||
self._y = y
|
||||
self._world = world
|
||||
super().__init__()
|
||||
|
||||
def _item_factory(self, x: int) -> GridItem:
|
||||
return Tile(Point(x, self._y), self._world)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return "[" + " ".join((str(c) for c in self._l)) + "]"
|
||||
|
||||
def to_str(self) -> str:
|
||||
return "".join((c.to_str() for c in self._l))
|
||||
|
||||
|
||||
class Floor(World):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
def _item_factory(self, y: int) -> TileRow:
|
||||
return TileRow(y, self)
|
||||
|
||||
def iter_items(self) -> Iterable[GridItem]:
|
||||
for r in self:
|
||||
for t in r:
|
||||
yield t
|
||||
|
||||
def get_point(self, p: Point, expand=True) -> Optional[GridItem]:
|
||||
try:
|
||||
return self.get(
|
||||
p.y,
|
||||
expand=expand,
|
||||
).get(
|
||||
p.x,
|
||||
expand=expand,
|
||||
)
|
||||
except IndexError:
|
||||
return None
|
||||
|
||||
def get_all_bounds(self) -> Tuple[Point, Point]:
|
||||
min_y, max_y = self.get_bounds()
|
||||
min_x, max_x = 0, 0
|
||||
|
||||
for r in self:
|
||||
if r.min_index() < min_x:
|
||||
min_x = r.min_index()
|
||||
|
||||
if r.max_index() > max_x:
|
||||
max_x = r.max_index()
|
||||
|
||||
return Point(min_x, min_y, 0), Point(max_x, max_y, 0)
|
||||
|
||||
def true_up(self):
|
||||
min_point, max_point = self.get_all_bounds()
|
||||
|
||||
for r in self:
|
||||
r.resize(min_point.x, max_point.x)
|
||||
|
||||
def expand_all(self, i: int):
|
||||
min_point, max_point = self.get_all_bounds()
|
||||
min_point = add_points(min_point, Point(-i, -i))
|
||||
max_point = add_points(max_point, Point(i, i))
|
||||
self.get_point(min_point, expand=True)
|
||||
self.get_point(max_point, expand=True)
|
||||
|
||||
def tick(self):
|
||||
for t in self.iter_items():
|
||||
t.tick()
|
||||
|
||||
def tock(self):
|
||||
for t in self.iter_items():
|
||||
t.tock()
|
||||
|
||||
|
||||
def sample():
|
||||
print(directions_to_point("nwwswee"))
|
||||
|
||||
seen = {Point(0, 0)}
|
||||
floor = Floor()
|
||||
for line in (
|
||||
"sesenwnenenewseeswwswswwnenewsewsw",
|
||||
"neeenesenwnwwswnenewnwwsewnenwseswesw",
|
||||
"seswneswswsenwwnwse",
|
||||
"nwnwneseeswswnenewneswwnewseswneseene",
|
||||
"swweswneswnenwsewnwneneseenw",
|
||||
"eesenwseswswnenwswnwnwsewwnwsene",
|
||||
"sewnenenenesenwsewnenwwwse",
|
||||
"wenwwweseeeweswwwnwwe",
|
||||
"wsweesenenewnwwnwsenewsenwwsesesenwne",
|
||||
"neeswseenwwswnwswswnw",
|
||||
"nenwswwsewswnenenewsenwsenwnesesenew",
|
||||
"enewnwewneswsewnwswenweswnenwsenwsw",
|
||||
"sweneswneswneneenwnewenewwneswswnese",
|
||||
"swwesenesewenwneswnwwneseswwne",
|
||||
"enesenwswwswneneswsenwnewswseenwsese",
|
||||
"wnwnesenesenenwwnenwsewesewsesesew",
|
||||
"nenewswnwewswnenesenwnesewesw",
|
||||
"eneswnwswnwsenenwnwnwwseeswneewsenese",
|
||||
"neswnwewnwnwseenwseesewsenwsweewe",
|
||||
"wseweeenwnesenwwwswnew",
|
||||
):
|
||||
p = directions_to_point(line)
|
||||
print(f"Parsed point {p}")
|
||||
if p in seen:
|
||||
print("seen!")
|
||||
seen.add(p)
|
||||
floor.get_point(p, expand=True).flip()
|
||||
|
||||
black = count_black(floor.iter_items())
|
||||
print("Day 0")
|
||||
print(f"Number black is {black}")
|
||||
|
||||
for day in range(100):
|
||||
floor.expand_all(1)
|
||||
floor.true_up()
|
||||
floor.tick()
|
||||
floor.tock()
|
||||
black = count_black(floor.iter_items())
|
||||
total = sum(map(lambda x: 1, floor.iter_items()))
|
||||
print(f"Day {day+1}: {black} / {total}")
|
||||
|
||||
|
||||
def part1():
|
||||
floor = Floor()
|
||||
with open("input.txt") as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
p = directions_to_point(line)
|
||||
floor.get_point(p, expand=True).flip()
|
||||
|
||||
black = count_black(floor.iter_items())
|
||||
print(f"Number black is {black}")
|
||||
|
||||
|
||||
def part2():
|
||||
floor = Floor()
|
||||
with open("input.txt") as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
p = directions_to_point(line)
|
||||
floor.get_point(p, expand=True).flip()
|
||||
|
||||
black = count_black(floor.iter_items())
|
||||
print("Day 0")
|
||||
print(f"Number black is {black}")
|
||||
|
||||
for day in range(1, 11):
|
||||
floor.tick()
|
||||
floor.tock()
|
||||
black = count_black(floor.iter_items())
|
||||
print(f"Day {day}: {black}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sample()
|
||||
# part1()
|
||||
# part2()
|
136
d24/main2.py
Executable file
136
d24/main2.py
Executable file
@ -0,0 +1,136 @@
|
||||
#! /usr/bin/env python3
|
||||
from typing import Iterable
|
||||
# from typing import Tuple
|
||||
from typing import Set
|
||||
from typing import Dict
|
||||
# from typing import Optional
|
||||
|
||||
import itertools
|
||||
from collections import Counter
|
||||
from collections import namedtuple
|
||||
|
||||
|
||||
Point = namedtuple("Point", "x y")
|
||||
|
||||
D2P = {
|
||||
"se": Point(1, -1),
|
||||
"sw": Point(-1, -1),
|
||||
"ne": Point(1, 1),
|
||||
"nw": Point(-1, 1),
|
||||
"w": Point(-2, 0),
|
||||
"e": Point(2, 0),
|
||||
}
|
||||
|
||||
|
||||
def directions_to_point(s: str) -> Point:
|
||||
point = Point(0, 0)
|
||||
direction = ""
|
||||
for c in s:
|
||||
direction += c
|
||||
if direction in D2P:
|
||||
point = add_points(point, D2P[direction])
|
||||
direction = ""
|
||||
|
||||
if direction != "":
|
||||
raise ValueError("Something left over unexpectedly")
|
||||
|
||||
return point
|
||||
|
||||
|
||||
def add_points(p1, p2) -> Point:
|
||||
return Point(
|
||||
p1.x + p2.x,
|
||||
p1.y + p2.y,
|
||||
)
|
||||
|
||||
|
||||
def neighbors(point: Point) -> Iterable[Point]:
|
||||
for diff in D2P.values():
|
||||
yield add_points(point, diff)
|
||||
|
||||
|
||||
def neighbor_counts(points: Set[Point]) -> Dict[Point, int]:
|
||||
# return {
|
||||
# p: sum(map(lambda x: 1 if x in points else 0, neighbors(p)))
|
||||
# for p in points
|
||||
# }
|
||||
return Counter(itertools.chain.from_iterable(map(neighbors, points)))
|
||||
|
||||
|
||||
def next_generation(points: Set[Point]):
|
||||
counts = neighbor_counts(points)
|
||||
return (
|
||||
{p for p in points if counts[p] in (1, 2)} |
|
||||
{p for p in counts if p not in points and counts[p] == 2}
|
||||
)
|
||||
|
||||
|
||||
def point_deltas() -> Iterable[Point]:
|
||||
return D2P.values()
|
||||
|
||||
|
||||
def life(points: Set[Point], n: int) -> Set[Point]:
|
||||
for r in range(n):
|
||||
points = next_generation(points)
|
||||
|
||||
return points
|
||||
|
||||
|
||||
def sample():
|
||||
black: Set[Point] = set()
|
||||
for line in (
|
||||
"sesenwnenenewseeswwswswwnenewsewsw",
|
||||
"neeenesenwnwwswnenewnwwsewnenwseswesw",
|
||||
"seswneswswsenwwnwse",
|
||||
"nwnwneseeswswnenewneswwnewseswneseene",
|
||||
"swweswneswnenwsewnwneneseenw",
|
||||
"eesenwseswswnenwswnwnwsewwnwsene",
|
||||
"sewnenenenesenwsewnenwwwse",
|
||||
"wenwwweseeeweswwwnwwe",
|
||||
"wsweesenenewnwwnwsenewsenwwsesesenwne",
|
||||
"neeswseenwwswnwswswnw",
|
||||
"nenwswwsewswnenenewsenwsenwnesesenew",
|
||||
"enewnwewneswsewnwswenweswnenwsenwsw",
|
||||
"sweneswneswneneenwnewenewwneswswnese",
|
||||
"swwesenesewenwneswnwwneseswwne",
|
||||
"enesenwswwswneneswsenwnewswseenwsese",
|
||||
"wnwnesenesenenwwnenwsewesewsesesew",
|
||||
"nenewswnwewswnenesenwnesewesw",
|
||||
"eneswnwswnwsenenwnwnwwseeswneewsenese",
|
||||
"neswnwewnwnwseenwseesewsenwsweewe",
|
||||
"wseweeenwnesenwwwswnew",
|
||||
):
|
||||
p = directions_to_point(line)
|
||||
if p in black:
|
||||
black.remove(p)
|
||||
else:
|
||||
black.add(p)
|
||||
|
||||
print(f"Num black is {len(black)}")
|
||||
|
||||
rounds = 100
|
||||
black = life(black, rounds)
|
||||
print(f"Num black after {rounds} is {len(black)}")
|
||||
|
||||
|
||||
def part2():
|
||||
black: Set[Point] = set()
|
||||
with open("input.txt") as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
p = directions_to_point(line)
|
||||
if p in black:
|
||||
black.remove(p)
|
||||
else:
|
||||
black.add(p)
|
||||
|
||||
print(f"Num black is {len(black)}")
|
||||
|
||||
rounds = 100
|
||||
black = life(black, rounds)
|
||||
print(f"Num black after {rounds} is {len(black)}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# sample()
|
||||
part2()
|
14
main.go
Normal file
14
main.go
Normal file
@ -0,0 +1,14 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
wm := NewLinkedGrid(5, 5)
|
||||
wm.Print()
|
||||
|
||||
a := []int{1, 2, 3, 4}
|
||||
_ = MapInt(a, func(v int) (int, error) { return v * 2, nil })
|
||||
fmt.Println(a)
|
||||
r, _ := ReduceInt(a, 0, func(t, v int) (int, error) { return t + v, nil })
|
||||
fmt.Println(r)
|
||||
}
|
300
util.go
Normal file
300
util.go
Normal file
@ -0,0 +1,300 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"os"
|
||||
)
|
||||
|
||||
var (
|
||||
errItemAlreadySet = errors.New("cannot set item in direction as one is already set")
|
||||
)
|
||||
|
||||
// ProcessLines maps a function on lines parsed from a file.
|
||||
func ProcessLines(path string, f func(string) (stop bool, err error)) error {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
scanner := bufio.NewScanner(file)
|
||||
for scanner.Scan() {
|
||||
stop, err := f(scanner.Text())
|
||||
if stop || err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ProcessGroups maps a function on groups of lines parsed from a file separated by some string.
|
||||
func ProcessGroups(path, separator string, f func([]string) (stop bool, err error)) error {
|
||||
group := []string{}
|
||||
|
||||
if err := ProcessLines(path, func(line string) (stop bool, err error) {
|
||||
if line == separator {
|
||||
stop, err = f(group)
|
||||
if stop || err != nil {
|
||||
return
|
||||
}
|
||||
group = []string{}
|
||||
} else {
|
||||
group = append(group, line)
|
||||
}
|
||||
|
||||
return
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err := f(group)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// StringSet is a set of strings..
|
||||
type StringSet map[string]bool
|
||||
|
||||
// Add an item to a StringSet.
|
||||
func (s *StringSet) Add(v string) {
|
||||
(*s)[v] = true
|
||||
}
|
||||
|
||||
// AddAll adds all items in a list to the set.
|
||||
func (s *StringSet) AddAll(l []string) {
|
||||
for _, v := range l {
|
||||
s.Add(v)
|
||||
}
|
||||
}
|
||||
|
||||
// Items returns all values in the set as a list.
|
||||
func (s StringSet) Items() []string {
|
||||
values := []string{}
|
||||
for k := range s {
|
||||
values = append(values, k)
|
||||
}
|
||||
|
||||
return values
|
||||
}
|
||||
|
||||
// NewStringSet creates an empty string set.
|
||||
func NewStringSet(values []string) StringSet {
|
||||
v := StringSet{}
|
||||
v.AddAll(values)
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
// Union returns the union of two SringSets.
|
||||
func Union(s1, s2 StringSet) StringSet {
|
||||
union := NewStringSet(s1.Items())
|
||||
union.AddAll(s2.Items())
|
||||
|
||||
return union
|
||||
}
|
||||
|
||||
// Intersection returns the union of two SringSets.
|
||||
func Intersection(s1, s2 StringSet) StringSet {
|
||||
intersect := StringSet{}
|
||||
|
||||
for v := range s1 {
|
||||
if _, ok := s2[v]; ok {
|
||||
intersect.Add(v)
|
||||
}
|
||||
}
|
||||
|
||||
return intersect
|
||||
}
|
||||
|
||||
// Difference returns the value of s1 with values of s2 removed.
|
||||
func Difference(s1, s2 StringSet) StringSet {
|
||||
difference := StringSet{}
|
||||
|
||||
for v := range s1 {
|
||||
if _, ok := s2[v]; !ok {
|
||||
difference.Add(v)
|
||||
}
|
||||
}
|
||||
|
||||
return difference
|
||||
}
|
||||
|
||||
// Point represents a point on a coordinate system.
|
||||
type Point struct {
|
||||
x, y int
|
||||
}
|
||||
|
||||
// AddPoints adds two points together.
|
||||
func AddPoints(p1, p2 Point) Point {
|
||||
return Point{
|
||||
p1.x + p2.x,
|
||||
p1.y + p2.y,
|
||||
}
|
||||
}
|
||||
|
||||
// PowInt is equivalent to math.Pow but for integers.
|
||||
func PowInt(x, y int) int {
|
||||
return int(math.Pow(float64(x), float64(y)))
|
||||
}
|
||||
|
||||
// LinkedGridItem is a single item in a linked grid.
|
||||
type LinkedGridItem struct {
|
||||
location Point
|
||||
left, right, up, down *LinkedGridItem
|
||||
grid *LinkedGrid
|
||||
}
|
||||
|
||||
func (item LinkedGridItem) String() string {
|
||||
return fmt.Sprintf("%v", item.location)
|
||||
}
|
||||
|
||||
// Location of the item.
|
||||
func (item LinkedGridItem) Location() Point {
|
||||
return item.location
|
||||
}
|
||||
|
||||
// Left gives a pointer to the item on the left.
|
||||
func (item LinkedGridItem) Left() *LinkedGridItem {
|
||||
return item.left
|
||||
}
|
||||
|
||||
// Up gives a pointer to the item above.
|
||||
func (item LinkedGridItem) Up() *LinkedGridItem {
|
||||
return item.up
|
||||
}
|
||||
|
||||
// Right gives a pointer to the item on the right.
|
||||
func (item LinkedGridItem) Right() *LinkedGridItem {
|
||||
return item.right
|
||||
}
|
||||
|
||||
// Down gives a pointer to the item below.
|
||||
func (item LinkedGridItem) Down() *LinkedGridItem {
|
||||
return item.down
|
||||
}
|
||||
|
||||
// SetLeft gives a pointer to the item on the left.
|
||||
func (item *LinkedGridItem) SetLeft(other *LinkedGridItem) error {
|
||||
if item.left != nil || other.right != nil {
|
||||
return errItemAlreadySet
|
||||
}
|
||||
|
||||
item.left = other
|
||||
other.right = item
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetUp gives a pointer to the item on the up.
|
||||
func (item *LinkedGridItem) SetUp(other *LinkedGridItem) error {
|
||||
if item.up != nil || other.down != nil {
|
||||
return errItemAlreadySet
|
||||
}
|
||||
|
||||
item.up = other
|
||||
other.down = item
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetRight gives a pointer to the item on the right.
|
||||
func (item *LinkedGridItem) SetRight(other *LinkedGridItem) error {
|
||||
if item.right != nil || other.left != nil {
|
||||
return errItemAlreadySet
|
||||
}
|
||||
|
||||
item.right = other
|
||||
other.left = item
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetDown gives a pointer to the item on the down.
|
||||
func (item *LinkedGridItem) SetDown(other *LinkedGridItem) error {
|
||||
if item.down != nil || other.up != nil {
|
||||
return errItemAlreadySet
|
||||
}
|
||||
|
||||
item.down = other
|
||||
other.up = item
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// LinkedGrid is a 2d array of grid square.
|
||||
type LinkedGrid [][]*LinkedGridItem
|
||||
|
||||
// Print a linked grid.
|
||||
func (grid LinkedGrid) Print() {
|
||||
for _, row := range grid {
|
||||
for _, item := range row {
|
||||
fmt.Print(item.String())
|
||||
}
|
||||
|
||||
fmt.Print("\n")
|
||||
}
|
||||
}
|
||||
|
||||
// NewLinkedGrid initializes a new linked grid of a given size.
|
||||
func NewLinkedGrid(width, height int) *LinkedGrid {
|
||||
|
||||
var w = make(LinkedGrid, height)
|
||||
|
||||
for y := 0; y < height; y++ {
|
||||
w[y] = make([]*LinkedGridItem, width)
|
||||
|
||||
for x := 0; x < height; x++ {
|
||||
item := LinkedGridItem{location: Point{x, y}}
|
||||
|
||||
if x != 0 {
|
||||
_ = item.SetLeft(w[y][x-1])
|
||||
}
|
||||
|
||||
if y != 0 {
|
||||
_ = item.SetUp(w[y-1][x])
|
||||
}
|
||||
|
||||
w[y][x] = &item
|
||||
}
|
||||
}
|
||||
|
||||
return &w
|
||||
}
|
||||
|
||||
// MapInt maps a function onto a list of ints.
|
||||
func MapInt(a []int, f func(int) (int, error)) error {
|
||||
var err error
|
||||
|
||||
for i, v := range a {
|
||||
a[i], err = f(v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ReduceInt maps a function onto a list of ints.
|
||||
func ReduceInt(a []int, start int, f func(int, int) (int, error)) (int, error) {
|
||||
var err error
|
||||
|
||||
result := start
|
||||
|
||||
for _, v := range a {
|
||||
result, err = f(result, v)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
Loading…
Reference in New Issue
Block a user