Done day 7
authorNeil Smith <neil.git@njae.me.uk>
Sun, 8 Dec 2019 17:51:12 +0000 (17:51 +0000)
committerNeil Smith <neil.git@njae.me.uk>
Sun, 8 Dec 2019 17:51:12 +0000 (17:51 +0000)
advent07/package.yaml [new file with mode: 0644]
advent07/src/advent07.hs [new file with mode: 0644]
data/advent07.txt [new file with mode: 0644]
problems/day07.html [new file with mode: 0644]
stack.yaml

diff --git a/advent07/package.yaml b/advent07/package.yaml
new file mode 100644 (file)
index 0000000..18d6c87
--- /dev/null
@@ -0,0 +1,61 @@
+# This YAML file describes your package. Stack will automatically generate a
+# Cabal file when you run `stack build`. See the hpack website for help with
+# this file: <https://github.com/sol/hpack>.
+
+name: advent07
+synopsis: Advent of Code
+version: '0.0.1'
+
+default-extensions:
+- AllowAmbiguousTypes
+- ApplicativeDo
+- BangPatterns
+- BlockArguments
+- DataKinds
+- DeriveFoldable
+- DeriveFunctor
+- DeriveGeneric
+- DeriveTraversable
+- EmptyCase
+- FlexibleContexts
+- FlexibleInstances
+- FunctionalDependencies
+- GADTs
+- GeneralizedNewtypeDeriving
+- ImplicitParams
+- KindSignatures
+- LambdaCase
+- MonadComprehensions
+- MonoLocalBinds
+- MultiParamTypeClasses
+- MultiWayIf
+- NegativeLiterals
+- NumDecimals
+- OverloadedLists
+- OverloadedStrings
+- PartialTypeSignatures
+- PatternGuards
+- PatternSynonyms
+- PolyKinds
+- RankNTypes
+- RecordWildCards
+- ScopedTypeVariables
+- TemplateHaskell
+- TransformListComp
+- TupleSections
+- TypeApplications
+- TypeInType
+- TypeOperators
+- ViewPatterns
+
+
+executables:
+  advent07:
+    main: advent07.hs
+    source-dirs: src
+    dependencies:
+    - base >= 2 && < 6
+    - text
+    - megaparsec
+    - containers
+    - mtl
diff --git a/advent07/src/advent07.hs b/advent07/src/advent07.hs
new file mode 100644 (file)
index 0000000..6e4275f
--- /dev/null
@@ -0,0 +1,271 @@
+import Debug.Trace
+
+import Data.Text (Text)
+import qualified Data.Text.IO as TIO
+
+import Data.Void (Void)
+
+import Text.Megaparsec hiding (State)
+import Text.Megaparsec.Char
+import qualified Text.Megaparsec.Char.Lexer as L
+import qualified Control.Applicative as CA
+
+import Control.Monad (unless)
+import Control.Monad.State.Strict
+import Control.Monad.Reader
+import Control.Monad.Writer
+import Control.Monad.RWS.Strict
+
+
+import qualified Data.IntMap.Strict as M
+import Data.IntMap.Strict ((!))
+import Data.List
+import Data.Function (on)
+
+type Memory = M.IntMap Int
+
+data Machine = Machine { _memory :: Memory
+                       , _ip :: Int
+                       , _inputIndex :: Int
+                       } 
+               deriving (Show, Eq)
+
+type ProgrammedMachine = RWS [Int] [Int] Machine
+
+data EncapsulatedMacine = EncapsulatedMacine 
+    { _machine :: Machine
+    , _executionState :: ExecutionState
+    , _initialInput :: [Int]
+    , _currentInput :: [Int]
+    , _machineOutput :: [Int]
+    } deriving (Show, Eq)
+
+data ParameterMode = Position | Immediate deriving (Ord, Eq, Show)
+
+data ExecutionState = Runnable | Blocked | Terminated  deriving (Ord, Eq, Show)
+
+type Pipeline = M.IntMap EncapsulatedMacine
+
+
+main :: IO ()
+main = do 
+        text <- TIO.readFile "data/advent07.txt"
+        let mem = successfulParse text
+        print $ part1 mem
+        print $ part2 mem
+
+
+part1 mem = maximum outputs
+    where inputs = permutations [0..4]
+          outputs = map (chainMachines mem) inputs
+
+chainMachines mem settings = foldl' (chainMachine mem) 0 settings
+
+chainMachine mem prevOutput setting = findMachineOutput [setting, prevOutput] mem
+
+
+part2 mem = maximum outputs
+    where   inputs = permutations [5..9]
+            pipelines = map (buildPipeline mem) inputs
+            outputs = map runPipeline pipelines
+
+buildPipeline :: [Int] -> [Int] -> Pipeline
+buildPipeline mem input = M.insert 0 machine0' pipeline
+    where pipeline = M.fromList $ zip [0..] $ map (encapsulate mem) input
+          machine0 = pipeline!0
+          machine0' = machine0 { _initialInput = (_initialInput machine0) ++ [0]}
+
+
+encapsulate :: [Int] -> Int -> EncapsulatedMacine
+encapsulate mem input = EncapsulatedMacine 
+    { _machine = makeMachine mem
+    , _executionState = Runnable
+    , _initialInput = [input]
+    , _machineOutput = []
+    , _currentInput = [input]
+    }
+
+
+runPipeline :: Pipeline -> Int
+-- runPipeline pipeline | trace (pipelineTrace pipeline) False = undefined
+runPipeline pipeline 
+    | finished pipeline = last $ _machineOutput $ snd $ M.findMax pipeline
+    | otherwise = runPipeline pipeline''
+    where   (indexToRun, machineToRun) = M.findMin $ runnableMachines pipeline
+            feedsIntoIndex = (indexToRun + 1) `mod` (M.size pipeline)
+            feedsIntoMachine = pipeline!feedsIntoIndex
+            fimi = _initialInput feedsIntoMachine
+            machine' = runEncapsulatedMachine machineToRun
+            fullOutput = _machineOutput machine'
+            feedsIntoState = case (_executionState feedsIntoMachine) of
+                                  Blocked -> Runnable
+                                  Terminated -> Terminated
+                                  Runnable -> Runnable
+            feedsIntoMachine' = feedsIntoMachine {_executionState = feedsIntoState, _currentInput = fimi ++ fullOutput}
+            pipeline' = M.insert indexToRun machine' pipeline
+            pipeline'' = M.insert feedsIntoIndex feedsIntoMachine' pipeline'
+
+
+
+pipelineTrace :: Pipeline -> String
+pipelineTrace pipeline = show $ M.toList $ M.map emTrace pipeline
+
+emTrace e = intercalate " ; " terms
+    where terms = [ show $ _executionState e
+                  , "in"
+                  , show $ _currentInput e 
+                  , "out"
+                  , show $ _machineOutput e
+                  ]
+
+
+finished :: Pipeline -> Bool
+finished pipeline = M.null $ runnableMachines pipeline
+
+runnableMachines :: Pipeline -> Pipeline
+runnableMachines = M.filter (\e -> _executionState e == Runnable)
+
+runEncapsulatedMachine :: EncapsulatedMacine -> EncapsulatedMacine
+runEncapsulatedMachine e = e { _machine = machine'
+                             , _executionState = halted
+                             , _machineOutput = (_machineOutput e) ++ output
+                             }
+    where   machine = _machine e
+            input = _currentInput e
+            (halted, machine', output) = runRWS runAll input machine
+
+
+findMachineOutput :: [Int] -> [Int] -> Int
+findMachineOutput inputs program = last output
+    where (_haltedBecause, _machine, output) = runRWS runAll inputs (makeMachine program)
+
+
+makeMachine :: [Int] -> Machine
+makeMachine memory = Machine    {_ip = 0, _inputIndex = 0
+                                , _memory = M.fromList $ zip [0..] memory
+                                }
+
+
+runAll :: ProgrammedMachine ExecutionState
+runAll = do mem <- gets _memory
+            ip <- gets _ip
+            input <- ask
+            iIndex <- gets _inputIndex
+            let acutalInputLength = length input
+            let requiredInputLength = iIndex + 1
+            if (mem!ip == 99)
+            then return Terminated
+            else    if (mem!ip == 3 && requiredInputLength > acutalInputLength)
+                    then return Blocked
+                    else do runStep
+                            runAll
+
+runStep :: ProgrammedMachine ()
+runStep = 
+    do mem <- gets _memory
+       ip <- gets _ip
+       let opcode = (mem!ip) `mod` 100
+       let modes = parameterModes ((mem!ip) `div` 100)
+       fetchInput opcode
+       putOutput opcode modes
+       mem' <- gets _memory
+       let (mem'', ip') = perform opcode ip modes mem'
+       modify (\m -> m {_ip = ip', _memory = mem''})
+
+fetchInput :: Int -> ProgrammedMachine ()
+-- fetchInput opcode | trace ("Input with opcode " ++ show opcode) False = undefined
+fetchInput 3 =
+    do mem <- gets _memory
+       ip <- gets _ip
+       inputIndex <- gets _inputIndex
+       inputs <- ask 
+       let mem' = iInsert (ip + 1) (inputs!!inputIndex) mem
+       modify (\m -> m {_inputIndex = inputIndex + 1, _memory = mem'})
+fetchInput _ = return ()
+
+putOutput :: Int -> [ParameterMode] -> ProgrammedMachine ()
+-- putOutput opcode _modes | trace ("Output with opcode " ++ show opcode) False = undefined
+putOutput 4 modes =
+    do mem <- gets _memory
+       ip <- gets _ip
+       let v = getMemoryValue (ip + 1) (modes!!0) mem
+       tell [v]
+putOutput _ _ = return ()       
+
+
+perform :: Int -> Int -> [ParameterMode] -> Memory -> (Memory, Int)
+-- perform instr ip modes mem | trace ("Perform ip " ++ show ip ++ " opcode " ++ show instr ++ " modes " ++ (show (take 3 modes)) ++ " args " ++ (intercalate ", " (map show [(mem!(ip+1)), (mem!(ip+2)), (mem!(ip+3))]))) False = undefined
+perform 1 ip modes mem = (iInsert (ip + 3) (a + b) mem, ip + 4)
+    where a = getMemoryValue (ip + 1) (modes!!0) mem
+          b = getMemoryValue (ip + 2) (modes!!1) mem
+perform 2 ip modes mem = (iInsert (ip + 3) (a * b) mem, ip + 4)
+    where a = getMemoryValue (ip + 1) (modes!!0) mem
+          b = getMemoryValue (ip + 2) (modes!!1) mem
+perform 3 ip _ mem = (mem, ip + 2)
+perform 4 ip _ mem = (mem, ip + 2)
+perform 5 ip modes mem = (mem, ip')
+    where a = getMemoryValue (ip + 1) (modes!!0) mem
+          b = getMemoryValue (ip + 2) (modes!!1) mem
+          ip' = if a /= 0 then b else ip + 3
+perform 6 ip modes mem = (mem, ip')
+    where a = getMemoryValue (ip + 1) (modes!!0) mem
+          b = getMemoryValue (ip + 2) (modes!!1) mem
+          ip' = if a == 0 then b else ip + 3
+perform 7 ip modes mem = (iInsert (ip + 3) res mem, ip + 4)
+    where a = getMemoryValue (ip + 1) (modes!!0) mem
+          b = getMemoryValue (ip + 2) (modes!!1) mem
+          res = if a < b then 1 else 0
+perform 8 ip modes mem = (iInsert (ip + 3) res mem, ip + 4)
+    where a = getMemoryValue (ip + 1) (modes!!0) mem
+          b = getMemoryValue (ip + 2) (modes!!1) mem
+          res = if a == b then 1 else 0
+perform _ ip _ mem = (mem, ip)
+
+
+getMemoryValue loc Position mem = mem!>loc
+getMemoryValue loc Immediate mem = mem!loc
+
+
+parameterModes :: Int -> [ParameterMode]
+parameterModes modeCode = unfoldr generateMode modeCode
+
+generateMode :: Int -> Maybe (ParameterMode, Int)
+generateMode modeCode = Just (mode, modeCode `div` 10)
+    where mode = case (modeCode `mod` 10) of 
+                    0 -> Position
+                    1 -> Immediate
+
+
+-- Some IntMap utility functions, for syntactic sugar
+
+-- prefix version of (!)
+lkup k m = m!k
+
+-- indirect lookup
+(!>) m k = m!(m!k)
+
+-- indirect insert
+iInsert k v m = M.insert (m!k) v m
+
+
+
+-- Parse the input file
+type Parser = Parsec Void Text
+
+sc :: Parser ()
+sc = L.space (skipSome spaceChar) CA.empty CA.empty
+-- sc = L.space (skipSome (char ' ')) CA.empty CA.empty
+
+lexeme  = L.lexeme sc
+integer = lexeme L.decimal
+signedInteger = L.signed sc integer
+symb = L.symbol sc
+comma = symb ","
+
+memoryP = signedInteger `sepBy` comma
+
+successfulParse :: Text -> [Int]
+successfulParse input = 
+        case parse memoryP "input" input of
+                Left  _err -> [] -- TIO.putStr $ T.pack $ parseErrorPretty err
+                Right memory -> memory
\ No newline at end of file
diff --git a/data/advent07.txt b/data/advent07.txt
new file mode 100644 (file)
index 0000000..4785785
--- /dev/null
@@ -0,0 +1 @@
+3,8,1001,8,10,8,105,1,0,0,21,42,51,76,101,118,199,280,361,442,99999,3,9,101,5,9,9,102,2,9,9,1001,9,4,9,102,2,9,9,4,9,99,3,9,1002,9,3,9,4,9,99,3,9,1002,9,4,9,1001,9,3,9,1002,9,5,9,101,3,9,9,1002,9,2,9,4,9,99,3,9,101,4,9,9,1002,9,2,9,1001,9,3,9,1002,9,3,9,101,4,9,9,4,9,99,3,9,101,3,9,9,1002,9,3,9,101,2,9,9,4,9,99,3,9,1002,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,1,9,4,9,99,3,9,1001,9,1,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,1,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,1002,9,2,9,4,9,99,3,9,1002,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,2,9,9,4,9,99,3,9,1002,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,101,1,9,9,4,9,99,3,9,1002,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,2,9,9,4,9,99
diff --git a/problems/day07.html b/problems/day07.html
new file mode 100644 (file)
index 0000000..a7ca566
--- /dev/null
@@ -0,0 +1,168 @@
+<!DOCTYPE html>
+<html lang="en-us">
+<head>
+<meta charset="utf-8"/>
+<title>Day 7 - Advent of Code 2019</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?24"/>
+<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, ads, 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="/2019/about">[About]</a></li><li><a href="/2019/events">[Events]</a></li><li><a href="https://teespring.com/adventofcode-2019" target="_blank">[Shop]</a></li><li><a href="/2019/settings">[Settings]</a></li><li><a href="/2019/auth/logout">[Log Out]</a></li></ul></nav><div class="user">Neil Smith <a href="/2019/support" class="supporter-badge" title="Advent of Code Supporter">(AoC++)</a> <span class="star-count">14*</span></div></div><div><h1 class="title-event">&nbsp;&nbsp;<span class="title-event-wrap">{year=&gt;</span><a href="/2019">2019</a><span class="title-event-wrap">}</span></h1><nav><ul><li><a href="/2019">[Calendar]</a></li><li><a href="/2019/support">[AoC++]</a></li><li><a href="/2019/sponsors">[Sponsors]</a></li><li><a href="/2019/leaderboard">[Leaderboard]</a></li><li><a href="/2019/stats">[Stats]</a></li></ul></nav></div></header>
+
+<div id="sidebar">
+<div id="sponsor"><div class="quiet">Our <a href="/2019/sponsors">sponsors</a> help make Advent of Code possible:</div><div class="sponsor"><a href="https://www.reaktor.com/advent-of-code" target="_blank" onclick="if(ga)ga('send','event','sponsor','sidebar',this.href);" rel="noopener">Reaktor</a> - Tracking Santa from space since 2018. Always looking for more talented Santa&apos;s little helpers.</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 7: Amplification Circuit ---</h2><p>Based on the navigational maps, you're going to need to send more power to your ship's thrusters to reach Santa in time. To do this, you'll need to configure a series of <a href="https://en.wikipedia.org/wiki/Amplifier">amplifiers</a> already installed on the ship.</p>
+<p>There are five <span title="As you can see, I know exactly how rockets work.">amplifiers connected in series</span>; each one receives an input signal and produces an output signal.  They are connected such that the first amplifier's output leads to the second amplifier's input, the second amplifier's output leads to the third amplifier's input, and so on.  The first amplifier's input value is <code>0</code>, and the last amplifier's output leads to your ship's thrusters.</p>
+<pre><code>    O-------O  O-------O  O-------O  O-------O  O-------O
+0 -&gt;| Amp A |-&gt;| Amp B |-&gt;| Amp C |-&gt;| Amp D |-&gt;| Amp E |-&gt; (to thrusters)
+    O-------O  O-------O  O-------O  O-------O  O-------O
+</code></pre>
+<p>The Elves have sent you some <em>Amplifier Controller Software</em> (your puzzle input), a program that should run on your <a href="5">existing Intcode computer</a>. Each amplifier will need to run a copy of the program.</p>
+<p>When a copy of the program starts running on an amplifier, it will first use an input instruction to ask the amplifier for its current <em>phase setting</em> (an integer from <code>0</code> to <code>4</code>). Each phase setting is used <em>exactly once</em>, but the Elves can't remember which amplifier needs which phase setting.</p>
+<p>The program will then call another input instruction to get the amplifier's input signal, compute the correct output signal, and supply it back to the amplifier with an output instruction. (If the amplifier has not yet received an input signal, it waits until one arrives.)</p>
+<p>Your job is to <em>find the largest output signal that can be sent to the thrusters</em> by trying every possible combination of phase settings on the amplifiers. Make sure that memory is not shared or reused between copies of the program.</p>
+<p>For example, suppose you want to try the phase setting sequence <code>3,1,2,4,0</code>, which would mean setting amplifier <code>A</code> to phase setting <code>3</code>, amplifier <code>B</code> to setting <code>1</code>, <code>C</code> to <code>2</code>, <code>D</code> to <code>4</code>, and <code>E</code> to <code>0</code>. Then, you could determine the output signal that gets sent from amplifier <code>E</code> to the thrusters with the following steps:</p>
+<ul>
+<li>Start the copy of the amplifier controller software that will run on amplifier <code>A</code>. At its first input instruction, provide it the amplifier's phase setting, <code>3</code>.  At its second input instruction, provide it the input signal, <code>0</code>.  After some calculations, it will use an output instruction to indicate the amplifier's output signal.</li>
+<li>Start the software for amplifier <code>B</code>. Provide it the phase setting (<code>1</code>) and then whatever output signal was produced from amplifier <code>A</code>. It will then produce a new output signal destined for amplifier <code>C</code>.</li>
+<li>Start the software for amplifier <code>C</code>, provide the phase setting (<code>2</code>) and the value from amplifier <code>B</code>, then collect its output signal.</li>
+<li>Run amplifier <code>D</code>'s software, provide the phase setting (<code>4</code>) and input value, and collect its output signal.</li>
+<li>Run amplifier <code>E</code>'s software, provide the phase setting (<code>0</code>) and input value, and collect its output signal.</li>
+</ul>
+<p>The final output signal from amplifier <code>E</code> would be sent to the thrusters. However, this phase setting sequence may not have been the best one; another sequence might have sent a higher signal to the thrusters.</p>
+<p>Here are some example programs:</p>
+<ul>
+<li><p>Max thruster signal <em><code>43210</code></em> (from phase setting sequence <code>4,3,2,1,0</code>):</p><pre><code>3,15,3,16,1002,16,10,16,1,16,15,15,4,15,99,0,0</code></pre></li>
+<li><p>Max thruster signal <em><code>54321</code></em> (from phase setting sequence <code>0,1,2,3,4</code>):</p><pre><code>3,23,3,24,1002,24,10,24,1002,23,-1,23,<br/>101,5,23,23,1,24,23,23,4,23,99,0,0</code></pre></li>
+<li><p>Max thruster signal <em><code>65210</code></em> (from phase setting sequence <code>1,0,4,3,2</code>):</p><pre><code>3,31,3,32,1002,32,10,32,1001,31,-2,31,1007,31,0,33,<br/>1002,33,7,33,1,33,31,31,1,32,31,31,4,31,99,0,0,0</code></pre></li>
+</ul>
+<p>Try every combination of phase settings on the amplifiers.  <em>What is the highest signal that can be sent to the thrusters?</em></p>
+</article>
+<p>Your puzzle answer was <code>75228</code>.</p><article class="day-desc"><h2 id="part2">--- Part Two ---</h2><p>It's no good - in this configuration, the amplifiers can't generate a large enough output signal to produce the thrust you'll need.  The Elves quickly talk you through rewiring the amplifiers into a <em>feedback loop</em>:</p>
+<pre><code>      O-------O  O-------O  O-------O  O-------O  O-------O
+0 -+-&gt;| Amp A |-&gt;| Amp B |-&gt;| Amp C |-&gt;| Amp D |-&gt;| Amp E |-.
+   |  O-------O  O-------O  O-------O  O-------O  O-------O |
+   |                                                        |
+   '--------------------------------------------------------+
+                                                            |
+                                                            v
+                                                     (to thrusters)
+</code></pre>
+<p>Most of the amplifiers are connected as they were before; amplifier <code>A</code>'s output is connected to amplifier <code>B</code>'s input, and so on. <em>However,</em> the output from amplifier <code>E</code> is now connected into amplifier <code>A</code>'s input. This creates the feedback loop: the signal will be sent through the amplifiers <em>many times</em>.</p>
+<p>In feedback loop mode, the amplifiers need <em>totally different phase settings</em>: integers from <code>5</code> to <code>9</code>, again each used exactly once. These settings will cause the Amplifier Controller Software to repeatedly take input and produce output many times before halting. Provide each amplifier its phase setting at its first input instruction; all further input/output instructions are for signals.</p>
+<p>Don't restart the Amplifier Controller Software on any amplifier during this process. Each one should continue receiving and sending signals until it halts.</p>
+<p>All signals sent or received in this process will be between pairs of amplifiers except the very first signal and the very last signal. To start the process, a <code>0</code> signal is sent to amplifier <code>A</code>'s input <em>exactly once</em>.</p>
+<p>Eventually, the software on the amplifiers will halt after they have processed the final loop. When this happens, the last output signal from amplifier <code>E</code> is sent to the thrusters. Your job is to <em>find the largest output signal that can be sent to the thrusters</em> using the new phase settings and feedback loop arrangement.</p>
+<p>Here are some example programs:</p>
+<ul>
+<li><p>Max thruster signal <em><code>139629729</code></em> (from phase setting sequence <code>9,8,7,6,5</code>):</p><pre><code>3,26,1001,26,-4,26,3,27,1002,27,2,27,1,27,26,<br/>27,4,27,1001,28,-1,28,1005,28,6,99,0,0,5</code></pre></li>
+<li><p>Max thruster signal <em><code>18216</code></em> (from phase setting sequence <code>9,7,8,5,6</code>):</p><pre><code>3,52,1001,52,-5,52,3,53,1,52,56,54,1007,54,5,55,1005,55,26,1001,54,<br/>-5,54,1105,1,12,1,53,54,53,1008,54,0,55,1001,55,1,55,2,53,55,53,4,<br/>53,1001,56,-1,56,1005,56,6,99,0,0,0,0,10</code></pre></li>
+</ul>
+<p>Try every combination of the new phase settings on the amplifier feedback loop.  <em>What is the highest signal that can be sent to the thrusters?</em></p>
+</article>
+<p>Your puzzle answer was <code>79846026</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="/2019">return to your Advent calendar</a> and try another puzzle.</p>
+<p>If you still want to see it, you can <a href="7/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+%22Amplification+Circuit%22+%2D+Day+7+%2D+Advent+of+Code+2019&amp;url=https%3A%2F%2Fadventofcode%2Ecom%2F2019%2Fday%2F7&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+%22Amplification+Circuit%22+%2D+Day+7+%2D+Advent+of+Code+2019+%23AdventOfCode+https%3A%2F%2Fadventofcode%2Ecom%2F2019%2Fday%2F7'}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
index 2f11803..b087b0a 100644 (file)
@@ -43,6 +43,7 @@ packages:
 - advent04
 - advent05
 - advent06
+- advent07
 
 
 # Dependency packages to be pulled from upstream that are not in the resolver.