~cdv/aoc-2018-rs

fd04524d7267b494d86c15777763936c881998eb — Christopher Vittal 1 year, 9 months ago 88767b3 master day20
Solve day twenty
3 files changed, 350 insertions(+), 1 deletions(-)

A data/day20
A descriptions/Day20.md
M src/bin/day20.rs
A data/day20 => data/day20 +1 -0
@@ 0,0 1,1 @@
^WNWNENNWSWWSWNWWSSSSWSEENEENN(WSWNNSSENE|)E(N|SSSSENESSENEEENESEESSWNWWWSW(N|SWNWSWSWSWWWNENWWSSSESWSSSSSSWNWNNWWNNEES(W|E(NNNWSWWWWSESSSSENESSWWSWWNNNWWWNWWSWWSWWWWWWNNNNESSENNNEESSSW(S(WW|EENNESENENESENEEE(NWNENENENWNWNNNWNWSSSWWNWWSWWWWSSWNNWSWWSSSWWWSSSESWWSWSWSWWSESWWNWNWWWWNWSWSWNNWNENEEES(WWSNEE|)ENNWWWNENNNNENNWWS(SWNNWSWNNENNWNWWNEEEEENEESSW(N|SSS(WWNNN(ESSNNW|)W|EEENNEENNWSWW(SSWNSENN|)NENEEESSSSENNNESSSENNNNNWSWNNENWNWNWSWNNWSWWSESSES(W(WNNWWWWSEEESWWSWWN(E|NNWSSSWWWWSESSE(NN|EES(E|SSWSSSSWNNNNWSW(SESWSESEESESWSSSESWWNNWSW(SSE(N|SENEESEE(SSEEESENEESWSWWWNWSWWN(E|NNWSSSWWNWNN(W(SSSESEEESSWSWWSW(NNN(ESENEWSWNW|)N|SEEEEN(EN(ESSENEESSW(SWWWWSWNWN(EEE(EE|N)|WWSESSE(EEEESESSSSSENNESSENNENWNWSWNNENN(WSWNWW|ESSEEESW(SEEEESSSENNENWNEENEENWWNNEEES(SESEENWNWNEEEENWWWWWWWNWSWNWNENENWNWWWSWSSEE(SSESSE(N|SSWWSWNNNN(ESSEWNNW|)WNN(ESNW|)WSSWW(SSEEE(NWWEES|)SS|NNNNNEE(SSW(SS|N)|NNE(S|EEEENWWWNNEN(EESS(W(N|W)|EEEEENWNNEEN(ESSSENENN(WSNE|)ESSEESWWSSEEEN(NENESSENENNESE(NNNWSWNW(SWNWSWWS(WNSE|)E(EEESNWWW|)S|N)|SENESESENEEESWWSSWWN(WWN(E|WW(WSSSWSESENEENE(SEEESEENWN(WWW|NESESSESWSEEESEESSSSWWSWNNENWN(EESSNNWW|)NWWWNNWWSESWSWWWNENWWWSSWSEE(NN|ESENESSSSWSESENNNNNNESEEE(SWWSEESSESEENEENN(NNEEEESEESSEESSWWSWWNNE(NWWWW(NEN(ESEEWWNW|)W|SSSEE(NWNEWSES|)SSENESESSWNWWSSSSSWSSWSS(EEN(W|EENNNNNESEEEENNWWW(SEEWWN|)(WWW(N|SSSSSWN(SENNNNSSSSWN|))|NNNEEESWS(WNSE|)EESSSSESWSEESS(EEENNENEENEESEENNENEENNWWS(WSWS(S|WWNWWWWNWNNESENEENNNNWNEENWWWNENENWNENNENWNWWWWNNNNESENESEESWWWS(WNSE|)EEESESSSWSSSEESESWSESSEEESWSEEENNW(NEENESENNNENWWSSWWNNE(S|NNWSWWNENENEENENWNENNNWWNWSWWWSSENESSWWWWNENWWSS(SESSW(SSENENES(SWSESESWSEE(NN|S(WSWNW(NNNWNWWN(SEESESNWNWWN|)|S)|E))|ENENN(EE(SWEN|)NNW(NEESNWWS|)S|WSWWNE))|N)|WNNNNNWSW(SEWN|)NWSWNWWNNEEEEENNNNESSSSS(WWWWW|EENWNNNENNENWWWWS(EESNWW|)WNWWSSWNNWWWSSWNNWNWNNESEEEEES(ENESEENWNENWNEENEESESWSEESESEENNNNNNNENWWNWWWWWWNEEENWWWWNNWSWNWWNWWNEEEES(W|ENNWNNESESEENNEEESSSSEEENESSWWWWS(EEEESEENWNNNNWNNNWSSSWSWNNENWNENEENWNNENEESWS(ESEEESSWWWSEESWSSENENEN(W|NNNENNEENNWNNEENNNWNNEES(W|ENENESSEENNNW(WNENENWWSWSWWWSEE(E|SWWWWSSWSSWNNNNE(NENE(S|NWWSWSWSSSSSSWSWSESSSES(ENNNW(NEN(W|NE(EENWN|SSSSE))|S)|WWNNNWNWNENWWSWSS(E(N|E)|WS(E|SWWNENWWSSSSENES(ENSW|)SWWWS(WWW(SESNWN|)WWWNWWNWWNNEENEENWNNESEESESENENNNWSSWNNWW(SEWN|)NNEENNWWNENWWWNNWSSSEESS(WNWWSWSSWWWNWNNEES(W|SENNENWNENNWSWWNNNNNEEESEEENWWNNESENNNNWSSWNWWWSSWNWWNEENWWWWSWNNWSSSSSWWSSSSESEEEENENWNNNWNW(NEE(SESSE(N(EEENE(NWES|)S|N)|S(SSSWSWWSSSWSSSWWNWSSWWSSWWWWNEENWWNNWSWWWNNEE(SWEN|)EENWNNNNEENWWWSSSWWWSS(EEENWW|SWWSSESE(NNWESS|)SSSWWSEESENNESSENNNE(SSSSEESSSSSES(EEESENEESENNNWNENEEESSWNWSSEESWWSESWSSWWSWS(W(W(SEE|WWN)|NNNN(WSSNNE|)E(N|ES(WS|EN)))|EEEN(ENNEENWNEENWNNNEESWSEEEEES(EENNW(WN(WSWNW(N(WNNNNWNNESES(ENNWNWN(EESEE(SSW(N|S)|NEENNWW(N|WS(EE|S)))|WWS(WSESSWNWWWSEESEEESSW(SEWN|)NWSWWWWSWNWSWWNNNENWWSW(SESWSSSEEN(WNSE|)EEESS(WW(NEWS|)WW|E)|NWSWNNEEEEEENEN(WWSNEE|)NEESEE(SWWW(N|SWSWSS(WSNE|)EEEE(NWW(W|N)|E))|NNNE(S(S|E)|NW(WSSSNNNE|)NNNEE(N|EESWWWS(NEEENWESWWWS|)))))|E))|SSS)|EE)|S)|E)|S)|WWWSSE(N|SWWN(NN|WSSEEEENESESSEN(EESESWSEEESS(WNWSSWNWWNNWN(EE(SSEWNN|)N|WWNENWWSWWWN(EE|WW(NEWS|)SWS(W|ESSENN(N|EESWSSSSES(ESEENWNNENWNW(SW(SESNWN|)N|NE(NWES|)ESE(SSS(SSEEENNNWW(SESWENWN|)NN|W)|N))|WWNWN(ENWESW|)WSSESWSWWNENWNENWNWSWSWSSEE(SWSESWWWSSWSWSESEESESSESSENNNWNENNWNENENEEEN(ESSE(N|SWSEEEEN(WW|NNESSSENEEE(NWNSES|)SSWW(NEWS|)WWWSSWWWNN(ESENSWNW|)WWNWSWNN(EENWWEESWW|)WSSSESSEENE(NWWSNEES|)SSWWSSENESSSENNEESWSEE(SSSWSESWSWSEENENESS(ENNNNWSWNNEEESS(NNWWWSNEEESS|)|SW(WWSWNWWNWNWW(SES(ESEESSWSS(EEENW(NEEENW(WW|NEESSSSWW(NEWS|)S(WSESSWSW(SEENESEES(ENEWSW|)WSWW(WNEE|SSEN)|NN(NWNEWSES|)E)|EEEENNW(NN|S)))|W)|WN(NNEWSS|)WSW(N|W))|W)|WWNNNENNENEN(WNNW(N(NN|E)|SSWWWWSWNNWNEESE(NNWNWN(E|NWWNWWSWNW(NEENWNNENNNW(NEEESSE(NE(SENSWN|)NNNWS(W|S)|SWS(W(S(W|SS|E)|NNN)|E))|SWS(E|SSS))|SSW(SS(WW|ES(W|SES(ESWSEESEEN(ESSWSEENENE(NW(WSNE|)NEE(SS|E)|SSSW(N|WWW))|WNN(ESNW|)NW(SS|WNNW(S|N(NEE(N|S(ENESS(WSWNSENE|)E|W))|W))))|W)))|NWWWW(NEE(N|EE)|W))))|EE))|ESSSENEEESWWSSE(SWW(SESNWN|)NNWSSWWWNENE(S|N(N|W))|N)))|N))|NNNWWWNEEE(NWWWEEES|)EE)))|WN(WWS(E|W(SWWWSSE(NEWS|)S(SE|WWN)|N))|EN(N|W)))|N(W|N)))))))|EEEEN(NWSWWNE(WSEENEWSWWNE|)|ESSWSW(NWES|)SEE(S(W|S)|N)))|N))))|W))|SWWWNE(E|NNWNNE(S|NWWWSESWWNWWWSEESSSESWWNWSWSSWNWNENWWNEEE(S|N(ESENSWNW|)NWSWNNWSWNWWSESE(SWWWSSWNNWWWSSWWWNNWNWSWNWSWNWWNWW(NWNNWSS(SEWN|)WNNWWNENEEENWWWNEEEENEESWSSW(S(WWW|SES(W|SEENNW(S|N(EEEESWWSESWS(EENESEEEENNNWWSS(ENSW|)WNNNNENWNENENEESSSESWWW(NEN(W|N)|S(W|EESESEENES(EENNW(WNWSW(NNNESEEENNWNENNENNWWNEENEEESWSW(N|SEESE(SWWSSEEN(W|ESS(ENSW|)WWSESSWWSS(ENEENESS(WWSWENEE|)EEN(EE|W)|WWNNN(NEE(S(WSSNNE|)E|NWNNW(NENEWSWS|)SS)|WW)))|NN(W|ENWNEE(SS|NENWWSWWNENEEEENNENWWSSWWNNNNES(EEENEEESSWNWSSES(WWSSSWN(SENNNEWSSSWN|)|ENEENESSENE(NWNWWNNNEEEESWWWSEE(S|EENNNNWWWS(EE|WWWSS(SSS|WWWNENNNNNNNENESENNWNWWS(E|SWSSWWWSEESWWSSEES(WWSS(WNWWWNWSWWSSWSSSWSESEESWWS(SWWWSWSWNNENWNENESES(ENNWNWNENWNWSSWWWSSSWWWNEENNNNWNEEEE(NNNNENNENNWWNEENWWNENWNEEESWSESENESSEENESESWWWSEESSEES(WWWNWWWSSWNW(SSESWS(WNNNSSSE|)EE(NEN(NE(NWES|)E|W)|S(W|S))|NENNEE(NWNWSNESES|)S(EE|W))|SEENWNNE(S|NNNNNNESSEE(SWWEEN|)NENWNEEEEENESS(SENNNNNWWWS(SWWNNNNEEN(EEESWWS(WWSSNNEE|)EEEENWNEESENESESWSESSSENESSEENENEEESSSSSWNWSWSWSWWWWNWWNNWSWNW(NNENEEE(SWWS(W|EEENESEEES(ENNEE(NW|SW)|SWNWSS(WNNWWSE(WNEESSNNWWSE|)|E)))|NWWNN(NESSEWNNWS|)WWSESWS(NENWNEWSESWS|))|WSESSEE(NWES|)SWWWNWSWNWSSES(ENEEEEENNESSESENEN(WW|EEENENEEESESENENESESESSWSSSWWNNE(NWN(WWWNWNWSWSESE(EEESSSSESWSSESESESESW(WNWSWNN(E|WN(E|WWS(WWW(NNESEWNWSS|)S|SSSS|E)))|SSEEENW(W|NNENEENESSENENESSWSWWWNWS(W|SSSESWSWWW(NEN(ESNW|)W|S(EEEEESWWWSEEES(WWWSSWSESWWWSS(EEN(W|E)|WNNWS(WWN(EN(EN(ESEEWWNW|)N|W)|WW)|S))|ENNENWNNW(SWEN|)NEESENEEESE(SWS(E|WNW(NE|SWNW)|S)|NNNNNWWW(SWSWS(WWWNEE|EENEE(SW|NW))|NNEES(ENNNEENWNENENEEENWWWNWWWNWWWWWNNENNNNWWSWSWSEE(NE(S|N)|SSWSESSENESSWSESENEENN(NWWSSEN(SWNNEEWWSSEN|)|EEESWWS(SWS(E|SWS(WNN(ENSW|)WSWNWSWS(E(S|EE)|WWWS(WNNEEENENE(NWN(E|WNENWNNWN(EE|NNWSWS(SSSSWSSSWSSS(WN(W|NN)|SE(SEWN|)NNNENEE(SWEN|)ENWWN(WSNE|)NE(S|NWN(E|NN)))|WNNW(NWSWNWNNEES(EENESS(ENEE(SWEN|)NWWNEENNNENNWWS(SWSWWWSWNWSWNNENNWSWWWNEEN(EEEESWSSEEN(E(S|NE(N(WWSNEE|)EEEEEEESWSEESEENNESSSSWSSESWWWNNE(S|NN(WSWNNWWSSSS(EN(ESSSSSSS(W|ENNNEEEN(EENNNNNNENWNEN(ESSESSEENWNNWNEEEEEEESSESWSSSESWSEE(NNNN(WSNE|)NNNNWS|SSSSWNWNN(ESNW|)WNNNWNNNNN(ESSSSNNNNW|)WWS(WNSE|)SSE(NN|SWSSE(ESSWNWWWSSSWWWSSESENEN(ESESSESWWW(N(NESNWS|)WWWNWNWNWN(ENE(ENESENNNWNN(ESEE(SW|NW)|N(WSSSSE|N))|SS)|WSS(WNN|ESE))|SSSWSESEEESEEEENE(NWWSWWNNNN(NESSS(S|ENEE(SWEN|)NNWW(SEWN|)NENWN(EESSNNWW|)NWNWN(E|WSS(WNNNWSS(NNESSSNNNWSS|)|SE(N|ESW(SEWN|)W))))|WSSWS(E|WNNENW))|SSWSESWSESSWSESWW(SWSEEE(NWES|)SSWSWWWWSSSESWSWNNWNNE(S|NNEEEN(WNNWSSWWW(SESWW(SESWSSE(N|SWSWNNWSSWSESWSSSSSENNNNENEN(W|ENE(SSESENNEN(WWSNEE|)ESSESWSW(NN|SSEESSESWSWSWNNNWSSSSWSSWNNWNNNENNWNWNN(NE(SSEN(ESS(E(S(EESSNNWW|)WSSSSWN(SENNNNSSSSWN|)|NN)|W)|N)|N)|WSSSSSWNWSWWSWNW(NEENN(NE(SSS|N)|WSWNW(S|NNNWNNN(EEE|N)))|SSWNWS(SSSENESEESESSEEENESESENEESESSWNW(N|WWWWSESWSWNWSWSWSWNWNWWSSSESESWSWS(WNWWS(E|SWNNWSW(NNENNW(SWNSEN|)NNENN(NWWWN(NN(WSSSNNNE|)N|EE)|EESSW(S(EESSE(NNNNN(WSSNNE|)NNNENENN(EESSE(SWW(NN|SW(SW(SEENENESS(WSEWNE|)ENENN(WSNE|)E(SS|EE)|N)|N))|N)|WW(N|S(E|S)))|ESWWWNW(NEWS|)S)|W)|N))|WSE(SWWNNSSEEN|)E))|SEEN(NEEENWNEN(WW(WNWNSESE|)SS|NEEN(ESENEN(W|NNESE(N|SENEENNEENNWNWNWW(NNENESS(W|ESESE(SSSSSSWSSWWWSEEEE(NN|SSWNWSSEESSWSESWWWSWWWNWSSEEESSESSEEE(SWWSSSEE(NNWSNESS|)SWSWWSWSWWNENNWWNEEENWWWNWSWNNWSWSSSESESEE(SSESWSWSSWNWWSESSENESEEEENEESENNE(NNWSWWNWSS(WSWWNNE(S|EN(W|NEN(EES(W|S|EENNW(S|W(NEENSWWS|)W))|W)))|EE)|SSSWSESWSWS(EENSWW|)WWWWNNWWNEEN(EESEN(N|ESSWWS(WNNSSE|)E)|WWWWWSEESSS(EENWESWW|)WWNWSWWWWWNWSWNWWNWNENESEEES(WWW|ENESENES(SWWWEEEN|)E(EESNWW|)NNWNNE(SENSWN|)NNNEENNWSWWWSWWSWNWW(NENN(WSNE|)ESSEENNW(S|NNNEEESSSS(WNNNWS|ENNN(NNNWWNW(SSEEWWNN|)WNNN(NESSSEENWNNNNNWSSWNNNEEENEESENNNENENWWWW(SE(SSWNWWS(E|SW(NN|W))|E)|NEEEN(WWW|ENESS(SEEESWWWSWSWSSSSE(NNNEEENN(WSWENE|)EE(E(SSWW(NE|SW)|E)|NNNWWNW(NEN(WWNSEE|)EEN(E(NNESNWSS|)S|W)|S))|SWWSSWS(W(S(SWEN|)E|NNW(NEE(NENWW(SWNSEN|)N|S)|S))|EENNEENESSWSEEN(ESSES(WWNW(WWNNSSEE|)S|SSS(WSNE|)E)|NN)))|W)))|WSSSWNNW(ESSENNSSWNNW|))|ESSE(ESE(SWSNEN|)N|N))))|WW(SSENESE(SWWS(EEES(WW|ENNN(WSNE|)ESE(SSWNSENN|)NN(E(S|N)|W))|W(N|WSW(N|SSW(NN|WWWSEES(WWWWWN(WSNE|)EN(E(S|N)|W)|EEN(ESEEWWNW|)W)))))|N)|WWWWWNEENWWNNW(NNNWWEESSS|)SSW(SESWSWS(EE(S|EN(E|W))|W(N|W))|NN))))))|N(E|WNNW(WNSE|)S))|NWNW(NWNEEE(NWWEES|)S(W|S)|S)))|NNWNWNEE(NW(W|NENNNNNW(SS|W(NENNE(NNWNNWW(S(ESSEWNNW|)W|NNN(WSNE|)ESSEE(NWNENSWSES|)SS)|SS)|W)))|S)))|S(ESESEWNWNW|)WNWSWNNNWSWS(E|WNW(SSEWNN|)NNWS(WNN(WS(S|WW)|ENEEESW(W|SE(SWEN|)ENNNN(N|E)))|S)))))|W))|W)))|WNW(S|NWSWWNE(WSEENEWSWWNE|))))))|NN)))|W)|NEEN(WW|N))|E(E|S)))|NNN(N(W|NNNWWWWSWNWN(WNWSSS(E(N|SE(E|N))|WNWN(ENNN(WSSNNE|)E(N(E|W)|S)|WSS(E|W(NN|S(S|E)))))|EE))|E))))|WW)|N)))|WW(SSSSSS(W|SS)|WWWS(WNSE|)S))|WWW))|NN)|WW(S|NENWNENNNES(NWSSSWENNNES|)))|E))|S))|W)|WWWSSWWSWNWNEEENWWWWSW(NWES|)SESWSEE(N|E(SWSNEN|)EEEEN(WW|EESSW(N|SE(SSW(N|SES(SENSWN|)W)|EEEE(EEN(EENSWW|)W|S))))))|E)|W|S)|W)|S))))|E)|E))|E))|E)))|W))))|WW)))))|SWWWN(NWWS(E|W)|E)|N)|E(NWES|)E)|S))|WW(NNNNEEE(NN|E)|SS)))|WWWWWSSENESSSWWS(WNWSWWWNENE(S|NNEE(NWWWWWSWNWSSWNWSSEESEE(NWNEE(ENWESW|)S|SSESS(WWN(NNWSWW(SEESSNNWWN|)NWWWNWSWSWWWWSSSSSSESWWNWNENNNNWWSWWSESE(SSSSWNWNWSSWNNNNE(NWWWNNWWNNENWWSSSWNWNWSWNNENENWWNN(ESENEEESWWSEEES(EENNW(N(WSNE|)EESSENEESSSSWSE(EEENEEENWWNWWW(SSENEWSWNN|)NNN(EESWSEEESENNWWNEEESENEESSS(ENE(SS(EESNWW|)W|NN(WSNE|)EE)|WN(WWSESWS(NENWNEWSESWS|)|N))|WWW)|SWWNWNN(E(EN(N|WW)|S)|WSS(SES(W|E)|W(NN|W))))|S)|WWWS(W|S))|WWWSWWSSSEENEN(WWSNEE|)E(NWES|)S(SWSESSSWNNWNWWWNWW(NNESENNWWNEEEE(WWWWSEWNEEEE|)|SESWSEEEN(W|ESESWSWSSEEEESSWNWSWWSEESWWSSSSWWNENNWNW(NNENWNNNEE(SWSES(EE|SS(S|W))|N(WW|E))|SS(SSSSSSEESSWSEEEEESSWSSWNNWN(WWSESWSW(SSESWSEEESWSWW(NEWS|)SSSSSENEESSSS(ENEES(EEENNWW(SEWN|)WNWNW(SSEWNN|)NENNESSEESS(WNWESE|)EEN(ES(SW|EN)|WNNWNNNNESSSE(NE(NNNNWS(WWNNNWN(NNENESEEEEEENNNWWNNNEEENNWWNNENWNNENWWNEENWWWWSSE(N|SSWNWWW(SESWWNNWSSWSESESENN(ESSSEEE(E(NNNN(NN|WWSESWW(SEEWWN|)NNN)|EE)|SWWWSESWSWNWNNN(ESSNNW|)WNWW(N(E|NN)|SWSWS(WNNEWSSE|)ESESS(WNSE|)EEN(ES(S|EEEEE(NW(NENWESWS|)W|ES(ENSW|)WWW))|NW(S|NWNE(ESNW|)N))))|W)|NEENNWNW(SSEWNN|)N(EEES(W|EENWN(WWNWWSE(WNEESEWNWWSE|)|EESSEESSSSS(W|SEESWS(W(W|N)|EENENN(W(S|N|WW)|ESSSWSESSSSWWWSSESSESESSEESENNEEEE(SWSWW(NEWS|)S(SWWN(E|WSSWWNNWWWS(EESSSS(WNSE|)EEENE(SSSSWENNNN|)N(WWSWN|NE)|WWSWWWNEENWWNEEENENEESEN(NWNNWSW(S(E|WSWNWSWNWSWNWS(WNSE|)SS(EEN(W|EEE)|S))|NNNNE(N(WWSWNSENEE|)NEES(ENNWWWNEE(WWSEEEWWWNEE|)|W)|SS))|ESS(WWW(WSWENE|)N|E(E|SS)))))|EEENESEENWN(ENE(N|SE(SWS(SS(SEWN|)WWW(NEEWWS|)S|E)|E))|W))|NWNWN(WSS(WWSWNNEN(ESNW|)WNENNENE(S|NWNWNW(SSS(ENSW|)SSWW(W|SES(S|W))|NNNNESESWSE(EEENE(NNWWS(W(SEWN|)NN(W(WWNSEE|)S|ENNNNW(NNESENN(ESSSWSESE(SWW(SEEWWN|)N|E)|WW)|S))|E)|S)|S)))|E)|EE(NNNE(E|S)|S))))))))|WWS(W(N|W)|E))))|WSSESWWNWWW(NENSWS|)(SSEE(NWES|)SESES(E(NNWN(E|W)|SS)|WW(SW(S(WNWSSEE(WWNNESNWSSEE|)|E)|N)|N))|W))|SS)|S)|SS))|W)|SWWW(NENE(S|N(WWSNEE|)N)|SSENESEN(SWNWSWENESEN|)))|NNNNNNE(WSSSSSNNNNNE|))|EE)|E))))|E))|ES(ESNW|)W)|EN(W|N))|E)|SENE(SSWSESWWSE(WNEENWESWWSE|)|NWNEEEESS(NNWWWWEEEESS|))))|SS(WNSE|)EE))|EE))|EE)|W)))|SSWNWS)|W)|EEENNENNE(S|NWWWSESWWNNNENEN(ESS(ENNEWSSW|)W|W)))|SENNES)|ENN(NN|WW))))))|SSWWW(NWES|)SSSESESSSE(NENWNENWWNEN(WWSNEE|)ESESEE(NWES|)SWWSSE(N|S)|SWW(SS|WNW(S|NEE(NWWN(WNENWESWSE|)E|S))))))|SS)))))|W|S)|S)|SSS(E|WWWNEN(ESNW|)WW(SSWW(SESWENWN|)W|N)))))|W)|W))))|N)|SESEESS(WNSE|)SESWSSESEEENESENEESESWW(S(WNWSWWWSSEE(SWS(E|WWN(E|WWWSSESSES(WWWNENWWSSSWWW(SEEEEE(SWW(S|WWWW)|N(W|E(E|S)))|NNENNE(SSSWENNN|)NWNWNEEENEEEN(ESS(ENNN(WNSE|)EEE|WWWSSSWNNW(ESSENNSSWNNW|))|WWWWW(NEWS|)S(E|WWSSSWSSE(SWEN|)EN(W|N))))|ENNNW(NWES|)S)))|N(W|EE))|EEENNESSENENWNNESENNN(ESSSSE(NENN(ESES(ES(W|SENNN(NNESSESWSEE(NENNW(WNEENENN(NWS(WNSE|)S|E)|S)|SSSEES(ENN(ESSES(S|ENN(ES|WNNW))|WW)|WSSSWNWW(NNWNN(WSNE|)EE(NWES|)S(SESWENWN|)W|SWS(EENSWW|)W)))|W))|W)|NNW(WWNEEWWSEE|)SSS)|S(WWNSEE|)S)|WWWS(EE|SSWWNWNEN(WWSSWWWWW(SEWN|)(NENESEN(ESNW|)NWWN(WWSESNWNEE|)EE|W)|E(NNESNWSS|)SS))))|N))|E)))))|NNWWS(SWNNSSEN|)E))|W))|N)|SSSWS(WNNEWSSE|)EE(SWWEEN|)NN))|EE)|EE)))))|S))|SS)))|W)|WWWWNENESENNW(WWSWN|NNES)))|WWWW))))|S))|E)|WWN(E|WNNWN(E|WWWSEESWSES(WW(WW|NN)|E(NN|E)))))))|WWWWWWWWWWWWNNESEEEENWWNNNWSWNWNEEENESESSS(WNNSSE|)ENESESWS(WNSE|)EEENNW(S|NWNENNESENEE(NNNWN(E|WNW(NEWS|)WSSSEN(N|ESS(ENSW|)WWWSSWW(SEWN|)NENNENNNWSWS(E|WWWNWWN(WNWWSSSSSSWNNNWNWWNWSSWNNWSSSSWSSEEN(NESESESESSWWN(E|WSSEESWS(EENEES(ENNNWNNN(E(SSESEES(NWWNWNSESEES|)|NENNEE(S(WSEWNE|)ENESE(NESNWS|)S|NWWNW(N|SSS)))|W(WNWNN(ESNW|)NWS(S|WW)|SSSS(E|W)))|W)|WWN(E|NNNN(WWSSSE(SWWNNWWNENWNNNESE(S(W|SS)|NNENNNWWSESWWS(WSSSWWSSWSEENE(NWES|)SSSS(WWWWNWSWNWWS(E|WNNENWNWWSESSWWS(EE|WWWWNWNEESEENNE(SEWN|)NNWSWS(WWWWWWNNESENNWNWNENNEESSEEEESENNNWSWNWN(W(SSEWNN|)WWWWNNNNNWNWSSSE(N|SWSSSE(ESWSSWNNWWNWW(NNNNNEESWSESWSEE(NNNNNNWSWNW(NN|S)|S)|SSE(EESSWWSESSSSENNNNENE(E|SSWSESWSS(EEN(W|ESE(NNWWEESS|)E)|WWWWNNE(NWN(NNNEEWWSSS|)E|S)))|N))|NN))|ENN(WSNE|)NEEESSS(WWNENW|EESWSW(SSEESES(ES(ESWSEEE(NWNNWNENNWWS(WNW(NEENWNNEENW(W|NNESEEEENN(WSWWN(ENSW|)W|ESESWSSSWWWNW(NEESEN|SSW(NWES|)SEESEEE(NWWN(EEENENWNENENWNWNNEN(WW|EEEESWWSEEENEENWWNENNWSWNWWNNWSS(SES(E(E|N)|W)|WNNWWNNNENN(E(N|SSSS(WNSE|)EEEESS(WNSE|)ENE(SE(N|EE(SWS(E|W(N|SESSEEESES(ENSW|)WWWSSWS(WWNNE(S|ENN(EE|WWS(WSWWSEESWWW(W|NNN(EE|WN(W|N)))|E)))|ES(E(S|NNEENWW(EESWWSNEENWW|))|W))))|EEEEE(NWWWWEEEES|)SS))|NNW(N(EENWWN|WWWWSEEE(WWWNEEWWSEEE|))|S)))|WSW(NNNWESSS|)WSSWWSESSES(WWNW(W|N(NNNN(EESW|WSS)|E))|EN(ESENSWNW|)NWNENN))))|W)|SWWWSS(ENSW|)S))))|W)|E|S)|EES(ENSW|)W)|W)|WWNW(WWWSWSWWNNE(EN(WWWNNSSEEE|)E|S)|S))|N)))|S)))|ENNESSEEE(WWWNNWESSEEE|))|E))|NN)|E(E|N)))))|W)|EENEE(NNWW(SEWN|)NN|ESWSWN)))))|SSW(N|SW(NWSNES|)S(E|SS))))))|S|EE)|WWS(W(S|W)|E))|NNWW(SEWN|)W)))|NWWNWSSE(WNNESEWNWSSE|))|N))|E))|WW)|NWWNEN(WWSWSSSSS(WNNN(WSNE|)N|ENNN(N|EE))|NNNWNEES(SSSS|EENNEES(W|ENENENESEENEESE(ENWN(NN|WWWW(S|N|WWWWS(SWWWW(NEWS|)SS|E)))|SWW(WSEESWWWNNWWSESSWWN(N|E)|N)))))))|WWNWWS(ESSS(ENNSSW|)WSSWWSS(SSSSWENNNN|)WNNN(WSWWN(E|WSSEESEN(SWNWWNSEESEN|))|EE)|WNN(WSSWN(WWSEWNEE|)N|EE)))))))|N(NESNWS|)W)|WW)|W))|N))|N)|W)|WW))|N)|ESE(S|NN)))|NNW(NNN(WSNE|)ENWNNWNNEN(WNSE|)ESS(W|ES(WSES|ENNW))|S)))|NNNN(ESSENN|N))|NNN(NN|EEESWW)))))|S)|ENEE(SW|NWWWN))))|E)|SS(WNWSNESE|)E(N|SSS)))|NN)|SS))))$

A descriptions/Day20.md => descriptions/Day20.md +207 -0
@@ 0,0 1,207 @@
\-\-- Day 20: A Regular Map \-\--
---------------------------------

While you were learning about instruction pointers, the Elves made
considerable progress. When you look up, you discover that the North
Pole base construction project has completely surrounded you.

The area you are in is made up entirely of *rooms* and *doors*. The
rooms are arranged in a grid, and rooms only connect to adjacent rooms
when a door is present between them.

For example, drawing rooms as `.`, walls as `#`, doors as `|` or `-`,
your current position as `X`, and where north is up, the area you\'re in
might look like this:

    #####
    #.|.#
    #-###
    #.|X#
    #####

You get the attention of a passing construction Elf and ask for a map.
\"I don\'t have time to draw out a map of this place - it\'s *huge*.
Instead, I can give you directions to *every room in the facility*!\" He
writes down some directions on a piece of parchment and runs off. In the
example above, the instructions might have been `^WNE$`, a [regular
expression](https://en.wikipedia.org/wiki/Regular_expression) or
\"*regex*\" (your puzzle input).

The regex matches routes (like `WNE` for \"west, north, east\") that
will take you from your current room through various doors in the
facility. In aggregate, the routes will take you through *every door in
the facility at least once*; mapping out all of these routes will let
you build a proper map and find your way around.

`^` and `$` are at the beginning and end of your regex; these just mean
that the regex doesn\'t match anything outside the routes it describes.
(Specifically, `^` matches the start of the route, and `$` matches the
end of it.) These characters will not appear elsewhere in the regex.

The rest of the regex matches various sequences of the characters `N`
(north), `S` (south), `E` (east), and `W` (west). In the example above,
`^WNE$` matches only one route, `WNE`, which means you can move *west,
then north, then east* from your current position. Sequences of letters
like this always match that exact route in the same order.

Sometimes, the route can *branch*. A branch is given by a *list of
options* separated by pipes (`|`) and wrapped in parentheses. So,
`^N(E|W)N$` contains a branch: after going north, you must choose to go
*either east or west* before finishing your route by going north again.
By tracing out the possible routes after branching, you can determine
where the doors are and, therefore, where the rooms are in the facility.

For example, consider this regex: `^ENWWW(NEEE|SSE(EE|N))$`

This regex begins with `ENWWW`, which means that from your current
position, all routes must begin by moving east, north, and then west
three times, in that order. After this, there is a branch. Before you
consider the branch, this is what you know about the map so far, with
doors you aren\'t sure about marked with a `?`:

    #?#?#?#?#
    ?.|.|.|.?
    #?#?#?#-#
        ?X|.?
        #?#?#

After this point, there is `(NEEE|SSE(EE|N))`. This gives you exactly
two options: `NEEE` and `SSE(EE|N)`. By following `NEEE`, the map now
looks like this:

    #?#?#?#?#
    ?.|.|.|.?
    #-#?#?#?#
    ?.|.|.|.?
    #?#?#?#-#
        ?X|.?
        #?#?#

Now, only `SSE(EE|N)` remains. Because it is in the same parenthesized
group as `NEEE`, it starts from the same room `NEEE` started in. It
states that starting from that point, there exist doors which will allow
you to move south twice, then east; this ends up at another branch.
After that, you can either move east twice or north once. This
information fills in the rest of the doors:

    #?#?#?#?#
    ?.|.|.|.?
    #-#?#?#?#
    ?.|.|.|.?
    #-#?#?#-#
    ?.?.?X|.?
    #-#-#?#?#
    ?.|.|.|.?
    #?#?#?#?#

Once you\'ve followed all possible routes, you know the remaining
unknown parts are all walls, producing a finished map of the facility:

    #########
    #.|.|.|.#
    #-#######
    #.|.|.|.#
    #-#####-#
    #.#.#X|.#
    #-#-#####
    #.|.|.|.#
    #########

Sometimes, a list of options can have an *empty option*, like
`(NEWS|WNSE|)`. This means that routes at this point could effectively
skip the options in parentheses and move on immediately. For example,
consider this regex and the corresponding map:

    ^ENNWSWW(NEWS|)SSSEEN(WNSE|)EE(SWEN|)NNN$

    ###########
    #.|.#.|.#.#
    #-###-#-#-#
    #.|.|.#.#.#
    #-#####-#-#
    #.#.#X|.#.#
    #-#-#####-#
    #.#.|.|.|.#
    #-###-###-#
    #.|.|.#.|.#
    ###########

This regex has one main route which, at three locations, can optionally
include additional detours and be valid: `(NEWS|)`, `(WNSE|)`, and
`(SWEN|)`. Regardless of which option is taken, the route continues from
the position it is left at after taking those steps. So, for example,
this regex matches all of the following routes (and more that aren\'t
listed here):

-   `ENNWSWWSSSEENEENNN`
-   `ENNWSWWNEWSSSSEENEENNN`
-   `ENNWSWWNEWSSSSEENEESWENNNN`
-   `ENNWSWWSSSEENWNSEEENNN`

By following the various routes the regex matches, a full map of all of
the doors and rooms in the facility can be assembled.

To get a sense for the size of this facility, you\'d like to determine
which room is *furthest* from you: specifically, you would like to find
the room for which the *shortest path to that room would require passing
through the most doors*.

-   In the first example (`^WNE$`), this would be the north-east corner
    `3` doors away.
-   In the second example (`^ENWWW(NEEE|SSE(EE|N))$`), this would be the
    south-east corner `10` doors away.
-   In the third example (`^ENNWSWW(NEWS|)SSSEEN(WNSE|)EE(SWEN|)NNN$`),
    this would be the north-east corner `18` doors away.

Here are a few more examples:

    Regex: ^ESSWWN(E|NNENN(EESS(WNSE|)SSS|WWWSSSSE(SW|NNNE)))$
    Furthest room requires passing 23 doors

    #############
    #.|.|.|.|.|.#
    #-#####-###-#
    #.#.|.#.#.#.#
    #-#-###-#-#-#
    #.#.#.|.#.|.#
    #-#-#-#####-#
    #.#.#.#X|.#.#
    #-#-#-###-#-#
    #.|.#.|.#.#.#
    ###-#-###-#-#
    #.|.#.|.|.#.#
    #############

    Regex: ^WSSEESWWWNW(S|NENNEEEENN(ESSSSW(NWSW|SSEN)|WSWWN(E|WWS(E|SS))))$
    Furthest room requires passing 31 doors

    ###############
    #.|.|.|.#.|.|.#
    #-###-###-#-#-#
    #.|.#.|.|.#.#.#
    #-#########-#-#
    #.#.|.|.|.|.#.#
    #-#-#########-#
    #.#.#.|X#.|.#.#
    ###-#-###-#-#-#
    #.|.#.#.|.#.|.#
    #-###-#####-###
    #.|.#.|.|.#.#.#
    #-#-#####-#-#-#
    #.#.|.|.|.#.|.#
    ###############

*What is the largest number of doors you would be required to pass
through to reach a room?* That is, find the room for which the shortest
path from your starting location to that room would require passing
through the most doors; what is the fewest doors you can pass through to
reach it?

\-\-- Part Two \-\-- {#part2}
--------------------

Okay, so the facility is
[*big*]{title="Really, really big. No, bigger than that. Even bigger. Keep going. Move. No, more. Look, we're talking krakens and dreadnoughts for housepets. It was big!"}.

*How many rooms have a shortest path from your current location that
pass through at least `1000` doors?*

M src/bin/day20.rs => src/bin/day20.rs +142 -1
@@ 1,1 1,142 @@
fn main() {}
use std::ops::{Add, Index, IndexMut, Not};
use std::str::Chars;

use rustc_hash::*;

static INPUT: &str = "data/day20";
const ORIGIN: (i32, i32) = (0, 0);
const DIRS: [Dir; 4] = [Dir::N, Dir::S, Dir::E, Dir::W];

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
enum Dir {
    N,
    S,
    E,
    W,
}

#[derive(Clone, Copy, Debug, Eq, PartialEq, Default)]
struct Room {
    n: bool,
    s: bool,
    e: bool,
    w: bool,
}

fn build_map(s: &str) -> FxHashMap<(i32, i32), Room> {
    fn fill(chars: &mut Chars, start: (i32, i32), map: &mut FxHashMap<(i32, i32), Room>) {
        let mut pos = start;
        macro_rules! build {
            ($d:ident, $dir:expr) => {{
                let r = map.entry(pos).or_default();
                r[$dir] = true;
                pos = $dir + pos;
                let r = map.entry(pos).or_default();
                r[!$dir] = true;
            }};
        }
        while let Some(c) = chars.next() {
            match c {
                'N' => build!(n, Dir::N),
                'S' => build!(s, Dir::S),
                'E' => build!(e, Dir::E),
                'W' => build!(w, Dir::W),
                ')' => return,
                '|' => pos = start,
                '(' => fill(chars, pos, map),
                _ => {}
            }
        }
    }
    let mut map = FxHashMap::default();
    let mut chars = s.chars();
    fill(&mut chars, ORIGIN, &mut map);
    map
}

fn solve(input: &str, start: (i32, i32)) -> (usize, usize) {
    let map = build_map(input);
    let mut seen = FxHashSet::default();
    seen.insert(start);
    let mut front = FxHashSet::default();
    front.insert(start);

    let mut next = FxHashSet::default();
    let mut counts = Vec::new();

    while !front.is_empty() {
        counts.push(seen.len());
        for p in front.drain() {
            for &dir in DIRS.iter() {
                if map[&p][dir] && seen.insert(dir + p) {
                    next.insert(dir + p);
                }
            }
        }
        std::mem::swap(&mut next, &mut front);
        next.clear();
    }
    (
        counts.len() - 1,
        if let Some(n) = counts.get(1000 - 1) {
            counts.last().unwrap() - n
        } else {
            0
        },
    )
}

fn main() {
    let input = aoc::file::first_line(INPUT);
    let (p1, p2) = solve(&input, ORIGIN);
    println!("  1: {}", p1);
    println!("  2: {}", p2);
}

impl Index<Dir> for Room {
    type Output = bool;
    fn index(&self, dir: Dir) -> &bool {
        match dir {
            Dir::N => &self.n,
            Dir::S => &self.s,
            Dir::E => &self.e,
            Dir::W => &self.w,
        }
    }
}

impl IndexMut<Dir> for Room {
    fn index_mut(&mut self, dir: Dir) -> &mut bool {
        match dir {
            Dir::N => &mut self.n,
            Dir::S => &mut self.s,
            Dir::E => &mut self.e,
            Dir::W => &mut self.w,
        }
    }
}

impl Not for Dir {
    type Output = Dir;
    fn not(self) -> Dir {
        match self {
            Dir::N => Dir::S,
            Dir::S => Dir::N,
            Dir::E => Dir::W,
            Dir::W => Dir::E,
        }
    }
}

impl Add<(i32, i32)> for Dir {
    type Output = (i32, i32);
    fn add(self, mut other: Self::Output) -> Self::Output {
        match self {
            Dir::N => other.1 -= 1,
            Dir::S => other.1 += 1,
            Dir::E => other.0 += 1,
            Dir::W => other.0 -= 1,
        }
        other
    }
}