BNBZNSU24N7EDOZ6VPC2NTJAGYHW3Y4F2H5H2WAIMHF7ZY2LZYDAC
import Data.Maybe
import qualified Data.Set as S
type Deck = [Int]
member = S.member
playerOne =
[ 26,
16,
33,
8,
5,
46,
12,
47,
39,
27,
50,
10,
34,
20,
23,
11,
43,
14,
18,
1,
48,
28,
31,
38,
41
]
playerTwo =
[ 45,
7,
9,
4,
15,
19,
49,
3,
36,
25,
24,
2,
21,
37,
35,
44,
29,
13,
32,
22,
17,
30,
42,
40,
6
]
playRound :: Deck -> Deck -> Maybe (Deck, Deck)
playRound (x : xs) (y : ys) =
if x > y
then Just (xs ++ [x, y], ys)
else Just (xs, ys ++ [y, x])
playRound _ _ = Nothing
playGame :: Deck -> Deck -> Deck
playGame xs ys =
case playRound xs ys of
Just (xs', ys') -> playGame xs' ys'
Nothing -> xs ++ ys
solveOne :: () -> Int
solveOne () =
sum $ zipWith (*) [1 ..] $ reverse $ playGame playerOne playerTwo
takeExact :: Int -> [a] -> Maybe [a]
takeExact 0 _ = Just []
takeExact _ [] = Nothing
takeExact n (x : xs) = (x :) <$> takeExact (n -1) xs
recursiveCombat :: S.Set (Deck, Deck) -> Deck -> Deck -> Either Deck Deck
recursiveCombat _ p1 [] = Left p1
recursiveCombat _ [] p2 = Right p2
recursiveCombat seen p1@(x : xs) p2@(y : ys) =
if (p1, p2) `member` seen
then Left p1
else
let seen' = S.insert (p1, p2) seen
in case (takeExact x xs, takeExact y ys) of
(_, Nothing) -> uncurry (recursiveCombat seen') $ fromJust $ playRound p1 p2
(Nothing, _) -> uncurry (recursiveCombat seen') $ fromJust $ playRound p1 p2
(Just xs', Just ys') ->
case recursiveCombat seen' xs' ys' of
Left _ -> recursiveCombat seen' (xs ++ [x, y]) ys
Right _ -> recursiveCombat seen' xs (ys ++ [y, x])
unEither :: Either a a -> a
unEither (Left x) = x
unEither (Right x) = x
solveTwo :: () -> Int
solveTwo () =
sum $
zipWith (*) [1 ..] $
reverse $ unEither $ recursiveCombat S.empty playerOne playerTwo
mxmxvkd kfcds sqjhc nhms (contains dairy, fish)
trh fvjkl sbzzf mxmxvkd (contains dairy)
sqjhc fvjkl (contains soy)
sqjhc mxmxvkd sbzzf (contains fish)
kxddqq qjnqkj slhjm kmvqht stf kdggj szjdxh tddgr zbnv xfrhjm cdqqt nzp zcdcdf kxzkbk brfpvc rgxnd jmpj xxrck nfjl fdm nddjz nvhhp kkxjgg kpsdtv rvfhqbz zggxkc zkmbc pmjzb dqbjj bmvpz kdxmz prs krjt smrks cxbqtf ccsxr brfpl rdn qndk bvlksl nnlg pcjsl kgbzf jkbrhq fllssz vfs jzlflq jpcsh cmmpcm sxvr zmsh tcl nnrn ljzcbx tmcql dxftvrth fvvrc fnpdz pbbhtd qjxbtlc sltqs hpnnf dhqfbv xpjdsc btfh fxsxh qpxhfp fhbldf mzjhbl ckrj xzrn czvgtl dqnd hlvl jcfsd xgf pngbxj svhqc mpzz lhnd nsmss mctnbp nnffp nhvx jxmg hmm (contains wheat, shellfish)
zcdcdf fxsxh mqls kpsdtv fllssz llhzxnrz sxbjr svsq xfrhjm tvxxn zggxkc znnf czplkc rblrbnhp pzmg kdggj nzlpn mzjhbl fgvhf dnjjt vlfgsn nhvx kgbzf fvvrc dbjtns jmpj fnzgd rgxnd lnljt hrrbkv jrrqzc ckrj lmxrnmg rmpf jcfsd xgf bvlksl jvgxg tddgr tcl cxbqtf kcj rrnhxk kksxbr xbtfvdn hpnnf hdm sfxmr qlhm xjkk dxjdbh kfjf dqbjj czvgtl szjdxh slhjm rtct nvhhp svhqc pzk (contains soy, dairy, shellfish)
kfjf tmcql fvvrc zmsh jrdpn nddjz zcdcdf sltqs dhqfbv tpmkh mfmcgt kgbzf xbtfvdn jxdn czplkc ztx rmpf ljzcbx kcj nzp fnzgd jcfsd xzrn qjnqkj nlcqt lzmfqvz hxltpq trfmsz dxftvrth hchsm kpsdtv dqbjj kmvqht fllssz pzmg kxzkbk jkbrhq vfs snkk pzk (contains peanuts)
tpmkh hxltpq kksxbr nkfjx zkmbc ccsxr kqdk dhqfbv zggxkc tvxxn fvvrc lmxrnmg zbnv vxd jpcsh jzlflq kgvmlg jqvppk rmpf mpzz fcnbzf qpxhfp stf ndvvpgr bmvpz nhvx vmnfl zcdcdf dqbjj mctnbp qkkkvb skr jccbbc dvkcq pcjsl jhc tdkfbq kkxjgg znnf tmcql rrnhxk rrbklsh nlcqt fdm cdqqt kzmfh zrxk dxftvrth czvgtl sfxmr xdzlvg kbrdv msczg jmpj fzmcnxjx ppv kdxmz krjt hpnnf qlhm nfjl tddgr jrdpn dqnd prs dxjdbh fllssz hlvl kpsdtv nnlg jfbvzd nzlpn pzk bvlksl qjnqkj brfpvc hdm sltqs trfmsz cmmpcm fxsxh brfpl xjkk zpmqcv qxctmd xfrhjm xhlfkd pzmg mvzs bnjmx (contains peanuts)
rhkxdmvz nnffp pcxfhk tvxxn ccsxr ddnql fvvrc mpzz jcfsd hlfnt gfth kkxjgg lzmfqvz llhzxnrz dxftvrth rrbklsh jmpj kpsdtv sfxmr bzbm tksln tcl szjdxh rkgqk zcdcdf kksxbr fllssz mvzs sxvr hblgrjgp xjkk rgxnd nkfjx vfs brfpl qndk mctnbp prmglh nhvx rjqrpb lnljt lgzmz nlcqt msczg qpxhfp xxrck nsmss pzmg smrks kgbzf znkx dsghqp fcnbzf lbxd pmjzb nvhhp bnjmx qgqqm jrdpn (contains dairy, nuts, wheat)
nzp rkgqk ppv xgf cxbqtf zph jrrqzc btfh dxjdbh kpsdtv mzjhbl ktqn jcfsd fvvrc sxvr mfmcgt hmm djffq gmdxrp slhjm kqdk ccsxr rvfhqbz trfmsz jrdpn rgxnd kxzkbk dbjtns qkkkvb dqnd hxltpq jpcsh dgc qpstz krjt tdkfbq skr kcj ddnql nnffp qxctmd qpxhfp bbljn pzmg hvgxt ztx nlcqt kgbzf dqbjj tksln fllssz rblrbnhp pmjzb (contains peanuts)
hvgxt jvgxg fxsxh ddnql cdqqt krjt ppv vlfgsn brfpvc llhzxnrz jrdpn qndk fllssz nhvx mctnbp sxbjr svhqc snkk kgbzf fvvrc zbnv rtct lnljt nnffp nddjz xxrck dsghqp kdggj hchsm qjxbtlc dnjjt bzbm brfpl dqnd hxbbn prs jmpj slhjm pngbxj dxjdbh kcj rbhjgg qlhm qpxhfp tfbcbzz xhlfkd gfth trfmsz tpmkh fgvhf mvzs nkfjx dcj ndvvpgr pmjzb dqbjj zpmqcv ccsxr bbljn jnpbc rmpf ckrj hxltpq kpsdtv zcdcdf qgqqm jfbvzd lbxd nzlpn hpnnf zzzgx zmsh hdm zvvffr vxd xgf (contains nuts, eggs)
ztx jkbrhq jzlflq xzrn cmmpcm znkx sxbjr qpxhfp rjqrpb vmnfl rtct rbhjgg zrxk sflkzc kksxbr nzlpn gfth zggxkc nnlg tmfgp jmpj brfpvc bvlksl snkk pzk vlfgsn pzmg vfs vxd qxctmd btfh bmvpz zcdcdf qndk hmm dztlx bzkfh ljzcbx kmvqht fnzgd kfjf kzmfh ppv jxdn ddnql ckrj kcj fllssz jvgxg hxltpq jnpbc pngbxj hlvl nlcqt pmjzb fxsxh hvgxt xgf lhnd dqbjj mpzz dxjdbh nhvx nnffp jfbvzd jrrqzc lkr mfmcgt fzmcnxjx fnpdz tpmkh hxbbn kgbzf fvvrc (contains wheat, dairy, eggs)
fllssz rkgqk qlhm jxdn pzk rdn fgvhf jcfsd rmpf qjnqkj hchsm hxltpq kgbzf jccbbc jrdpn dcj kxzkbk vmnfl xbtfvdn dbjtns mzjhbl gmdxrp pzmg nkfjx lhnd mvzs hrrbkv ktqn xhlfkd rrbklsh nvhhp cdqqt rgxnd qpxhfp djffq kpsdtv hmm fcnbzf jvgxg dxftvrth ljzcbx jkbrhq xxrck rjqrpb stf pngbxj bvlksl jpcsh dnjjt dztlx sxbjr pmjzb mqls lnljt dqbjj jqvppk kbrdv tvxxn bzkfh nhvx fvvrc tmcql zzzgx bbljn xjkk qndk zggxkc xdzlvg fzmcnxjx xgqzlrd rrnhxk jfbvzd hlvl zkmbc ndvvpgr qgqqm pbbhtd prmglh snkk fdm nsmss (contains dairy, soy, eggs)
dqbjj qndk hxltpq brfpvc mpzz zzzgx dcj qgqqm czvgtl fllssz rrbklsh nnrn dvkcq snkk jcfsd zbnv glnj kgbzf fvvrc qkkkvb zcdcdf lbxd llhzxnrz nlcqt kmvqht xzrn sfxmr tksln vfs nvhhp kpsdtv pcxfhk jpcsh ljzcbx sxvr szjdxh qjnqkj qpxhfp rrnhxk prs (contains shellfish, wheat)
rrbklsh kgbzf fdm lhnd fhbldf rscln msczg fcnbzf jccbbc dxftvrth jzlflq xhlfkd hxltpq qjnqkj kxzkbk rvfhqbz lzmfqvz hxbbn nlcqt lkr szjdxh zcdcdf qpxhfp fvvrc dsghqp rblrbnhp btfh xzrn hdm sxvr hvgxt dcj xgf bnjmx tvxxn jkbrhq gfth rtct ztx kkxjgg vlfgsn pzmg brfpl ppv kbrdv xdzlvg smrks pmjzb brfpvc czvgtl svsq xbtfvdn dqbjj hblgrjgp jqvppk qjxbtlc dqnd zbnv nfjl xfrhjm nnrn jvgxg qndk kpsdtv pcjsl nzlpn hlvl (contains peanuts, eggs)
jrdpn dsghqp xhlfkd jnpbc dqbjj sltqs fhbldf mzjhbl kcj ddnql cmmpcm mpzz tfbcbzz pzmg qkkkvb jkbrhq jvgxg dztlx nzp ktqn fgvhf nfjl kgbzf kxzkbk bmvpz ndvvpgr lzmfqvz bbljn zggxkc kpsdtv rdn fdm qpxhfp fllssz dqnd rkgqk hvgxt zcdcdf nhvx fztbgq fnpdz dcj rrbklsh tddgr nlcqt nnrn kbrdv vfs (contains soy, eggs, dairy)
kbrdv vfs qjxbtlc tmcql jxdn rkgqk zggxkc sflkzc szjdxh fllssz pbbhtd nzp hchsm hrrbkv fnpdz rrnhxk ndvvpgr hdm dhqfbv dztlx bvlksl nnrn mpzz kmvqht fvvrc gfth xgf qpxhfp nhvx dbjtns rrbklsh kfjf pzmg xjkk prs hlfnt tfbcbzz rjqrpb llhzxnrz tmfgp jzlflq ppv tddgr xxrck cdqqt bmvpz rtct jvgxg xhlfkd skr xpjdsc kpsdtv tdkfbq brfpvc zcdcdf rdn vlfgsn ljzcbx czplkc fztbgq xfrhjm kgvmlg dqbjj ztx lgzmz (contains peanuts)
hxltpq tmfgp pcxfhk dqbjj rtct xjkk fhbldf rmpf rblrbnhp fgvhf rbhjgg fllssz rhkxdmvz rdn tvxxn znnf svhqc nkfjx ccsxr dnjjt pzmg qjnqkj zcdcdf fztbgq xhlfkd nnffp svsq rvfhqbz znkx mqls kxddqq vxd qpxhfp nfjl kxzkbk ppv tpmkh jzlflq nlcqt kgbzf pcjsl bmvpz lmxrnmg xxrck vfs sltqs mfmcgt dxjdbh kpsdtv (contains nuts, dairy)
krjt dqnd qlhm rrbklsh stf jmpj lmxrnmg xfrhjm nfjl kmvqht jrrqzc lnljt dxftvrth ppv djffq kpsdtv zcdcdf nnrn ktqn nnffp sltqs bvlksl tdkfbq fvvrc hdm jpcsh rrnhxk cdqqt jnpbc dqbjj jqvppk dvkcq znnf kgbzf tddgr fllssz fdm qpstz rhkxdmvz zggxkc jxmg pmjzb kbrdv pzmg zkmbc (contains eggs)
gmdxrp kksxbr sltqs lnljt pbbhtd rdn zggxkc tdkfbq xgf xpjdsc cjxff trfmsz fzmcnxjx rbhjgg kcj dcj lmxrnmg gfth pngbxj jzlflq nsmss llhzxnrz bnjmx rjqrpb kmvqht jnpbc pzmg jhc nkfjx mvzs xhlfkd dnjjt jxmg btfh nzp lzmfqvz rmpf prs rtct vmnfl fvvrc tvxxn qxctmd jvgxg ztx zpmqcv tmcql rblrbnhp qpxhfp prmglh mpzz tfbcbzz dxftvrth msczg pcjsl vlfgsn nvhhp zmsh kgbzf cxbqtf qjxbtlc lhnd dqbjj qpstz czvgtl rscln dgc sfxmr znnf zcdcdf rgxnd tcl sflkzc ccsxr lgzmz fllssz tddgr (contains shellfish, eggs, dairy)
nnrn fnpdz rjqrpb kxzkbk kxddqq ndvvpgr svsq jhc vxd xjkk dqbjj djffq zph nddjz pngbxj jfbvzd dztlx cxbqtf tmfgp pzk kpsdtv hxltpq fvvrc cjxff xgqzlrd lmxrnmg kfjf pzmg czvgtl mvzs gmdxrp sxvr zggxkc fllssz mqls kbrdv rblrbnhp kcj rvfhqbz kgbzf zcdcdf znnf rscln kkxjgg trfmsz nsmss jpcsh jmpj nzlpn jrrqzc rbhjgg (contains nuts)
brfpvc lmxrnmg dxftvrth jpcsh rkgqk nkfjx zggxkc pmjzb nnffp nnrn krjt kqdk jxdn dztlx tvxxn djffq mctnbp fgvhf fxsxh czplkc jnpbc ppv hxltpq kgbzf xzrn pzmg szjdxh hxbbn fvvrc lkr xhlfkd gcmzg dbjtns dxjdbh kxzkbk rrbklsh kdggj tdkfbq trfmsz cmmpcm qkkkvb xpjdsc jzlflq dgc vxd dqbjj sxbjr kksxbr rhkxdmvz mpzz zcdcdf dvkcq hpnnf bmvpz znkx kmvqht jqvppk mfmcgt tpmkh lzmfqvz pngbxj sltqs fztbgq sflkzc rmpf cdqqt kpsdtv xxrck bnjmx nhvx kcj ztx fnpdz smrks znnf fllssz (contains sesame, peanuts)
cmmpcm pzk gcmzg qpxhfp fvvrc dhqfbv pmjzb qgqqm xpjdsc hrrbkv rdn jcfsd pzmg slhjm qlhm kgbzf prs dsghqp lmxrnmg dqbjj hlfnt djffq nhvx mfmcgt dvkcq cxbqtf kxddqq xzrn kksxbr ckrj jfbvzd zcdcdf vmnfl xdzlvg hxbbn dxjdbh tcl ztx rkgqk brfpl kdggj kpsdtv smrks tpmkh kmvqht nzp jrdpn skr hvgxt ddnql pcxfhk lgzmz fxsxh jhc mzjhbl xgf rvfhqbz kfjf vxd bbljn lkr sltqs nnlg rtct kxzkbk msczg svsq tdkfbq czplkc pcjsl bzkfh rblrbnhp kcj tmcql mctnbp bnjmx (contains eggs, sesame)
rkgqk znkx kzmfh fllssz cmmpcm fxsxh vxd kmvqht smrks kgbzf xjkk fnzgd jpcsh zpmqcv xgqzlrd nzlpn djffq pbbhtd svhqc kpsdtv dnjjt kkxjgg nkfjx snkk hmm czvgtl xxrck brfpl sfxmr hlfnt tmfgp pzmg zzzgx qpxhfp zrxk qlhm trfmsz dhqfbv dsghqp krjt dxjdbh dxftvrth rmpf zcdcdf qjnqkj sxvr rscln dqbjj gfth xgf dcj bnjmx lzmfqvz brfpvc qjxbtlc hblgrjgp kdggj hxbbn zggxkc jccbbc lmxrnmg fzmcnxjx jvgxg xhlfkd jrdpn fdm gmdxrp prmglh ljzcbx ccsxr (contains soy, nuts, peanuts)
rmpf kdggj lhnd lzmfqvz lbxd dxftvrth xgf stf hmm hxltpq jfbvzd hdm pzmg jxmg mpzz rjqrpb fnpdz svhqc qgqqm fvvrc qpstz bnjmx ckrj nfjl qjnqkj jcfsd dnjjt bzbm lmxrnmg msczg pcxfhk tpmkh prs zggxkc szjdxh xpjdsc kgbzf zcdcdf rkgqk fllssz xhlfkd fcnbzf zph qpxhfp kpsdtv hpnnf cxbqtf xgqzlrd dsghqp (contains wheat, shellfish, eggs)
dqbjj kgbzf bnjmx tfbcbzz sxbjr hlfnt rgxnd zcdcdf szjdxh vxd dqnd zkmbc fllssz hvgxt qlhm qkkkvb rrbklsh nnffp hblgrjgp qpxhfp dbjtns pzmg bzbm cjxff cdqqt kmvqht ktqn hxbbn tddgr kbrdv kxddqq ztx hxltpq zvvffr zpmqcv sxvr fvvrc nnrn lgzmz prmglh jcfsd pngbxj qxctmd mpzz lhnd xfrhjm vmnfl smrks vlfgsn hchsm ddnql fnzgd bbljn gmdxrp prs mvzs rdn (contains dairy, peanuts, soy)
dgc tpmkh kzmfh czplkc jxdn kxddqq dqbjj jccbbc nnrn svhqc kfjf smrks skr nnlg djffq jnpbc trfmsz xjkk pcjsl qpxhfp svsq fvvrc vlfgsn ktqn cdqqt tcl zbnv fhbldf hxltpq ddnql zcdcdf pzmg brfpl jmpj rblrbnhp nfjl kxzkbk znkx xzrn ztx rhkxdmvz dcj bzbm qkkkvb nzlpn nhvx glnj zzzgx hchsm dztlx pbbhtd jzlflq zkmbc tksln hxbbn kksxbr qjxbtlc bmvpz kdggj jrrqzc gmdxrp kgbzf jfbvzd hvgxt dsghqp rbhjgg lkr rvfhqbz tfbcbzz mvzs tmfgp rtct dvkcq kgvmlg gcmzg lgzmz znnf fllssz tdkfbq slhjm (contains wheat, nuts)
skr cmmpcm zzzgx kbrdv hxbbn fztbgq nzp prmglh dnjjt svhqc kpsdtv qpxhfp brfpl rvfhqbz mzjhbl stf fvvrc sxvr mfmcgt jxmg cjxff brfpvc szjdxh nlcqt ztx lbxd nzlpn tmfgp sfxmr kcj hlvl pzk dqbjj xgqzlrd qndk ccsxr ktqn dgc gcmzg czplkc jccbbc zbnv fcnbzf lmxrnmg qpstz fllssz tdkfbq hvgxt jzlflq nnrn kgvmlg cxbqtf nddjz zcdcdf gfth dztlx rtct kgbzf djffq hchsm (contains sesame)
zpmqcv hvgxt tdkfbq fllssz tksln dqbjj slhjm tfbcbzz rmpf jpcsh pzmg zbnv hlvl jrdpn svhqc kxddqq zzzgx jrrqzc nnlg qkkkvb pcjsl dvkcq dcj kqdk qgqqm jzlflq kxzkbk lhnd kpsdtv fnpdz kksxbr dsghqp pngbxj kkxjgg zcdcdf skr llhzxnrz xgf qxctmd zkmbc zvvffr sflkzc kgbzf ccsxr jcfsd nzlpn kzmfh glnj brfpl fztbgq jkbrhq lnljt gcmzg bzkfh mfmcgt fhbldf nvhhp lmxrnmg jccbbc qpxhfp nddjz jqvppk rtct pbbhtd nlcqt ddnql rkgqk (contains sesame)
hxbbn brfpvc dqbjj xfrhjm hchsm kkxjgg tdkfbq nzlpn vxd kdxmz hblgrjgp zggxkc sxbjr ppv pcxfhk dhqfbv rjqrpb mctnbp nlcqt nhvx zzzgx tksln jcfsd kxzkbk nzp dztlx ndvvpgr mvzs nnffp stf kgbzf ljzcbx fgvhf rbhjgg fdm cmmpcm qxctmd kqdk kksxbr znnf rrnhxk lgzmz ccsxr znkx jzlflq rtct hvgxt svsq ktqn qkkkvb zbnv tmfgp rgxnd zcdcdf qjnqkj fztbgq jkbrhq sltqs cjxff jrdpn rrbklsh fvvrc zmsh skr jpcsh cxbqtf nfjl rdn xzrn qpxhfp hlfnt fllssz zpmqcv nsmss mpzz nvhhp rscln xpjdsc jhc pzmg qlhm mzjhbl pbbhtd mfmcgt (contains shellfish, eggs, peanuts)
lzmfqvz kcj jxmg ccsxr cdqqt rdn lgzmz jnpbc tcl kxzkbk tmcql qndk ppv tddgr ljzcbx btfh mctnbp dsghqp xgf jkbrhq bzbm jhc zcdcdf ckrj kgbzf jrdpn sxvr qpstz fhbldf tpmkh stf xpjdsc nkfjx nnffp qpxhfp hblgrjgp pzmg dqnd sxbjr hpnnf xdzlvg vxd djffq glnj dvkcq tmfgp vmnfl hvgxt fvvrc dxftvrth rbhjgg czplkc sflkzc rvfhqbz kpsdtv kksxbr xgqzlrd bmvpz ktqn rmpf rhkxdmvz dqbjj svsq (contains peanuts, sesame)
brfpvc xhlfkd gcmzg gmdxrp fllssz zkmbc qgqqm ljzcbx tvxxn jvgxg kqdk lbxd dcj tmfgp dxjdbh zmsh dgc dnjjt dvkcq tcl pzmg vlfgsn qpxhfp kgbzf znkx sfxmr rkgqk dxftvrth kpsdtv mctnbp nnlg msczg dqbjj znnf sxbjr rrbklsh pngbxj zcdcdf ppv dbjtns jrrqzc lhnd bbljn jrdpn mvzs jzlflq ccsxr kksxbr jxdn ndvvpgr jkbrhq nsmss fnzgd (contains soy, sesame, peanuts)
hchsm fvvrc cjxff sfxmr vlfgsn djffq qpxhfp tfbcbzz jxmg smrks ckrj lbxd kzmfh fxsxh sltqs zzzgx cxbqtf zmsh qjxbtlc nnffp kgbzf gcmzg fdm zpmqcv sxvr hdm jvgxg tvxxn hxltpq nddjz fztbgq kmvqht svsq qjnqkj nlcqt xxrck cdqqt fllssz pngbxj tmfgp xpjdsc tddgr xfrhjm kpsdtv szjdxh ztx mctnbp xbtfvdn lmxrnmg xgf pzmg dvkcq zcdcdf rjqrpb lzmfqvz tpmkh (contains eggs, dairy, sesame)
zrxk kxzkbk bvlksl dxjdbh xjkk hlvl nfjl rmpf jqvppk kdxmz fnpdz dqnd hdm rhkxdmvz tdkfbq czplkc bmvpz fllssz djffq fxsxh nlcqt fhbldf btfh dqbjj brfpl xhlfkd jnpbc zggxkc ljzcbx szjdxh rbhjgg kkxjgg glnj fvvrc msczg zvvffr ztx jrrqzc ndvvpgr hxltpq prmglh pzmg sfxmr ccsxr zph fdm vfs cjxff zcdcdf zbnv svsq jxdn dgc tvxxn kqdk snkk kpsdtv nhvx kgbzf (contains nuts)
jkbrhq brfpl rkgqk jzlflq znkx xdzlvg kpsdtv ljzcbx bvlksl kdggj mctnbp hxbbn qjnqkj ktqn kgbzf tmfgp ndvvpgr jvgxg nnrn qgqqm qjxbtlc fnzgd bzkfh zcdcdf hpnnf fnpdz hblgrjgp dhqfbv stf fzmcnxjx tdkfbq skr fllssz hlvl zzzgx czvgtl xxrck zpmqcv kfjf tmcql fvvrc fdm dztlx mzjhbl hmm svhqc mpzz jrdpn ccsxr qpxhfp sxbjr dxjdbh sltqs rtct msczg rhkxdmvz dxftvrth xgqzlrd trfmsz jqvppk kxzkbk qlhm zrxk qndk ztx pcxfhk nzlpn xjkk kdxmz dqnd glnj cdqqt zkmbc dgc kzmfh zggxkc dqbjj rbhjgg pzk (contains soy, shellfish, dairy)
jnpbc fvvrc zcdcdf nnffp lzmfqvz hlvl nnrn czvgtl kgbzf dqbjj bzbm hrrbkv rrbklsh pmjzb fzmcnxjx hvgxt fllssz sxvr jrrqzc zbnv vmnfl fxsxh dxftvrth slhjm xhlfkd tdkfbq lbxd rdn brfpl kgvmlg cmmpcm nhvx mqls kcj rtct rkgqk tpmkh qgqqm lkr pngbxj cdqqt dztlx dbjtns rgxnd djffq ckrj xdzlvg kdggj jhc zvvffr mvzs mzjhbl tcl xjkk szjdxh cxbqtf pzmg dhqfbv bmvpz qpxhfp qlhm (contains wheat)
bnjmx kpsdtv xzrn gcmzg llhzxnrz zzzgx zpmqcv dsghqp jrrqzc djffq rkgqk qpxhfp qkkkvb kbrdv vmnfl btfh rgxnd prs gmdxrp vfs pzmg fgvhf tvxxn mqls xbtfvdn xxrck trfmsz sxvr qndk kzmfh xgqzlrd fxsxh dxjdbh kmvqht mzjhbl jqvppk bvlksl pmjzb jrdpn kdxmz kdggj kgbzf mpzz lmxrnmg gfth ztx nvhhp zcdcdf hdm prmglh fvvrc ktqn bzkfh glnj tksln hblgrjgp pngbxj nnffp znkx fllssz czvgtl xdzlvg pcxfhk bzbm lkr (contains dairy, wheat, nuts)
import Control.Arrow
import Data.Function
import Data.List
import Data.Map.Merge.Strict hiding (merge)
import qualified Data.Map.Merge.Strict as MM
import qualified Data.Map.Strict as M
import Data.Maybe
import qualified Data.Set as S
parse :: [String] -> M.Map String (S.Set String)
parse = foldr combine M.empty . map (go S.empty . words)
where
go _ [] = undefined
go ingredients (s : ss) =
case s of
"(contains" ->
-- every word here will have a trailing char, be it ',' or ')'
let allergens = map init ss
in foldr (flip M.insert ingredients) M.empty allergens
_ -> go (S.insert s ingredients) ss
combine =
MM.merge
preserveMissing
preserveMissing
(zipWithMatched (\_ -> S.intersection))
solveOne :: String -> Int
solveOne =
length
. uncurry filter
. first potentialAllergen
. (parse &&& allIngredients)
. lines
where
allIngredients = concat . map (words . takeWhile (/= '('))
potentialAllergen = flip S.notMember . M.foldr' S.union S.empty
solveConstraints :: M.Map String (S.Set String) -> M.Map String String
solveConstraints ms = go ms id (\_ -> undefined)
where
go ms s k =
if M.null ms
then s M.empty
else
let (allergen, candidates) =
minimumBy (compare `on` (S.size . snd)) $ M.assocs ms
in case S.minView candidates of
Nothing -> k ()
Just (guess, others) ->
let ms' = M.map (S.delete guess) $ M.delete allergen ms
in go
ms'
(s . M.insert allergen guess)
( \() ->
let ms'' = M.insert allergen others
in go ms' s k
)
solveTwo :: String -> String
solveTwo =
filter (not . (`elem` "[ \"]"))
. show
. M.elems
. solveConstraints
. parse
. lines
import Control.Arrow
import Control.Monad
import Data.Function
import Data.List
import Data.List.Split
import Data.Maybe
-- We could use [M.Map (Int, Int) Bool] here, but I don't think it's really
-- necessary, as the tiles are relatively small.
type Tile = [[Bool]]
parse :: String -> [(Integer, Tile)]
parse = map (parseTile . lines) . splitOn "\n\n"
where
parseTile [] = undefined
parseTile (number : rest) =
let n :: Integer
n = read $ init $ head $ tail $ words number
grid = map (map (== '#')) rest
in (n, grid)
edges :: [[a]] -> [[a]]
edges =
uncurry (++)
. (id &&& map reverse)
. flip map [head, last, map head, map last]
. flip ($)
solveOne :: String -> Integer
solveOne = product . take 4 . go . map (second edges) . parse
where
go [] = undefined
go ((n, es) : rest) =
if null $ drop 2 $ filter (any (`elem` es)) $ map snd rest
then n : go (rest ++ [(n, es)])
else go (rest ++ [(n, es)])
tryMerge :: Tile -> Tile -> [Tile]
tryMerge g1 g2 =
[ reverse (tail g1') ++ tail g2''
| g1' <- [g1, reverse g1],
g2' <- [g2, reverse g2],
g2'' <- take 4 $ iterate (transpose . reverse) g2',
head g1' == head g2''
]
mergeCol :: [Tile] -> [Tile]
mergeCol (grid : grids) = go [] grids
where
go gs [] = reverse gs ++ [grid]
go gs' (g : gs) =
case tryMerge grid g of
(g' : _) -> mergeCol (g' : (reverse gs' ++ gs))
[] -> go (g : gs') gs
removeBorders :: Tile -> Tile
removeBorders = map (init . tail) . init . tail
stitch :: [Tile] -> Tile
stitch [grid] = removeBorders grid
stitch grids =
stitch $ map transpose $ repeatUntil ((==) `on` length) mergeCol grids
where
repeatUntil pred f xs =
let ys = f xs
in if pred xs ys then ys else repeatUntil pred f ys
data Compact = E | F deriving (Eq)
compress :: Tile -> [[Compact]]
compress = map $ map toChar
where
toChar True = F
toChar False = E
findMonstersH :: [[Compact]] -> Integer
findMonstersH ([] : _) = 0
findMonstersH [] = 0
-- thanks, I hate it
{- ORMOLU_DISABLE -}
findMonstersH g@(
(_ : _ : _ : _ : _ : _ : _ : _ : _ : _ : _ : _ : _ : _ : _ : _ : _ : _ : F : _ : _) :
(F : _ : _ : _ : _ : F : F : _ : _ : _ : _ : F : F : _ : _ : _ : _ : F : F : F : _) :
(_ : F : _ : _ : F : _ : _ : F : _ : _ : F : _ : _ : F : _ : _ : F : _ : _ : _ : _) :
_) =
(+ 1) $ findMonstersH $ map tail g
{- ORMOLU_ENABLE -}
findMonstersH g = findMonstersH $ map tail g
findMonstersV :: [[Compact]] -> Integer
findMonstersV = sum . map findMonstersH . tails
countBest :: [[Compact]] -> Integer
countBest g =
maximum
[ findMonstersV g''
| g' <- [g, reverse g],
g'' <- take 4 $ iterate (transpose . reverse) g'
]
sea :: [[Compact]] -> Integer
sea =
uncurry (-) . ((toInteger . length . filter (== F) . concat) &&& ((* 15) . countBest))
solveTwo :: String -> Integer
solveTwo = sea . compress . stitch . map snd . parse
Tile 2477:
....#...#.
#..##...#.
...#.....#
..#...#.#.
#.#......#
.#.#######
..#.#...#.
.#.....#..
#..#......
.###.####.
Tile 2609:
.##...####
...#.##.##
...#......
...#....#.
.##....#.#
..........
....##....
#....#..##
..######..
.##.##.#.#
Tile 3461:
##.##..##.
.##....#..
...#....#.
#.#.#...#.
........#.
.#.#..#..#
..#.......
#..##.....
...#.....#
.#..####..
Tile 1753:
#...#####.
#...#.#..#
#.#....#..
#.......#.
.....###.#
.......#..
.....#....
..##...#.#
#......#..
#.#..##.#.
Tile 1259:
...##...##
#.##.#.###
#.#.....#.
###..#...#
...#......
##.#..#...
#........#
..##.####.
..##....##
....##.#..
Tile 3181:
.#######.#
#...#....#
#.....#..#
#.#.#...#.
.#..#.....
....#.....
#.......#.
#.........
..#..###..
.##..#...#
Tile 1123:
#..####.#.
#...#.....
#.........
....#.#..#
..........
..##...#.#
#..#......
#...#.#..#
.##.##....
#####.####
Tile 2699:
....###.#.
#.#......#
#..##....#
..#.....#.
#.#......#
....#...##
.##...#.##
..........
#.#...#...
##.#...#.#
Tile 2897:
#.#.##..##
#....#..##
....#...#.
..........
#..#..#..#
#.........
##.......#
##.##....#
........##
#.##.#...#
Tile 2531:
.##....#.#
#...#..###
...#....#.
#.......##
#.......##
......#...
#.#.......
#......#.#
#..#.#...#
...#.##..#
Tile 3917:
.#.#.#..#.
##..#....#
....#....#
#.##..#..#
#...#....#
.....#.#.#
.....#.#.#
##..#.#.##
.....#...#
.##.###.##
Tile 1193:
#.###...##
#..##.####
#.#......#
...###....
.#.#..#...
##...#...#
##.......#
..........
...#......
##..#.#.#.
Tile 2011:
####.#..#.
..#...#..#
#.....#...
..........
..#.#.....
#........#
.....#...#
#........#
.........#
.###..##..
Tile 3209:
######.##.
......#..#
....#...##
..##..#...
...#.....#
....##...#
#.......##
..#..#....
....#.....
.#..#.####
Tile 3659:
.#...##..#
........#.
#...#.....
#........#
....##...#
#..#....#.
.#..#..#..
#....#.#.#
.........#
###.#.#..#
Tile 3623:
.##..##...
..#.....##
#.........
.#.#.....#
...#.....#
.......##.
#.......#.
...#.#...#
#......#.#
..#####...
Tile 3049:
####.#####
..#.....#.
.#..#...#.
.#..##...#
#........#
#.#.......
#.##......
.#....#..#
##........
.####..#.#
Tile 3361:
....#.#..#
...#...###
#....#...#
#....##..#
###.#.##.#
...#.#...#
##.#......
#....##..#
.#.....###
.##.#.....
Tile 2861:
.#.##.#..#
#..#...#..
....#....#
..#.....##
...#.....#
#..##.....
##.......#
.....#...#
.#..#..#..
..#.#.#.#.
Tile 3797:
.......##.
#....#....
#..#...#..
#..#..###.
#.#...#..#
.#...#...#
...##.....
.#.....#..
..#.....#.
#.##.##..#
Tile 3593:
.#.....###
..##....#.
..##..#...
#...#...##
.#.....#.#
#.#...#..#
#....#...#
#.....#..#
###..#.###
.##..##.#.
Tile 2161:
.#.##....#
#....#....
....#....#
####...##.
#..#..##.#
#.........
..#.#...##
#.....#..#
.........#
#.###.#...
Tile 3769:
#..###....
##........
#.#....#..
....#.....
#..##.#...
#....#.#..
#........#
......#.#.
##.....#.#
.#....#..#
Tile 3467:
..#.#.####
##.......#
.##..#....
...###...#
.##.###..#
....###..#
.....#....
##.......#
#....##...
#.#..#..#.
Tile 2503:
#..###.###
.#.....#.#
#......#.#
...#.##...
###.#....#
....#....#
#.#...##..
#.......#.
#.#.#....#
....######
Tile 3389:
#..###..##
..........
.......##.
..........
..........
..........
#.....###.
.........#
##.#.##..#
.##.##.#..
Tile 3919:
..#..#.#..
##....##.#
##..#...#.
#.......##
#.#.#.#...
##..#.#..#
......##.#
...###...#
#...#.....
..#.#.#...
Tile 2663:
#.#...####
.......#.#
.#.....#..
#.....#.##
.#..#.....
..##..#..#
#......##.
...#...#..
#.##...#.#
...##.....
Tile 3253:
.#####..#.
.......#.#
#..#...##.
....#.....
.........#
...#.#....
##........
........#.
#....#...#
.####.##.#
Tile 3329:
......####
.......#.#
..##......
#....#...#
.....##...
.....#..##
.....#....
.#.#.#....
.#.......#
#.##......
Tile 2393:
.#...#...#
....#.....
....#...##
#.#..##.#.
...#.#...#
.....#..#.
.##..##..#
##..#..#..
.#........
.##.#.#.#.
Tile 2339:
##....##.#
..#......#
##.....##.
.........#
...##....#
#....#.##.
#.#.....##
.#..#.##..
##.###..#.
######..#.
Tile 1097:
###.##.#.#
.#.#.....#
...#.#....
##...##...
.#....##..
#....##.##
....##....
#.#......#
#.#..#...#
#.####....
Tile 2423:
#....#.#..
#.....#...
#.........
#...#.....
..###.#..#
#...##....
#.........
#..#.....#
...#..#...
#..##.#...
Tile 3067:
.#####.#.#
###..#.#..
..........
#........#
..##.....#
#......#..
.#..#.#...
##...#..##
....#.....
...#.##.##
Tile 3541:
#.#.##.###
..........
..#.#...##
#..##.#..#
.........#
#.....#...
#..#......
#.##......
.#...#.#.#
.#####..##
Tile 3559:
##.#.#.#..
#....#..#.
##...#....
.....#..##
#.........
..#...#...
.#...#...#
#...#..#..
....#....#
.....###.#
Tile 2797:
.....#..##
#.#....#..
##...#....
#.........
...#......
...#...#..
#.......#.
..........
....#....#
#......###
Tile 2803:
##....#.##
..#.......
.###.#....
#.#.#.....
.........#
#..#...##.
#.#.##..#.
.##...##.#
#.#......#
.###.#.#..
Tile 2297:
.#.#.##.#.
#.##.....#
#.##....#.
.......#.#
#..#......
.##.#..#..
..........
..#.##..##
#.......##
.###.##.#.
Tile 3511:
...#.#....
#.....#..#
.......#..
..##.#.##.
#.#....#..
#.#.#.#...
.#........
#.#.....##
.#....#..#
####..#.#.
Tile 2083:
#####.....
##..#.#..#
....#....#
...#......
##....##.#
#....#.#..
##.....##.
.......#.#
##........
###..##.##
Tile 1567:
####.###.#
....#....#
.#..##.#..
#........#
...#.#...#
#.#..##.##
##...#....
##........
#........#
#...#.#..#
Tile 2767:
..###.##..
#..#..#..#
.###.....#
#..#......
......####
....#..#..
#.....##.#
#.#...#..#
.#....##..
.#..####..
Tile 2081:
.#.##.####
#...#.#...
#...#.##..
..#.....##
...##....#
...#......
...#.#....
..........
..........
.####..###
Tile 1697:
...#...###
#..#..#...
.....#..#.
#........#
#..#......
#.......#.
#....#....
#...#.##..
#....#..##
#.##..#...
Tile 3433:
.###...##.
#........#
.#...###.#
##.......#
.......#.#
.....##.#.
#..#..#...
.......#..
.....###..
.....#.#.#
Tile 1543:
#.###.##..
.#...#....
##.....###
#..####.#.
#...#.....
.#......##
#.........
....#.#.##
##.......#
.#........
Tile 2389:
#....#####
.##......#
###.#....#
..#.......
...#.#...#
.......#.#
#....#....
...#...#..
#.#.......
.##..###.#
Tile 2347:
#....##..#
#......###
........#.
.#...#.#..
#........#
.....##...
#........#
#.....#...
##....#..#
##...#.###
Tile 1877:
.#.#.##.#.
#..##...##
#...#...##
##.#......
........##
....#.#..#
#..##.....
....#...##
#.#.#.#..#
.#..#..#.#
Tile 2927:
.#.#...###
#...#.....
..#.......
##...#...#
#..#...#.#
..........
#.#..##...
#.#.......
.....#...#
......###.
Tile 1483:
..#.#...#.
###.##....
#..##.....
.#...##..#
...#.##.##
#.#..#.#.#
..#..#....
#..#......
#........#
....##.##.
Tile 1493:
#.#....##.
..#....#..
..........
.....#...#
.....##..#
...#..#..#
.........#
#.#.#....#
.#.....#.#
..###...#.
Tile 2621:
#..##.#..#
..##.#...#
..........
#......#..
.###..#...
###.#....#
##..#....#
##..#....#
.........#
##.#......
Tile 3167:
..#.###..#
###.#....#
#........#
..##......
###.#..#..
##...#...#
..........
##.#...#.#
.###.....#
####.##...
Tile 3701:
.#.#...##.
......#...
#.........
......#..#
....#....#
....#.#..#
#..##....#
#.....#..#
#...###..#
..##.#....
Tile 1663:
##.#..##..
#.....#...
....###...
#....##..#
....#...#.
#..####..#
...##.....
.##..#....
#.#....#..
#..##.#.##
Tile 1879:
.#....#...
....###.#.
#....#...#
#..##.....
#......#.#
.....#....
#.........
.........#
.#........
##.#...#.#
Tile 1021:
..#.......
.#......##
.##...#...
.##.......
##.#...#.#
#..#.....#
.#........
...###...#
###.......
....#..###
Tile 3767:
..#.#....#
.....#.#..
..#..#....
##..##....
.#.......#
...#......
......##.#
#.......##
#........#
.######.##
Tile 1847:
....####.#
##.#...#..
##.#.##..#
..####...#
#........#
#.........
#...#....#
##.#.#..##
..##.....#
##.##..#..
Tile 3691:
#.##..#...
...#....#.
#...#.....
.....#....
......#.#.
.#........
.#........
.........#
..........
#.....##.#
Tile 2351:
###..###.#
#....##...
#......#..
###......#
#...##.###
##...##..#
..#.......
.#....##..
...#......
.###.##.##
Tile 2753:
#.####..#.
#.......#.
..#.#.....
.....#....
#..#..#...
#......#..
..#...####
#.......##
....#...#.
....#.#..#
Tile 2141:
....##...#
..#..#....
..........
..........
###....#..
...##.#...
##.#.....#
.#....#..#
#.#....#..
.#########
Tile 1901:
.....#.#.#
#......#..
#...#...#.
...#....##
#..#.#....
........#.
.......#.#
#.....##..
#...#.#.##
.#....##.#
Tile 3137:
.##...#...
.#.....###
#.#.#..#.#
#.###.#...
#..##...#.
.........#
#.#..###.#
#......#.#
#......#..
.#..#.#...
Tile 3407:
.#.###.###
...#......
..#.##....
.#.....#..
....#.#..#
...#...#..
....#..#..
##...#....
.#....###.
##.###.##.
Tile 1013:
##.#.###..
#...#.##.#
#........#
#..#.....#
..........
.........#
...#......
.#.....#.#
.......#..
.#...####.
Tile 1049:
...#....##
#.........
#.....#..#
#..#....##
.##...#...
......#..#
##..#.#...
#.##....##
....#....#
#####.#.#.
Tile 2549:
#.#..###.#
#..#......
...#....#.
.....#...#
#.##.....#
###..#.#..
...##.....
##...#....
#......#..
..##.####.
Tile 2843:
.##.###...
....#....#
#.......##
#........#
.......#.#
#.......##
#.#..#...#
#...#.....
#...#....#
.....###..
Tile 1889:
##.##..#..
...#....##
#........#
#......#..
##..#.#.##
......#...
..#.......
..#......#
#.#..#....
..#......#
Tile 2887:
.####.##.#
#..#......
#.........
#....#....
#....#...#
.....#...#
#.#.#.##.#
.#........
##.#.#....
...#.#.##.
Tile 1579:
..######.#
..........
#.##..#...
####..#..#
#........#
...##....#
..#.......
..........
..........
....#....#
Tile 3079:
##.#....#.
###.....##
...##...##
#....#..#.
....###...
...####...
...#.#....
.#.#.#..##
.....#..#.
##...#..#.
Tile 1297:
.####.###.
##...#...#
.....#..#.
#...#.....
###......#
.#..#....#
#....#..##
.##...#...
#....#....
###.####.#
Tile 1783:
...#.#.#..
#...#.....
..#..#...#
......##..
###..#.##.
.#...###..
#.........
#........#
..#......#
..#..##.#.
Tile 1609:
.#.##..#.#
.#.#....#.
#.##......
..#......#
.##.#.#.##
..#.......
###......#
...#...#.#
...###....
..#.....#.
Tile 3793:
##.#.##.#.
...#......
..##....#.
#...#...##
.......#.#
.....#.#..
....#....#
#.##.....#
#..#.##..#
###.##..#.
Tile 1069:
..#.#...#.
..#.#....#
##..#.#..#
.....#....
.....##.#.
.#.##.#...
#.......##
##........
....#.#..#
.#..###.##
Tile 1229:
..#.#####.
.......#..
....#.#.##
.#........
#...#..##.
##....#.#.
#........#
..........
.......#..
##.##....#
Tile 1163:
....#.#.#.
#..#.#...#
.........#
#........#
#....#....
..#.#....#
#...#....#
#....##...
#..#......
#..##.#.##
Tile 3847:
#...#.####
.........#
......#...
#..#..#.##
.....##...
#........#
#...#....#
#.#....#.#
#...#....#
#....#####
Tile 3823:
#..##.....
..#..#.#..
#.........
#.#.##....
#....#...#
#..#......
#...#.....
..........
..........
...#..#..#
Tile 3583:
#...#.###.
##......##
.#........
..#.......
....##..#.
.........#
##........
###.#...#.
.#........
#.#..####.
Tile 2399:
#..##..#..
##......#.
#.#.#.#...
...##.#..#
......#..#
#.#.###...
.#.....#.#
###..#....
.#.#..#..#
###..##...
Tile 3347:
.#.#....#.
..#.#....#
..........
#.##.#.#.#
....#.....
.#....#...
#........#
#....#...#
#..####..#
..#####.#.
Tile 1307:
#...#...#.
....#....#
.#.......#
.......#..
#.#.#...##
#..#.#.#.#
##.#.#.##.
....##....
#.....#.##
.#..#...#.
Tile 2099:
.##...####
...#.##.##
.....##...
#...#.#...
.#......#.
#........#
...#..####
....##..#.
.....#....
..#.###...
Tile 3109:
#..#.###.#
....#.#.##
....##..##
#.#...#...
#.......#.
#..#......
.#.....#.#
#.##....#.
..#.......
....##..#.
Tile 1787:
#...#...##
#.........
###.......
...#..##..
#.#.##....
##....#..#
##........
#..##.##.#
..#....###
....#..#.#
Tile 3019:
#.##...#.#
#...##...#
...#..#.#.
......##.#
.#..####..
#.#.....#.
#......#..
#.........
..........
...###...#
Tile 2857:
.#...##.#.
#.....#..#
#.....##..
#......#.#
...#..#...
...#.....#
#...###..#
.....##..#
...#...#..
##.#....##
Tile 3083:
#..##..##.
.#....#.##
#..#....##
..........
#...#..#.#
.........#
.#........
##.......#
..........
.##...##..
Tile 1583:
#.###.....
....##.#..
..........
#.....#.##
#........#
##........
#......#..
.........#
#.#.#.....
.#.####...
Tile 2693:
...####.#.
.........#
#.........
....#.##.#
#.......#.
.........#
...#......
.......#.#
..#.#....#
.#..#..#..
Tile 1019:
.#.#......
#......#.#
.#...#.#.#
#.#.......
......#.#.
#........#
##..#..#.#
#.#####.#.
.....#...#
.......###
Tile 1031:
#..#......
.........#
#.....#..#
....#.#.#.
..#......#
#...#....#
...#..##..
.#..#...#.
.......##.
.#.#..#...
Tile 3119:
...#.#..##
#.##......
....#.#.##
##..#.#..#
........#.
#...#.#...
...#.....#
..##....##
#..#...#.#
###...#.#.
Tile 1811:
.####..###
#......#.#
#.........
.......#..
..#.##...#
........##
#....#....
#..#.#.#.#
#..#...#..
..####.###
Tile 2473:
.#....####
##.....#..
....#..###
#..#....#.
###...##..
..........
...#.#...#
........##
##......##
....#.....
Tile 1373:
..#..#....
#...####.#
....#....#
....###...
...#.##.#.
#..#.#...#
...#..#..#
#..#.#...#
##.###....
.#.#####..
Tile 3803:
#...##.#.#
#.#..#..#.
.........#
..#......#
.#.#..#..#
..........
##..#.###.
..#####.##
....##...#
.#.##.##..
Tile 1291:
#..#.....#
#..#..##.#
#.#......#
....#...#.
##.######.
#........#
#....#....
#.....#...
#####.....
#######.#.
Tile 1489:
#...#...##
#..#....#.
....##....
....#.....
#........#
#.#......#
##......##
#.#.#.....
.....#.#.#
#.#.###.##
Tile 2633:
.#..##.#..
..#.#...##
#.........
#..#......
#..#.....#
#.........
#....#..##
#.###.....
#.##.#..#.
...#..###.
Tile 2441:
#.#..###..
...#.....#
#...##...#
#.##...#..
#.....####
#..#....#.
...#......
#.........
#.#.......
....###.#.
Tile 2689:
##..#.....
.#........
..........
#.#.......
....#...##
..........
#.....#...
#...#.....
#.....#...
####...#..
Tile 1559:
#..###..#.
#.......##
......#...
.##..###..
#..#..##.#
..#...##.#
#.........
#..#.#...#
##.....###
.#.....#..
Tile 1973:
.###......
#......#.#
.#........
...#.....#
..#....#..
....##....
..........
......#..#
.....#....
#..#.#...#
Tile 2113:
#.##.#.#.#
..#..##...
#...#.#...
.#.#......
.#..###..#
........#.
#........#
#.#.#..#..
..........
##.##...#.
Tile 2903:
..#...##.#
#...#.....
#..###.###
...#.#...#
#...#...##
#..#..#..#
#........#
##.###...#
#.#..#...#
.#....#...
Tile 2003:
.##.#..#..
...##...##
.#.....#.#
##..##...#
...#.#.#.#
.........#
#...#.##..
.....##..#
#.#..#....
###...##.#
Tile 2273:
...##.#...
.##....##.
#......##.
#.......##
....##...#
......#...
..#.#.....
.#.#..##.#
#........#
..#.#..#..
Tile 2111:
#.#..#..##
#...##...#
..........
###.....##
##......#.
..........
#....#####
#...#.#.#.
....#..#.#
#...#.###.
Tile 2203:
.#####.##.
#...##...#
#..#...#..
#.###...##
#....##.##
#....#..##
....#.....
...#....##
#.#...#...
#.#.#..###
Tile 2153:
#.###..#..
..........
...#.....#
..###..##.
...#.....#
....#....#
#...#....#
#.........
#..##...#.
###.##..#.
Tile 2963:
.#.#.####.
#....#....
.........#
#........#
#..#.....#
#.#......#
......#.##
.....#....
#...###...
.####..##.
Tile 3491:
...##.####
#.#.....##
.#..#..##.
#........#
.#...#...#
....#...#.
#.#......#
.........#
....#...#.
##.##..#.#
Tile 2087:
#.#......#
#..##..#..
#..#......
#...##...#
#......#.#
#.#...#...
......#..#
#...#....#
#....#....
##.#..#..#
Tile 2063:
..##...##.
....#....#
#..#...#.#
#........#
##......##
..#..##..#
......#.#.
#.#.......
..##.#....
.#######..
Tile 3851:
.#........
#.#.....#.
.........#
......#...
.#....#..#
...##.....
#........#
#.......#.
#.#......#
##.####..#
Tile 1117:
##.......#
..#......#
##.......#
##........
...####.#.
..##.##..#
...#....#.
##.#......
.........#
.#.##....#
Tile 3967:
...#.##...
#..#..##.#
#.....##.#
#......#.#
#.......#.
##........
#..#.#.#..
....#.#.##
.#.#..#...
###.##.##.
Tile 2879:
###..#..##
.....#.#..
...##.....
#.###.#..#
.........#
.#.#.....#
#.#.##....
#..##....#
##.......#
#.##.#####
Tile 2851:
###..#.##.
.###...##.
...##.#.#.
#........#
#........#
.#.#......
##.#......
..###.....
.#...#..#.
#.####..#.
Tile 3529:
.#.#.#####
..........
...#..#..#
...#.....#
#.#......#
#....####.
.....#...#
#.##......
.#...#...#
#.#..###.#
Tile 3307:
#.#..###..
....#..###
#.##....##
#..#.##.#.
#.#...##.#
.#....#...
...#.#...#
...#...#.#
##......#.
...#......
Tile 3739:
#.###.#...
.#.#..##.#
..#..#..##
#...##...#
#...#..#..
.........#
.....#...#
##....#...
.#......##
...#..#..#
Tile 2617:
##.###.#..
..#......#
..#....#..
.#....#...
.#..#.....
...#..##..
...#.....#
#.......#.
#.#..#...#
..###..#..
Tile 2053:
.#....#.##
#...#.....
.........#
#........#
...#..##..
###..#.###
........#.
.....#####
##....#...
.###.##..#
Tile 2447:
.#.....##.
......##.#
#......#..
.#......#.
.#.##.#..#
#.#....###
#.#......#
##........
.#.......#
#.#.#....#
Tile 1999:
.#...###..
#...#..#..
#.#.......
...#....##
#.#.......
##...###..
#......#..
...###.#..
####...##.
.....#..#.
Tile 1009:
...#####.#
....##...#
...#.#....
#..#.#.#.#
#...##....
........##
#.....#..#
.#..##.#.#
#..#...#..
...#.#..##
Tile 2267:
.#.#..##..
.#.......#
#........#
.#.......#
#..#...#.#
#..#..#..#
.####.....
..#......#
##.....#..
##...####.
Tile 2131:
###.#..##.
.#....#...
...##.####
..#.#..#..
#.#....#.#
...###.#..
#.....#..#
..#...####
##.#..#..#
#..###..##
Tile 2251:
###.......
....#.#..#
.....#....
...#..#...
.........#
##..#.....
##.......#
.#.....#.#
#.#.....#.
#...#.....
Tile 1109:
..##....#.
.#...#..##
#.........
#..##....#
...#...#..
#.##......
.#...#.#..
...#..##..
.#...##...
.##.###.#.
Tile 3343:
..###.#.##
#....#.###
....#....#
.........#
..##....#.
#.....##..
#..#......
.........#
.###...#..
.#..######
Tile 2383:
.#.####.##
#.....#..#
#......#.#
##.....##.
#......###
....#...#.
....#...#.
##....#..#
##..###..#
.####.#...
Tile 2281:
..#...##..
#..#...#.#
.#........
.#.#....##
..##.#.#..
..#...#...
###.#..#.#
#...##.#.#
...##.#..#
#..#.....#
Tile 3191:
.###.###.#
..#.......
.##....###
...#..#...
..#......#
#...#.....
#........#
#....#..##
#.#.#...#.
#.......#.