From ef375e534c1022a0f7764b44a9fe99e1a70f3dd6 Mon Sep 17 00:00:00 2001 From: Ettore Dreucci Date: Fri, 25 Dec 2020 23:40:39 +0100 Subject: [PATCH] AoC 2020: day20 Signed-off-by: Ettore Dreucci --- 2020-python/inputs/day_20 | 1728 +++++++++++++++++++++++++++++++ 2020-python/solutions/day_20.py | 306 ++++++ README.md | 4 +- 3 files changed, 2036 insertions(+), 2 deletions(-) create mode 100644 2020-python/inputs/day_20 create mode 100644 2020-python/solutions/day_20.py diff --git a/2020-python/inputs/day_20 b/2020-python/inputs/day_20 new file mode 100644 index 0000000..6f28196 --- /dev/null +++ b/2020-python/inputs/day_20 @@ -0,0 +1,1728 @@ +Tile 2131: +###..#...# +##..#.##.# +..###...#. +......#..# +##.#.....# +..#..#...# +......#... +......#... +.........# +#.##..#.## + +Tile 2441: +..#.#..... +#.#....... +.......... +...#.#.... +....###.#. +#....#...# +#.#...#... +#...#..... +#...#....# +.##.#.#..# + +Tile 1571: +....#....# +...#...##. +.#.....#.. +....#..#.. +#....##.## +###..#.... +....#.#.#. +..#....#.. +#...###..# +#.######## + +Tile 2179: +#####..#.# +##......## +#.....#.#. +#...#....# +.....#.#.. +####.....# +.#..#.#..# +##..###... +##.....##. +..#.####.# + +Tile 1433: +#....#..## +#.##...#.. +.........# +#..#....#. +#......#.. +.#.....### +#......### +#..#..#... +.........# +.#.#.#.... + +Tile 1283: +...#.##... +##.......# +#..#.....# +.####.##.. +..#..#.### +#.....#... +.##..##.## +#........# +.......... +#.##...... + +Tile 1667: +.#####.#.# +...#.....# +##...#...# +#..#....#. +.........# +...##..#.# +...#..#..# +#.#.....## +#......... +#..#..#### + +Tile 1657: +##.#.#..## +#.....#.#. +#........# +....#....# +......#... +......#..# +#..#.....# +.##....... +#...#.##.# +.#.##..##. + +Tile 1259: +..#.....## +##.......# +.......#.# +#..#.....# +.#..#..... +#.#..##..# +.##.....## +##.......# +##...#.... +########.. + +Tile 2161: +.#.#.###.# +....##.#.. +..##.#...# +....#.#..# +#......... +.#.#...... +#.#....... +#.##.....# +##.##....# +.#######.# + +Tile 3793: +.##.##..## +#......... +........#. +.#.......# +.......#.# +.#.......# +#.......## +....#....# +#.#....... +####..##.# + +Tile 2953: +....####.. +#..#...##. +.........# +.#...#..## +..#..#.#.. +.......... +#......... +....##.#.. +##..###.#. +...####.## + +Tile 1979: +.####.###. +.....#.##. +##..#.#..# +.##..#.### +#..#..#..# +.#...####. +#....##..# +###.#...## +.#...##..# +.##.#..##. + +Tile 3061: +...####..# +#...#....# +..#...#... +#.##...... +.........# +#.#....... +#........# +.....#.... +#.#......# +.##....#.. + +Tile 2731: +..#...##.# +#......#.# +.....##... +.....##..# +#.##.#..#. +##....##.. +.......... +#........# +.........# +##..#...#. + +Tile 1439: +..###.#### +....##...# +........## +.........# +#.......## +..##...#.# +....#.#..# +......#... +#.##.#.#.# +##.##...## + +Tile 3347: +..#.##.### +...#...#.# +#.#.#...#. +#..#...### +.##....#.. +##........ +##.#..#..# +..#....#.. +..##..#.#. +..#######. + +Tile 1559: +###.#.#### +#.......#. +#.......#. +..#.##..#. +..#.....#. +#...#..#.# +#..#....## +#.##...... +#.#..#...# +.#..#####. + +Tile 3559: +...##.##.. +#........# +..##...... +#...#..... +##.#..##.. +#......... +#.#....#.# +#......... +....#....# +#...#.###. + +Tile 3109: +.##..#.... +#........# +#.....##.# +.....##.#. +#.#......# +#.##...... +#......#.# +#....##..# +.#.##..### +.#.....#.. + +Tile 3701: +#..#..#... +..#..#...# +#......... +#......... +.....#.### +.....#.... +.#..#...## +#......... +#.#.#....# +#..###..## + +Tile 1597: +.##.#.#.#. +..#.#.#..# +#.......## +...#.....# +#........# +.#.......# +..#.#....# +.......... +#.#.##...# +.....####. + +Tile 1231: +.#####.... +#....##... +##..#..#.# +...#...... +#......... +#..#...... +#.#...#..# +..#..#..## +#..##..#.. +##.###.... + +Tile 3389: +.###....#. +#.......#. +#....#.... +#...#....# +..#.##...# +.....##.## +.......... +###...#..# +#..#.#.#.. +#####..##. + +Tile 3461: +....#.###. +.......... +.......... +...#...#.# +#....##... +..#..#.... +##.#..#..# +#....#...# +...#.#...# +....###### + +Tile 2837: +##..#...## +#....##..# +...#....## +.#...#.... +#.....#... +#.#...##.# +##..###..# +#........# +#......... +..###..#.. + +Tile 1423: +####.#...# +#.#......# +...#.....# +#####.#... +#..#..##.. +.....##... +##.##..... +#.#....#.# +...#.....# +#.#.#..#.. + +Tile 3943: +#.....#..# +...##..#.. +...#...... +.#.#...... +#...#..... +#.#.#..#.. +........## +.........# +##..##.#.# +..#.#.##.. + +Tile 3779: +..#.#..#.# +...##...## +.......#.# +..#.....#. +..##...... +#.#....### +.#.#.....# +#......... +##...#...# +#.#.##.### + +Tile 1583: +##..#.##.# +..#.....#. +#..#...##. +#..#.#.#.# +.......#.# +#.##..###. +#######.#. +..#.....## +#.##....## +#..##.#.## + +Tile 3041: +...#.###.. +#......#.. +..#....#.. +.##.....## +#.#...##.# +......#.#. +.......... +.#...#.#.. +..#..#...# +#.##.##.#. + +Tile 1889: +...#.##.#. +.#..#..... +#..#.....# +........#. +.........# +..#...#..# +###....### +#.#....... +#..#.....# +...##..#.. + +Tile 1493: +....##..#. +#........# +#..#...... +.....#..#. +#......... +...#.....# +.........# +.#.#.....# +.......... +...####### + +Tile 1987: +#..#####.. +#........# +###..##..# +.#....#... +......#... +#...##..## +........#. +.##.....#. +##...###.. +##..##.#.. + +Tile 2003: +..#.#.#### +##..###### +#.#..#.#.# +...#.....# +#......... +......#..# +.......#.# +##........ +##....#..# +..#..#.##. + +Tile 1297: +.....###.. +...#...#.# +...#.#...# +.......... +.....#...# +#.......#. +..#....... +..#....... +....#....# +#.#######. + +Tile 3049: +#..###..#. +..###...## +##........ +#........# +.....#.#.. +##..##..#. +#..#.#.... +#.....#... +###.#..... +#..#....## + +Tile 2143: +#...#.#.#. +#......#.# +#.#..##### +###..#.#.. +#.##...### +....#.#.#. +#........# +.......... +#...#...#. +.##.##..## + +Tile 1753: +#.#.#..##. +....#..... +#...###... +#.....#.#. +#.#..###.. +......#... +...#.....# +..#....#.# +#...##.... +..#.#..##. + +Tile 3407: +..###.##.. +....#.#..# +.#...#.... +....##.... +#..##....# +....#..... +.....#.... +.#.......# +#.....#..# +.##...#.## + +Tile 1783: +.#..####.. +##........ +...###..## +#......#.# +#......... +.......... +##........ +........#. +##.####.## +.####.#.#. + +Tile 3593: +#.#.....## +......#..# +##...#.#.# +#.#.#...#. +.......... +.....###.. +#...#.#... +###...##.. +#.#...#... +..#.....## + +Tile 1249: +###....##. +##..#..#.# +.#.#.##..# +..#....... +.........# +#....#.#.# +..##..#..# +###.####.# +.#.#.....# +....##...# + +Tile 2963: +..##.#..#. +#..##....# +#.#..#..## +.#...####. +..#......# +##...##.#. +.........# +#....#...# +##.....#.# +####.#.... + +Tile 1289: +.#....#... +.##.#..... +.##.#..... +#......... +....#...## +##.......# +...#.....# +.......... +.......... +.#.##.#... + +Tile 2053: +#.#.#...#. +....#.##.# +.........# +#.....#..# +....#..... +.##......# +#...#.#... +#...#.#... +...#..#... +#..#.#.### + +Tile 3001: +.#...#...# +....##..#. +....##...# +...###...# +#..#....## +#.......#. +#.##.....# +....#.#.## +.#..##.#.. +.##.....## + +Tile 2591: +.####.##.. +......#.## +..#......# +....#....# +..#....### +..##...... +#........# +.......#.# +#....#.... +##.###...# + +Tile 1931: +.##..#.#.. +#......... +..#......# +.#.......# +....#..... +..#....... +##...##... +#...###..# +#.#.....#. +#.#..#...# + +Tile 3203: +.###.....# +...#..#..# +##........ +.........# +#.#....#.. +.#........ +#.......## +#....####. +#......... +##....#... + +Tile 1747: +#...##..## +...#.#...# +#.#......# +#....#..## +.##....... +##..#.##.. +##....#..# +#...#..... +#.#....#.. +.##.#.#.## + +Tile 3557: +#.##..#... +#.......## +.#.#.#.... +#...#.#... +#.#.##.... +#...#....# +.......... +#....#.... +#...#..... +####..###. + +Tile 3329: +#..##..... +.......... +..#....... +.....##.## +....#..... +.##....#.. +.....#.... +.......... +#####.#..# +#..#.##... + +Tile 3067: +#..##....# +.#.#..#..# +..#......# +#...#....# +#.....#... +..#.#....# +#.#...#..# +.....#.... +..#......# +.#.##..... + +Tile 3371: +#.###..#.. +#.#....#.. +#....#...# +#.....#..# +..#..##..# +#.#.....#. +.#.#..#### +#.#..#.... +..#..#.... +##......#. + +Tile 3467: +#.#....#.. +##....##.# +...#..#### +...#.#...# +.........# +..#....... +...#...#.# +...#...... +.####....# +..#.....#. + +Tile 3923: +...#...##. +#........# +.#........ +#.......## +#.#.#..... +.........# +....#..... +#......... +...#.#..## +#.######.. + +Tile 1453: +#.#...##.. +##....#..# +#......#.. +.......... +#.#.##...# +#........# +.....#.... +.##....#.. +.......... +#.###.###. + +Tile 3331: +.##.#..#.# +.......#.# +#......#.. +..#......# +#..#.....# +#..#.....# +#.#.....## +#......... +.......... +####.#...# + +Tile 2633: +..#.#....# +###......# +.......#.# +....#....# +###.#...#. +.#....#..# +##.....#.# +.##..#.... +#...#...#. +..#...##.. + +Tile 1811: +#..####### +.##.....#. +#.....##.# +#..#...#.. +#...#..... +##..#..#.. +#.##.#..#. +.#........ +##...#.#.# +.####.#..# + +Tile 1777: +.####...#. +.#....#.#. +###..#.... +..#..#...# +#.#.#.##.. +#...#..### +#....#...# +......#... +.....#...# +####.#..## + +Tile 1697: +#.##..#..# +#........# +##.####... +##......#. +#.##....#. +##..#..#.. +#..#..#..# +#.....#### +...#.#.... +##.###.#.# + +Tile 2551: +#..###..## +..#...#... +.......... +.#..#..... +##.....#.. +...#.#.#.. +..#..##..# +.##....... +.###...... +...###.##. + +Tile 2351: +#...#####. +......##.# +....##...# +.........# +#......... +#.....#..# +#........# +..##.....# +....#..#.. +.#.#....## + +Tile 2689: +..###..### +.........# +#...#..... +##..#..#.. +#.#.###... +....#....# +#........# +......#.#. +#.#..####. +####.###.# + +Tile 3253: +..##...... +..#.#....# +..#.#...#. +#...#..... +#..#.#.... +.#....#... +....#..... +#......... +#......#.. +#..#.##### + +Tile 2843: +####..#... +#.....##.# +##....#... +.##..#.#.. +..###.#... +...#...### +#..#..#... +.....#..## +#....#..## +...#..#.#. + +Tile 1187: +.##.####.# +......#..# +...#.....# +.....#...# +.......#.# +.........# +#..#...... +..#......# +#...#....# +#####...## + +Tile 3529: +.....##### +.#...#.... +#..#.#.... +#........# +.#....#.## +##..##.#.. +..##.#..## +.#........ +......#..# +###..#.##. + +Tile 1489: +.##.#.#### +#.#..#.#.. +#....#.... +#.#..#.... +.#...#.... +.......... +#.#..##..# +.........# +.......#.. +.....###.# + +Tile 1097: +###.###.#. +.#...#.... +.......#.. +.#....#.#. +.....#...# +#.#.....## +####..##.# +###......# +#........# +##..#.#.## + +Tile 3491: +#...#.##.. +...##....# +..#.....#. +#.#.#....# +#..#.#...# +.....#...# +....#..... +....#.#..# +........## +##....#... + +Tile 3947: +######.#.# +#.#.#....# +...#.#..#. +...#.#.... +#...#...## +....#..... +.......#.. +##..#....# +..#..#.... +.###..#### + +Tile 3313: +.#....#.## +.##....... +#.##...... +##........ +#.#....... +...#.....# +...#...... +......#..# +##......#. +####.#..#. + +Tile 1277: +#..###..#. +#....#...# +.##....### +#........# +#....##... +#.#...#..# +#...#....# +...#...#.. +...##....# +.#...#.#.# + +Tile 3121: +.#...#..## +........#. +..#..##### +#.....#.## +..#.....## +.......... +#......... +#..###...# +.........# +###.#.#.#. + +Tile 2287: +#....#.#.# +#.#..#.... +#.....#... +.......... +##.#...... +##..#..### +..##....## +.....#.... +#........# +..#.#...#. + +Tile 1171: +#..#.#...# +..#...#... +##.......# +####...#.# +#.#.#.#... +.#.......# +##....#### +#...##..#. +........#. +##.###.##. + +Tile 2503: +#...#.#..# +..#..##.## +...#...### +.##.#...## +#......... +#........# +##.......# +....#.#... +...#.....# +..#...#.## + +Tile 2579: +#.#..#..## +.........# +####...... +..#....#.. +#.#..##..# +#.....##.# +....#....# +.........# +..#..#..## +#..##.#### + +Tile 1867: +.##.....#. +.........# +.#....#.#. +#....#..## +##........ +...#...... +#....##..# +##..##.#.# +#......... +####..##.# + +Tile 2081: +.##..#...# +......###. +..##.#..## +##..##.... +#..#.#...# +....#...#. +##.....#.# +..#....#.. +#...#...## +.####..#.# + +Tile 3319: +..#...#.#. +.....#.... +.#........ +#.......#. +#......... +.....#...# +#.....###. +#........# +........## +#...#####. + +Tile 3727: +##.#.#...# +#......... +..##.....# +#...#.#... +#.#.#...#. +.###.#.... +......#.## +#...#....# +...#.#...# +#..#.#..## + +Tile 1103: +###.##.#.. +.#..#.##.. +.#..###.#. +#.#..##.#. +.##...##.# +....#....# +....#..#.# +...#...### +...#..#.#. +###.#..##. + +Tile 3463: +##...#.#.# +....#..##. +........## +.#.......# +..#..#.... +#.#....#.. +##....#..# +...#..#..# +#.#......# +#.###..##. + +Tile 3449: +..###.##.. +..#..#.... +#...##.... +.####..### +.#..###.## +#.#....##. +......#..# +.......... +##........ +#.......#. + +Tile 2207: +#...#.#.#. +.##.....#. +#####....# +..#.#..... +#..#....## +.#....##.# +#....#.#.# +...#....#. +..#.#..... +##..#.##.# + +Tile 2647: +.#####..#. +.#..#....# +....#.#..# +.##....... +...#..###. +####...### +##.....#.# +#..#.....# +#.#.....## +..##.##..# + +Tile 2539: +##..#..### +...#..#..# +.#....#... +###....#.. +.#...#.... +...##..... +..#..##.#. +...#...... +#...#....# +#.#.##.... + +Tile 2927: +.#.....##. +#.......#. +#..##..##. +#...#..... +....#...## +.#.#.#..## +........## +###.#...#. +...#.....# +.##.....## + +Tile 2153: +#.#..##..# +...#.####. +#..##..... +.........# +#.....#..# +...##..... +...#...### +..##..#### +...#...### +##.#.##.## + +Tile 3083: +###.#..#.# +...#.....# +#.......## +..#......# +...#.....# +.......... +..#......# +.##....#.. +#......### +..#......# + +Tile 1237: +.#....###. +#......... +#...#...## +.....#.#.. +#......... +....#..#.. +........## +##......#. +#......... +#..##.#... + +Tile 2239: +#.....##.# +##........ +....##.... +#.##....## +###.#..### +#........# +.........# +#..#.#.#.. +.........# +.#..#..... + +Tile 1093: +.####..#.. +##....#... +..#.#...## +...#..#... +#........# +#...#.#..# +#.#####..# +....#.#... +#.#.#..#.# +#.#..##### + +Tile 2221: +......#.#. +....#..#.# +#..#...#.# +.#........ +#........# +##....##.# +##.....#.# +##...#...# +#..#..#... +..##....#. + +Tile 1523: +##.###.### +###..#..#. +#..##...## +#..#.#.... +#..#.....# +#.#......# +#.......#. +#......... +.#.###.##. +...#.#...# + +Tile 3673: +###.##..#. +.......... +.#.......# +#..#.##... +......#..# +#.....##.. +##....#..# +..#...#... +#...#...#. +#####...## + +Tile 2063: +####.....# +#........# +......#..# +#.#..#.... +#.#.....#. +...#.....# +#...##..#. +#.....#... +......#.## +..##.#.##. + +Tile 3631: +#.#.#.#### +...#.#.... +...#.#...# +#....#.#.. +#..#...### +#.##...... +#..#...### +#.#.#..#.. +.......##. +.#.#...... + +Tile 2693: +###.####.# +...#...... +....#.#..# +#.#..#.... +.....###.# +#....#.... +##.###.... +#.....#..# +#.....#... +######.#.# + +Tile 2593: +###.....## +.....#.... +..#...#... +.....#...# +..##...... +###....... +.##......# +#....#...# +#..#..#..# +#.###.#.#. + +Tile 3607: +.##.##.#.. +#...#..##. +....#..#.. +#......#.# +.......... +.......... +.......#.. +#....##..# +.......#.# +.#####.... + +Tile 1223: +.####..#.# +......##.. +.........# +...#....#. +#....#.#.. +##.#...#.. +.#......## +.........# +#.#.#....# +##.#..#..# + +Tile 3433: +##.###..## +#..#.##... +##....#..# +#......... +###.##.#.# +....##.... +#...#.#..# +...#...... +##....#..# +##.#.#...# + +Tile 1217: +#..###.### +#.#...#... +..#.##.... +#.......#. +#.......#. +##...#..## +#..#..#... +#..####..# +#...##...# +.####.###. + +Tile 2861: +#..##.#.#. +#...#.##.. +.#...####. +.......#.# +..#...#..# +#...##...# +#.....#.#. +......##.# +##..#.##.. +###..####. + +Tile 1327: +....#.#### +...####... +....#.#... +..#...#.#. +....#....# +..#..#...# +....##.... +......#... +#....##.## +##.######. + +Tile 3613: +#.##.###.. +#..#..#..# +..##.##... +..#..##### +...###..## +#...#.#.## +#....#.... +...#.....# +.###.#..## +####...### + +Tile 2909: +#####..#.. +#...#..#.. +#.#....#.. +..#....... +...##...#. +.#.##..### +...#.....# +.........# +...#.##..# +#######.## + +Tile 1709: +#.#.##.... +#......#.# +.#........ +#......#.. +.........# +......#.#. +..##...... +.....#.... +..#.##.... +#....##### + +Tile 2857: +###.#...## +#.#....#.. +........## +#.#...#..# +#......#.. +.....####. +......#..# +.......... +#.#.....## +..#..##... + +Tile 3541: +#.#.##.### +.....##..# +..#.#..... +#..#.....# +##....#... +#.#...#... +....##.... +.........# +.##....#.# +...#.....# + +Tile 2459: +##..#.#..# +...#.#.##. +##...#.... +.##.#.#... +#.....#..# +...#.....# +......#... +.....##... +...##...#. +..#..###.. + +Tile 1621: +#.##.###.. +##..#.#... +.#.##...## +.###.#..## +.#..##.#.. +#.......## +.....##... +..#....... +#......... +#..#..###. + +Tile 3833: +#..#...### +.........# +#.....#... +#..#...#.# +#......#.. +.#........ +..#....... +.........# +......##.# +.#..#.#.## + +Tile 1117: +..##.....# +..##...... +#..#.#...# +#...##..## +....#...#. +#...#....# +....#..#.# +...#.....# +#..#.....# +..#.##..## + +Tile 3413: +#.#..#.### +....##.#.# +...#.....# +.........# +#......... +.....##.## +..#....#.. +#.....##.. +#........# +#.######.. + +Tile 2141: +.##.#..#.# +#.###..... +#..#....#. +#..#....#. +..#....... +.#.....#.# +##......#. +..#..#.### +...#.....# +...#..#..# + +Tile 3547: +####.#..## +...#.#...# +......#... +##.#...... +#........# +.##...#..# +.#...#..## +#..#..#... +#.##...... +##.###..#. + +Tile 1069: +##.#..##.# +.#....#..# +.##......# +.#....#.## +#..#..#... +..#.#..... +.......... +#....#..#. +##........ +..#...##.# + +Tile 3169: +##.##.#..# +#.....#### +.##...##.. +#....#.#.# +#.#..##... +#........# +.#.......# +.#........ +.........# +#..#...#.# + +Tile 1307: +..##..#.## +###.#...## +..##.....# +#.##.....# +.....#.#.. +..#....#.. +....#...#. +.....#..## +.#.....#.# +##.#.....# + +Tile 3359: +#.#.#..#.. +........#. +.#...#...# +#....##..# +.#.#...... +#...#.#.#. +.#...###.# +#........# +.#.#.....# +###.#..#.. + +Tile 2713: +#...#...## +##.###.#.. +..##....#. +...#.....# +..#.....#. +#....#...# +....#..... +#..##....# +.........# +#######..# + +Tile 2897: +...####..# +...#...#.# +#.......#. +......#... +.....#...# +.........# +.#.#...... +######..## +...#..#..# +#..###.### + +Tile 3929: +....#.#.#. +.#...#.... +#.##..###. +..##...... +#.##...#.. +#...#..... +.......### +#.##.....# +#...#..... +...####### + +Tile 1031: +#####.#.#. +#....##.#. +#..#..#..# +.........# +##.#...#.# +....#...#. +.......#.. +#......#.. +......#..# +.#.....#.# + +Tile 1361: +#.#.#..... +.#........ +..##...#.# +#..##.#..# +.....##### +.......##. +#........# +.......... +#..#...#.# +##.###.#.# + +Tile 3853: +#..##..... +.........# +#..#...... +#......... +###.....#. +...#.#...# +#......... +.......... +.......... +##.##.#### + +Tile 1009: +...#.#...# +..##....#. +.......#.. +.....#...# +#..#...#.# +.#..#..#.. +..##.#..#. +....#.#..# +#..#.#.... +###.#.#### + +Tile 3761: +.##.#.#.#. +..#......# +#....##... +.#........ +#...#..#.# +.........# +#......... +.........# +.#.......# +#..#...... + +Tile 2521: +.#.....### +#........# +...##....# +###....... +#....#.... +###..#...# +##....#..# +.#........ +.........# +#..#...### + +Tile 1907: +.####.#..# +...#..#..# +#.#..##.## +##....##.# +#........# +#...#..... +#......... +#.#..#...# +##....###. +.##.###.#. + +Tile 2039: +...##..### +###...#... +.#.......# +...##.#... +.........# +......#..# +#........# +###....#.# +#.#......# +#..#...#.. + +Tile 2389: +##.##.###. +#.#....... +........## +.........# +...#...... +.......... +#...#..#.# +#.......#. +....#..### +####.###.# + +Tile 2089: +#.#..#.#.# +#........# +.#.....#.. +.......... +#....#...# +#........# +#......... +#......... +#...#..... +#.#...#..# + +Tile 2137: +.#####..## +..#......# +#.#..#.... +.#......#. +#...#..... +......#... +....##..#. +.##....#.# +#..#..#..# +#..####.## + +Tile 3191: +..###....# +.........# +........## +....#..#.. +.........# +#......... +..#..#..#. +.#....###. +#.....#..# +#..#####.# + +Tile 2789: +#.#.#.##.# +...#.....# +#..###...# +#........# +##.......# +#..##....# +.#........ +.........# +..#......# +......#..# + +Tile 1567: +....#....# +#..##..##. +.....#.... +#.##.##... +....##.... +##...#...# +#.#.#....# +......###. +..#.#..#.# +.#..##.#.# + +Tile 1163: +.###..##.. +.#.....#.# +#...###..# +.....#.... +.........# +..#...#..# +..#..##.## +.##..###.# +.........# +##.##..#.# + diff --git a/2020-python/solutions/day_20.py b/2020-python/solutions/day_20.py new file mode 100644 index 0000000..cb19675 --- /dev/null +++ b/2020-python/solutions/day_20.py @@ -0,0 +1,306 @@ +"""AOC 2020 Day 20""" + +import pathlib +import time +import collections +import operator +import itertools + +TEST_INPUT = """Tile 2311: +..##.#..#. +##..#..... +#...##..#. +####.#...# +##.##.###. +##...#.### +.#.#.#..## +..#....#.. +###...#.#. +..###..### + +Tile 1951: +#.##...##. +#.####...# +.....#..## +#...###### +.##.#....# +.###.##### +###.##.##. +.###....#. +..#.#..#.# +#...##.#.. + +Tile 1171: +####...##. +#..##.#..# +##.#..#.#. +.###.####. +..###.#### +.##....##. +.#...####. +#.##.####. +####..#... +.....##... + +Tile 1427: +###.##.#.. +.#..#.##.. +.#.##.#..# +#.#.#.##.# +....#...## +...##..##. +...#.##### +.#.####.#. +..#..###.# +..##.#..#. + +Tile 1489: +##.#.#.... +..##...#.. +.##..##... +..#...#... +#####...#. +#..#.#.#.# +...#.#.#.. +##.#...##. +..##.##.## +###.##.#.. + +Tile 2473: +#....####. +#..#.##... +#.##..#... +######.#.# +.#...#.#.# +.######### +.###.#..#. +########.# +##...##.#. +..###.#.#. + +Tile 2971: +..#.#....# +#...###... +#.#.###... +##.##..#.. +.#####..## +.#..####.# +#..#.#..#. +..####.### +..#.#.###. +...#.#.#.# + +Tile 2729: +...#.#.#.# +####.#.... +..#.#..... +....#..#.# +.##..##.#. +.#.####... +####.#.#.. +##.####... +##..#.##.. +#.##...##. + +Tile 3079: +#.#.#####. +.#..###### +..#....... +######.... +####.#..#. +.#...#.##. +#.#####.## +..#.###... +..#....... +..#.###...""" + +MONSTER_PATTERN = ( + ' # ', + '# ## ## ###', + ' # # # # # # ' +) + +def read_input(input_path: str) -> str: + """take input file path and return a str with the file's content""" + with open(input_path, 'r') as input_file: + input_data = input_file.read().strip() + return input_data + +def extract(input_data: str) -> dict: + """take input data and return the appropriate data structure""" + tiles = dict() + for tile in input_data.split('\n\n'): + parts = tile.split('\n') + tile_id = int(parts[0][5:-1]) + tiles[tile_id] = parts[1:] + return tiles + +def edge(matrix: list, side: str) -> str: + """return a side of a matrix""" + if side == 'n': + return matrix[0] + if side == 's': + return matrix[-1] + if side == 'e': + return ''.join(map(operator.itemgetter(-1), matrix)) + return ''.join(map(operator.itemgetter(0), matrix)) + +def get_tiles_corners(tiles: dict) -> dict: + """return the corners of a set of tiles""" + matching_sides = collections.defaultdict(str) + corners = {} + + for id_tile1, id_tile2 in itertools.combinations(tiles, 2): + tile1, tile2 = tiles[id_tile1], tiles[id_tile2] + + for side_a in 'nsew': + for side_b in 'nsew': + edge_a, edge_b = edge(tile1, side_a), edge(tile2, side_b) + + if edge_a == edge_b or edge_a == edge_b[::-1]: + matching_sides[id_tile1] += side_a + matching_sides[id_tile2] += side_b + + for tid, sides in matching_sides.items(): + if len(sides) == 2: + corners[tid] = sides + + assert len(corners) == 4 + return corners + +def rotate90(matrix: list) -> tuple: + """return the matrix rotated by 90""" + return tuple(''.join(column)[::-1] for column in zip(*matrix)) + +def possible_orientations(matrix: list) -> list: + """return all possible orientations of a given matrix""" + orientations = [matrix] + for _ in range(3): + matrix = rotate90(matrix) + orientations.append(matrix) + return orientations + +def possible_arrangements(matrix: list) -> list: + """return all possible arrangements of a given matrix""" + arrangements = possible_orientations(matrix) + arrangements.extend(possible_orientations(matrix[::-1])) + return arrangements + +def strip_edges(matrix: list) -> list: + """return a matrix without it's edges""" + return [row[1:-1] for row in matrix[1:-1]] + +def matching_tile(tile: list, tiles: dict, side_a: str, side_b: str) -> list: + """return the adjacent tile of a given one""" + edge_a = edge(tile, side_a) + + for other_id, other_tile in tiles.items(): + if tile is other_tile: + continue + + for other_arr in possible_arrangements(other_tile): + if edge_a == edge(other_arr, side_b): + tiles.pop(other_id) + return other_arr + +def matching_row(prev: list, tiles: dict, tiles_per_row: int) -> list: + """return matching tiles in the row of a given one""" + matching_tiles = [prev] + tile = prev + for _ in range(tiles_per_row - 1): + tile = matching_tile(tile, tiles, 'e', 'w') + matching_tiles.append(tile) + return matching_tiles + +def build_image(top_left_tile: list, tiles: dict, image_dimension: int) -> list: + """build an image of a set of tiles""" + first = top_left_tile + image = [] + + while 1: + image_row = matching_row(first, tiles, image_dimension) + image_row = map(strip_edges, image_row) + image.extend(map(''.join, zip(*image_row))) + + if not tiles: + break + + first = matching_tile(first, tiles, 's', 'n') + + return image + +def count_pattern(image: list, pattern: tuple) -> int: + """return the number of times a given pattern appears in an image""" + pattern_h, pattern_w = len(pattern), len(pattern[0]) + image_sz = len(image) + deltas = [] + + for row_index, row in enumerate(pattern): + for cell_index, cell in enumerate(row): + if cell == '#': + deltas.append((row_index, cell_index)) + + for img in possible_arrangements(image): + appearances = 0 + for row_index in range(image_sz - pattern_h): + for cell_index in range(image_sz - pattern_w): + if all(img[row_index + dr][cell_index + dc] == '#' for dr, dc in deltas): + appearances += 1 + + if appearances != 0: + return appearances + +def part1(entries: dict) -> int: + """part1 solver""" + corners = get_tiles_corners(entries) + corners_prod = 1 + for tile_id in corners: + corners_prod *= tile_id + return corners_prod + +def part2(entries: dict) -> int: + """part2 solver""" + corners = get_tiles_corners(entries) + top_left_id, matching_sides = corners.popitem() + top_left = entries[top_left_id] + + if matching_sides in ('ne', 'en'): + top_left = rotate90(top_left) + elif matching_sides in ('nw', 'wn'): + top_left = rotate90(rotate90(top_left)) + elif matching_sides in ('sw', 'ws'): + top_left = rotate90(rotate90(rotate90(top_left))) + + image_dimension = int(len(entries) ** 0.5) + entries.pop(top_left_id) + + image = build_image(top_left, entries, image_dimension) + monster_cells = sum(row.count('#') for row in MONSTER_PATTERN) + water_cells = sum(row.count('#') for row in image) + n_monsters = count_pattern(image, MONSTER_PATTERN) + + return water_cells - n_monsters * monster_cells + +def test_input_day_20(): + """pytest testing function""" + entries = extract(TEST_INPUT) + assert part1(entries) == 20899048083289 + assert part2(entries) == 273 + +def test_bench_day_20(benchmark): + """pytest-benchmark function""" + benchmark(main) + +def main(): + """main function""" + input_path = str(pathlib.Path(__file__).resolve().parent.parent) + "/inputs/" + str(pathlib.Path(__file__).stem) + start_time = time.time() + input_data = read_input(input_path) + entries = extract(input_data) + print("Part 1: %d" % part1(entries)) + print("Part 2: %d" % part2(entries)) + end_time = time.time() + print("Execution time: %f" % (end_time-start_time)) + +if __name__ == "__main__": + main() diff --git a/README.md b/README.md index 9a849dc..76f340a 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ | [Day 7](https://adventofcode.com/2020/day/7) | [1.689ms](./2020-python/solutions/day_07.py) | [1.565ms](./2020-python/solutions/day_07.py) | | [Day 8](https://adventofcode.com/2020/day/8) | [6.313ms](./2020-python/solutions/day_08.py) | [794.417µs](./2020-python/solutions/day_08.py) | | [Day 9](https://adventofcode.com/2020/day/9) | [7.220ms](./2020-python/solutions/day_09.py) | [4.783ms](./2020-python/solutions/day_09.py) | -| [Day 10](https://adventofcode.com/2020/day/10) | [139.110us](./2020-python/solutions/day_10.py) | [98.594µs](./2020-python/solutions/day_10.py) | +| [Day 10](https://adventofcode.com/2020/day/10) | [139.110µs](./2020-python/solutions/day_10.py) | [98.594µs](./2020-python/solutions/day_10.py) | | [Day 11](https://adventofcode.com/2020/day/11) | [2.879s](./2020-python/solutions/day_11.py) | [419.447ms](./2020-python/solutions/day_11.py) | | [Day 12](https://adventofcode.com/2020/day/12) | [746.181µs](./2020-python/solutions/day_12.py) | [211.216µs](./2020-python/solutions/day_12.py) | | [Day 13](https://adventofcode.com/2020/day/13) | [122.107µs](./2020-python/solutions/day_13.py) | [100.671µs](./2020-python/solutions/day_13.py) | @@ -29,7 +29,7 @@ | [Day 17](https://adventofcode.com/2020/day/17) | [743.804ms](./2020-python/solutions/day_17.py) | [836.255ms](./2020-python/solutions/day_17.py) | | [Day 18](https://adventofcode.com/2020/day/18) | [10.263ms](./2020-python/solutions/day_18.py) | [2.053ms](./2020-python/solutions/day_18.py) | | [Day 19](https://adventofcode.com/2020/day/19) | [145.980ms](./2020-python/solutions/day_19.py) | [259.030ms](./2020-python/solutions/day_19.py) | -| [Day 20](https://adventofcode.com/2020/day/19) | | | +| [Day 20](https://adventofcode.com/2020/day/19) | [513.955ms](./2020-python/solutions/day_20.py) | [316.973ms](./2020-python/solutions/day_20.py) | | [Day 21](https://adventofcode.com/2020/day/21) | [2.177ms](./2020-python/solutions/day_21.py) | [1.578ms](./2020-python/solutions/day_21.py) | | [Day 22](https://adventofcode.com/2020/day/22) | [1.516s](./2020-python/solutions/day_22.py) | [1.353s](./2020-python/solutions/day_22.py) | | [Day 23](https://adventofcode.com/2020/day/23) | [14.754s](./2020-python/solutions/day_23.py) | [3.572s](./2020-python/solutions/day_23.py) |