diff --git a/2020/20/example b/2020/20/example new file mode 100644 index 0000000..b07aa4b --- /dev/null +++ b/2020/20/example @@ -0,0 +1,107 @@ +Tile 2311: +..##.#..#. +##..#..... +#...##..#. +####.#...# +##.##.###. +##...#.### +.#.#.#..## +..#....#.. +###...#.#. +..###..### + +Tile 1951: +#.##...##. +#.####...# +.....#..## +#...###### +.##.#....# +.###.##### +###.##.##. +.###....#. +..#.#..#.# +#...##.#.. + +Tile 1171: +####...##. +#..##.#..# +##.#..#.#. +.###.####. +..###.#### +.##....##. +.#...####. +#.##.####. +####..#... +.....##... + +Tile 1427: +###.##.#.. +.#..#.##.. +.#.##.#..# +#.#.#.##.# +....#...## +...##..##. +...#.##### +.#.####.#. +..#..###.# +..##.#..#. + +Tile 1489: +##.#.#.... +..##...#.. +.##..##... +..#...#... +#####...#. +#..#.#.#.# +...#.#.#.. +##.#...##. +..##.##.## +###.##.#.. + +Tile 2473: +#....####. +#..#.##... +#.##..#... +######.#.# +.#...#.#.# +.######### +.###.#..#. +########.# +##...##.#. +..###.#.#. + +Tile 2971: +..#.#....# +#...###... +#.#.###... +##.##..#.. +.#####..## +.#..####.# +#..#.#..#. +..####.### +..#.#.###. +...#.#.#.# + +Tile 2729: +...#.#.#.# +####.#.... +..#.#..... +....#..#.# +.##..##.#. +.#.####... +####.#.#.. +##.####... +##..#.##.. +#.##...##. + +Tile 3079: +#.#.#####. +.#..###### +..#....... +######.... +####.#..#. +.#...#.##. +#.#####.## +..#.###... +..#....... +..#.###... diff --git a/2020/20/input b/2020/20/input new file mode 100644 index 0000000..e93c317 --- /dev/null +++ b/2020/20/input @@ -0,0 +1,1728 @@ +Tile 2129: +.#.#..##.. +..#..#.... +.......... +...###..#. +..#....... +#...#...## +#...#..... +#...#.#... +##.......# +.#..###..# + +Tile 2861: +##..##.### +#..#...... +.#...#.... +#.#....#.. +....#.#... +.#......## +#.#..#.#.# +........#. +#......... +..#..###.# + +Tile 1789: +#...##..## +...#.##... +#.....#... +....#..... +.#...#.... +.....#..## +....#..#.# +.....##..# +.........# +##.#...##. + +Tile 2371: +..##.##..# +..#.##.... +.......... +#..##..#.. +....##.#.. +....#...#. +...#.##... +...##....# +#..#.#.... +##.#.##..# + +Tile 3613: +#######..# +#........# +.#......## +#...#..... +...##....# +#.#..#..#. +##.......# +#.#.#..#.# +.##..#..#. +##..###### + +Tile 1697: +.##..##### +........#. +..##...... +....#.#..# +#...#.#..# +#..##..#.# +#......#.# +..#......# +#..#.....# +.#.#.#.#.. + +Tile 1607: +#.#...#..# +#.#.##...# +.#..#..... +##........ +#......... +.....#.### +...#...#.# +#......#.# +........#. +##.#.####. + +Tile 1657: +#.#.#....# +..####...# +##........ +.#.....#.. +#..#...... +##.##...#. +.##..#..## +#.#.##...# +#....##... +...#...#.. + +Tile 1249: +.#.#...... +.#.......# +#..#....## +#..###.#.# +##.....#.. +.##......# +.......... +.##...##.. +..#....#.# +.#..####.# + +Tile 1223: +#....#..#. +..#....#.# +..#.#..#.# +#.#.....#. +#........# +#....#..#. +#.....#... +#......... +####...... +#...###.## + +Tile 1373: +.....##.## +#..#....## +#......... +##...#.... +.#.......# +...##..... +..#......# +#.......#. +.......... +##.##.#.#. + +Tile 1109: +.#.###.... +#........# +#.#..#...# +.........# +#........# +.#..#....# +#.##...... +....#.##.# +...###..#. +...#.##.## + +Tile 3607: +##.#...### +#.......#. +.#.##.#... +....##..#. +..#...#..# +.....#..## +.....###.. +##..#.#... +.##....... +.#...###.. + +Tile 2309: +.##.#...## +..#..#...# +##...#.#.. +#........# +#........# +.#..#..... +.....#.#.. +#...#....# +........## +##...##.## + +Tile 3041: +.#..#.#### +#.#.....## +..#....#.# +#.......## +#......#.# +.#.......# +##...#.... +##..#...## +##...#...# +..#.##.... + +Tile 1427: +.##..###.. +.....###.# +#......... +.........# +#.#..##..# +###..##.#. +##....##.. +#........# +....#....# +####..##.# + +Tile 3461: +.#.####... +.......... +.......#.# +........#. +#......... +..#......# +#....#...# +.#.......# +......#... +..###..... + +Tile 1327: +#..#####.. +#....#.... +#..#...... +....##..## +.......#.# +##....#... +###....... +........#. +..##.....# +..#..#.#.. + +Tile 1289: +.#.##..##. +#..#...... +.......#.# +...#.#.... +#.##...#.# +##..#...## +##.......# +...#....#. +####..#... +#...#.###. + +Tile 2857: +##.#####.# +.........# +.#.##..#.. +###..#.... +##....#... +...#.#.#.# +#.......#. +##.##....# +#...##.##. +###.##..## + +Tile 3823: +#......... +..#....... +...#...... +#......... +#...##.#.# +..##.#.... +..##.....# +.#..#.#... +#...#....# +.###...#.. + +Tile 3557: +.##.#.##.# +#..#.#..## +....###.## +##...#..#. +#...#.#..# +#...###..# +#...#..#.. +.##.#..#.. +###..#.... +##..##..#. + +Tile 2713: +...##.###. +#......... +.........# +..##...#.. +.....#...# +.......##. +...#...... +#.#....#.. +#.#....... +.#....###. + +Tile 1213: +.##..#.##. +#.#....... +........#. +.....##... +....#....# +#....#.### +...##....# +#.#...#..# +#...##...# +.###..##.. + +Tile 2341: +.#######.. +..#....##. +####...#.. +.###.....# +#....#..#. +...#...##. +....##...# +#........# +#..#.....# +.#.#..##.. + +Tile 3467: +....#..##. +....##.#.# +....##...# +##..###... +...#...... +#......#.. +#.....#..# +....###..# +#....#.... +..#.#.#.#. + +Tile 1583: +.#.#.#.#.# +.#.#...... +#...#..... +...###.#.# +##........ +#..#...#.# +#...#....# +....#..... +#....##... +##..###### + +Tile 1087: +###.#.#..# +#.#....... +#.#......# +##........ +.#.#...#.# +#........# +#.#......# +#......##. +.....#.... +.##.#.#.## + +Tile 3691: +###.#..... +#.#..#...# +.....##..# +#..#.##... +#........# +#.##.....# +.##.#....# +#........# +##......#. +#.##.###.. + +Tile 3881: +#.#..##... +#..#.....# +..#.#....# +###......# +#..##....# +....#..#.# +##....#.#. +.#.#....## +###....... +#...##.##. + +Tile 1033: +...#.##..# +#.##...#.. +......#.#. +..####.... +....#..#.. +#........# +..#..#...# +...#...... +##...#.#.# +##.##.#### + +Tile 3361: +..##.#.... +.........# +..##...... +....##...# +##....#..# +...#....#. +.##......# +###......# +..#..#...# +.....##..# + +Tile 1459: +#.#.##..#. +........#. +...#...#.. +.#........ +..#.#....# +#...###..# +#.#..##..# +#..#.#...# +...##..... +##.#...##. + +Tile 3833: +.#..####.# +..#.#....# +###.####.# +..#..#..## +#......... +#.......#. +.......... +......#.#. +#....#.... +##......#. + +Tile 3779: +..###...## +......#... +.....###.. +####.....# +.......#.# +....#.#... +....##.#.. +#...#....# +#...#....# +.#..#..... + +Tile 2333: +...###.### +#..#...... +.........# +#.#......# +#..#..#.#. +###....### +#.#....... +#.....#..# +.......#.# +.#..#...## + +Tile 2099: +#..##.#..# +#......... +#........# +..#......# +#......... +#..##.##.# +#..##...#. +...###.... +....#.#..# +.....#.##. + +Tile 1801: +####.###.# +#..#.....# +#......#.# +.......... +.....#..#. +..#...#... +.........# +#...#..... +.#.....#.# +#....##.#. + +Tile 2237: +##..##.#.. +..#.#..#.. +...#..#..# +.....#...# +..#....#.# +...##.##.. +#......#.. +......#### +......###. +.#.##.###. + +Tile 2357: +...#.###.# +#..#.#...# +#..#..#... +##......#. +.......... +#..##....# +..#..##... +#....#...# +#....#.... +.#..#..##. + +Tile 1597: +..#.###..# +...#...... +#...#..... +...#.#.#.. +#....#.... +#....#.... +.....#.#.. +#..#..#.#. +#....#...# +.#...##.## + +Tile 3229: +#.......## +#......... +#...###..# +..#.#..... +.......... +.#.#.....# +#.#..#.### +.......#.. +#...#....# +..#.##.### + +Tile 2609: +...#.#.##. +..##...... +#.#......# +#....#.#.# +#...#.#... +..##...##. +#..#...#.. +.#.#.#..## +#.##.....# +...###.... + +Tile 2719: +#..#.#.### +##.#....#. +......##.# +.##.#..... +.##...##.# +###...#... +.........# +.......... +....##.... +######.##. + +Tile 3407: +..#.###### +.........# +#......#.# +#........# +#......... +#.#......# +#.....#..# +.........# +.#.#...... +..###.###. + +Tile 1063: +.####.###. +#..#.....# +#..#...#.# +.........# +#......#.. +#......... +..#..#...# +.#..#.#..# +...#.##... +#.##.....# + +Tile 2111: +.#.####### +..##...#.. +.#.#...... +...##..... +##.......# +.##...#..# +#........# +#.#.#.#... +#......... +#.#..####. + +Tile 1499: +..#..###.# +.#.....#.# +.........# +##....#.#. +..#.##..## +##.#..#..# +....##.... +........#. +#......... +.###.##.## + +Tile 1283: +#...##..#. +......#.## +.....##... +..#....#.. +......#..# +#........# +....#....# +##........ +.#......## +.#..##.#.. + +Tile 3499: +...#.#.#.# +..#......# +#...##...# +#...#....# +...###.#.# +.#.#..#..# +#.....##.. +..#.#..#.# +.#.##..#.. +##....#... + +Tile 2251: +##.##..... +###..#...# +#.....#... +....#..#.. +#..#..#... +........#. +......#... +#.#.#....# +#....#.... +#.##.#...# + +Tile 2819: +..#...#..# +.#.#.##... +.#..##.... +##...#.#.. +##.......# +........#. +#..#..#... +.#...#.#.# +......#... +...###...# + +Tile 2711: +.......#.# +#..#.##..# +....#.#... +.......... +.......... +#....#.... +#..##....# +#....#.... +#......... +.######### + +Tile 2423: +#....####. +....#.#..# +....#.#### +..#.....## +##.......# +##..#.#..# +...#.....# +#.....#... +.##...#..# +#.##.#.... + +Tile 3907: +..#..#.#.. +##.......# +....##.... +#....##..# +.......#.. +#....#.#.. +##.......# +###....##. +#....#..#. +#..##.#... + +Tile 3929: +##.##.###. +...#..#.## +....#..... +#.#..#...# +.#......## +.....#.... +....#..##. +.#........ +..##.....# +.#..#..... + +Tile 1879: +..#.###..# +##...#.#.. +#........# +##.......# +#........# +....#...#. +#.......## +#..##....# +........## +##.###.### + +Tile 1951: +#...###.#. +#..###...# +#......#.. +#.#.....#. +#.##.....# +...###.... +.#.#....#. +.........# +.#.#...... +.##.#.#..# + +Tile 2503: +#.#..##... +#.....##.# +#......... +..###...#. +#.#.#....# +###...#... +.##..#...# +...#...... +###..#...# +.....#.#.. + +Tile 3539: +.####.#.## +....##.#.# +#.......#. +.#.#.#..## +.#.#.....# +#...##..#. +...#.#.... +...#...##. +##..#.##.# +.#####..#. + +Tile 2039: +.##.#...## +....#....# +...#.....# +.......#.# +..##..#... +.........# +##........ +#......#.. +.#...#.... +.##.#..##. + +Tile 2243: +..####.... +#....#...# +#........# +#...##...# +#.#...#... +#......... +##..#....# +...#...... +#........# +.##....#.# + +Tile 1103: +##..###.#. +...#..#..# +#...#..... +...#.#...# +.##..#..## +....#.#..# +#..##....# +#.......#. +#...#....# +.#..#..### + +Tile 2693: +.#..##...# +#....#...# +..#....... +.........# +#.####.#.. +#.....#... +....#..##. +......#..# +....#..#.. +....##...# + +Tile 2971: +#..#..##.. +#......... +#...#..... +...#...... +...#..#..# +.#.......# +#...#..#.. +#.##.....# +......#... +.#.####... + +Tile 1483: +.##.###..# +#......##. +..#.#..... +#...#..#.# +#..#....## +..##.##.## +.#.#..#### +#.....##.. +..#....... +..###..##. + +Tile 3583: +###.#....# +.....#.... +#...###... +#.....#... +......#.## +.......... +.........# +##........ +....#.#... +.##.##.#.. + +Tile 2179: +##.....### +....#..... +#......... +##.....#.# +##.......# +.####..... +#...#.#.#. +...#...... +.....#.... +....#...## + +Tile 1567: +#.######.. +###....... +.......... +.....#.#.. +#..#...... +.......#.# +........#. +......#.#. +.......... +#..#.####. + +Tile 3851: +..###..#.# +.##..#..## +#..###.#.. +..##..##.# +###....... +.......#.. +#.###.#... +#..#....#. +##.##..#.# +##..####.# + +Tile 3343: +##.##...## +....#..... +.......#.# +.....#..#. +#...##.#.# +.......##. +#..#.....# +...#...... +.........# +.####.##.# + +Tile 3319: +#.#....... +..#....#.. +....#...#. +.##......# +.....#.... +..#.#..... +#...#...#. +#.#...#..# +###....... +#..##..... + +Tile 3947: +.#..#..##. +.##....... +##....#... +.#.#...... +..#.#.#..# +.....#...# +......#... +..#.#.#### +#...#....# +.#.##..#.. + +Tile 1559: +.....#...# +##....#... +##......## +#.###..### +##..#..... +##.......# +...###.#.# +#.......#. +..##....#. +##..####.# + +Tile 2063: +#.#..#.#.. +...#.....# +#........# +.#.#....## +#.#.#....# +......#..# +#..##....# +.##...#... +##...#.... +.#.##..##. + +Tile 3163: +..##.#.##. +....#.#... +#......... +#..###...# +#..#..#..# +#..#....## +#......#.# +.....#.... +#..#....#. +##..#.##.# + +Tile 3659: +.#....#..# +##.......# +#.....#... +#..#.....# +#.#......# +###.#..### +##...##### +.#....##.# +#.#....#.. +####.##.#. + +Tile 1229: +....###... +...#.#...# +....#....# +.......### +......#.## +#....###.. +#......#.# +......#..# +#..#...#.. +.......#.. + +Tile 1433: +.###.....# +....#.#... +##....#..# +.....#.#.# +.......... +.##...#..# +#.#..#.... +#....##... +.....###.# +....####.# + +Tile 1487: +.##.###.## +####..#.## +###..#.... +....#..... +.......... +##.#...#.# +..#...#..# +#.#....... +.##..#...# +...##.#... + +Tile 2939: +.#....###. +##........ +##........ +##......#. +.#........ +.#.##..#.. +.#.#.##..# +.......... +...#...... +#..###.##. + +Tile 2753: +###.#...## +##....#... +##.#.#...# +#.....#..# +.........# +##.......# +#........# +#.#.#..#.. +#....#..## +.###..##.# + +Tile 1429: +..##....#. +......#..# +#.#..##... +#.......## +#......... +#.....#... +....#.#.## +#...#..... +#......#.. +...#.#.#.. + +Tile 3371: +.#........ +.........# +#........# +#.###.#..# +....###..# +.##.##.#.. +###.##.... +##....#.#. +...##....# +#.#.##.##. + +Tile 1973: +..##.#.... +...#...#.. +.###..#.## +.#.#.....# +#...#..... +..#..#.#.# +##...#.#.. +....#..#.# +#.##...#.# +#.####.#.. + +Tile 3967: +..#..#.##. +#..#..#... +##..#....# +.##.....#. +...#.....# +..#.#....# +........## +#..##..#.. +.......... +#..##.###. + +Tile 2207: +.##...###. +#...#.##.. +....#..#.# +.......... +##..#..... +.......... +#..#.....# +#.....#..# +.........# +#.#..#.#.. + +Tile 1669: +....#..#.# +...#...#.# +#..#...#.. +#.....#..# +#.##.#.... +...#....## +#......... +#......... +.........# +###....#.# + +Tile 1361: +#....#..## +.......#.# +#...#.#... +.........# +##..#.#.## +.........# +..#..##... +#....#.... +....##.... +..#..#.### + +Tile 2851: +##..#...## +##.#....#. +##.....### +.#.##..... +...##....# +#...##...# +##..#...## +.......#.# +#.#...#.#. +.##.##.... + +Tile 1217: +...#.#.#.. +#.#..#.#.# +#......#.. +.#..##..#. +#..#...... +##..#....# +#..##...#. +#..#...#.. +.#.....#.# +#..##.##.# + +Tile 3631: +......#### +#...#.#.## +......##.. +...#..#.#. +#......#.# +.#.#...#.# +#...##...# +#......#.. +#......#.. +...##..#.. + +Tile 3571: +#....#.#.. +#.....#... +......#.#. +.......... +#...#..... +.#....#... +..##.###.. +#.##....## +#......... +.......##. + +Tile 3067: +##........ +.........# +#...#..... +...#....## +#........# +##.......# +#.....#..# +#......... +...#..#... +##.....#.# + +Tile 2069: +.#.##..... +#......### +..#.##...# +.##..#.... +#.....###. +#.#...##.# +........#. +#......... +.......... +..#.#.##.. + +Tile 2551: +##.#.##... +....##..#. +......#... +#......... +..#..#...# +......#... +...#.##.## +...#...#.. +#......#.. +#..#.###.. + +Tile 1747: +##.#...... +#....#.#.# +....#....# +....#..#.. +#..#...#.# +#....#.... +#......... +#.#...##.. +.......#.. +..######.# + +Tile 2017: +.#####.... +##.##.##.# +.........# +#.##.....# +#.....#.#. +......#.## +#.##...... +#.....#..# +....#.#... +.#.#.###.. + +Tile 2789: +..#.....## +##.....#.# +#.....##.. +#.#...#... +.......#.# +.#.#...#.# +.#.......# +##.....#.# +#.#..##... +#######... + +Tile 2477: +####.##.## +.##....... +#.#....#.. +#.#....#.. +#..##..#.# +##...##... +#....#.... +......#... +.......... +#####..##. + +Tile 3299: +#.##..#### +.......#.# +#.###..#.# +#.#..##.#. +##.#..##.. +.......#.. +#......... +....#.#... +#..##.#... +.##...#..# + +Tile 3169: +#...##.### +#.....##.# +#.#.#..#.# +#.......#. +#...#..... +.#...#.... +#.#....... +#...#..... +..#...#..# +...##.#..# + +Tile 2887: +#.#..#...# +.#...##.#. +#......#.# +#.....##.# +#.....##.# +#........# +.......... +....#...## +.....#.#.. +#...#.##.# + +Tile 3917: +#....#.#.# +.##..##.#. +##....##.. +#.##.....# +....#..... +#...#.#... +........## +##...#.... +.......... +##..#.#... + +Tile 3761: +...#.##.## +.....##..# +#.....##.# +...#..#..# +####...##. +.........# +#.#..#.... +#######.## +#......#.. +..##...... + +Tile 1511: +##.#.##.## +....#....# +..##....## +##.##..#.. +....###.#. +#..###...# +.#........ +#..#.#.... +....#..... +.###.#.##. + +Tile 3023: +.#.###.#.. +.....#...# +.......#.. +.#..#....# +....###..# +###.#..### +.......... +#......... +#.....#..# +..###.#.## + +Tile 3221: +.......##. +##..#.#..# +...#...... +#......... +#...#.#... +#..#.#...# +.###....#. +.#..#..#.# +.###.#..#. +###.##.... + +Tile 1009: +.#.#....## +.#...#.... +..#.##...# +..##...##. +#..#...... +...####..# +.......... +.#.###.#.. +...##....# +...####### + +Tile 1931: +..##.##### +.....#.... +#..##..... +#.#.....## +#####..#.. +.....#.... +.#........ +#.......#. +#.....#... +##..##.... + +Tile 1783: +#..##.#### +....#..#.# +...#...#.. +......#... +...##..... +...##....# +#...##..#. +##..##.... +...#...#.. +#..#.#.#.. + +Tile 1129: +..#.#..### +##........ +.#..#.#.## +....##...# +.......#.# +#.#.###... +.....#..## +..#..#.... +#.#.....## +..#..#.### + +Tile 1051: +.######.## +.#..#...## +.#....#### +.......#.# +.....#..#. +......#... +#...#.##.. +.##....... +#......... +..###.#..# + +Tile 1693: +.##.##.### +.......... +.....#.... +#....#.#.. +#.....#... +#...#.##.# +#.#..#...# +#.#.#.#..# +.##....... +..##.##..# + +Tile 3719: +...##..#.. +#...#..... +...#.#..## +.#..##...# +.....#..#. +#......... +...#.#.##. +...#..#..# +......##.. +.#.....##. + +Tile 1493: +##..#...## +....#..#.# +#..#....#. +#.##.#.### +###.#.#... +.###.#...# +#..#.#..#. +.....##... +#.#...#..# +...#..###. + +Tile 1013: +.##.###.## +.......... +....#..#.# +........## +....#..#.. +#.##.##.#. +#......... +#.##..##.# +#......#.. +.#####..#. + +Tile 2087: +...######. +#...###.## +#.#....... +.......... +#.....#.#. +..#..#...# +.....#...# +#....#.... +.#...#.##. +....#.##.# + +Tile 1201: +##...#..#. +.....#..## +.........# +..#...#... +.....#.### +#..#..#... +.....#.#.# +.#........ +#...##..#. +..#.#.##.# + +Tile 1877: +...###..#. +#..###...# +...#...#.# +#......### +.#........ +#.......#. +#......... +.#..#....# +#.#..##..# +##.#.###.. + +Tile 3697: +..#..#.... +.........# +#..#.#.... +#.##..#..# +.##..#.#.# +...#..#..# +.......#.. +..##.....# +#........# +#.##..#... + +Tile 1187: +#...####.# +#........# +...#..#.## +.........# +#........# +#..#..#..# +.........# +##.....##. +#.#....#.# +.##.#...#. + +Tile 1303: +##..##.##. +.......... +#.....#... +...##....# +....#..... +.###.#.... +....##.... +.#..#...## +#....#...# +.#..#..### + +Tile 3109: +..##....#. +..#.#....# +....#..#.. +...##.#... +#...#..#.. +..#..#...# +.......#.# +#..#.###.. +..#.....#. +####...##. + +Tile 1553: +.#.#####.. +#...##.... +..#....#.. +#....#.#.. +#..#....#. +#.#.#.##.# +...##...## +#.....#..# +.........# +.##.#.##.# + +Tile 2797: +.#.##...## +#.......## +##...#...# +####.#.... +##.##...## +.....#.... +.....#.... +##..#...#. +...#....#. +##.##..### + +Tile 3301: +###...##.. +#.......#. +....#...#. +###.##.#.# +..##...### +#.....#... +##.......# +.#........ +...#.....# +#.###..#.# + +Tile 2707: +#.#.##...# +..###..... +.......... +..#.#.#..# +..#....##. +.......#.. +......#..# +.#..#..... +.#.....#.# +.#........ + +Tile 1409: +#..#..#.#. +#..#..#..# +.........# +......#..# +####..#.## +##..#..#.# +..#.#....# +.#......## +..#.#.#..# +#.###..#.# + +Tile 1297: +..##..##.# +...#.##... +...#####.. +....##...# +#.......#. +.#..#..... +#.#.#....# +..#....... +###....... +.#..###... + +Tile 2729: +..##.##.#. +#...#.#.## +#..#.#.##. +###...##.. +#.#....#.# +........## +#........# +#...#..### +.#....#... +.#...#.#.. + +Tile 3359: +##...#.#.. +...#...... +...#..#..# +##.......# +.......### +#...##.#.# +##.#..##.. +.#....#..# +.....#.... +.#.##.#..# + +Tile 1321: +..####..#. +#..##...#. +.........# +.........# +##..#.##.. +###..##.#. +...#.....# +.#....#..# +#..#.##..# +###...#... + +Tile 1307: +......#.## +...#.#..## +###.#.#... +..#...##.# +#..#...#.. +........#. +#...#..##. +#.....#### +...#.....# +###..###.# + +Tile 1949: +.#.####..# +#..##...#. +#......#.. +.......... +#...##.... +#.####..#. +#.....#... +......##.# +#...#...## +....#.#.## + +Tile 3637: +..#######. +#....#.#.. +#.....#..# +..#....... +........#. +.#......#. +#.....#..# +..##..#... +.#...#.... +#.#.....## + +Tile 1601: +##..##.... +.##......# +........## +#......... +#.#....... +##.#...... +..#.#....# +.......... +##...#.#.. +.#..#..#.. + +Tile 3389: +.###.#..## +#.......## +.#......#. +..###..... +....#....# +........## +#...#....# +.......#.. +...#...... +#.####.... + +Tile 3253: +##.###.#.. +#.#.....## +#......... +.......... +...#.....# +#........# +..#....#.# +#..#...... +....#....# +.#...#.### + +Tile 1933: +.#..#.#.## +........#. +..#..#.... +.....#...# +.......#.. +#.#..##..# +.........# +..#..#..#. +#.#......# +###..###.. + +Tile 3463: +......#... +###......# +...#.#.... +..#..##.#. +##....#... +#..#...#.. +.#....#.#. +###...#### +#..#.#.#.. +###..#.... + +Tile 1279: +.##..#..## +##.....#.# +....#..... +..#......# +#.#.#..... +.....#.... +..##...... +#.....##.# +...#...#.. +###..###.# + +Tile 3793: +...#..##.# +....#.##.. +..##....## +........## +.....#.... +........## +......#... +.........# +#......... +###..#.### + +Tile 2671: +##.#.#.#.# +#.##..#..# +#.##..###. +.........# +#..#.#.... +....##..#. +....##.#.. +.#.#...... +....#..#.# +.##.####.# + diff --git a/2020/20/solution1.js b/2020/20/solution1.js new file mode 100644 index 0000000..a7befe3 --- /dev/null +++ b/2020/20/solution1.js @@ -0,0 +1,63 @@ +const fs = require("fs"); + +const input = fs.readFileSync("input", "utf-8").trim(); + +const tiles = Object.fromEntries( + input + .split("\n\n") + .map((tile) => tile.split("\n")) + .map((line) => [line[0].match("[0-9]+")[0], line.slice(1)]) +); + +// console.log(tiles); + +const tileEdges = {}; + +for (const [id, tile] of Object.entries(tiles)) { + const n = tile[0]; + const w = tile.map((line) => line[0]).join(""); + const e = tile.map((line) => line[line.length - 1]).join(""); + const s = tile[tile.length - 1]; + tileEdges[id] = [n, w, e, s]; +} + +// console.log(tileEdges); + +const edgeMap = {}; + +const reverse = (str) => str.split("").reverse().join(""); +const isCanonical = (edge) => edge < reverse(edge); + +for (const [id, edges] of Object.entries(tileEdges)) { + for (const edge of edges) { + const key = isCanonical(edge) ? edge : reverse(edge); + if (typeof edgeMap[key] === "undefined") { + edgeMap[key] = []; + } + edgeMap[key].push(id); + if (edgeMap[key].length > 2) { + console.warn( + "Assumption does not hold: One edge is present in more than two tiles" + ); + } + } +} + +// console.log(edgeMap); + +const edgeTiles = new Set(); +const cornerTiles = new Set(); + +for (const ids of Object.values(edgeMap)) { + if (ids.length === 1) { + const id = ids[0]; + if (edgeTiles.has(id)) { + edgeTiles.delete(id); + cornerTiles.add(id); + } else { + edgeTiles.add(id); + } + } +} + +console.log(Array.from(cornerTiles).reduce((a, b) => a * b, 1)); diff --git a/2020/20/solution2.js b/2020/20/solution2.js new file mode 100644 index 0000000..03aa51c --- /dev/null +++ b/2020/20/solution2.js @@ -0,0 +1,310 @@ +/** + * TODO: optimize for reduced complexity + * TODO: optimize for cleaner code + */ + +const fs = require("fs"); + +function main() { + const input = fs.readFileSync("input", "utf-8").trim(); + const tiles = input.split("\n\n").map((tile) => new Tile(tile)); + const tilesMap = Object.fromEntries(tiles.map((tile) => [tile.id, tile])); + const tileSet = new Set(tiles); + // console.log(tiles); + // console.log(tileSet); + + const borderMap = {}; + for (const tile of tiles) { + for (const border of Object.values(tile.borders)) { + const key = canonical(border); + if (typeof borderMap[key] === "undefined") { + borderMap[key] = []; + } + borderMap[key].push(tile.id); + if (borderMap[key].length > 2) { + console.warn( + "Assumption does not hold: One edge is present in more than two tiles" + ); + } + } + } + // console.log(borderMap); + + const edgeTiles = new Set(); + const cornerTiles = new Set(); + const neighbors = {}; + + for (const ids of Object.values(borderMap)) { + if (ids.length === 1) { + const id = ids[0]; + if (edgeTiles.has(id)) { + edgeTiles.delete(id); + cornerTiles.add(id); + } else { + edgeTiles.add(id); + } + } else { + const [tileA, tileB] = ids; + if (typeof neighbors[tileA] === "undefined") neighbors[tileA] = []; + if (typeof neighbors[tileB] === "undefined") neighbors[tileB] = []; + neighbors[tileA].push(tileB); + neighbors[tileB].push(tileA); + } + } + console.log(neighbors); + let topLeft = tilesMap[Array.from(cornerTiles)[0]]; + console.log("TopLeft:", topLeft.id); + + const isEdge = (border) => borderMap[canonical(border)].length === 1; + + console.log(topLeft.pprint()); + const reprs = []; + for (const t of allOrientations(topLeft)) { + reprs.push(t.pprint().split("\n")); + } + for (let i = 0; i < reprs[0].length; i++) { + for (let j = 0; j < reprs.length; j++) { + process.stdout.write(reprs[j][i]); + process.stdout.write(" "); + } + process.stdout.write("\n"); + } + + while (isEdge(topLeft.borders.e) || isEdge(topLeft.borders.s)) { + console.log("rotating corner tile"); + topLeft.rot90(); + } + // console.log(topLeft) + tileSet.delete(topLeft); + + let curRow = [topLeft]; + const orderedTiles = []; + const tileBuffer = Array.from(tileSet); + + let lastTile = topLeft; + let loopDetection = 0; + while (tileBuffer.length > 0) { + // console.log("Tiles in buffer:", tileBuffer.length); + let cur = tileBuffer.shift(); + + if (isEdge(lastTile.borders.e)) { + // console.log("Looking for southener of", topLeft.id, cur.id); + for (cur of allOrientations(cur)) { + if (reverse(topLeft.borders.s) === cur.borders.n) { + orderedTiles.push(curRow); + curRow = []; + lastTile = cur; + topLeft = cur; + curRow.push(cur); + break; + } + } + } else { + // console.log("Looking for eastern of", lastTile.id, cur.id); + for (cur of allOrientations(cur)) { + if (lastTile.borders.e === reverse(cur.borders.w)) { + lastTile = cur; + curRow.push(cur); + break; + } + } + } + if (cur !== lastTile) { + tileBuffer.push(cur); + } else { + // console.log("Tile found! Its", cur.id); + loopDetection = 0; + } + // sleep(50); + if (loopDetection > tileBuffer.length) { + console.log("loop detected"); + break; + } + loopDetection++; + } + orderedTiles.push(curRow); + console.log("Found map arrangement"); + console.log(orderedTiles); + + let map = ""; + for (const row of orderedTiles) { + for (let i = 0; i < row[0].content.length; i++) { + for (let j = 0; j < row.length; j++) { + map += row[j].content[i].join(""); + // map += " "; + } + map += "\n"; + } + // map += "\n"; + } + const hashCount = map.match(/#/g).length; + console.log("hashCount", hashCount); + // console.log(map); + map = map.split("\n").map((row) => row.split("")); + + let sumSeamonsters; + for (let i = 0; i < 8; i++) { + if (i === 4) { + console.log("flip map"); + map = flipH(map); + } else { + console.log("rotate map"); + map = rotSquare(map); + } + + sumSeamonsters = findSeamonster(map); + console.log("Seamonsters found:", sumSeamonsters); + if (sumSeamonsters) { + break; + } + } + const seamonsterHashes = 15 * sumSeamonsters; + console.log(hashCount - seamonsterHashes); +} + +const reverse = (str) => str.split("").reverse().join(""); +const isCanonical = (edge) => edge < reverse(edge); +const canonical = (edge) => (isCanonical(edge) ? edge : reverse(edge)); +const trimEnds = (arr) => arr.slice(1, arr.length - 1); +function rotSquare(mat) { + const result = []; + const length = mat.length; + for (let i = 0; i < length; i++) { + const row = []; + for (let j = 0; j < length; j++) { + row.push(mat[length - 1 - j][i]); + } + result.push(row); + } + return result; +} +const flipH = (mat) => mat.map((row) => row.reverse()); +const flipV = (mat) => mat.reverse(); +function* allOrientations(tile) { + tile.rot90(); + yield tile; + tile.rot90(); + yield tile; + tile.rot90(); + yield tile; + tile.rot90(); + yield tile; + tile.flipH(); + yield tile; + tile.rot90(); + yield tile; + tile.rot90(); + yield tile; + tile.rot90(); + yield tile; +} + +function findSeamonster(map) { + map = map.map((row) => row.join("")); + const sm1 = " # "; + const sm2 = "# ## ## ###"; + const sm3 = " # # # # # # "; + const pattern1 = new RegExp(`(?=${sm1.replaceAll(" ", ".")})`, "g"); + const pattern2 = new RegExp(`(?=${sm2.replaceAll(" ", ".")})`, "g"); + const pattern3 = new RegExp(`(?=${sm3.replaceAll(" ", ".")})`, "g"); + + let sum = 0; + for (let lineIdx = 0; lineIdx < map.length - 3; lineIdx++) { + const [line1, line2, line3] = map.slice(lineIdx, lineIdx + 3); + let solutions1 = new Set(); + let solutions2 = new Set(); + let solutions3 = new Set(); + // console.log("Processing line", lineIdx, line1); + for (const match of line1.matchAll(pattern1)) { + solutions1.add(match.index); + } + // console.log(solutions1); + for (const match of line2.matchAll(pattern2)) { + if (solutions1.has(match.index)) solutions2.add(match.index); + } + // console.log(solutions2); + for (const match of line3.matchAll(pattern3)) { + if (solutions2.has(match.index)) solutions3.add(match.index); + } + // console.log(solutions3); + if (solutions3.size) { + for (const idx of solutions3) { + console.log(`Seamonster found at [${lineIdx}, ${idx}]`); + } + } + sum += solutions3.size; + } + return sum; +} + +const rot90Map = { n: "w", w: "s", s: "e", e: "n" }; +const flipHMap = { w: "e", e: "w" }; +const flipVMap = { n: "s", s: "n" }; + +function applyMap(map, obj, doReverse = false) { + const result = {}; + for (const [target, source] of Object.entries(map)) { + if (obj[source] === undefined) { + console.log(source, obj); + throw Error("aa"); + } + result[target] = doReverse ? reverse(obj[source]) : obj[source]; + } + return { ...obj, ...result }; +} + +class Tile { + constructor(rawInput) { + const lines = rawInput.split("\n"); + this.id = lines.shift().match("[0-9]+")[0]; + this.borders = { + n: lines[0], + e: lines.map((line) => line[line.length - 1]).join(""), + s: reverse(lines[lines.length - 1]), + w: reverse(lines.map((line) => line[0]).join("")), + }; + this.content = trimEnds(lines) + .map(trimEnds) + .map((line) => line.split("")); + } + + rot90(times = 1) { + while (times--) { + this.borders = applyMap(rot90Map, this.borders); + this.content = rotSquare(this.content); + } + } + + flipH() { + this.borders = applyMap(flipHMap, this.borders, true); + this.borders.n = reverse(this.borders.n); + this.borders.s = reverse(this.borders.s); + this.content.map((row) => row.reverse()); + } + + flipV() { + this.borders = applyMap(flipVMap, this.borders, true); + this.borders.w = reverse(this.borders.w); + this.borders.e = reverse(this.borders.e); + this.content.reverse(); + } + + pprint() { + let str = ""; + str += " " + this.borders.n + " \n"; + for (let i = 0; i < this.borders.w.length; i++) { + str += reverse(this.borders.w)[i]; + if (i === 0 || i === this.borders.w.length - 1) { + str += " ".repeat(this.borders.w.length); + } else { + str += " " + this.content[i - 1].join("") + " "; + } + str += this.borders.e[i]; + str += "\n"; + } + str += " " + reverse(this.borders.s) + " "; + return str; + } +} + +main();