diff --git a/2021/day19.hs b/2021/day19.hs new file mode 100644 index 0000000..337e4d9 --- /dev/null +++ b/2021/day19.hs @@ -0,0 +1,98 @@ +module Day19 where +import Data.List.Split (splitOn) +import Debug.Trace (trace, traceShow) +import Data.List (delete, transpose, maximumBy, sort, nub) +import Data.Ord (comparing) +import qualified Data.Bifunctor + +type Coord = (Int,Int,Int) + +add :: Coord -> Coord -> Coord +add (x,y,z) (a,b,c) = (x+a, y+b, z+c) + +readScanner :: [String] -> [Coord] +readScanner [] = error "empty scanner" +readScanner (x:xs) = map pos xs where + pos line = (x,y,z) where [x,y,z] = map read $ splitOn "," line + +-- shamelessly stolen from spoiler +transformCoord :: Coord -> [Coord] +transformCoord (x,y,z) = [ + (x,y,z), + (-x,-y,z), + (-x,y,-z), + (x,-y,-z), + (y,z,x), + (-y,-z,x), + (-y,z,-x), + (y,-z,-x), + (z,x,y), + (-z,-x,y), + (-z,x,-y), + (z,-x,-y), + (x,z,-y), + (x,-z,y), + (-x,z,y), + (-x,-z,-y), + (y,x,-z), + (y,-x,z), + (-y,x,z), + (-y,-x,-z), + (z,y,-x), + (z,-y,x), + (-z,y,x), + (-z,-y,-x)] + +deltas :: [Coord] -> [(Coord, [Coord])] +deltas coords = map (\c -> (c, deltas' c)) coords where + deltas' c = map (delta c) (c `delete` coords) + delta (x,y,z) (a,b,c) = (x-a, y-b, z-c) + +findOverlap :: [Coord] -> [Coord] -> [Coord] +findOverlap sc1 sc2 = map fst $ filter (in2 . snd) d1 where + d1 = deltas sc1 + d2 = concatMap snd (deltas sc2) + in2 c = any (`elem` d2) c + +maxi :: (Ord a1) => [a1] -> (a1, Int) +maxi xs = maximumBy (comparing fst) (zip xs [0..]) + +merge :: ([Coord], [Coord]) -> ([Coord], [Coord]) -> ([Coord], [Coord]) +merge (diffs, known) (overlappingNew, scanner) = (diff:diffs, nub $ sort $ known ++ map (add diff) scanner) where + overlappingOrig = findOverlap scanner known + diff = (x-nx, y-ny, z-nz) where (x,y,z) = minimum overlappingNew; (nx,ny,nz) = minimum overlappingOrig + + +discover :: [Coord] -> [Coord] -> [[[Coord]]] -> ([Coord], [Coord], [[[Coord]]]) +discover diffs known [] = (diffs, known, []) +discover diffs known aux = trace ("total: " ++ show (length newKnown) ++ "; best: " ++ show (map (length.fst) bestPer)) $ + if bestScore < 12 then (diffs, known, aux) else (diffs ++ fst newKnown, snd newKnown, newAux) where + overlapKnown = map (map (\x -> (findOverlap known x, x))) aux + bestPer = map (maximumBy (\x y -> compare (length $ fst x) (length $ fst y))) overlapKnown + bestScore = maximum $ map (length . fst) bestPer + scanners = filter (\scanner -> length (fst scanner) >= 12) bestPer + newKnown = foldl merge ([], known) scanners + newAux = filter (\s -> all ((`notElem` s) . snd) scanners) aux + +discoverUntil :: [Coord] -> [Coord] -> [[[Coord]]] -> ([Coord], [Coord], [[[Coord]]]) +discoverUntil diffs known aux = if known == known' then (diffs', known', aux') else discoverUntil diffs' known' aux' where + (diffs', known', aux') = discover diffs known aux + +manhattan :: Coord -> Coord -> Int +manhattan (a,b,c) (x,y,z) = abs (a-x) + abs (b-y) + abs (c-z) + +main :: IO () +main = do + input <- map readScanner . splitOn [""] . lines <$> getContents + + let known = head input + let aux = transpose $ map (\i -> map (map (\c -> transformCoord c !! i)) (tail input)) [0..23] + + let (diffs, final, aux') = discoverUntil [] known aux + + putStr "part 1: " + print $ length final + + putStr "part 2: " + let manhattans = concatMap (\s -> map (manhattan s) diffs) diffs + print $ maximum manhattans \ No newline at end of file diff --git a/2021/inputs/day19.input b/2021/inputs/day19.input new file mode 100644 index 0000000..534b6f5 --- /dev/null +++ b/2021/inputs/day19.input @@ -0,0 +1,717 @@ +--- scanner 0 --- +-610,495,658 +619,646,813 +824,672,-795 +46,-39,48 +417,571,821 +-805,453,-303 +-888,396,-338 +-476,-659,-760 +-565,451,589 +-360,-695,-736 +747,682,-698 +-640,-788,852 +-456,499,642 +-639,-860,768 +755,-706,572 +-510,-763,-684 +326,-630,-599 +486,672,902 +426,-582,-537 +773,654,-588 +-484,-887,839 +395,-595,-768 +-735,509,-330 +735,-629,606 +810,-851,608 + +--- scanner 1 --- +691,-615,-596 +459,-820,345 +727,421,-583 +-504,778,-728 +-304,-931,507 +680,257,604 +105,-55,-128 +625,275,720 +-490,654,-884 +547,-713,263 +722,381,-665 +587,-500,-582 +723,-543,-526 +-324,402,601 +-706,-573,-643 +566,303,707 +687,485,-677 +-382,-788,510 +-8,-168,-10 +408,-812,285 +-852,-572,-742 +-395,727,-808 +-378,372,416 +-793,-676,-748 +-364,-872,401 +-455,385,572 + +--- scanner 2 --- +-630,539,-832 +453,-736,716 +-620,-486,518 +409,-817,634 +340,-827,665 +390,847,-459 +343,713,-531 +-730,-493,648 +449,614,601 +-862,-862,-324 +-33,-19,15 +507,583,604 +-562,629,-717 +-396,674,378 +656,-758,-378 +-775,-556,549 +386,595,-469 +619,-844,-379 +-529,509,-821 +-331,644,348 +-906,-785,-305 +-877,-919,-415 +584,584,578 +-444,785,330 +587,-926,-418 + +--- scanner 3 --- +789,696,-627 +-434,-942,427 +-333,613,529 +758,626,-782 +-323,716,-425 +907,-683,654 +591,446,446 +766,-789,-704 +673,365,402 +34,11,-117 +-347,-799,419 +154,-87,57 +-309,569,-489 +773,-813,-798 +-287,606,-505 +-601,-856,-467 +659,689,-737 +895,-719,864 +-666,-833,-413 +944,-718,635 +-445,-937,366 +-731,-759,-465 +-491,676,498 +-470,608,672 +642,355,333 +794,-861,-887 + +--- scanner 4 --- +-594,-270,766 +-18,91,75 +-408,-554,-590 +-496,427,605 +787,-666,849 +-541,-326,669 +590,914,-478 +-607,-251,615 +819,-259,-460 +-613,-589,-554 +675,-271,-532 +566,411,590 +680,457,487 +699,-559,931 +578,911,-741 +-506,-436,-520 +838,-658,909 +815,-307,-557 +621,429,474 +-794,879,-625 +-440,554,550 +-660,890,-528 +-791,864,-664 +-556,410,584 +543,956,-616 + +--- scanner 5 --- +-175,44,-29 +800,604,736 +-600,591,-761 +-665,-613,322 +349,440,-453 +-818,-516,-844 +699,-529,-374 +-755,-545,437 +708,-480,-508 +-499,490,-693 +-843,-572,-909 +284,512,-486 +526,-505,-423 +-805,-538,-751 +-20,-22,55 +-839,360,623 +632,673,776 +793,-860,739 +659,-889,849 +-973,407,695 +-721,403,685 +736,-845,830 +718,636,775 +319,535,-369 +-606,618,-669 +-635,-512,333 + +--- scanner 6 --- +-316,579,-312 +-297,-790,-711 +-348,-730,-719 +435,-474,503 +607,833,578 +-557,860,858 +-436,-812,-612 +415,-568,-830 +53,112,121 +698,887,-370 +657,774,487 +566,-503,486 +-455,-368,404 +816,926,-466 +-569,-471,358 +-545,597,861 +741,896,506 +-320,676,-360 +821,807,-428 +-514,-355,376 +-460,651,-324 +-592,735,903 +151,164,-31 +475,-674,-771 +489,-659,473 +493,-565,-687 + +--- scanner 7 --- +435,557,-655 +-770,550,-327 +-699,515,-271 +-577,-446,442 +451,-860,586 +-808,647,655 +637,-442,-503 +-567,-543,519 +280,262,615 +319,360,662 +-937,-885,-798 +-733,621,601 +-650,645,652 +801,-410,-429 +-66,-68,143 +537,711,-636 +297,271,557 +-595,-653,493 +773,-436,-359 +341,-912,565 +478,737,-709 +-696,352,-330 +411,-845,593 +-849,-848,-800 +-698,-875,-797 + +--- scanner 8 --- +-664,-627,704 +-841,494,-595 +652,-801,406 +-862,425,-585 +637,459,554 +530,-629,-385 +-515,697,751 +691,487,683 +-552,-681,-615 +686,-801,451 +-552,720,692 +-634,-725,-696 +-603,-794,-706 +298,374,-483 +-690,-550,705 +509,-455,-453 +316,454,-362 +326,504,-379 +372,-598,-448 +-583,833,701 +540,-833,430 +-59,-49,80 +645,513,567 +-667,-685,735 +-848,556,-701 + +--- scanner 9 --- +414,487,-749 +-680,-624,-479 +-67,-57,-44 +484,-790,-397 +583,522,-818 +816,-659,919 +-706,-549,-533 +621,282,721 +826,-420,920 +-714,346,-731 +-704,-707,-530 +-665,637,422 +668,240,583 +594,-762,-371 +-574,-658,393 +645,474,-718 +633,285,458 +3,-121,131 +387,-780,-320 +-829,281,-756 +-581,656,544 +-531,565,485 +789,-508,922 +-609,-587,449 +-411,-661,452 +-890,366,-746 + +--- scanner 10 --- +-627,-609,-816 +-591,-495,-690 +-585,-502,631 +-650,814,782 +-858,529,-758 +380,305,-577 +-647,671,704 +444,-523,-703 +751,-594,590 +-31,-131,-124 +-756,755,722 +-745,551,-609 +319,-487,-616 +452,488,-605 +725,412,376 +844,450,381 +-826,591,-589 +692,-503,540 +-575,-442,-752 +428,394,-598 +361,-474,-773 +-741,-489,708 +805,354,499 +-556,-519,762 +814,-522,456 + +--- scanner 11 --- +-838,-676,-466 +511,284,707 +52,-49,-52 +-742,-794,-427 +-504,423,318 +416,368,677 +612,-860,308 +-127,-13,-146 +-848,342,-677 +542,-744,-631 +-884,-824,233 +-913,-934,367 +645,433,-888 +-884,482,-702 +649,-861,394 +-780,-799,-546 +558,-658,-628 +-896,338,-774 +-869,-915,290 +488,401,742 +-529,338,500 +771,421,-767 +620,490,-741 +580,-821,226 +479,-690,-459 +-553,289,327 + +--- scanner 12 --- +-717,579,534 +766,749,-954 +177,64,26 +666,686,530 +-672,728,-741 +-604,548,543 +632,-727,-468 +949,-544,805 +-684,-574,-532 +-371,-695,552 +671,-668,-552 +801,663,500 +-343,-641,681 +661,-697,-616 +-643,670,-662 +99,-14,-127 +852,697,-857 +917,-690,784 +-397,-649,668 +883,593,-939 +-5,128,-65 +-639,-550,-476 +-581,511,484 +743,660,531 +917,-656,829 +-686,703,-802 +-637,-530,-607 + +--- scanner 13 --- +-326,-746,-526 +753,-765,472 +-329,-483,-514 +710,500,848 +-284,-608,-479 +570,-829,453 +-518,693,-502 +19,28,139 +-361,-599,858 +615,-944,-331 +-566,793,-564 +-350,-696,724 +-642,364,607 +-787,309,643 +746,372,-663 +-531,724,-733 +712,-877,524 +736,295,-760 +109,-158,-31 +635,702,856 +718,346,-553 +376,-945,-321 +736,633,937 +-376,-560,855 +-565,384,641 +464,-947,-358 + +--- scanner 14 --- +287,538,833 +456,-658,-332 +649,-664,559 +-499,651,634 +437,470,781 +566,373,-671 +338,-640,-388 +-676,-568,-309 +-682,-426,-329 +-855,-673,936 +-682,-697,887 +567,445,-755 +687,-630,401 +662,-686,466 +411,346,-742 +-57,-87,160 +-828,527,-475 +4,86,-14 +350,-743,-361 +-399,603,696 +-808,604,-509 +-468,638,865 +-772,-547,-416 +403,574,857 +-883,382,-511 +-864,-722,802 + +--- scanner 15 --- +469,-858,324 +693,669,-643 +-397,-551,-564 +478,-668,303 +157,-16,-98 +-447,698,716 +-377,729,561 +439,-707,-392 +692,643,-566 +-2,74,-8 +753,899,272 +-467,-347,439 +723,646,-508 +-504,-369,423 +-708,613,-468 +461,-644,388 +894,917,385 +783,869,337 +-460,-393,-595 +-384,599,671 +-465,-530,-738 +-718,582,-399 +-627,531,-512 +-357,-383,359 +394,-673,-392 +418,-561,-360 + +--- scanner 16 --- +663,520,581 +-790,410,759 +429,-660,365 +-840,596,-622 +700,-660,-851 +-379,-459,547 +333,614,-851 +-816,546,628 +550,-570,452 +-524,-514,511 +-648,-843,-598 +66,-103,36 +-601,-534,545 +571,-666,345 +-600,-943,-660 +345,542,-707 +628,484,376 +-882,458,-575 +-635,-874,-829 +-98,-25,-89 +381,517,-847 +510,554,474 +-837,333,-610 +676,-487,-900 +725,-478,-766 +-805,449,762 + +--- scanner 17 --- +574,-491,651 +537,816,632 +521,665,-272 +-630,560,-520 +-370,-583,-408 +444,822,542 +675,-414,640 +-631,382,-571 +636,-494,-690 +662,670,-394 +-47,-16,78 +-653,356,-528 +-367,-635,410 +-351,-438,-486 +669,670,-300 +-324,-507,464 +585,-397,-567 +593,-418,678 +-658,603,839 +-416,-570,-482 +-368,-478,428 +562,-544,-547 +411,832,763 +-721,643,761 +-672,451,760 + +--- scanner 18 --- +581,674,-678 +-850,707,-718 +814,-386,-737 +-877,-306,-508 +550,677,-620 +-718,-253,783 +-860,738,-787 +538,789,727 +-739,479,432 +409,-219,436 +597,826,704 +-712,-444,690 +562,-396,-741 +438,-264,382 +-791,-305,-471 +680,-458,-784 +-959,-345,-540 +-90,118,131 +-769,789,-674 +-855,493,563 +-18,-7,-47 +551,651,-543 +547,758,840 +-632,-391,788 +-749,500,501 +447,-419,482 + +--- scanner 19 --- +-476,-439,905 +633,600,635 +-583,-527,987 +52,-52,78 +-365,324,743 +492,621,-719 +498,-427,608 +766,657,691 +784,-490,-411 +571,589,-550 +-883,-407,-404 +-484,-388,965 +555,675,-547 +776,598,490 +379,-429,438 +-871,-551,-476 +-835,-411,-501 +-729,725,-751 +-825,607,-712 +-767,730,-632 +658,-502,-290 +633,-559,-437 +334,-462,592 +-424,384,849 +-508,402,740 + +--- scanner 20 --- +590,-944,-534 +475,296,714 +-735,-479,-428 +456,418,630 +-355,-394,819 +746,-872,939 +-326,-528,929 +-343,613,-343 +-459,385,794 +-391,516,-347 +830,595,-572 +625,-875,-365 +766,-857,763 +-370,-451,910 +-355,541,-487 +638,-844,-596 +827,332,-584 +872,457,-619 +-401,305,671 +-497,266,789 +-686,-488,-294 +80,-56,98 +547,359,580 +-60,-91,-46 +831,-882,878 +-710,-661,-343 + +--- scanner 21 --- +374,727,-469 +508,655,-422 +504,-877,510 +-350,604,-754 +747,-729,-653 +-258,573,-801 +-712,-467,-629 +-715,-591,-772 +592,469,483 +-757,-666,590 +-683,-594,537 +682,354,551 +741,-637,-680 +848,-661,-552 +-616,716,435 +106,90,-59 +712,365,450 +-9,-37,39 +-549,657,492 +-641,-565,597 +-407,652,-862 +-679,-594,-517 +529,-812,454 +626,717,-465 +-587,738,431 +542,-719,476 + +--- scanner 22 --- +-434,572,693 +-527,-427,869 +697,410,-675 +583,-761,494 +812,308,570 +-655,-470,923 +-498,-471,905 +-511,471,682 +-552,260,-484 +-564,-942,-373 +513,-641,-413 +560,-506,-520 +682,491,-679 +623,-824,572 +796,434,701 +-570,-751,-466 +54,-67,182 +-520,448,-474 +-665,368,-500 +802,341,791 +717,558,-804 +-438,490,655 +546,-727,-464 +-650,-804,-368 +-85,-160,55 +431,-775,573 + +--- scanner 23 --- +466,697,-742 +-453,-516,611 +288,626,597 +573,-781,-775 +438,769,-925 +-54,-38,-158 +459,721,-836 +-520,305,-780 +-515,424,-818 +-638,344,-876 +-380,-489,-951 +-570,509,504 +443,-788,-665 +325,591,616 +-624,337,441 +641,-538,408 +559,-457,364 +-656,506,520 +337,627,826 +-454,-430,574 +-493,-348,542 +474,-718,-820 +-490,-355,-922 +590,-447,295 +-399,-412,-907 + +--- scanner 24 --- +-705,508,-364 +483,-792,588 +-521,-543,-626 +-554,-629,-575 +-370,-621,758 +-539,-589,679 +-568,-408,-519 +315,-752,657 +-652,559,617 +562,-653,-573 +-690,589,-360 +26,-59,116 +831,470,749 +512,546,-565 +657,466,-539 +-678,490,466 +-799,502,592 +766,437,821 +796,353,726 +-542,-675,695 +556,-844,-666 +544,358,-555 +-725,656,-235 +397,-791,625 +642,-706,-671 + +--- scanner 25 --- +-549,544,757 +24,-9,-115 +-652,560,-521 +-326,-827,581 +-746,553,-497 +-611,713,789 +706,419,-627 +-728,-421,-794 +-385,-767,687 +-835,532,-449 +-690,-426,-913 +805,-494,529 +-589,564,676 +594,-476,-709 +-469,-749,578 +551,890,246 +687,382,-592 +527,881,472 +-786,-544,-874 +610,-562,-712 +916,431,-591 +531,-530,-881 +815,-553,328 +497,886,320 +672,-551,473 \ No newline at end of file diff --git a/2021/inputs/day19.sample b/2021/inputs/day19.sample new file mode 100644 index 0000000..4e496e9 --- /dev/null +++ b/2021/inputs/day19.sample @@ -0,0 +1,136 @@ +--- scanner 0 --- +404,-588,-901 +528,-643,409 +-838,591,734 +390,-675,-793 +-537,-823,-458 +-485,-357,347 +-345,-311,381 +-661,-816,-575 +-876,649,763 +-618,-824,-621 +553,345,-567 +474,580,667 +-447,-329,318 +-584,868,-557 +544,-627,-890 +564,392,-477 +455,729,728 +-892,524,684 +-689,845,-530 +423,-701,434 +7,-33,-71 +630,319,-379 +443,580,662 +-789,900,-551 +459,-707,401 + +--- scanner 1 --- +686,422,578 +605,423,415 +515,917,-361 +-336,658,858 +95,138,22 +-476,619,847 +-340,-569,-846 +567,-361,727 +-460,603,-452 +669,-402,600 +729,430,532 +-500,-761,534 +-322,571,750 +-466,-666,-811 +-429,-592,574 +-355,545,-477 +703,-491,-529 +-328,-685,520 +413,935,-424 +-391,539,-444 +586,-435,557 +-364,-763,-893 +807,-499,-711 +755,-354,-619 +553,889,-390 + +--- scanner 2 --- +649,640,665 +682,-795,504 +-784,533,-524 +-644,584,-595 +-588,-843,648 +-30,6,44 +-674,560,763 +500,723,-460 +609,671,-379 +-555,-800,653 +-675,-892,-343 +697,-426,-610 +578,704,681 +493,664,-388 +-671,-858,530 +-667,343,800 +571,-461,-707 +-138,-166,112 +-889,563,-600 +646,-828,498 +640,759,510 +-630,509,768 +-681,-892,-333 +673,-379,-804 +-742,-814,-386 +577,-820,562 + +--- scanner 3 --- +-589,542,597 +605,-692,669 +-500,565,-823 +-660,373,557 +-458,-679,-417 +-488,449,543 +-626,468,-788 +338,-750,-386 +528,-832,-391 +562,-778,733 +-938,-730,414 +543,643,-506 +-524,371,-870 +407,773,750 +-104,29,83 +378,-903,-323 +-778,-728,485 +426,699,580 +-438,-605,-362 +-469,-447,-387 +509,732,623 +647,635,-688 +-868,-804,481 +614,-800,639 +595,780,-596 + +--- scanner 4 --- +727,592,562 +-293,-554,779 +441,611,-461 +-714,465,-776 +-743,427,-804 +-660,-479,-426 +832,-632,460 +927,-485,-438 +408,393,-506 +466,436,-512 +110,16,151 +-258,-428,682 +-393,719,612 +-211,-452,876 +808,-476,-593 +-575,615,604 +-485,667,467 +-680,325,-822 +-627,-443,-432 +872,-547,-609 +833,512,582 +807,604,487 +839,-516,451 +891,-625,532 +-652,-548,-490 +30,-46,-14