From 133559acebf7fdefd20a0653833311ea1a6f8811 Mon Sep 17 00:00:00 2001 From: Neil Smith Date: Sun, 30 Jul 2023 09:26:10 +0100 Subject: [PATCH 1/4] Solved adventure game --- .gitignore | 42 +++++ CoinSolver.hs | 19 ++ README.md | 137 +++++++++++++++ adventure_input.txt | 9 + all_coins.txt | 49 ++++++ challenge.bin | Bin 0 -> 60100 bytes coins_used.txt | 63 +++++++ found_teleporter.txt | 72 ++++++++ login-details.txt | 2 + red_blue_coin.txt | 37 ++++ red_coin.txt | 30 ++++ src/Main.hs | 177 +++++++++++++++++++ src/SynacorEngine.hs | 295 ++++++++++++++++++++++++++++++++ src/synacor_codes.txt | 17 ++ synacor-challenge.tgz | Bin 0 -> 52985 bytes synacor.cabal | 117 +++++++++++++ synacor.sublime-project | 8 + test1.txt | 2 + test2.txt | 11 ++ twisty_passages.txt | 15 ++ twisty_passages_can.txt | 20 +++ twisty_passages_code.txt | 25 +++ twisty_passages_lit_lantern.txt | 22 +++ 23 files changed, 1169 insertions(+) create mode 100644 .gitignore create mode 100644 CoinSolver.hs create mode 100644 README.md create mode 100644 adventure_input.txt create mode 100644 all_coins.txt create mode 100644 challenge.bin create mode 100644 coins_used.txt create mode 100644 found_teleporter.txt create mode 100644 login-details.txt create mode 100644 red_blue_coin.txt create mode 100644 red_coin.txt create mode 100644 src/Main.hs create mode 100644 src/SynacorEngine.hs create mode 100644 src/synacor_codes.txt create mode 100644 synacor-challenge.tgz create mode 100644 synacor.cabal create mode 100644 synacor.sublime-project create mode 100644 test1.txt create mode 100644 test2.txt create mode 100644 twisty_passages.txt create mode 100644 twisty_passages_can.txt create mode 100644 twisty_passages_code.txt create mode 100644 twisty_passages_lit_lantern.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1a0ee39 --- /dev/null +++ b/.gitignore @@ -0,0 +1,42 @@ +# Extensionless files +* +!/**/ +!*.* + +# Haskell bits +dist +dist-* +cabal-dev +*.o +*.hi +*.chi +*.chs.h +*.dyn_o +*.dyn_hi +.hpc +.hsenv +.cabal-sandbox/ +cabal.sandbox.config +*.prof +*.aux +*.hp +*.eventlog +cabal.project.local +.HTF/ + + +# IPython / IHaskell notebook checkpoints +.ipynb* + +# Sublime text +*.sublime-workspace + +# Logs +*.log + +# Profile exports +*.ps + +# KDE +.directory + diff --git a/CoinSolver.hs b/CoinSolver.hs new file mode 100644 index 0000000..d3a9e13 --- /dev/null +++ b/CoinSolver.hs @@ -0,0 +1,19 @@ +import Data.Map.Strict as M +import Data.Map.Strict ((!)) +import Data.List + +data Coins = Red | Blue | Shiny | Corroded | Concave + deriving (Ord, Eq, Show, Enum, Bounded) + +allCoins = [Red .. Concave] + +main = print solve + +coins :: M.Map Coins Int +coins = M.fromList $ zip [Red .. Concave] [2, 9, 5, 3, 7] + +solve :: [[Coins]] +solve = [ [a, b, c, d, e] + | [a, b, c, d, e] <- permutations allCoins + , (coins ! a) + (coins ! b) * (coins ! c) ^2 + (coins ! d) ^3 - (coins ! e) == 399 + ] diff --git a/README.md b/README.md new file mode 100644 index 0000000..a617b7c --- /dev/null +++ b/README.md @@ -0,0 +1,137 @@ +--- +title: "Advent of Code 2022" +output: html_document +css: modest.css +--- +Code to solve the [Advent of Code](http://adventofcode.com/2022/) puzzles. This year, I'm using the puzzles to develop my skills in [Haskell](https://wiki.haskell.org/Haskell). I'm writing up a [commentary on these puzzles and my solutions](https://work.njae.me.uk/tag/advent-of-code/) on my blog. + +[Learn you a Haskell](http://learnyouahaskell.com/chapters), [Introduction to Haskell 98](https://www.haskell.org/tutorial/index.html), and [Hackage](https://hackage.haskell.org/) are good resources. + +The [Cabal user guide](https://cabal.readthedocs.io/en/latest/index.html) and [How I Start: Haskell](http://howistart.org/posts/haskell/1/) are good sources of using the tools. + +# Toolchain + +Install Ghcup following [the instructions](https://www.haskell.org/ghcup/install/#installation), making sure to load the updated environment with + +```bash +source /home/neil/.ghcup/env +``` + +and then set the default GHC to use with `ghcup set ghc 9.0.1` . + +Install [Haskell Language Server](https://haskell-language-server.readthedocs.io/en/latest/configuration.html) for Sublime Text + + +## Creating the repository and project +Create the repository as normal: create the project in Gitolite, clone it, and insert the `.gitignore` and `README.md` files. + +There's one package per day, with the code for each package in sub-directories of the root directory. + +Create the basic `cabal` project. + +``` +cabal init +``` + +Modify the `advent-of-code21.cabal` file as needed, such as updating the Cabal version and writing the `common` stanzas. + +## Creating subsequent days + +Each day lives in a separate directory, with code in the `src` directory. + +Compile with +``` +cabal build +``` +or +``` +cabal build advent01 +``` + +Run with +``` +cabal run advent01 +``` + +If you want to pass in additional RTS parameters, do it like this: +``` +cabal run advent01 -- +RTS -K0 -RTS +``` + +Run interactively with +``` +cabal repl advent01 +``` +or +``` +stack ghci advent01:exe:advent01 +``` +if the first form is ambiguous. + +## Profiling + +To profile, use + +``` +cabal run advent01 --enable-profiling -- +RTS -N -p -s -hT +``` + +Or, you can simplify the RTS options by adding them to a new stanza in the cabal file: + +``` +executable advent01prof + import: common-extensions, build-directives + main-is: advent01/Main.hs + build-depends: text, containers, linear, array, pqueue, mtl, lens + ghc-options: -O2 + -Wall + -threaded + -eventlog + -rtsopts "-with-rtsopts=-N -p -s -hT" +``` + +Only include the `-eventlog` directive if you want to use Threadscope to investigate parallel behaviour. + +then running + +``` +cabal run advent01prof --enable-profiling +``` + + +Generate the profile graph with +``` +hp2ps -M advent01.hp +``` + + +# Packages + +Packages I used a lot: + +* [Containers](https://hackage.haskell.org/package/containers) (and some [better documentation](https://haskell-containers.readthedocs.io/en/latest/intro.html)); [Unordered containers](https://hackage.haskell.org/package/unordered-containers) is a mostly-equivalent alternative. +* [Attoparsec](https://hackage.haskell.org/package/attoparsec) (and [Megaparsec](https://hackage.haskell.org/package/megaparsec), and [ReadP](https://hackage.haskell.org/package/base-4.14.1.0/docs/Text-ParserCombinators-ReadP.html) once). + +There are somewhat decent [tutorials on Megaparsec](https://markkarpov.com/tutorial/megaparsec.html) and [Attoparsec](https://www.schoolofhaskell.com/school/starting-with-haskell/libraries-and-frameworks/text-manipulation/attoparsec). + +Packages I didn't use much, but need to remember: + +* [Arithmoi](https://hackage.haskell.org/package/arithmoi) for number theory +* [Pointed List](https://hackage.haskell.org/package/pointedlist-0.6.1) for zipper lists (sometimes circular) +* [Vector](https://hackage.haskell.org/package/vector) for array-like things +* [Linear](https://hackage.haskell.org/package/linear) for coordinate-vector like things +* [Grid](https://hackage.haskell.org/package/grid) for 2-d grids +* [Graph-wrapper](https://hackage.haskell.org/package/graph-wrapper) for graphs +* [Lens](https://hackage.haskell.org/package/lens) (and a [summary of operators](https://github.com/ekmett/lens/wiki/Operators)). I didn't use these much this year, but did a lot last year. +* [RWS](https://hackage.haskell.org/package/mtl-2.2.2/docs/Control-Monad-RWS-Lazy.html) (Reader-Writer-State monad stack); again, used a lot last year but not this year +* [Monad loops](https://hackage.haskell.org/package/monad-loops-0.4.3/docs/Control-Monad-Loops.html), and [a description](https://conscientiousprogrammer.com/blog/2015/12/11/24-days-of-hackage-2015-day-11-monad-loops-avoiding-writing-recursive-functions-by-refactoring/) +* [Replace-Megaparsec](https://github.com/jamesdbrock/replace-megaparsec), for using Mpc for all sorts of things traditionally done with regex substitutions. + +# Readme + +Build this readme file wth +``` +pandoc -s README.md > README.html +``` + +(Using the [Modest style](https://github.com/markdowncss/modest).) diff --git a/adventure_input.txt b/adventure_input.txt new file mode 100644 index 0000000..c3ac999 --- /dev/null +++ b/adventure_input.txt @@ -0,0 +1,9 @@ +take tablet +go doorway +go north +go north +go bridge +continue +down +west +passage diff --git a/all_coins.txt b/all_coins.txt new file mode 100644 index 0000000..3122ffd --- /dev/null +++ b/all_coins.txt @@ -0,0 +1,49 @@ +take tablet +use tablet +doorway +north +north +bridge +continue +down +east +take empty lantern +west +west +passage +ladder +west +south +north +take can +use can +use lantern +west +ladder +darkness +continue +west +west +west +west +north +take red coin +north +north +west +take blue coin +up +take shiny coin +down +east +east +take concave coin +down +take corroded coin +up +west +look red coin +look blue coin +look shiny coin +look corroded coin +look concave coin diff --git a/challenge.bin b/challenge.bin new file mode 100644 index 0000000000000000000000000000000000000000..ffe2d2a5447a07eb52e6ff147238ae9ddb12f4cd GIT binary patch literal 60100 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 xk4GIyc{ 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, (:>), (:<), indices) + +import Control.Monad.State.Strict +import Control.Monad.Reader +import Control.Monad.Writer +import Control.Monad.RWS.Strict + +-- import Data.Bits +import Data.Word +import Data.Binary.Get +import qualified Data.ByteString.Lazy as BL + + +data SynacorState = SynacorState + { _ssMachines :: [Machine] + , _ssInputs :: [String] + , _ssOutputs :: [String] + , _ssContinue :: Bool + , _ssUnsaved :: Bool + , _ssState :: [ExecutionState] + } deriving (Ord, Eq) +makeLenses ''SynacorState + +instance Show SynacorState + where + show state = + intercalate ", " + [ "SynacorState" + , (show (length (state ^. ssMachines)) ++ " machines") + , "inputs " ++ (intercalate ":" $ state ^. ssInputs) + , "outputs " ++ (intercalate ":" $ fmap (take 20) $ state ^. ssOutputs) + , "conts " ++ (show $ state ^. ssContinue) + , "unsaved " ++ (show $ state ^. ssUnsaved) + , "states " ++ (show $ state ^. ssState) + ] + +main :: IO () +main = + do -- mem <- getMemory + -- print $ [(n, showHex (mem ! n) "") | n <- [0..5] ] + -- machineInput <- readFile "adventure_input.txt" + -- let mInp = wordify machineInput + -- let machine = makeMachine mem + -- let (exState, _machine, output) = runMachine mInp machine + -- print exState + -- putStrLn $ showOutput output + + state0 <- emptyState + let state1 = runWithoutInput state0 + let newOutput = head $ state1 ^. ssOutputs + putStrLn newOutput + -- let state1 = runOneInput state "take tablet" + -- print state0 + -- print state + -- print state1 + + stateF <- adventureHarness state1 + return () + -- print $ stateF ^. ssInputs + -- print $ stateF ^. ssOutputs + -- print $ stateF ^. ssState + -- let machs = stateF ^. ssMachines + -- let machPairs = zipWith (==) machs $ tail machs + -- print $ machPairs + +emptyState :: IO SynacorState +emptyState = + do mem <- getMemory + let machine = makeMachine mem + return $ SynacorState [machine] [] [] True False [Runnable] + +adventureHarness :: SynacorState -> IO SynacorState +adventureHarness state = + do command <- prompt "> " + state' <- handleCommand command state + let newOutput = head $ state' ^. ssOutputs + putStrLn newOutput + if (state' ^. ssContinue) + then (adventureHarness state') + else return state' + + +handleCommand :: String -> SynacorState -> IO SynacorState +handleCommand ":quit" state = return $ state & ssContinue .~ False +handleCommand ":save" state = + do filename <- prompt "Save as? " + let inputs = unlines $ tail $ reverse $ state ^. ssInputs + writeFile filename inputs + return $ state & ssUnsaved .~ True +handleCommand ":load" state = + do filename <- prompt "From? " + machineInput <- readFile filename + let inputs = lines machineInput + initialState <- emptyState + let nonComments = filter (\i -> head i == '#') inputs + let state = foldl' runOneInput initialState ("" : nonComments) + return $ state & ssUnsaved .~ False +handleCommand ":undo" state = + return $ state & ssMachines %~ tail + & ssInputs %~ tail + & ssOutputs %~ tail + & ssContinue .~ True + & ssUnsaved .~ True + & ssState %~ tail +handleCommand ":recap" state = + do let inputs = take 3 $ state ^. ssInputs + let outputs = "" : (tail $ take 3 $ state ^. ssOutputs) + let inOuts = reverse $ zip inputs outputs + forM_ inOuts (\(i, o) -> + do putStrLn ("#> " ++ i) + putStrLn o + ) + return state +handleCommand command state = return $ runOneInput state command + + +runWithoutInput :: SynacorState -> SynacorState +runWithoutInput state = state & ssMachines %~ (machine' :) + -- & ssInputs %~ (input :) + & ssOutputs %~ ((showOutput output) :) + & ssContinue .~ True + & ssUnsaved .~ True + & ssState %~ (exState :) + where machine = head $ state ^. ssMachines + (exState, machine', output) = runMachine [] (machine & inputIndex .~ 0) + +runOneInput :: SynacorState -> String -> SynacorState +runOneInput state input = state & ssMachines %~ (machine' :) + & ssInputs %~ (input :) + & ssOutputs %~ ((showOutput output) :) + & ssContinue .~ True + & ssUnsaved .~ True + & ssState %~ (exState :) + where machine = head $ state ^. ssMachines + inputW = wordify (input ++ "\n") + (exState, machine', output) = runMachine inputW (machine & inputIndex .~ 0) + -- output' = trace ("runone " ++ (show (machine == machine')) ++ " " ++ (show exState) ++ " " ++ (showOutput output)) output + + +prompt :: String -> IO String +prompt text = do + putStr text + hFlush stdout + getLine + +wordify :: String -> [Word16] +wordify cs = fmap (fromIntegral . ord) cs + +showOutput :: [Word16] -> String +showOutput output = fmap (chr . fromInteger . fromIntegral) output + +getMemory :: IO Memory +getMemory = do + input <- BL.readFile "challenge.bin" + let cells = runGet getCells input + return $ M.fromList $ zip [0..] cells + +getCells :: Get [Word16] +getCells = do + empty <- isEmpty + if empty + then return [] + else do cell <- getWord16le + cells <- getCells + return (cell:cells) + + diff --git a/src/SynacorEngine.hs b/src/SynacorEngine.hs new file mode 100644 index 0000000..e036f5c --- /dev/null +++ b/src/SynacorEngine.hs @@ -0,0 +1,295 @@ +module SynacorEngine where + +import Debug.Trace + +-- import System.Environment +import Data.Bits +import Data.Word +-- import Data.Binary.Get +-- import qualified Data.ByteString.Lazy as BL +import qualified Data.Map.Strict as M +import Data.Map.Strict ((!)) +import Control.Lens +import Data.List +import Numeric + +import Control.Monad.State.Strict +import Control.Monad.Reader +import Control.Monad.Writer +import Control.Monad.RWS.Strict + +type Memory = M.Map Word16 Word16 + + + +data Machine = Machine { _memory :: Memory + , _ip :: Word16 + , _registers :: Memory + , _inputIndex :: Int + , _stack :: [Word16] + } + deriving (Show, Eq, Ord) +makeLenses ''Machine + +type ProgrammedMachine = RWS [Word16] [Word16] Machine + +data ExecutionState = Runnable | Blocked | Terminated deriving (Ord, Eq, Show) + +-- returns (returnValue, finalMachine, outputs) + +runMachine :: [Word16] -> Machine -> (ExecutionState, Machine, [Word16]) +runMachine inputs machine = runRWS runAll inputs machine + + +makeMachine :: Memory -> Machine +makeMachine memory = Machine + { _ip = 0 + , _inputIndex = 0 + , _registers = M.fromList [ (r, 0) | r <- [0..7] ] + , _memory = memory + , _stack = [] + } + +-- traceMachine x = +-- do cip <- gets _ip +-- opcode <- getLocation cip +-- arg1 <- getValue (cip + 1) +-- arg2 <- getValue (cip + 2) +-- arg3 <- getValue (cip + 3) +-- mem <- gets _memory +-- regs <- gets _registers +-- let raw1 = mem ! (cip + 1) +-- let raw2 = mem ! (cip + 2) +-- let raw3 = mem ! (cip + 3) +-- let x' = trace ( +-- intercalate ": " +-- [ "IP Addr" +-- , show (showHex (cip * 2) "") +-- , "IP" +-- , (show (showHex cip "")) +-- , "Op" +-- , show (opcode) +-- , "Args" +-- , show (showHex arg1 "") +-- , show (showHex arg2 "") +-- , show (showHex arg3 "") +-- , "Raw" +-- , show (showHex raw1 "") +-- , show (showHex raw2 "") +-- , show (showHex raw3 "") +-- , show (M.elems regs) +-- ] +-- ) x +-- return x' + +runAll :: ProgrammedMachine ExecutionState +runAll = do cip <- gets _ip + opcode <- getLocation cip + -- opcode' <- traceMachine opcode + -- exState <- runStep opcode' + exState <- runStep opcode + case exState of + Terminated -> return Terminated + Blocked -> return Blocked + _ -> runAll + + +runStep :: Word16 -> ProgrammedMachine ExecutionState +-- runStep n | trace (show n) False = undefined +runStep 0 = return Terminated +runStep 1 = + do cip <- gets _ip + regR <- getLocation (cip + 1) + let reg = regR .&. 7 + value <- getValue (cip + 2) + advanceIP 3 + modify (\m -> m & registers . ix reg .~ value) + return Runnable +runStep 2 = + do cip <- gets _ip + value <- getValue (cip + 1) + advanceIP 2 + modify (\m -> m & stack %~ (value :) ) + return Runnable +runStep 3 = + do cip <- gets _ip + tgt <- getLocation (cip + 1) + val <- gets (\m -> head $ m ^. stack) + modify (\m -> m & stack %~ tail ) + putValue tgt val + advanceIP 2 + return Runnable +runStep 4 = + do cip <- gets _ip + tgt <- getLocation (cip + 1) + b <- getValue (cip + 2) + c <- getValue (cip + 3) + putValue tgt (if b == c then 1 else 0) + modify (\m -> m & ip %~ (+ 4)) + return Runnable +runStep 5 = + do cip <- gets _ip + tgt <- getLocation (cip + 1) + b <- getValue (cip + 2) + c <- getValue (cip + 3) + putValue tgt (if b > c then 1 else 0) + advanceIP 4 + return Runnable +runStep 6 = + do cip <- gets _ip + tgt <- getLocation (cip + 1) + modify (\m -> m & ip .~ tgt) + return Runnable +runStep 7 = + do cip <- gets _ip + a <- getValue (cip + 1) + tgt <- getLocation (cip + 2) + if a /= 0 + then modify (\m -> m & ip .~ tgt) + else advanceIP 3 + return Runnable +runStep 8 = + do cip <- gets _ip + a <- getValue (cip + 1) + tgt <- getLocation (cip + 2) + if a == 0 + then modify (\m -> m & ip .~ tgt) + else advanceIP 3 + return Runnable + +runStep 9 = + do cip <- gets _ip + a <- getLocation (cip + 1) + b <- getValue (cip + 2) + c <- getValue (cip + 3) + putValue a (b + c) + advanceIP 4 + return Runnable +runStep 10 = + do cip <- gets _ip + a <- getLocation (cip + 1) + b <- getValue (cip + 2) + c <- getValue (cip + 3) + putValue a (b * c) + advanceIP 4 + return Runnable +runStep 11 = + do cip <- gets _ip + a <- getLocation (cip + 1) + b <- getValue (cip + 2) + c <- getValue (cip + 3) + putValue a (b `mod` c) + advanceIP 4 + return Runnable +runStep 12 = + do cip <- gets _ip + a <- getLocation (cip + 1) + b <- getValue (cip + 2) + c <- getValue (cip + 3) + putValue a (b .&. c) + advanceIP 4 + return Runnable +runStep 13 = + do cip <- gets _ip + a <- getLocation (cip + 1) + b <- getValue (cip + 2) + c <- getValue (cip + 3) + putValue a (b .|. c) + advanceIP 4 + return Runnable +runStep 14 = + do cip <- gets _ip + a <- getLocation (cip + 1) + b <- getValue (cip + 2) + putValue a (complement b) + advanceIP 3 + return Runnable + +runStep 15 = + do cip <- gets _ip + a <- getLocation (cip + 1) + b <- getValue (cip + 2) + v <- getValue b + putValue a v + advanceIP 3 + return Runnable +runStep 16 = + do cip <- gets _ip + a <- getValue (cip + 1) + b <- getValue (cip + 2) + putValue a b + advanceIP 3 + return Runnable + +runStep 17 = + do cip <- gets _ip + a <- getValue (cip + 1) + modify (\m -> m & stack %~ ((cip + 2) :) + & ip .~ a) + return Runnable + +runStep 18 = + do val <- gets (\m -> head $ m ^. stack) + modify (\m -> m & stack %~ tail + & ip .~ val) + return Runnable + +runStep 19 = + do cip <- gets _ip + v <- getValue (cip + 1) + tell [v] + advanceIP 2 + return Runnable + +runStep 20 = + do iIndex <- gets _inputIndex + inputs <- ask + cip <- gets _ip + tgt <- getLocation (cip + 1) + if (iIndex + 1) > (length inputs) + then return Blocked + else do let char = (inputs!!iIndex) + putValue tgt char + modify (\m -> m & inputIndex %~ (+ 1)) + advanceIP 2 + return Runnable + +runStep 21 = + do advanceIP 1 + return Runnable +runStep _ = + do advanceIP 1 + return Runnable + + +getValue :: Word16 -> ProgrammedMachine Word16 +getValue loc = + do mem <- gets _memory + regs <- gets _registers + let val = mem ! loc + if val < (2 ^ 15) + then return val + else return (regs ! (val .&. 7)) + + + + -- | loc < 32768 = + -- do mem <- gets _memory + -- return $ mem ! loc + -- | otherwise = + -- do regs <- gets _registers + -- return $ regs ! (loc `shiftR` 15) + +getLocation :: Word16 -> ProgrammedMachine Word16 +getLocation loc = + do mem <- gets _memory + return $ mem ! loc + +putValue :: Word16 -> Word16 -> ProgrammedMachine () +putValue loc value + | loc < (2 ^ 15) = modify (\m -> m & memory . ix loc .~ v) + | otherwise = modify (\m -> m & registers . ix (loc .&. 7) .~ v) + where v = value `mod` (2 ^ 15) + +advanceIP :: Word16 -> ProgrammedMachine () +advanceIP delta = modify (\m -> m & ip %~ (+ delta)) diff --git a/src/synacor_codes.txt b/src/synacor_codes.txt new file mode 100644 index 0000000..f32d370 --- /dev/null +++ b/src/synacor_codes.txt @@ -0,0 +1,17 @@ +Please record your progress by putting codes like +this one into the challenge website: hORWzmTEPkRE + +The self-test completion code is: YSDJvoycpDhu + +You find yourself writing "PRfkKApjpukS" on the tablet. Perhaps it's some kind of code? + +Chiseled on the wall of one of the passageways, you see: + + MSVFHKWMXrVA + +You take note of this and keep walking. + + +You activate the teleporter! As you spiral through time and space, you think you see a pattern in the stars... + + QiAHRHuQGxPx diff --git a/synacor-challenge.tgz b/synacor-challenge.tgz new file mode 100644 index 0000000000000000000000000000000000000000..840a2e0e14e56b4981e70d0e314e922fabdfa55a GIT binary patch literal 52985 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.16 + default-language: Haskell2010 + hs-source-dirs: ., app, src + other-modules: SynacorEngine + ghc-options: -O2 + -Wall + -threaded + -rtsopts "-with-rtsopts=-N" + +executable synacor + import: common-extensions, build-directives + main-is: Main.hs + build-depends: split + main-is: Main.hs + + -- Modules included in this executable, other than Main. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + build-depends: containers, binary, bytestring, mtl, lens + hs-source-dirs: app, src + default-language: Haskell2010 + +executable coinsolver + import: common-extensions + main-is: Main.hs + build-depends: split + main-is: CoinSolver.hs + build-depends: base >=4.16, containers + hs-source-dirs: app, src + default-language: Haskell2010 + hs-source-dirs: ., app, src + ghc-options: -O2 + -Wall + -threaded + -rtsopts "-with-rtsopts=-N" + + +library + import: common-extensions + build-depends: base >=4.16, containers, binary, bytestring, mtl, lens + hs-source-dirs: ., app, src + exposed-modules: SynacorEngine diff --git a/synacor.sublime-project b/synacor.sublime-project new file mode 100644 index 0000000..24db303 --- /dev/null +++ b/synacor.sublime-project @@ -0,0 +1,8 @@ +{ + "folders": + [ + { + "path": "." + } + ] +} diff --git a/test1.txt b/test1.txt new file mode 100644 index 0000000..558f944 --- /dev/null +++ b/test1.txt @@ -0,0 +1,2 @@ +take tablet +doorway diff --git a/test2.txt b/test2.txt new file mode 100644 index 0000000..b14ced5 --- /dev/null +++ b/test2.txt @@ -0,0 +1,11 @@ + +take tablet +inv +go south +go north +go doorway +north +north +bridge +continue +down diff --git a/twisty_passages.txt b/twisty_passages.txt new file mode 100644 index 0000000..8110a03 --- /dev/null +++ b/twisty_passages.txt @@ -0,0 +1,15 @@ + +take tablet +inv +go doorway +north +north +bridge +continue +down +east +take empty lantern +west +west +passage +ladder diff --git a/twisty_passages_can.txt b/twisty_passages_can.txt new file mode 100644 index 0000000..eaa9080 --- /dev/null +++ b/twisty_passages_can.txt @@ -0,0 +1,20 @@ + +take tablet +inv +go doorway +north +north +bridge +continue +down +east +take empty lantern +west +west +passage +ladder +west +south +north +take can +west diff --git a/twisty_passages_code.txt b/twisty_passages_code.txt new file mode 100644 index 0000000..540cf57 --- /dev/null +++ b/twisty_passages_code.txt @@ -0,0 +1,25 @@ +take tablet +use tablet +go doorway +north +north +bridge +continue +down +east +take empty lantern +west +west +passage +ladder +west +south +north +take can +west +use can +use lantern +west +south +north +west diff --git a/twisty_passages_lit_lantern.txt b/twisty_passages_lit_lantern.txt new file mode 100644 index 0000000..d8ab10f --- /dev/null +++ b/twisty_passages_lit_lantern.txt @@ -0,0 +1,22 @@ + +take tablet +inv +go doorway +north +north +bridge +continue +down +east +take empty lantern +west +west +passage +ladder +west +south +north +take can +west +use can +use lantern -- 2.34.1 From a0df5c6aec6ff0271ab47205f915e4647fbad4ec Mon Sep 17 00:00:00 2001 From: Neil Smith Date: Sun, 30 Jul 2023 15:42:39 +0100 Subject: [PATCH 2/4] Done tracing --- src/Main.hs | 49 ++++++++++++++++++++++++++++++++++++++---- src/SynacorEngine.hs | 51 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 95 insertions(+), 5 deletions(-) diff --git a/src/Main.hs b/src/Main.hs index 0c9ceea..be6e522 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -28,6 +28,8 @@ data SynacorState = SynacorState , _ssContinue :: Bool , _ssUnsaved :: Bool , _ssState :: [ExecutionState] + , _ssTracing :: Bool + , _ssDumpFile :: String } deriving (Ord, Eq) makeLenses ''SynacorState @@ -42,6 +44,8 @@ instance Show SynacorState , "conts " ++ (show $ state ^. ssContinue) , "unsaved " ++ (show $ state ^. ssUnsaved) , "states " ++ (show $ state ^. ssState) + , "tracing " ++ (show $ state ^. ssTracing) + , "dumping to " ++ (state ^. ssDumpFile) ] main :: IO () @@ -77,19 +81,43 @@ emptyState :: IO SynacorState emptyState = do mem <- getMemory let machine = makeMachine mem - return $ SynacorState [machine] [] [] True False [Runnable] + return $ SynacorState + { _ssMachines = [machine] + , _ssInputs = [] + , _ssOutputs = [] + , _ssContinue = True + , _ssUnsaved = False + , _ssState = [Runnable] + , _ssTracing = False + , _ssDumpFile = "" + } + -- [machine] [] [] True False [Runnable] adventureHarness :: SynacorState -> IO SynacorState adventureHarness state = do command <- prompt "> " state' <- handleCommand command state - let newOutput = head $ state' ^. ssOutputs + let traceAndOutput = head $ state' ^. ssOutputs + let (newOutput, tracing) = spliceOut traceAndOutput putStrLn newOutput + when (state' ^. ssTracing) + (appendFile (state' ^. ssDumpFile) $ unlines tracing) if (state' ^. ssContinue) then (adventureHarness state') else return state' +spliceOut :: String -> (String, [String]) +spliceOut s = doingOut s "" [] + where doingOut s out traces + | null s = (reverse out, reverse traces) + | ">> " `isPrefixOf` s = doingTrace (drop 3 s) out traces "" + | otherwise = doingOut (tail s) (head s : out) traces + doingTrace s out traces tr + | "<<" `isPrefixOf` s = doingOut (drop 2 s) out (reverse tr : traces) + | otherwise = doingTrace (tail s) out traces (head s : tr) + + handleCommand :: String -> SynacorState -> IO SynacorState handleCommand ":quit" state = return $ state & ssContinue .~ False handleCommand ":save" state = @@ -102,7 +130,7 @@ handleCommand ":load" state = machineInput <- readFile filename let inputs = lines machineInput initialState <- emptyState - let nonComments = filter (\i -> head i == '#') inputs + let nonComments = filter (\i -> head i /= '#') inputs let state = foldl' runOneInput initialState ("" : nonComments) return $ state & ssUnsaved .~ False handleCommand ":undo" state = @@ -121,6 +149,16 @@ handleCommand ":recap" state = putStrLn o ) return state +handleCommand ":trace" state = + do filename <- prompt "Dump to? " + return $ state & ssTracing .~ True & ssDumpFile .~ filename +handleCommand ":untrace" state = + return $ state & ssTracing .~ False & ssDumpFile .~ "" +handleCommand ":poke8" state = + do let machines = state ^. ssMachines + let machine = head machines + let machine' = machine & registers . ix 7 .~ 1 + return $ state & ssMachines .~ (machine' : (tail machines)) handleCommand command state = return $ runOneInput state command @@ -141,7 +179,10 @@ runOneInput state input = state & ssMachines %~ (machine' :) & ssContinue .~ True & ssUnsaved .~ True & ssState %~ (exState :) - where machine = head $ state ^. ssMachines + where machine0 = head $ state ^. ssMachines + machine = if (state ^. ssTracing) + then machine0 & tracing .~ True + else machine0 & tracing .~ False inputW = wordify (input ++ "\n") (exState, machine', output) = runMachine inputW (machine & inputIndex .~ 0) -- output' = trace ("runone " ++ (show (machine == machine')) ++ " " ++ (show exState) ++ " " ++ (showOutput output)) output diff --git a/src/SynacorEngine.hs b/src/SynacorEngine.hs index e036f5c..cbd5e04 100644 --- a/src/SynacorEngine.hs +++ b/src/SynacorEngine.hs @@ -11,6 +11,7 @@ import qualified Data.Map.Strict as M import Data.Map.Strict ((!)) import Control.Lens import Data.List +import Data.Char import Numeric import Control.Monad.State.Strict @@ -27,6 +28,7 @@ data Machine = Machine { _memory :: Memory , _registers :: Memory , _inputIndex :: Int , _stack :: [Word16] + , _tracing :: Bool } deriving (Show, Eq, Ord) makeLenses ''Machine @@ -48,6 +50,7 @@ makeMachine memory = Machine , _registers = M.fromList [ (r, 0) | r <- [0..7] ] , _memory = memory , _stack = [] + , _tracing = False } -- traceMachine x = @@ -85,6 +88,7 @@ makeMachine memory = Machine runAll :: ProgrammedMachine ExecutionState runAll = do cip <- gets _ip opcode <- getLocation cip + traceMachine -- opcode' <- traceMachine opcode -- exState <- runStep opcode' exState <- runStep opcode @@ -251,7 +255,7 @@ runStep 20 = else do let char = (inputs!!iIndex) putValue tgt char modify (\m -> m & inputIndex %~ (+ 1)) - advanceIP 2 + advanceIP 2 return Runnable runStep 21 = @@ -262,6 +266,51 @@ runStep _ = return Runnable +traceMachine :: ProgrammedMachine () +traceMachine = do + isTracing <- gets _tracing + when isTracing + do cip <- gets _ip + opcode <- getLocation cip + a <- getLocation (cip + 1) + b <- getLocation (cip + 2) + c <- getLocation (cip + 3) + let sa = show a + let sb = show b + let sc = show c + va <- getValue (cip + 1) + vb <- getValue (cip + 2) + vc <- getValue (cip + 3) + let sva = show va + let svb = show vb + let svc = show vc + let traceText = + case opcode of + 0 -> ["halt"] + 1 -> ["set", sa, sb, "*", sva, svb] + 2 -> ["push", sa, "*", sva] + 3 -> ["pop", sa, "*", sva] + 4 -> ["eq", sa, sb, sc, "*", sva, svb, svc] + 5 -> ["gt", sa, sb, sc, "*", sva, svb, svc] + 6 -> ["jmp", sa, "*", sva] + 7 -> ["jt", sa, sb, "*", sva, svb] + 8 -> ["jf", sa, sb, "*", sva, svb] + 9 -> ["add", sa, sb, sc, "*", sva, svb, svc] + 10 -> ["mul", sa, sb, sc, "*", sva, svb, svc] + 11 -> ["mod", sa, sb, sc, "*", sva, svb, svc] + 12 -> ["and", sa, sb, sc, "*", sva, svb, svc] + 13 -> ["or", sa, sb, sc, "*", sva, svb, svc] + 14 -> ["not", sa, sb, "*", sva, svb] + 15 -> ["rmem", sa, sb, "*", sva, svb] + 16 -> ["wmem", sa, sb, "*", sva, svb] + 17 -> ["call", sa, "*", sva] + 18 -> ["ret"] + 19 -> ["out", sa, "*", sva] + 20 -> ["in", sa, "*", sva] + 21 -> ["noop", sa, sb, sc, "*", sva, svb, svc] + _ -> ["illegal", sa, sb, sc, "*", sva, svb, svc] + tell $ fmap (fromIntegral . ord) (">> " ++ (show cip) ++ ": " ++ (intercalate " " traceText) ++ "<<") + getValue :: Word16 -> ProgrammedMachine Word16 getValue loc = do mem <- gets _memory -- 2.34.1 From 56796d54a5048d5f38ac06b1fdea48c045bb626e Mon Sep 17 00:00:00 2001 From: Neil Smith Date: Tue, 1 Aug 2023 17:30:42 +0100 Subject: [PATCH 3/4] Done teleporter code --- codes_found.md | 18 ++++++ coins_used.txt | 2 - found_teleporter.txt | 12 ++-- full_solution.txt | 88 ++++++++++++++++++++++++++++++ got_orb.txt | 78 ++++++++++++++++++++++++++ src/Ackermann.hs | 64 ++++++++++++++++++++++ CoinSolver.hs => src/CoinSolver.hs | 0 src/Main.hs | 14 ++++- src/SynacorEngine.hs | 69 +++++++++++++++++------ synacor.cabal | 16 +++++- test1.txt | 2 - test2.txt | 11 ---- 12 files changed, 332 insertions(+), 42 deletions(-) create mode 100644 codes_found.md create mode 100644 full_solution.txt create mode 100644 got_orb.txt create mode 100644 src/Ackermann.hs rename CoinSolver.hs => src/CoinSolver.hs (100%) delete mode 100644 test1.txt delete mode 100644 test2.txt diff --git a/codes_found.md b/codes_found.md new file mode 100644 index 0000000..0cb6907 --- /dev/null +++ b/codes_found.md @@ -0,0 +1,18 @@ +## First code +From arch.spec hint section +> pwiuBbPSgwrt + +## Second code +After self-test +> hORWzmTEPkRE + +## Third code +After using the tablet +> PRfkKApjpukS + +## Fourth code +Lighting the lantern in the cavern +> MSVFHKWMXrVA + +## Using the teleporter +> PLqwUDZxwKuh diff --git a/coins_used.txt b/coins_used.txt index ad7f95d..c109ba4 100644 --- a/coins_used.txt +++ b/coins_used.txt @@ -1,6 +1,4 @@ take tablet -doorway - use tablet doorway look diff --git a/found_teleporter.txt b/found_teleporter.txt index 95d38c9..734b6c2 100644 --- a/found_teleporter.txt +++ b/found_teleporter.txt @@ -1,5 +1,5 @@ take tablet -# get first code +# get third code use tablet doorway north @@ -23,7 +23,7 @@ west west south north -# get second code +# get fourth code west ladder darkness @@ -61,12 +61,12 @@ use red coin use shiny coin use concave coin use corroded coin -# now got coin puzzle code +# now got fifth code code north take teleporter use teleporter take business card take strange book -look bookshelf -look business card -look strange book +# issue :poke8 command here +# this gets the sixth code +use teleporter diff --git a/full_solution.txt b/full_solution.txt new file mode 100644 index 0000000..ea1511d --- /dev/null +++ b/full_solution.txt @@ -0,0 +1,88 @@ +take tablet +# get third code +use tablet +doorway +north +north +bridge +continue +down +east +take empty lantern +west +west +passage +ladder +west +south +north +take can +use can +use lantern +west +west +south +north +# get fourth code +west +ladder +darkness +continue +west +west +west +west +north +take red coin +north +north +west +take blue coin +up +take shiny coin +down +east +east +take concave coin +inv +down +take corroded coin +up +west +look monument +look +look red coin +look blue coin +look shiny coin +look corroded coin +look concave coin +use blue coin +use red coin +use shiny coin +use concave coin +use corroded coin +# now got fifth code code +north +take teleporter +use teleporter +take business card +take strange book +look business card +look strange book +# issue :poke8 command here +:poke8 +# this gets the sixth code +use teleporter +north +north +north +north +north +north +north +east +take journal +west +north +north +take orb diff --git a/got_orb.txt b/got_orb.txt new file mode 100644 index 0000000..8420e94 --- /dev/null +++ b/got_orb.txt @@ -0,0 +1,78 @@ +use tablet +doorway +north +bridge +north +bridge +continue +down +east +take empty lantern +west +west +passage +ladder +west +south +north +take can +use can +use lantern +west +west +south +north +west +ladder +darkness +continue +west +west +west +west +north +take red coin +north +north +west +take blue coin +up +take shiny coin +down +east +east +take concave coin +down +take corroded coin +up +west +use blue coin +use red coin +use shiny coin +use concave coin +use corroded coin +north +take teleporter +use teleporter +take business card +take strange book +look strange book +use teleporter +north +north +north +north +north +north +north +north +north +take orb +look orb +north +north +north +east +east +east +vault diff --git a/src/Ackermann.hs b/src/Ackermann.hs new file mode 100644 index 0000000..4dc3b20 --- /dev/null +++ b/src/Ackermann.hs @@ -0,0 +1,64 @@ + +-- import Debug.Trace + +import Data.List +import qualified Data.Map.Strict as M +import Data.Map.Strict ((!)) +-- import Data.Maybe + +import Control.Monad.State.Strict +-- import Control.Monad.Reader +-- import Control.Monad.Writer +-- import Control.Monad.RWS.Strict + +import Control.Parallel.Strategies + + +type Memo = M.Map (Int, Int) Int + +type MemoF = State Memo + +main :: IO () +main = + do let resultPairs = fmap evalAck [0 .. (2 ^ 15 - 1)] `using` parList rdeepseq + let result = filter ((== 6) . snd) resultPairs + print result + +r7Gives6 :: Int -> Bool +r7Gives6 r7 = result == 6 + where result = evalState (ackermann 4 1 r7) M.empty + +evalAck :: Int -> (Int, Int) +evalAck r7 = (r7, evalState (ackermann 4 1 r7) M.empty) + + +ackermann :: Int -> Int -> Int -> MemoF Int +ackermann r0 r1 r7 = do + memoResult <- memoLookup r0 r1 + case memoResult of + Just r -> return r + Nothing -> + do if r0 == 0 + then do let res = ((r1 + 1) `mod` (2 ^ 15)) + memoStore r0 r1 res + return res + else if r1 == 0 + then do res <- ackermann (r0 - 1) r7 r7 + memoStore r0 r1 res + return res + else do subResult <- ackermann r0 (r1 - 1) r7 + res <- ackermann (r0 - 1) subResult r7 + memoStore r0 r1 res + return res + +memoLookup :: Int -> Int -> MemoF (Maybe Int) +memoLookup r0 r1 = + do table <- get + return $ M.lookup (r0, r1) table + +memoStore :: Int -> Int -> Int -> MemoF () +memoStore r0 r1 result = + do table <- get + let table' = M.insert (r0, r1) result table + put table' + diff --git a/CoinSolver.hs b/src/CoinSolver.hs similarity index 100% rename from CoinSolver.hs rename to src/CoinSolver.hs diff --git a/src/Main.hs b/src/Main.hs index be6e522..d7ad6f3 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -157,7 +157,11 @@ handleCommand ":untrace" state = handleCommand ":poke8" state = do let machines = state ^. ssMachines let machine = head machines - let machine' = machine & registers . ix 7 .~ 1 + let machine' = machine & registers . ix 7 .~ 25734 + & memory . ix 5489 .~ 21 + & memory . ix 5490 .~ 21 + & memory . ix 5495 .~ 7 + -- let machine' = machine & memory . ix 5451 .~ 7 return $ state & ssMachines .~ (machine' : (tail machines)) handleCommand command state = return $ runOneInput state command @@ -173,6 +177,14 @@ runWithoutInput state = state & ssMachines %~ (machine' :) (exState, machine', output) = runMachine [] (machine & inputIndex .~ 0) runOneInput :: SynacorState -> String -> SynacorState +runOneInput state ":poke8" = state & ssMachines .~ ssMAchinesNew + where machine0 = head $ state ^. ssMachines + machine = machine0 & registers . ix 7 .~ 25734 + & memory . ix 5489 .~ 21 + & memory . ix 5490 .~ 21 + & memory . ix 5495 .~ 7 + ssMAchinesNew = machine : (tail $ state ^. ssMachines) + runOneInput state input = state & ssMachines %~ (machine' :) & ssInputs %~ (input :) & ssOutputs %~ ((showOutput output) :) diff --git a/src/SynacorEngine.hs b/src/SynacorEngine.hs index cbd5e04..757bd5f 100644 --- a/src/SynacorEngine.hs +++ b/src/SynacorEngine.hs @@ -40,7 +40,7 @@ data ExecutionState = Runnable | Blocked | Terminated deriving (Ord, Eq, Show) -- returns (returnValue, finalMachine, outputs) runMachine :: [Word16] -> Machine -> (ExecutionState, Machine, [Word16]) -runMachine inputs machine = runRWS runAll inputs machine +runMachine inputs machine = runRWS (runAll (10 ^ 6)) inputs machine makeMachine :: Memory -> Machine @@ -85,17 +85,20 @@ makeMachine memory = Machine -- ) x -- return x' -runAll :: ProgrammedMachine ExecutionState -runAll = do cip <- gets _ip - opcode <- getLocation cip - traceMachine - -- opcode' <- traceMachine opcode - -- exState <- runStep opcode' - exState <- runStep opcode - case exState of - Terminated -> return Terminated - Blocked -> return Blocked - _ -> runAll +runAll :: Int -> ProgrammedMachine ExecutionState +runAll executionLimit + | executionLimit == 0 = return Terminated + | otherwise = + do cip <- gets _ip + opcode <- getLocation cip + traceMachine + -- opcode' <- traceMachine opcode + -- exState <- runStep opcode' + exState <- runStep opcode + case exState of + Terminated -> return Terminated + Blocked -> return Blocked + _ -> runAll (executionLimit - 1) runStep :: Word16 -> ProgrammedMachine ExecutionState @@ -270,11 +273,33 @@ traceMachine :: ProgrammedMachine () traceMachine = do isTracing <- gets _tracing when isTracing - do cip <- gets _ip + do cip <- gets _ip + (l, _) <- dissembleInstruction cip + registers <- gets _registers + let regVals = intercalate "; " $ fmap show $ M.elems registers + stack <- gets _stack + let stackVals = intercalate "; " $ fmap show $ take 10 stack + tell $ fmap (fromIntegral . ord) (">> " ++ l ++ " : r> " ++ regVals ++ " : s> " ++ stackVals ++ "<<") + +runDissemble :: Word16 -> Int -> Machine -> [String] +runDissemble startAt num machine =fst $ evalRWS (dissemble startAt num) [] machine + + +dissemble :: Word16 -> Int -> ProgrammedMachine [String] +dissemble startAt num = go startAt num [] + where go _ 0 ls = return $ reverse ls + go here n ls = + do (line, step) <- dissembleInstruction here + go (here + step) (n - 1) (line : ls) + +dissembleInstruction :: Word16 -> ProgrammedMachine (String, Word16) +dissembleInstruction cip = + do -- cip <- gets _ip opcode <- getLocation cip - a <- getLocation (cip + 1) - b <- getLocation (cip + 2) - c <- getLocation (cip + 3) + mem <- gets _memory + let a = mem ! (cip + 1) + let b = mem ! (cip + 2) + let c = mem ! (cip + 3) let sa = show a let sb = show b let sc = show c @@ -307,9 +332,17 @@ traceMachine = do 18 -> ["ret"] 19 -> ["out", sa, "*", sva] 20 -> ["in", sa, "*", sva] - 21 -> ["noop", sa, sb, sc, "*", sva, svb, svc] + 21 -> ["noop"] _ -> ["illegal", sa, sb, sc, "*", sva, svb, svc] - tell $ fmap (fromIntegral . ord) (">> " ++ (show cip) ++ ": " ++ (intercalate " " traceText) ++ "<<") + let stepSize = + if | opcode `elem` [0, 18, 21] -> 1 + | opcode `elem` [2, 3, 6, 17, 19, 20] -> 2 + | opcode `elem` [1, 7, 8, 14, 15, 16] -> 3 + | opcode `elem` [4, 5, 9, 10, 11, 12, 13] -> 4 + | otherwise -> 1 + return ( ((show cip) ++ ": " ++ (intercalate " " traceText)) + , stepSize + ) getValue :: Word16 -> ProgrammedMachine Word16 getValue loc = diff --git a/synacor.cabal b/synacor.cabal index 11f7b23..60ac8f5 100644 --- a/synacor.cabal +++ b/synacor.cabal @@ -95,10 +95,23 @@ executable synacor hs-source-dirs: app, src default-language: Haskell2010 +executable ackermann + import: common-extensions + main-is: Main.hs + main-is: Ackermann.hs + build-depends: base >=4.16, containers, mtl, parallel + hs-source-dirs: app, src + default-language: Haskell2010 + hs-source-dirs: ., app, src + ghc-options: -O2 + -Wall + -threaded + -rtsopts "-with-rtsopts=-N" + + executable coinsolver import: common-extensions main-is: Main.hs - build-depends: split main-is: CoinSolver.hs build-depends: base >=4.16, containers hs-source-dirs: app, src @@ -109,7 +122,6 @@ executable coinsolver -threaded -rtsopts "-with-rtsopts=-N" - library import: common-extensions build-depends: base >=4.16, containers, binary, bytestring, mtl, lens diff --git a/test1.txt b/test1.txt deleted file mode 100644 index 558f944..0000000 --- a/test1.txt +++ /dev/null @@ -1,2 +0,0 @@ -take tablet -doorway diff --git a/test2.txt b/test2.txt deleted file mode 100644 index b14ced5..0000000 --- a/test2.txt +++ /dev/null @@ -1,11 +0,0 @@ - -take tablet -inv -go south -go north -go doorway -north -north -bridge -continue -down -- 2.34.1 From 3836f842a8794a2d25cc5f8558d70becae8b7396 Mon Sep 17 00:00:00 2001 From: Neil Smith Date: Thu, 3 Aug 2023 14:25:59 +0100 Subject: [PATCH 4/4] Completed puzzle --- codes_found.md | 3 ++ full_solution.txt | 15 ++++++ src/Main.hs | 23 ++++---- src/OrbMaze.hs | 125 +++++++++++++++++++++++++++++++++++++++++++ src/SynacorEngine.hs | 16 +++--- synacor.cabal | 21 ++++++-- 6 files changed, 180 insertions(+), 23 deletions(-) create mode 100644 src/OrbMaze.hs diff --git a/codes_found.md b/codes_found.md index 0cb6907..e8e1ae5 100644 --- a/codes_found.md +++ b/codes_found.md @@ -16,3 +16,6 @@ Lighting the lantern in the cavern ## Using the teleporter > PLqwUDZxwKuh + +## After the orb maze +"qiwTT8UxHYxp" or mirrored to qxYHxU8TTwip diff --git a/full_solution.txt b/full_solution.txt index ea1511d..cbf3da8 100644 --- a/full_solution.txt +++ b/full_solution.txt @@ -86,3 +86,18 @@ west north north take orb +north +east +east +north +west +south +east +east +west +north +north +east +vault +take mirror +use mirror diff --git a/src/Main.hs b/src/Main.hs index d7ad6f3..101714e 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -1,19 +1,19 @@ import SynacorEngine -import Debug.Trace +-- import Debug.Trace -import Numeric +-- import Numeric import System.IO import Data.Char import Data.List import qualified Data.Map.Strict as M -import Data.Map.Strict ((!)) +-- import Data.Map.Strict ((!)) import Control.Lens -- hiding ((<|), (|>), (:>), (:<), indices) -import Control.Monad.State.Strict -import Control.Monad.Reader -import Control.Monad.Writer -import Control.Monad.RWS.Strict +import Control.Monad.State.Strict hiding (state) +-- import Control.Monad.Reader +-- import Control.Monad.Writer +-- import Control.Monad.RWS.Strict hiding (state) -- import Data.Bits import Data.Word @@ -69,6 +69,7 @@ main = -- print state1 stateF <- adventureHarness state1 + print stateF return () -- print $ stateF ^. ssInputs -- print $ stateF ^. ssOutputs @@ -98,17 +99,17 @@ adventureHarness state = do command <- prompt "> " state' <- handleCommand command state let traceAndOutput = head $ state' ^. ssOutputs - let (newOutput, tracing) = spliceOut traceAndOutput + let (newOutput, traces) = spliceOut traceAndOutput putStrLn newOutput when (state' ^. ssTracing) - (appendFile (state' ^. ssDumpFile) $ unlines tracing) + (appendFile (state' ^. ssDumpFile) $ unlines traces) if (state' ^. ssContinue) then (adventureHarness state') else return state' spliceOut :: String -> (String, [String]) -spliceOut s = doingOut s "" [] +spliceOut st = doingOut st "" [] where doingOut s out traces | null s = (reverse out, reverse traces) | ">> " `isPrefixOf` s = doingTrace (drop 3 s) out traces "" @@ -125,7 +126,7 @@ handleCommand ":save" state = let inputs = unlines $ tail $ reverse $ state ^. ssInputs writeFile filename inputs return $ state & ssUnsaved .~ True -handleCommand ":load" state = +handleCommand ":load" _state = do filename <- prompt "From? " machineInput <- readFile filename let inputs = lines machineInput diff --git a/src/OrbMaze.hs b/src/OrbMaze.hs new file mode 100644 index 0000000..b9888da --- /dev/null +++ b/src/OrbMaze.hs @@ -0,0 +1,125 @@ + +import qualified Debug.Trace as DT + +import Data.List +import Data.Maybe +import qualified Data.Map.Strict as M +import Data.Map.Strict ((!)) +import Linear +import Control.Lens + +-- type Position = V2 Int -- x, y, origin bottom left +newtype Position = Pos (V2 Int) -- x, y, origin bottom left + deriving (Show, Eq, Ord) + + +instance Semigroup Position where + (Pos p) <> (Pos q) = Pos $ p ^+^ q + +instance Monoid Position where + mempty = Pos (V2 0 0) + +data Operator = Times | Divide | Plus | Minus + deriving (Show, Eq, Ord) + +data Cell = Literal Int | Op Operator + deriving (Show, Eq, Ord) + +type Grid = M.Map Position Cell + +data SearchState = SearchState + { _path :: [Position] + , _value :: Int + , _operator :: Maybe Operator + } + deriving (Show, Eq, Ord) +makeLenses ''SearchState + +main :: IO () +main = + do -- print grid + let s = initialSearchState + -- print s + -- print $ neighbours s + let ps = bfs [s] + print ps + print $ presentPath $ (fromMaybe s ps) ^. path + +grid :: Grid +grid = M.fromList $ fmap (\(p, v) -> (Pos p, v)) + [ (V2 0 3, Op Times), (V2 1 3, Literal 8), (V2 2 3, Op Minus), (V2 3 3, Literal 1) + , (V2 0 2, Literal 4), (V2 1 2, Op Times), (V2 2 2, Literal 11), (V2 3 2, Op Times) + , (V2 0 1, Op Plus), (V2 1 1, Literal 4), (V2 2 1, Op Minus), (V2 3 1, Literal 18) + , (V2 0 0, Literal 22), (V2 1 0, Op Minus), (V2 2 0, Literal 9), (V2 3 0, Op Times) + ] + +initialSearchState :: SearchState +initialSearchState = SearchState {_path = [], _value = 22, _operator = Nothing} + +deltas :: [Position] +deltas = fmap Pos [V2 -1 0, V2 1 0, V2 0 -1, V2 0 1] + +-- adjacents :: Position -> Grid -> [Position] +-- adjacents here grid = filter (flip M.member grid) $ fmap (here <>) deltas + +neighbours :: SearchState -> [SearchState] +neighbours state = catMaybes $ fmap (step state) deltas + -- where here = mconcat $ state ^. path + +step :: SearchState -> Position -> Maybe SearchState +step state d = + do d' <- notStart state d + destination <- M.lookup ((currentPosition state) <> d') grid + state' <- addTerm state destination + return $ state' & path %~ (d' : ) + + +notStart :: SearchState -> Position -> Maybe Position +notStart state delta + | (mconcat (state ^. path)) <> delta == mempty = Nothing + | otherwise = Just delta + +bfs :: [SearchState] -> Maybe SearchState +-- bfs a | DT.trace (show a) False = undefined +bfs [] = Nothing +bfs (s:agenda) + | isGoal s = Just s + | currentPosition s == Pos (V2 3 3) = bfs agenda + | length (s ^. path) == 15 = bfs agenda + | s ^. value < 0 = bfs agenda + | s ^. value > (2 ^ 16) = bfs agenda + | otherwise = bfs (agenda ++ nexts) + where nexts = neighbours s + + +isGoal :: SearchState -> Bool +isGoal s = (currentPosition s == Pos (V2 3 3)) && (s ^. value == 30) + +currentPosition :: SearchState -> Position +currentPosition s = mconcat $ s ^. path + +currentValue :: SearchState -> Maybe Int +currentValue s + | (s ^. operator) == Nothing = Just $ s ^. value + | otherwise = Nothing + +addTerm :: SearchState -> Cell -> Maybe SearchState +-- addTerm s c | DT.trace (show (s, c)) False = undefined +addTerm s (Literal i) = + go (s ^. operator) i s + where + go Nothing _ _ = Nothing + go (Just Times) i s = Just $ s & value %~ (* i) & operator .~ Nothing + go (Just Divide) i s = Just $ s & value %~ (`div` i) & operator .~ Nothing + go (Just Plus) i s = Just $ s & value %~ (+ i) & operator .~ Nothing + go (Just Minus) i s = Just $ s & value %~ (+ (-i)) & operator .~ Nothing +addTerm s (Op op) + | (s ^. operator) == Nothing = Just $ s & operator .~ (Just op) + | otherwise = Nothing + +presentPath ps = fmap presentStep $ reverse ps + where + presentStep (Pos (V2 0 1)) = "north" + presentStep (Pos (V2 0 -1)) = "south" + presentStep (Pos (V2 1 0)) = "east" + presentStep (Pos (V2 -1 0)) = "west" diff --git a/src/SynacorEngine.hs b/src/SynacorEngine.hs index 757bd5f..63fb20c 100644 --- a/src/SynacorEngine.hs +++ b/src/SynacorEngine.hs @@ -1,6 +1,6 @@ module SynacorEngine where -import Debug.Trace +-- import Debug.Trace -- import System.Environment import Data.Bits @@ -12,7 +12,7 @@ import Data.Map.Strict ((!)) import Control.Lens import Data.List import Data.Char -import Numeric +-- import Numeric import Control.Monad.State.Strict import Control.Monad.Reader @@ -44,11 +44,11 @@ runMachine inputs machine = runRWS (runAll (10 ^ 6)) inputs machine makeMachine :: Memory -> Machine -makeMachine memory = Machine +makeMachine mem = Machine { _ip = 0 , _inputIndex = 0 , _registers = M.fromList [ (r, 0) | r <- [0..7] ] - , _memory = memory + , _memory = mem , _stack = [] , _tracing = False } @@ -275,10 +275,10 @@ traceMachine = do when isTracing do cip <- gets _ip (l, _) <- dissembleInstruction cip - registers <- gets _registers - let regVals = intercalate "; " $ fmap show $ M.elems registers - stack <- gets _stack - let stackVals = intercalate "; " $ fmap show $ take 10 stack + regs <- gets _registers + let regVals = intercalate "; " $ fmap show $ M.elems regs + stk <- gets _stack + let stackVals = intercalate "; " $ fmap show $ take 10 stk tell $ fmap (fromIntegral . ord) (">> " ++ l ++ " : r> " ++ regVals ++ " : s> " ++ stackVals ++ "<<") runDissemble :: Word16 -> Int -> Machine -> [String] diff --git a/synacor.cabal b/synacor.cabal index 60ac8f5..196d3f4 100644 --- a/synacor.cabal +++ b/synacor.cabal @@ -72,7 +72,7 @@ common common-extensions common build-directives build-depends: base >=4.16 - default-language: Haskell2010 + default-language: GHC2021 hs-source-dirs: ., app, src other-modules: SynacorEngine ghc-options: -O2 @@ -93,7 +93,7 @@ executable synacor -- other-extensions: build-depends: containers, binary, bytestring, mtl, lens hs-source-dirs: app, src - default-language: Haskell2010 + default-language: GHC2021 executable ackermann import: common-extensions @@ -101,7 +101,7 @@ executable ackermann main-is: Ackermann.hs build-depends: base >=4.16, containers, mtl, parallel hs-source-dirs: app, src - default-language: Haskell2010 + default-language: GHC2021 hs-source-dirs: ., app, src ghc-options: -O2 -Wall @@ -115,7 +115,20 @@ executable coinsolver main-is: CoinSolver.hs build-depends: base >=4.16, containers hs-source-dirs: app, src - default-language: Haskell2010 + default-language: GHC2021 + hs-source-dirs: ., app, src + ghc-options: -O2 + -Wall + -threaded + -rtsopts "-with-rtsopts=-N" + +executable orbmaze + import: common-extensions + main-is: Main.hs + main-is: OrbMaze.hs + build-depends: base >=4.16, containers, linear, lens + hs-source-dirs: app, src + default-language: GHC2021 hs-source-dirs: ., app, src ghc-options: -O2 -Wall -- 2.34.1