Done day 17
authorNeil Smith <neil.git@njae.me.uk>
Sun, 19 Dec 2021 13:33:01 +0000 (13:33 +0000)
committerNeil Smith <neil.git@njae.me.uk>
Sun, 19 Dec 2021 13:33:01 +0000 (13:33 +0000)
advent-of-code21.cabal
advent17/Main.hs [new file with mode: 0644]
data/advent17.txt [new file with mode: 0644]
problems/day17.html [new file with mode: 0644]

index 2532975bf97217da5feaf3777fb9c95bb56780b4..86523234e1571d96eb203b04c28f22aa3877e4bd 100644 (file)
@@ -187,3 +187,7 @@ executable advent16
   main-is: advent16/Main.hs
   build-depends: binary, bytestring, bitstream, mtl
 
+executable advent17
+  import: common-extensions, build-directives
+  main-is: advent17/Main.hs
+  build-depends: linear, text, attoparsec, lens
diff --git a/advent17/Main.hs b/advent17/Main.hs
new file mode 100644 (file)
index 0000000..b6a4dab
--- /dev/null
@@ -0,0 +1,72 @@
+-- Writeup at https://work.njae.me.uk/2021/12/19/advent-of-code-2021-day-17/
+
+import Data.Text ()
+import qualified Data.Text.IO as TIO
+import Data.Attoparsec.Text hiding (take, takeWhile)
+
+import Control.Lens
+import Linear (V2(..), (^+^), _x, _y)
+import Data.Ix
+
+type Coord = V2 Int
+type Bounds = (Coord, Coord)
+
+data Probe = Probe {_pos :: Coord, _vel :: Coord}
+  deriving (Show, Eq)
+makeLenses ''Probe
+
+
+
+main :: IO ()
+main = 
+  do  text <- TIO.readFile "data/advent17.txt"
+      let target = successfulParse text
+      print $ part1 target
+      print $ part2 target
+
+part1 :: Bounds -> Int
+part1 = findYMax 
+
+part2 :: Bounds -> Int
+part2 target@(V2 _minXT minYT, V2 maxXT _maxYT) = 
+  length $ filter (hits target) trajectories
+  where yMax = findYMax target
+        viable = (V2 0 minYT, V2 maxXT yMax)
+        launches = [Probe {_pos = V2 0 0, _vel = V2 x y} 
+                   | x <- [1..maxXT], y <- [minYT..(abs minYT)]
+                   ]
+        trajectories = map (simulate viable) launches
+
+findYMax :: Bounds -> Int
+findYMax (V2 _ y, _) = y' * (y' - 1) `div` 2
+  where y' = abs y
+
+step :: Probe -> Probe
+step probe = probe & pos .~ (probe ^. pos ^+^ probe ^. vel) & vel .~ vel'
+  where vel' = V2 (max 0 (vx - 1)) (vy - 1)
+        V2 vx vy = _vel
+        -- v = probe ^. vel
+        -- vel' = v & _x .~ (max 0 ((v ^. _x) - 1)) & _y .~ ((v ^. _y) - 1)
+
+simulate :: Bounds -> Probe -> [Probe]
+simulate viable = takeWhile (within viable) . iterate step
+
+within :: Bounds -> Probe -> Bool
+within limits probe = inRange limits (probe ^. pos)
+
+hits :: Bounds -> [Probe] -> Bool
+hits target = any (within target)
+
+
+-- Parse the input file
+
+targetP = boundify <$> ("target area: x=" *> regionP) <*> (", y=" *> regionP)
+  where boundify (x1, x2) (y1, y2) = (V2 x1 y1, V2 x2 y2)
+
+regionP = (,) <$> (signed decimal <* "..") <*> signed decimal
+
+-- successfulParse :: Text -> (Integer, [Maybe Integer])
+successfulParse input = 
+  case parseOnly targetP input of
+    Left  _err -> (V2 0 0, V2 0 0) -- TIO.putStr $ T.pack $ parseErrorPretty err
+    Right target -> target
diff --git a/data/advent17.txt b/data/advent17.txt
new file mode 100644 (file)
index 0000000..3d498ff
--- /dev/null
@@ -0,0 +1 @@
+target area: x=156..202, y=-110..-69
\ No newline at end of file
diff --git a/problems/day17.html b/problems/day17.html
new file mode 100644 (file)
index 0000000..7093cfa
--- /dev/null
@@ -0,0 +1,230 @@
+<!DOCTYPE html>
+<html lang="en-us">
+<head>
+<meta charset="utf-8"/>
+<title>Day 17 - Advent of Code 2021</title>
+<!--[if lt IE 9]><script src="/static/html5.js"></script><![endif]-->
+<link href='//fonts.googleapis.com/css?family=Source+Code+Pro:300&subset=latin,latin-ext' rel='stylesheet' type='text/css'/>
+<link rel="stylesheet" type="text/css" href="/static/style.css?26"/>
+<link rel="stylesheet alternate" type="text/css" href="/static/highcontrast.css?0" title="High Contrast"/>
+<link rel="shortcut icon" href="/favicon.png"/>
+</head><!--
+
+
+
+
+Oh, hello!  Funny seeing you here.
+
+I appreciate your enthusiasm, but you aren't going to find much down here.
+There certainly aren't clues to any of the puzzles.  The best surprises don't
+even appear in the source until you unlock them for real.
+
+Please be careful with automated requests; I'm not a massive company, and I can
+only take so much traffic.  Please be considerate so that everyone gets to play.
+
+If you're curious about how Advent of Code works, it's running on some custom
+Perl code. Other than a few integrations (auth, analytics, social media), I
+built the whole thing myself, including the design, animations, prose, and all
+of the puzzles.
+
+The puzzles are most of the work; preparing a new calendar and a new set of
+puzzles each year takes all of my free time for 4-5 months. A lot of effort
+went into building this thing - I hope you're enjoying playing it as much as I
+enjoyed making it for you!
+
+If you'd like to hang out, I'm @ericwastl on Twitter.
+
+- Eric Wastl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+-->
+<body>
+<header><div><h1 class="title-global"><a href="/">Advent of Code</a></h1><nav><ul><li><a href="/2021/about">[About]</a></li><li><a href="/2021/events">[Events]</a></li><li><a href="https://teespring.com/stores/advent-of-code" target="_blank">[Shop]</a></li><li><a href="/2021/settings">[Settings]</a></li><li><a href="/2021/auth/logout">[Log Out]</a></li></ul></nav><div class="user">Neil Smith <a href="/2021/support" class="supporter-badge" title="Advent of Code Supporter">(AoC++)</a> <span class="star-count">34*</span></div></div><div><h1 class="title-event">&nbsp;&nbsp;&nbsp;<span class="title-event-wrap">0xffff&amp;</span><a href="/2021">2021</a><span class="title-event-wrap"></span></h1><nav><ul><li><a href="/2021">[Calendar]</a></li><li><a href="/2021/support">[AoC++]</a></li><li><a href="/2021/sponsors">[Sponsors]</a></li><li><a href="/2021/leaderboard">[Leaderboard]</a></li><li><a href="/2021/stats">[Stats]</a></li></ul></nav></div></header>
+
+<div id="sidebar">
+<div id="sponsor"><div class="quiet">Our <a href="/2021/sponsors">sponsors</a> help make Advent of Code possible:</div><div class="sponsor"><a href="https://www.americanexpress.com/techcareers" target="_blank" onclick="if(ga)ga('send','event','sponsor','sidebar',this.href);" rel="noopener">American Express</a> - Work with the latest tech and back the engineering community through open source. Find your place in tech on #TeamAmex.</div></div>
+</div><!--/sidebar-->
+
+<main>
+<script>window.addEventListener('click', function(e,s,r){if(e.target.nodeName==='CODE'&&e.detail===3){s=window.getSelection();s.removeAllRanges();r=document.createRange();r.selectNodeContents(e.target);s.addRange(r);}});</script>
+<article class="day-desc"><h2>--- Day 17: Trick Shot ---</h2><p>You finally decode the Elves' message. <code><span title="Maybe you need to turn the message 90 degrees counterclockwise?">HI</span></code>, the message says. You continue searching for the sleigh keys.</p>
+<p>Ahead of you is what appears to be a large <a href="https://en.wikipedia.org/wiki/Oceanic_trench" target="_blank">ocean trench</a>. Could the keys have fallen into it? You'd better send a probe to investigate.</p>
+<p>The probe launcher on your submarine can fire the probe with any <a href="https://en.wikipedia.org/wiki/Integer" target="_blank">integer</a> velocity in the <code>x</code> (forward) and <code>y</code> (upward, or downward if negative) directions. For example, an initial <code>x,y</code> velocity like <code>0,10</code> would fire the probe straight up, while an initial velocity like <code>10,-1</code> would fire the probe forward at a slight downward angle.</p>
+<p>The probe's <code>x,y</code> position starts at <code>0,0</code>. Then, it will follow some trajectory by moving in <em>steps</em>. On each step, these changes occur in the following order:</p>
+<ul>
+<li>The probe's <code>x</code> position increases by its <code>x</code> velocity.</li>
+<li>The probe's <code>y</code> position increases by its <code>y</code> velocity.</li>
+<li>Due to drag, the probe's <code>x</code> velocity changes by <code>1</code> toward the value <code>0</code>; that is, it decreases by <code>1</code> if it is greater than <code>0</code>, increases by <code>1</code> if it is less than <code>0</code>, or does not change if it is already <code>0</code>.</li>
+<li>Due to gravity, the probe's <code>y</code> velocity decreases by <code>1</code>.</li>
+</ul>
+<p>For the probe to successfully make it into the trench, the probe must be on some trajectory that causes it to be within a <em>target area</em> after any step. The submarine computer has already calculated this target area (your puzzle input). For example:</p>
+<pre><code>target area: x=20..30, y=-10..-5</code></pre>
+<p>This target area means that you need to find initial <code>x,y</code> velocity values such that after any step, the probe's <code>x</code> position is at least <code>20</code> and at most <code>30</code>, <em>and</em> the probe's <code>y</code> position is at least <code>-10</code> and at most <code>-5</code>.</p>
+<p>Given this target area, one initial velocity that causes the probe to be within the target area after any step is <code>7,2</code>:</p>
+<pre><code>.............#....#............
+.......#..............#........
+...............................
+S........................#.....
+...............................
+...............................
+...........................#...
+...............................
+....................TTTTTTTTTTT
+....................TTTTTTTTTTT
+....................TTTTTTTT#TT
+....................TTTTTTTTTTT
+....................TTTTTTTTTTT
+....................TTTTTTTTTTT
+</code></pre>
+<p>In this diagram, <code>S</code> is the probe's initial position, <code>0,0</code>. The <code>x</code> coordinate increases to the right, and the <code>y</code> coordinate increases upward. In the bottom right, positions that are within the target area are shown as <code>T</code>. After each step (until the target area is reached), the position of the probe is marked with <code>#</code>. (The bottom-right <code>#</code> is both a position the probe reaches and a position in the target area.)</p>
+<p>Another initial velocity that causes the probe to be within the target area after any step is <code>6,3</code>:</p>
+<pre><code>...............#..#............
+...........#........#..........
+...............................
+......#..............#.........
+...............................
+...............................
+S....................#.........
+...............................
+...............................
+...............................
+.....................#.........
+....................TTTTTTTTTTT
+....................TTTTTTTTTTT
+....................TTTTTTTTTTT
+....................TTTTTTTTTTT
+....................T#TTTTTTTTT
+....................TTTTTTTTTTT
+</code></pre>
+<p>Another one is <code>9,0</code>:</p>
+<pre><code>S........#.....................
+.................#.............
+...............................
+........................#......
+...............................
+....................TTTTTTTTTTT
+....................TTTTTTTTTT#
+....................TTTTTTTTTTT
+....................TTTTTTTTTTT
+....................TTTTTTTTTTT
+....................TTTTTTTTTTT
+</code></pre>
+<p>One initial velocity that <em>doesn't</em> cause the probe to be within the target area after any step is <code>17,-4</code>:</p>
+<pre><code>S..............................................................
+...............................................................
+...............................................................
+...............................................................
+.................#.............................................
+....................TTTTTTTTTTT................................
+....................TTTTTTTTTTT................................
+....................TTTTTTTTTTT................................
+....................TTTTTTTTTTT................................
+....................TTTTTTTTTTT..#.............................
+....................TTTTTTTTTTT................................
+...............................................................
+...............................................................
+...............................................................
+...............................................................
+................................................#..............
+...............................................................
+...............................................................
+...............................................................
+...............................................................
+...............................................................
+...............................................................
+..............................................................#
+</code></pre>
+<p>The probe appears to pass through the target area, but is never within it after any step. Instead, it continues down and to the right - only the first few steps are shown.</p>
+<p>If you're going to fire a highly scientific probe out of a super cool probe launcher, you might as well do it with <em>style</em>. How high can you make the probe go while still reaching the target area?</p>
+<p>In the above example, using an initial velocity of <code>6,9</code> is the best you can do, causing the probe to reach a maximum <code>y</code> position of <code><em>45</em></code>. (Any higher initial <code>y</code> velocity causes the probe to overshoot the target area entirely.)</p>
+<p>Find the initial velocity that causes the probe to reach the highest <code>y</code> position and still eventually be within the target area after any step. <em>What is the highest <code>y</code> position it reaches on this trajectory?</em></p>
+</article>
+<p>Your puzzle answer was <code>5995</code>.</p><article class="day-desc"><h2 id="part2">--- Part Two ---</h2><p>Maybe a fancy trick shot isn't the best idea; after all, you only have one probe, so you had better not miss.</p>
+<p>To get the best idea of what your options are for launching the probe, you need to find <em>every initial velocity</em> that causes the probe to eventually be within the target area after any step.</p>
+<p>In the above example, there are <code><em>112</em></code> different initial velocity values that meet these criteria:</p>
+<pre><code>23,-10  25,-9   27,-5   29,-6   22,-6   21,-7   9,0     27,-7   24,-5
+25,-7   26,-6   25,-5   6,8     11,-2   20,-5   29,-10  6,3     28,-7
+8,0     30,-6   29,-8   20,-10  6,7     6,4     6,1     14,-4   21,-6
+26,-10  7,-1    7,7     8,-1    21,-9   6,2     20,-7   30,-10  14,-3
+20,-8   13,-2   7,3     28,-8   29,-9   15,-3   22,-5   26,-8   25,-8
+25,-6   15,-4   9,-2    15,-2   12,-2   28,-9   12,-3   24,-6   23,-7
+25,-10  7,8     11,-3   26,-7   7,1     23,-9   6,0     22,-10  27,-6
+8,1     22,-8   13,-4   7,6     28,-6   11,-4   12,-4   26,-9   7,4
+24,-10  23,-8   30,-8   7,0     9,-1    10,-1   26,-5   22,-9   6,5
+7,5     23,-6   28,-10  10,-2   11,-1   20,-9   14,-2   29,-7   13,-3
+23,-5   24,-8   27,-9   30,-7   28,-5   21,-10  7,9     6,6     21,-5
+27,-10  7,2     30,-9   21,-8   22,-7   24,-9   20,-6   6,9     29,-5
+8,-2    27,-8   30,-5   24,-7
+</code></pre>
+<p><em>How many distinct initial velocity values cause the probe to be within the target area after any step?</em></p>
+</article>
+<p>Your puzzle answer was <code>3202</code>.</p><p class="day-success">Both parts of this puzzle are complete! They provide two gold stars: **</p>
+<p>At this point, you should <a href="/2021">return to your Advent calendar</a> and try another puzzle.</p>
+<p>If you still want to see it, you can <a href="17/input" target="_blank">get your puzzle input</a>.</p>
+<p>You can also <span class="share">[Share<span class="share-content">on
+  <a href="https://twitter.com/intent/tweet?text=I%27ve+completed+%22Trick+Shot%22+%2D+Day+17+%2D+Advent+of+Code+2021&amp;url=https%3A%2F%2Fadventofcode%2Ecom%2F2021%2Fday%2F17&amp;related=ericwastl&amp;hashtags=AdventOfCode" target="_blank">Twitter</a>
+  <a href="javascript:void(0);" onclick="var mastodon_instance=prompt('Mastodon Instance / Server Name?'); if(typeof mastodon_instance==='string' && mastodon_instance.length){this.href='https://'+mastodon_instance+'/share?text=I%27ve+completed+%22Trick+Shot%22+%2D+Day+17+%2D+Advent+of+Code+2021+%23AdventOfCode+https%3A%2F%2Fadventofcode%2Ecom%2F2021%2Fday%2F17'}else{return false;}" target="_blank">Mastodon</a
+></span>]</span> this puzzle.</p>
+</main>
+
+<!-- ga -->
+<script>
+(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+ga('create', 'UA-69522494-1', 'auto');
+ga('set', 'anonymizeIp', true);
+ga('send', 'pageview');
+</script>
+<!-- /ga -->
+</body>
+</html>
\ No newline at end of file