From e37f18324ee8c929f7a7b7cc0175a7877e184c29 Mon Sep 17 00:00:00 2001 From: Neil Smith Date: Sat, 7 Dec 2019 14:50:59 +0000 Subject: [PATCH] Part 2 now using sets --- advent06/src/advent06.hs | 33 +++---- problems/day06.html | 208 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 223 insertions(+), 18 deletions(-) create mode 100644 problems/day06.html diff --git a/advent06/src/advent06.hs b/advent06/src/advent06.hs index b1da13a..53cd2bb 100644 --- a/advent06/src/advent06.hs +++ b/advent06/src/advent06.hs @@ -9,15 +9,15 @@ import qualified Text.Megaparsec.Char.Lexer as L import qualified Control.Applicative as CA import Data.List (foldl') --- import qualified Data.Set as S +import qualified Data.Set as S +import Data.Set ((\\)) import qualified Data.Map.Strict as M -import Data.Map.Strict ((!), (\\)) +import Data.Map.Strict ((!)) -- from satellite to primary type Orbits = M.Map String String --- transfer steps to each primary -type TransferDistances = M.Map String Int +type Transfers = S.Set String main :: IO () @@ -25,23 +25,20 @@ main = do text <- TIO.readFile "data/advent06.txt" let directOrbits = successfulParse text let orbits = buildOrbits directOrbits - print $ part1 orbits directOrbits + print $ part1 orbits print $ part2 orbits -part1 :: Orbits -> [(String, String)] -> Int -part1 orbits directOrbits = sum $ map (orbitCount orbits) satellites - where satellites = map snd directOrbits +part1 :: Orbits -> Int +part1 orbits = sum $ map (orbitCount orbits) $ M.keys orbits part2 :: Orbits -> Int part2 orbits = youDist + sanDist - where youTrans = transferDistance orbits M.empty (orbits!"YOU") 0 - sanTrans = transferDistance orbits M.empty (orbits!"SAN") 0 + where youTrans = transferSteps orbits S.empty (orbits!"YOU") + sanTrans = transferSteps orbits S.empty (orbits!"SAN") onlyYou = youTrans \\ sanTrans onlySan = sanTrans \\ youTrans - -- youDist = 1 + (maximum $ M.elems onlyYou) - -- sanDist = 1 + (maximum $ M.elems onlySan) - youDist = M.size onlyYou - sanDist = M.size onlySan + youDist = S.size onlyYou + sanDist = S.size onlySan buildOrbits :: [(String, String)] -> Orbits @@ -55,12 +52,12 @@ orbitCount orbits here | here `M.member` orbits = 1 + (orbitCount orbits (orbits!here)) | otherwise = 0 -transferDistance :: Orbits -> TransferDistances -> String -> Int -> TransferDistances -transferDistance orbits transfers here dist - | here `M.member` orbits = transferDistance orbits transfers' there (dist + 1) +transferSteps :: Orbits -> Transfers -> String -> Transfers +transferSteps orbits transfers here + | here `M.member` orbits = transferSteps orbits transfers' there | otherwise = transfers' where there = orbits!here - transfers' = M.insert here dist transfers + transfers' = S.insert here transfers -- Parse the input file diff --git a/problems/day06.html b/problems/day06.html new file mode 100644 index 0000000..1e1dfde --- /dev/null +++ b/problems/day06.html @@ -0,0 +1,208 @@ + + + + +Day 6 - Advent of Code 2019 + + + + + + + +

Advent of Code

Neil Smith (AoC++) 12*

   $year=2019;

+ + + +
+ +

--- Day 6: Universal Orbit Map ---

You've landed at the Universal Orbit Map facility on Mercury. Because navigation in space often involves transferring between orbits, the orbit maps here are useful for finding efficient routes between, for example, you and Santa. You download a map of the local orbits (your puzzle input).

+

Except for the universal Center of Mass (COM), every object in space is in orbit around exactly one other object. An orbit looks roughly like this:

+
                  \
+                   \
+                    |
+                    |
+AAA--> o            o <--BBB
+                    |
+                    |
+                   /
+                  /
+
+

In this diagram, the object BBB is in orbit around AAA. The path that BBB takes around AAA (drawn with lines) is only partly shown. In the map data, this orbital relationship is written AAA)BBB, which means "BBB is in orbit around AAA".

+

Before you use your map data to plot a course, you need to make sure it wasn't corrupted during the download. To verify maps, the Universal Orbit Map facility uses orbit count checksums - the total number of direct orbits (like the one shown above) and indirect orbits.

+

Whenever A orbits B and B orbits C, then A indirectly orbits C. This chain can be any number of objects long: if A orbits B, B orbits C, and C orbits D, then A indirectly orbits D. +

For example, suppose you have the following map:

+
COM)B
+B)C
+C)D
+D)E
+E)F
+B)G
+G)H
+D)I
+E)J
+J)K
+K)L
+
+

Visually, the above map of orbits looks like this:

+
        G - H       J - K - L
+       /           /
+COM - B - C - D - E - F
+               \
+                I
+
+

In this visual representation, when two objects are connected by a line, the one on the right directly orbits the one on the left.

+

Here, we can count the total number of orbits as follows:

+
    +
  • D directly orbits C and indirectly orbits B and COM, a total of 3 orbits.
  • +
  • L directly orbits K and indirectly orbits J, E, D, C, B, and COM, a total of 7 orbits.
  • +
  • COM orbits nothing.
  • +
+

The total number of direct and indirect orbits in this example is 42.

+

What is the total number of direct and indirect orbits in your map data?

+
+

Your puzzle answer was 314247.

--- Part Two ---

Now, you just need to figure out how many orbital transfers you (YOU) need to take to get to Santa (SAN).

+

You start at the object YOU are orbiting; your destination is the object SAN is orbiting. An orbital transfer lets you move from any object to an object orbiting or orbited by that object.

+

For example, suppose you have the following map:

+
COM)B
+B)C
+C)D
+D)E
+E)F
+B)G
+G)H
+D)I
+E)J
+J)K
+K)L
+K)YOU
+I)SAN
+
+

Visually, the above map of orbits looks like this:

+
                          YOU
+                         /
+        G - H       J - K - L
+       /           /
+COM - B - C - D - E - F
+               \
+                I - SAN
+
+

In this example, YOU are in orbit around K, and SAN is in orbit around I. To move from K to I, a minimum of 4 orbital transfers are required:

+
    +
  • K to J
  • +
  • J to E
  • +
  • E to D
  • +
  • D to I
  • +
+

Afterward, the map of orbits looks like this:

+
        G - H       J - K - L
+       /           /
+COM - B - C - D - E - F
+               \
+                I - SAN
+                 \
+                  YOU
+
+

What is the minimum number of orbital transfers required to move from the object YOU are orbiting to the object SAN is orbiting? (Between the objects they are orbiting - not between YOU and SAN.)

+
+

Your puzzle answer was 514.

Both parts of this puzzle are complete! They provide two gold stars: **

+

At this point, you should return to your Advent calendar and try another puzzle.

+

If you still want to see it, you can get your puzzle input.

+

You can also this puzzle.

+
+ + + + + + \ No newline at end of file -- 2.34.1