diff --git a/20/input.txt b/20/input.txt new file mode 100644 index 0000000..7c2d6f4 --- /dev/null +++ b/20/input.txt @@ -0,0 +1,141 @@ +############################################################################################################################################# +#.....#...#...#...###.....#.....###...#...#...#...#.....#...........###...#...........#...###...#.......#...#.........#...#...###...#...#...# +#.###.#.#.#.#.#.#.###.###.#.###.###.#.#.#.#.#.#.#.#.###.#.#########.###.#.#.#########.#.#.###.#.#.#####.#.#.#.#######.#.#.#.#.###.#.#.#.#.#.# +#...#...#...#...#...#...#.#...#.#...#...#.#.#.#.#.#...#.#.........#...#.#.#...#.....#.#.#.#...#.#.....#.#.#...#.......#.#...#...#.#.#.#.#.#.# +###.###############.###.#.###.#.#.#######.#.#.#.#.###.#.#########.###.#.#.###.#.###.#.#.#.#.###.#####.#.#.#####.#######.#######.#.#.#.#.#.#.# +#...#...#...#.......#...#.#...#.#...#.....#.#.#.#...#.#.###...###.#...#.#...#...#...#.#.#.#...#...#...#...#.....#...###.......#...#.#.#...#.# +#.###.#.#.#.#.#######.###.#.###.###.#.#####.#.#.###.#.#.###.#.###.#.###.###.#####.###.#.#.###.###.#.#######.#####.#.#########.#####.#.#####.# +#.....#...#.#.#...#...#...#...#.#...#...#...#...#...#.#.#...#.#...#.###.#...###...#...#.#.#...#...#.......#.#.....#...#...#...#.....#.#.....# +###########.#.#.#.#.###.#####.#.#.#####.#.#######.###.#.#.###.#.###.###.#.#####.###.###.#.#.###.#########.#.#.#######.#.#.#.###.#####.#.##### +#...#.......#...#.#.#...#...#.#.#...#...#...#...#...#.#.#...#.#...#.....#.....#...#...#.#.#...#.#...###...#...#.......#.#.#...#...#...#.....# +#.#.#.###########.#.#.###.#.#.#.###.#.#####.#.#.###.#.#.###.#.###.###########.###.###.#.#.###.#.#.#.###.#######.#######.#.###.###.#.#######.# +#.#.#...........#.#.#.#...#.#.#.#...#.#...#...#.#...#.#.###.#.....#.....#.....###...#...#.....#.#.#.#...#.......#...#...#.###...#...#.......# +#.#.###########.#.#.#.#.###.#.#.#.###.#.#.#####.#.###.#.###.#######.###.#.#########.###########.#.#.#.###.#######.#.#.###.#####.#####.####### +#.#.###...###...#.#.#.#.#...#.#.#...#.#.#.#...#.#...#.#...#.......#...#...#...#####...........#...#.#.#...#.......#.#...#.#.....#.....#...### +#.#.###.#.###.###.#.#.#.#.###.#.###.#.#.#.#.#.#.###.#.###.#######.###.#####.#.###############.#####.#.#.###.#######.###.#.#.#####.#####.#.### +#.#.....#...#...#...#.#.#.###.#.#...#.#.#.#.#...#...#...#.#...###...#...#...#...###...#...#...#...#...#...#.#.......#...#.#.....#...#...#...# +#.#########.###.#####.#.#.###.#.#.###.#.#.#.#####.#####.#.#.#.#####.###.#.#####.###.#.#.#.#.###.#.#######.#.#.#######.###.#####.###.#.#####.# +#.........#...#.#...#.#.#...#.#.#...#.#.#.#.....#.#...#.#.#.#.....#...#.#.#.....#...#.#.#.#.....#.......#...#...#...#.#...#...#.#...#.#.....# +#########.###.#.#.#.#.#.###.#.#.###.#.#.#.#####.#.#.#.#.#.#.#####.###.#.#.#.#####.###.#.#.#############.#######.#.#.#.#.###.#.#.#.###.#.##### +#.........#...#...#.#.#...#...#...#.#.#.#.#.....#.#.#.#.#...#.....#...#...#...###.#...#.#.#...#...#.....#.......#.#.#.#.###.#.#.#.###.#.#...# +#.#########.#######.#.###.#######.#.#.#.#.#.#####.#.#.#.#####.#####.#########.###.#.###.#.#.#.#.#.#.#####.#######.#.#.#.###.#.#.#.###.#.#.#.# +#.....#...#.........#.###...#...#...#.#.#.#.....#.#.#...#.....#...#...#.......#...#...#.#.#.#...#.#...#...#.....#.#.#.#.....#...#.....#...#.# +#####.#.#.###########.#####.#.#.#####.#.#.#####.#.#.#####.#####.#.###.#.#######.#####.#.#.#.#####.###.#.###.###.#.#.#.#####################.# +#...#...#...#.......#.#...#...#.....#...#...#...#.#.....#.....#.#.#...#.....###.#.....#.#.#.....#.....#...#...#.#.#.#.#.........#.....#.....# +#.#.#######.#.#####.#.#.#.#########.#######.#.###.#####.#####.#.#.#.#######.###.#.#####.#.#####.#########.###.#.#.#.#.#.#######.#.###.#.##### +#.#.......#.#.#.....#...#...#.....#.#.......#...#.#...#.#.....#.#.#...#.....#...#...###.#.#...#.........#...#.#...#...#.......#...#...#.....# +#.#######.#.#.#.###########.#.###.#.#.#########.#.#.#.#.#.#####.#.###.#.#####.#####.###.#.#.#.#########.###.#.###############.#####.#######.# +#.......#...#.#.........#...#...#...#...#...#...#.#.#.#.#...#...#.#...#.....#...#...#...#.#.#.#.......#...#...#.....#.......#.....#...#.....# +#######.#####.#########.#.#####.#######.#.#.#.###.#.#.#.###.#.###.#.#######.###.#.###.###.#.#.#.#####.###.#####.###.#.#####.#####.###.#.##### +#.......#.....###.......#.#...#.....#...#.#.#...#...#.#.#...#...#.#...#.....#...#...#...#.#.#.#.....#.#...#...#.#...#.....#.#.....###.#.....# +#.#######.#######.#######.#.#.#####.#.###.#.###.#####.#.#.#####.#.###.#.#####.#####.###.#.#.#.#####.#.#.###.#.#.#.#######.#.#.#######.#####.# +#.....#...#.....#.......#.#.#...#...#.#...#...#.....#...#...#...#.#...#.....#.....#.#...#.#.#.#.....#.#.#...#...#.......#.#.#...#...#.#.....# +#####.#.###.###.#######.#.#.###.#.###.#.#####.#####.#######.#.###.#.#######.#####.#.#.###.#.#.#.#####.#.#.#############.#.#.###.#.#.#.#.##### +#.....#.###...#.###.....#...#...#...#.#.....#.#...#.#.......#...#.#.....#...#...#.#.#.#...#.#.#...#...#.#.#...#...#...#...#...#...#.#.#.....# +#.#####.#####.#.###.#########.#####.#.#####.#.#.#.#.#.#########.#.#####.#.###.#.#.#.#.#.###.#.###.#.###.#.#.#.#.#.#.#.#######.#####.#.#####.# +#.......#...#.#...#...#.....#.#...#.#.#.....#.#.#.#.#.#...#...#.#.#...#.#...#.#...#...#.#...#...#.#.#...#...#...#...#...#...#.....#.#.#.....# +#########.#.#.###.###.#.###.#.#.#.#.#.#.#####.#.#.#.#.#.#.#.#.#.#.#.#.#.###.#.#########.#.#####.#.#.#.#################.#.#.#####.#.#.#.##### +###.......#.#...#.###...#...#...#...#...#...#...#.#.#...#.#.#.#.#...#...#...#.......#...#.#...#.#.#.#...#...............#.#.#...#...#.#.....# +###.#######.###.#.#######.###############.#.#####.#.#####.#.#.#.#########.#########.#.###.#.#.#.#.#.###.#.###############.#.#.#.#####.#####.# +#...#.....#.#...#.#.....#.................#...#...#.....#.#.#.#.........#.....#.....#...#...#.#...#...#.#.......###.......#...#...###.......# +#.###.###.#.#.###.#.###.#####################.#.#######.#.#.#.#########.#####.#.#######.#####.#######.#.#######.###.#############.########### +#.....###.#.#...#.#.#...#...#...#.......#...#.#...#.....#.#.#.#.......#.###...#.......#.#.....#...###...#.....#.....#...#...#...#...#...#...# +#########.#.###.#.#.#.###.#.#.#.#.#####.#.#.#.###.#.#####.#.#.#.#####.#.###.#########.#.#.#####.#.#######.###.#######.#.#.#.#.#.###.#.#.#.#.# +#...###...#...#.#...#.....#...#.#.....#.#.#.#.#...#.....#.#.#...#.....#...#.....#...#.#...#.....#...###...###.........#...#...#.....#.#.#.#.# +#.#.###.#####.#.###############.#####.#.#.#.#.#.#######.#.#.#####.#######.#####.#.#.#.#####.#######.###.#############################.#.#.#.# +#.#.....#...#...#...#.........#.......#...#...#.#...#...#.#.#.....#.....#.#.....#.#.#.....#...#...#...#...#...###...###...###...###...#...#.# +#.#######.#.#####.#.#.#######.#################.#.#.#.###.#.#.#####.###.#.#.#####.#.#####.###.#.#.###.###.#.#.###.#.###.#.###.#.###.#######.# +#.#...#...#...#...#...###...#.........#.....#...#.#...###...#.....#...#...#...#...#.#...#...#...#...#...#.#.#.....#...#.#...#.#...#.#.......# +#.#.#.#.#####.#.#########.#.#########.#.###.#.###.###############.###.#######.#.###.#.#.###.#######.###.#.#.#########.#.###.#.###.#.#.####### +#...#...#...#.#.#.........#...........#.#...#...#.......#.........#...#.....#.#...#.#.#.....#...###...#.#...#.........#.#...#...#...#.......# +#########.#.#.#.#.#####################.#.#####.#######.#.#########.###.###.#.###.#.#.#######.#.#####.#.#####.#########.#.#####.###########.# +#...###...#...#.#.#...#...#...#.........#.....#.#...#...#.#.......#.....#...#.#...#.#.#.......#.#...#.#.#...#.....#...#.#.#...#...#.........# +#.#.###.#######.#.#.#.#.#.#.#.#.#############.#.#.#.#.###.#.#####.#######.###.#.###.#.#.#######.#.#.#.#.#.#.#####.#.#.#.#.#.#.###.#.######### +#.#...#.......#.#.#.#...#...#.#.#.............#.#.#.#...#...###...#...#...###.#...#.#.#.......#...#...#...#.....#...#.#.#.#.#.###.#.........# +#.###.#######.#.#.#.#########.#.#.#############.#.#.###.#######.###.#.#.#####.###.#.#.#######.#################.#####.#.#.#.#.###.#########.# +#...#.###...#...#.#.#.......#...#.............#.#.#.#...#.......#...#.#...#...#...#...###...#.....#...........#.#.....#.#...#.....#.......#.# +###.#.###.#.#####.#.#.#####.#################.#.#.#.#.###.#######.###.###.#.###.#########.#.#####.#.#########.#.#.#####.###########.#####.#.# +#...#.#...#.....#...#.....#.......#...........#.#.#...###.......#.###.....#.#...###.......#.....#...#...#.....#.#.......#...#...#...#...#...# +#.###.#.#######.#########.#######.#.###########.#.#############.#.#########.#.#####.###########.#####.#.#.#####.#########.#.#.#.#.###.#.##### +#...#...#.....#.#.....###.......#.#...........#...#.....#...#...#.........#.#...#...#.........#.....#.#.#.....#...#...#...#...#.#.....#.....# +###.#####.###.#.#.###.#########.#.###########.#####.###.#.#.#.###########.#.###.#.###.#######.#####.#.#.#####.###.#.#.#.#######.###########.# +#...#.....#...#.#...#.#...#...#.#.#...........#...#...#.#.#...#.........#.#.....#.....#.......#####...#.......###.#.#.#.......#...#.........# +#.###.#####.###.###.#.#.#.#.#.#.#.#.###########.#.###.#.#.#####.#######.#.#############.#########################.#.#.#######.###.#.######### +#...#...#...#...#...#...#...#...#.#.............#.....#.#.....#.......#.#.#...........#.....#####################...#.#...#...###.#.........# +###.###.#.###.###.###############.#####################.#####.#######.#.#.#.#########.#####.#########################.#.#.#.#####.#########.# +#...#...#...#.###.....#.....#...#...............#...#...#.....#...#...#...#..E#######.......#####################...#...#...#.....#...#...#.# +#.###.#####.#.#######.#.###.#.#.###############.#.#.#.###.#####.#.#.#############################################.#.#########.#####.#.#.#.#.# +#...#.#.....#.........#.#...#.#...............#...#.#.###.#...#.#...#...#########################################.#.....#...#.....#.#...#...# +###.#.#.###############.#.###.###############.#####.#.###.#.#.#.#####.#.#########################################.#####.#.#.#####.#.######### +#...#.#.......#...#...#.#.....#...............#...#...#...#.#.#.....#.#...#######...#...#######.....#S............#...#...#.....#.#.......### +#.###.#######.#.#.#.#.#.#######.###############.#.#####.###.#.#####.#.###.#######.#.#.#.#######.###.###############.#.#########.#.#######.### +#...#.#...###...#...#...#...###.................#.....#.....#.#...#...#...#####...#...#...#####...#...............#.#...........#.#.....#...# +###.#.#.#.###############.#.#########################.#######.#.#.#####.#######.#########.#######.###############.#.#############.#.###.###.# +###...#.#...#.....#.......#...........................###...#.#.#.#.....#...#...#.......#...#...#...............#.#...........#...#...#...#.# +#######.###.#.###.#.#####################################.#.#.#.#.#.#####.#.#.###.#####.###.#.#.###############.#.###########.#.#####.###.#.# +###.....#...#...#.#.....#...#...........#...#...#...#.....#.#...#...#.....#.#.....#...#...#.#.#.#...........#...#...#.........#...#...###.#.# +###.#####.#####.#.#####.#.#.#.#########.#.#.#.#.#.#.#.#####.#########.#####.#######.#.###.#.#.#.#.#########.#.#####.#.###########.#.#####.#.# +#...#...#.......#.#.....#.#.#.#.........#.#...#...#...#.....#...#...#.....#.#...#...#...#.#.#.#.#.........#...#...#.#...........#.#.....#.#.# +#.###.#.#########.#.#####.#.#.#.#########.#############.#####.#.#.#.#####.#.#.#.#.#####.#.#.#.#.#########.#####.#.#.###########.#.#####.#.#.# +#.....#.........#.#.....#.#...#...........#...#.........#...#.#.#.#.#.....#.#.#.#.....#.#.#.#.#.#.......#.......#.#.............#...#...#.#.# +###############.#.#####.#.#################.#.#.#########.#.#.#.#.#.#.#####.#.#.#####.#.#.#.#.#.#.#####.#########.#################.#.###.#.# +#...............#...###...#...#.......#.....#...###...###.#...#.#.#.#.....#...#.#.....#...#...#.#.#...#.........#.#...............#...###...# +#.#################.#######.#.#.#####.#.###########.#.###.#####.#.#.#####.#####.#.#############.#.#.#.#########.#.#.#############.########### +#.........#...#...#.........#...#...#.#...###.....#.#.#...#.....#.#.#...#.#...#.#.....#.......#.#...#.......###...#.#.............#...#...### +#########.#.#.#.#.###############.#.#.###.###.###.#.#.#.###.#####.#.#.#.#.#.#.#.#####.#.#####.#.###########.#######.#.#############.#.#.#.### +#.........#.#.#.#.#...#...#.....#.#.#...#.....#...#.#.#...#.#...#.#...#...#.#...#...#...#.....#.............#...#...#...............#...#...# +#.#########.#.#.#.#.#.#.#.#.###.#.#.###.#######.###.#.###.#.#.#.#.#########.#####.#.#####.###################.#.#.#########################.# +#.......#...#.#.#.#.#.#.#.#...#...#.#...#.....#.....#.....#.#.#.#.........#...#...#.....#.#.......#...#...###.#...#.....#...................# +#######.#.###.#.#.#.#.#.#.###.#####.#.###.###.#############.#.#.#########.###.#.#######.#.#.#####.#.#.#.#.###.#####.###.#.################### +#.......#...#.#.#.#.#...#.....#.....#.....###.#.............#.#...#...#...#...#.......#.#...#.....#.#...#.....#.....###...#...#.........#...# +#.#########.#.#.#.#.###########.#############.#.#############.###.#.#.#.###.#########.#.#####.#####.###########.###########.#.#.#######.#.#.# +#.....#.....#.#.#.#.#...........#...#...#...#...###.......###.#...#.#.#...#.....#.....#.#...#.......#...........#...###...#.#...#.....#.#.#.# +#####.#.#####.#.#.#.#.###########.#.#.#.#.#.#######.#####.###.#.###.#.###.#####.#.#####.#.#.#########.###########.#.###.#.#.#####.###.#.#.#.# +#.....#.#.....#.#...#.....#.....#.#...#...#.#.....#.#.....#...#.#...#.#...#.....#.....#...#...#.....#.............#.....#...#...#...#...#.#.# +#.#####.#.#####.#########.#.###.#.#########.#.###.#.#.#####.###.#.###.#.###.#########.#######.#.###.#########################.#.###.#####.#.# +#.#...#.#.......###.......#.###...#.........#...#.#.#.#...#...#.#...#.#...#.....#...#.....#...#...#.......................#...#...#.......#.# +#.#.#.#.###########.#######.#######.###########.#.#.#.#.#.###.#.###.#.###.#####.#.#.#####.#.#####.#######################.#.#####.#########.# +#...#...#...###...#.........#...#...#...#...#...#.#.#...#...#.#.#...#...#...#...#.#...###.#.....#.......................#.#.#...#...........# +#########.#.###.#.###########.#.#.###.#.#.#.#.###.#.#######.#.#.#.#####.###.#.###.###.###.#####.#######################.#.#.#.#.############# +#.....#...#.....#.....###...#.#.#.....#...#...#...#...#.....#.#.#...#...#...#...#.#...#...#.....#...........#...........#...#.#.......#.....# +#.###.#.#############.###.#.#.#.###############.#####.#.#####.#.###.#.###.#####.#.#.###.###.#####.#########.#.###############.#######.#.###.# +#...#...#...........#.#...#...#...#.............#...#.#.#...#.#.#...#.#...#.....#.#...#...#.....#.........#.#.....###...#...#.#.......#.#...# +###.#####.#########.#.#.#########.#.#############.#.#.#.#.#.#.#.#.###.#.###.#####.###.###.#####.#########.#.#####.###.#.#.#.#.#.#######.#.### +###.....#...###...#.#.#.........#...#...###...###.#.#.#.#.#.#.#.#.#...#...#.#...#...#.###.#.....#...#...#.#.#...#...#.#.#.#.#.#.#.......#...# +#######.###.###.#.#.#.#########.#####.#.###.#.###.#.#.#.#.#.#.#.#.#.#####.#.#.#.###.#.###.#.#####.#.#.#.#.#.#.#.###.#.#.#.#.#.#.#.#########.# +#...#...#...#...#...#.....#...#.#...#.#...#.#...#.#.#.#.#.#.#.#.#.#...#...#.#.#.#...#.#...#.#...#.#.#.#.#.#...#...#...#.#.#...#...#.....#...# +#.#.#.###.###.###########.#.#.#.#.#.#.###.#.###.#.#.#.#.#.#.#.#.#.###.#.###.#.#.#.###.#.###.#.#.#.#.#.#.#.#######.#####.#.#########.###.#.### +#.#.#.....#...#.....#...#...#...#.#.#.#...#.###...#...#.#.#.#.#.#...#.#...#.#.#.#...#.#...#.#.#.#.#...#.#.#.....#.#...#...#...#.....###...### +#.#.#######.###.###.#.#.#########.#.#.#.###.###########.#.#.#.#.###.#.###.#.#.#.###.#.###.#.#.#.#.#####.#.#.###.#.#.#.#####.#.#.############# +#.#.#.......#...###...#.......#...#.#.#...#.......#.....#.#...#.#...#.#...#.#.#.#...#.#...#.#.#...#.....#...#...#...#...#...#.#.........#...# +#.#.#.#######.###############.#.###.#.###.#######.#.#####.#####.#.###.#.###.#.#.#.###.#.###.#.#####.#########.#########.#.###.#########.#.#.# +#.#.#...#...#.###...#.........#.#...#.###...#.....#...#...###...#...#...###...#.#.#...#.###.#.....#.#...#.....#####...#...###...#.....#...#.# +#.#.###.#.#.#.###.#.#.#########.#.###.#####.#.#######.#.#####.#####.###########.#.#.###.###.#####.#.#.#.#.#########.#.#########.#.###.#####.# +#.#...#...#...#...#...#.........#...#.....#.#.....###.#.###...#...#...........#...#...#...#...#...#.#.#.#.#...###...#.#.......#...###...#...# +#.###.#########.#######.###########.#####.#.#####.###.#.###.###.#.###########.#######.###.###.#.###.#.#.#.#.#.###.###.#.#####.#########.#.### +#...#.###...###.......#.#...#.......#...#.#.#...#.#...#.#...#...#...#.......#.#.....#...#...#.#...#.#.#.#...#...#...#.#.#.....#...#...#.#.### +###.#.###.#.#########.#.#.#.#.#######.#.#.#.#.#.#.#.###.#.###.#####.#.#####.#.#.###.###.###.#.###.#.#.#.#######.###.#.#.#.#####.#.#.#.#.#.### +#...#.....#...........#.#.#...#...#...#.#.#.#.#.#.#.#...#...#...###.#.#.....#.#...#.....#...#.....#...#...#...#.#...#...#...#...#...#.#.#...# +#.#####################.#.#####.#.#.###.#.#.#.#.#.#.#.#####.###.###.#.#.#####.###.#######.###############.#.#.#.#.#########.#.#######.#.###.# +#.....#...#.....#.....#.#.....#.#.#.###...#.#.#.#.#.#.....#...#...#.#.#.....#.###...#...#.........#.......#.#.#...#...#...#...#.......#.....# +#####.#.#.#.###.#.###.#.#####.#.#.#.#######.#.#.#.#.#####.###.###.#.#.#####.#.#####.#.#.#########.#.#######.#.#####.#.#.#.#####.############# +#.....#.#...#...#.###...###...#.#.#.....#...#.#.#.#.#.....#...#...#.#...###.#.#...#.#.#.#...#.....#.#.....#.#.#...#.#.#.#.#...#...###...#...# +#.#####.#####.###.#########.###.#.#####.#.###.#.#.#.#.#####.###.###.###.###.#.#.#.#.#.#.#.#.#.#####.#.###.#.#.#.#.#.#.#.#.#.#.###.###.#.#.#.# +#.#...#.....#...#.#.........#...#.#...#.#.#...#.#.#.#.#.....#...###...#...#.#.#.#...#.#.#.#.#.....#...#...#.#.#.#...#.#.#...#...#...#.#.#.#.# +#.#.#.#####.###.#.#.#########.###.#.#.#.#.#.###.#.#.#.#.#####.#######.###.#.#.#.#####.#.#.#.#####.#####.###.#.#.#####.#.#######.###.#.#.#.#.# +#.#.#.#...#.###...#...#.....#.###.#.#.#.#.#...#.#.#.#.#.#...#.......#...#.#...#...#...#.#.#.......###...#...#.#...#...#.....###...#...#...#.# +#.#.#.#.#.#.#########.#.###.#.###.#.#.#.#.###.#.#.#.#.#.#.#.#######.###.#.#######.#.###.#.###########.###.###.###.#.#######.#####.#########.# +#...#.#.#.#...#.......#.#...#...#...#.#.#.....#.#.#...#...#...#...#.#...#.###...#...#...#.......#.....#...#...#...#...#.....#...#...#.......# +#####.#.#.###.#.#######.#.#####.#####.#.#######.#.###########.#.#.#.#.###.###.#.#####.#########.#.#####.###.###.#####.#.#####.#.###.#.####### +#...#...#.....#.#.....#.#.#...#...###.#.......#...#.....#.....#.#...#...#.#...#.......#.........#.#...#...#...#.#.....#.......#...#.#.......# +#.#.###########.#.###.#.#.#.#.###.###.#######.#####.###.#.#####.#######.#.#.###########.#########.#.#.###.###.#.#.###############.#.#######.# +#.#.............#...#...#.#.#...#.#...#.......#...#...#...#...#...#...#.#.#...#...#...#.#...#...#...#.#...###.#.#.#...#...#...#...#...#.....# +#.#################.#####.#.###.#.#.###.#######.#.###.#####.#.###.#.#.#.#.###.#.#.#.#.#.#.#.#.#.#####.#.#####.#.#.#.#.#.#.#.#.#.#####.#.##### +#.#.......#.....#...#.....#...#.#.#...#.......#.#.....#...#.#.....#.#...#...#...#...#.#...#...#...###.#...#...#.#.#.#.#.#.#.#...#...#.#.....# +#.#.#####.#.###.#.###.#######.#.#.###.#######.#.#######.#.#.#######.#######.#########.###########.###.###.#.###.#.#.#.#.#.#.#####.#.#.#####.# +#.#.#.....#...#.#...#.....#...#...#...#...#...#.#.....#.#.#.....###.....#...#.........#...#.....#...#...#.#...#.#...#...#.#.......#.#...#...# +#.#.#.#######.#.###.#####.#.#######.###.#.#.###.#.###.#.#.#####.#######.#.###.#########.#.#.###.###.###.#.###.#.#########.#########.###.#.### +#.#.#...#...#.#.#...#.....#.....#...#...#.#...#.#.#...#.#...#...#.......#.#...#...#...#.#.#...#.#...#...#.#...#.....#.....#...#...#...#.#...# +#.#.###.#.#.#.#.#.###.#########.#.###.###.###.#.#.#.###.###.#.###.#######.#.###.#.#.#.#.#.###.#.#.###.###.#.#######.#.#####.#.#.#.###.#.###.# +#...###...#...#...###...........#.....###.....#...#.....###...###.........#.....#...#...#.....#...###.....#.........#.......#...#.....#.....# +############################################################################################################################################# diff --git a/20/main.go b/20/main.go new file mode 100644 index 0000000..1ddca2a --- /dev/null +++ b/20/main.go @@ -0,0 +1,209 @@ +package main + +import ( + "flag" + "fmt" + "os" + "strings" + "time" +) + +const ( + SaveAtLeast1 = 100 + CheatTime1 = 2 + + SaveAtLeast2 = 100 + CheatTime2 = 20 +) + +func catch(err error) { + if err != nil { + panic(err) + } +} + +func main() { + flag.Parse() + if flag.NArg() != 1 { + fmt.Println("Usage: go run . input.txt") + os.Exit(1) + } + + bs, err := os.ReadFile(flag.Arg(0)) + catch(err) + + parsed := parseInput(string(bs)) + part1(parsed) + part2(parsed) +} + +type Point struct { + X, Y int +} + +func (p Point) Add(o Point) Point { + return Point{X: p.X + o.X, Y: p.Y + o.Y} +} + +var Dirs = []Point{{0, 1}, {1, 0}, {0, -1}, {-1, 0}} + +type Parsed struct { + Map []string + W, H int + Start Point + End Point +} + +func parseInput(input string) *Parsed { + lines := strings.Split(input, "\n") + if len(lines[len(lines)-1]) == 0 { + lines = lines[:len(lines)-1] + } + parsed := &Parsed{Map: lines, W: len(lines[0]), H: len(lines)} + for y, line := range lines { + for x, c := range line { + if c == 'S' { + parsed.Start = Point{X: x, Y: y} + } + if c == 'E' { + parsed.End = Point{X: x, Y: y} + } + } + } + return parsed +} + +const Wall = '#' + +type Distances map[Point]int + +func (d Distances) Print(parsed *Parsed, label string) { + return + fmt.Printf("\n%s:\n", label) + for y := 0; y < parsed.H; y++ { + for x := 0; x < parsed.W; x++ { + p := Point{X: x, Y: y} + if steps, ok := d[p]; ok { + fmt.Printf("%3d", steps) + } else { + fmt.Printf(" %c", parsed.Map[y][x]) + } + } + fmt.Println() + } +} + +func bfs(parsed *Parsed, start, end Point) (steps int, visited Distances) { + visited = Distances{start: 0} // save steps to reach point + next := []Point{start} + var cur []Point + + var step int + for len(next) > 0 { + step++ // start with 1 + cur, next = next, cur[:0] + for _, p := range cur { + if p == end { + return step - 1, visited + } + for _, dir := range Dirs { + nb := p.Add(dir) + if nb.X < 0 || nb.X >= parsed.W || nb.Y < 0 || nb.Y >= parsed.H { + continue + } + if parsed.Map[nb.Y][nb.X] == Wall { + continue + } + + if _, ok := visited[nb]; ok { + continue + } + visited[nb] = step + next = append(next, nb) + } + } + } + panic("path not found") +} + +// brain! work! +// there were DFS tasks last days, so brain is **buzzled** with mem + DFS +// (typo is nice) +// Do we really need DFS? It just keeps popping in my head +// Nice move, Eric! 2 relaxing days and alignment with the task +// I think same trick was used in previous years, not sure +// +// 50 minutes in, and still no vision +// Cursor keeps suggesting BULLSHIT, that also is distracting +// Fuck you, Cursor! You hear me? +// +// Ok, vision is following: +// 1. BFS forward from the start +// 2. BFS backward from the end +// 3. cheat and count +// easy! + +func findWaysToCheat(parsed *Parsed, start, end Point, saveAtLeast, maxCheatTime int) (ways, stepsWithoutCheating int) { + // 1. simple bfs first, fill forward map + stepsForward, forward := bfs(parsed, start, end) + forward.Print(parsed, "forward") + + // 2. bfs backwards + stepsBackward, backward := bfs(parsed, end, start) + if stepsForward != stepsBackward { + panic("wut?") + } + backward.Print(parsed, "backward") + + // 3. iterate over all visited points and check if we can still cheat from there + // 2 cheat steps = 1 wall, because we need to land on empty space again + for p, cheatStep := range forward { + // p = (1,3) + if cheatStep > stepsForward-saveAtLeast-2 { + continue + } + // now we need to skip up to maxCheatTime + for dy := -maxCheatTime; dy <= maxCheatTime; dy++ { + cheatTimeLeft := maxCheatTime - abs(dy) + for dx := -cheatTimeLeft; dx <= cheatTimeLeft; dx++ { + np := Point{X: p.X + dx, Y: p.Y + dy} + if np.X < 0 || np.X >= parsed.W || np.Y < 0 || np.Y >= parsed.H { + continue + } + if parsed.Map[np.Y][np.X] == Wall { + continue + } + cheatTime := abs(dx) + abs(dy) + if backStep, ok := backward[np]; ok { + if cheatStep+cheatTime+backStep <= stepsForward-saveAtLeast { + ways++ + } + } + } + } + } + + return ways, stepsForward +} + +func abs(x int) int { + if x < 0 { + return -x + } + return x +} + +func part1(parsed *Parsed) { + timeStart := time.Now() + ways, stepsWithoutCheating := findWaysToCheat(parsed, parsed.Start, parsed.End, SaveAtLeast1, CheatTime1) + + fmt.Printf("Part 1: %d to save %d steps out of %d, with cheat time %d\t\tin %v\n", ways, SaveAtLeast1, stepsWithoutCheating, CheatTime1, time.Since(timeStart)) +} + +func part2(parsed *Parsed) { + timeStart := time.Now() + ways, stepsWithoutCheating := findWaysToCheat(parsed, parsed.Start, parsed.End, SaveAtLeast2, CheatTime2) + + fmt.Printf("Part 2: %d to save %d steps out of %d, with cheat time %d\t\tin %v\n", ways, SaveAtLeast2, stepsWithoutCheating, CheatTime2, time.Since(timeStart)) + +} diff --git a/20/sample.txt b/20/sample.txt new file mode 100644 index 0000000..c097dae --- /dev/null +++ b/20/sample.txt @@ -0,0 +1,15 @@ +############### +#...#...#.....# +#.#.#.#.#.###.# +#S#...#.#.#...# +#######.#.#.### +#######.#.#...# +#######.#.###.# +###..E#...#...# +###.#######.### +#...###...#...# +#.#####.#.###.# +#.#...#.#.#...# +#.#.#.#.#.#.### +#...#...#...### +############### diff --git a/20/task.txt b/20/task.txt new file mode 100644 index 0000000..051d456 --- /dev/null +++ b/20/task.txt @@ -0,0 +1,176 @@ +https://adventofcode.com/2024/day/20 + +--- Day 20: Race Condition --- +The Historians are quite pixelated again. This time, a massive, black building looms over you - you're right outside the CPU! + +While The Historians get to work, a nearby program sees that you're idle and challenges you to a race. Apparently, you've arrived just in time for the frequently-held race condition festival! + +The race takes place on a particularly long and twisting code path; programs compete to see who can finish in the fewest picoseconds. The winner even gets their very own mutex! + +They hand you a map of the racetrack (your puzzle input). For example: + +############### +#...#...#.....# +#.#.#.#.#.###.# +#S#...#.#.#...# +#######.#.#.### +#######.#.#...# +#######.#.###.# +###..E#...#...# +###.#######.### +#...###...#...# +#.#####.#.###.# +#.#...#.#.#...# +#.#.#.#.#.#.### +#...#...#...### +############### +The map consists of track (.) - including the start (S) and end (E) positions (both of which also count as track) - and walls (#). + +When a program runs through the racetrack, it starts at the start position. Then, it is allowed to move up, down, left, or right; each such move takes 1 picosecond. The goal is to reach the end position as quickly as possible. In this example racetrack, the fastest time is 84 picoseconds. + +Because there is only a single path from the start to the end and the programs all go the same speed, the races used to be pretty boring. To make things more interesting, they introduced a new rule to the races: programs are allowed to cheat. + +The rules for cheating are very strict. Exactly once during a race, a program may disable collision for up to 2 picoseconds. This allows the program to pass through walls as if they were regular track. At the end of the cheat, the program must be back on normal track again; otherwise, it will receive a segmentation fault and get disqualified. + +So, a program could complete the course in 72 picoseconds (saving 12 picoseconds) by cheating for the two moves marked 1 and 2: + +############### +#...#...12....# +#.#.#.#.#.###.# +#S#...#.#.#...# +#######.#.#.### +#######.#.#...# +#######.#.###.# +###..E#...#...# +###.#######.### +#...###...#...# +#.#####.#.###.# +#.#...#.#.#...# +#.#.#.#.#.#.### +#...#...#...### +############### +Or, a program could complete the course in 64 picoseconds (saving 20 picoseconds) by cheating for the two moves marked 1 and 2: + +############### +#...#...#.....# +#.#.#.#.#.###.# +#S#...#.#.#...# +#######.#.#.### +#######.#.#...# +#######.#.###.# +###..E#...12..# +###.#######.### +#...###...#...# +#.#####.#.###.# +#.#...#.#.#...# +#.#.#.#.#.#.### +#...#...#...### +############### +This cheat saves 38 picoseconds: + +############### +#...#...#.....# +#.#.#.#.#.###.# +#S#...#.#.#...# +#######.#.#.### +#######.#.#...# +#######.#.###.# +###..E#...#...# +###.####1##.### +#...###.2.#...# +#.#####.#.###.# +#.#...#.#.#...# +#.#.#.#.#.#.### +#...#...#...### +############### +This cheat saves 64 picoseconds and takes the program directly to the end: + +############### +#...#...#.....# +#.#.#.#.#.###.# +#S#...#.#.#...# +#######.#.#.### +#######.#.#...# +#######.#.###.# +###..21...#...# +###.#######.### +#...###...#...# +#.#####.#.###.# +#.#...#.#.#...# +#.#.#.#.#.#.### +#...#...#...### +############### +Each cheat has a distinct start position (the position where the cheat is activated, just before the first move that is allowed to go through walls) and end position; cheats are uniquely identified by their start position and end position. + +In this example, the total number of cheats (grouped by the amount of time they save) are as follows: + +There are 14 cheats that save 2 picoseconds. +There are 14 cheats that save 4 picoseconds. +There are 2 cheats that save 6 picoseconds. +There are 4 cheats that save 8 picoseconds. +There are 2 cheats that save 10 picoseconds. +There are 3 cheats that save 12 picoseconds. +There is one cheat that saves 20 picoseconds. +There is one cheat that saves 36 picoseconds. +There is one cheat that saves 38 picoseconds. +There is one cheat that saves 40 picoseconds. +There is one cheat that saves 64 picoseconds. +You aren't sure what the conditions of the racetrack will be like, so to give yourself as many options as possible, you'll need a list of the best cheats. How many cheats would save you at least 100 picoseconds? + +--- Part Two --- +The programs seem perplexed by your list of cheats. Apparently, the two-picosecond cheating rule was deprecated several milliseconds ago! The latest version of the cheating rule permits a single cheat that instead lasts at most 20 picoseconds. + +Now, in addition to all the cheats that were possible in just two picoseconds, many more cheats are possible. This six-picosecond cheat saves 76 picoseconds: + +############### +#...#...#.....# +#.#.#.#.#.###.# +#S#...#.#.#...# +#1#####.#.#.### +#2#####.#.#...# +#3#####.#.###.# +#456.E#...#...# +###.#######.### +#...###...#...# +#.#####.#.###.# +#.#...#.#.#...# +#.#.#.#.#.#.### +#...#...#...### +############### +Because this cheat has the same start and end positions as the one above, it's the same cheat, even though the path taken during the cheat is different: + +############### +#...#...#.....# +#.#.#.#.#.###.# +#S12..#.#.#...# +###3###.#.#.### +###4###.#.#...# +###5###.#.###.# +###6.E#...#...# +###.#######.### +#...###...#...# +#.#####.#.###.# +#.#...#.#.#...# +#.#.#.#.#.#.### +#...#...#...### +############### +Cheats don't need to use all 20 picoseconds; cheats can last any amount of time up to and including 20 picoseconds (but can still only end when the program is on normal track). Any cheat time not used is lost; it can't be saved for another cheat later. If cheat mode is active when the end position is reached, cheat mode ends automatically. + +You'll still need a list of the best cheats, but now there are even more to choose between. Here are the quantities of cheats in this example that save 50 picoseconds or more: + +There are 32 cheats that save 50 picoseconds. +There are 31 cheats that save 52 picoseconds. +There are 29 cheats that save 54 picoseconds. +There are 39 cheats that save 56 picoseconds. +There are 25 cheats that save 58 picoseconds. +There are 23 cheats that save 60 picoseconds. +There are 20 cheats that save 62 picoseconds. +There are 19 cheats that save 64 picoseconds. +There are 12 cheats that save 66 picoseconds. +There are 14 cheats that save 68 picoseconds. +There are 12 cheats that save 70 picoseconds. +There are 22 cheats that save 72 picoseconds. +There are 4 cheats that save 74 picoseconds. +There are 3 cheats that save 76 picoseconds. +Find the best cheats using the updated cheating rules. How many cheats would save you at least 100 picoseconds? +