{-# Language QuasiQuotes #-}
{-|
Module      : Main
Description : Day 25 solution
Copyright   : (c) Eric Mertens, 2019
License     : ISC
Maintainer  : emertens@gmail.com

<https://adventofcode.com/2019/day/25>

@
    #-# #-#
      | |
      # #
      | |
    #-#-S-#-#-#
          |
        #-#-#
            |
          #-#-#-#
                |
                #
@
-}
module Main (main) where

import Advent.Format (format)
import Data.Char (ord, chr)
import Data.Foldable (traverse_)
import Intcode (intcodeToList)

main :: IO ()
IO ()
main =
  do [Int]
inp <- [format|2019 25 %d&,%n|]
     (String -> IO ()) -> [String] -> IO ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ String -> IO ()
putStrLn ([Int] -> [String] -> [String]
asciiComputer [Int]
inp [String]
search)

asciiComputer :: [Int] -> [String] -> [String]
asciiComputer :: [Int] -> [String] -> [String]
asciiComputer [Int]
inp [String]
cmds =
  String -> [String]
lines (String -> [String]) -> String -> [String]
forall a b. (a -> b) -> a -> b
$ (Int -> Char) -> [Int] -> String
forall a b. (a -> b) -> [a] -> [b]
map Int -> Char
chr ([Int] -> String) -> [Int] -> String
forall a b. (a -> b) -> a -> b
$ [Int] -> [Int] -> [Int]
intcodeToList [Int]
inp ([Int] -> [Int]) -> [Int] -> [Int]
forall a b. (a -> b) -> a -> b
$ (Char -> Int) -> String -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map Char -> Int
ord (String -> [Int]) -> String -> [Int]
forall a b. (a -> b) -> a -> b
$ [String] -> String
unlines [String]
cmds

search :: [String]
search :: [String]
search =
  [ String
north,                             String -> String
take_ String
"sand"
  , String
north,                             String -> String
take_ String
"space heater"
  , String
east ,                             String -> String
take_ String
"semiconductor"
  , String
west , String
south, String
south, String
east ,        String -> String
take_ String
"ornament"
  , String
east , String
east , String
west , String
west , String
south, String -> String
take_ String
"festive hat"
  , String
east ,                             String -> String
take_ String
"asterisk"
  , String
south, String
east ,                      String -> String
take_ String
"cake"
  , String
east {- electromagnet -}
  , String
south, String
north, String
west , String
west , String
west , String -> String
take_ String
"food ration"
  , String
east , String
north, String
west , String
west {- photons -}
  , String
east , String
north, String
west , String
west {- molten lava -}
  , String
west , String
east , String
north {- infinite loop -}
  , String
north] [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ String
-> (String -> String) -> (String -> String) -> [String] -> [String]
forall a. a -> (a -> a) -> (a -> a) -> [a] -> [a]
graycode String
west String -> String
drop_ String -> String
take_ [String]
items

graycode ::
  a        {- attempt             -} ->
  (a -> a) {- action              -} ->
  (a -> a) {- inverse action      -} ->
  [a]      {- items               -} ->
  [a]      {- search instructions -}
graycode :: forall a. a -> (a -> a) -> (a -> a) -> [a] -> [a]
graycode a
tick a -> a
_  a -> a
_  [] = [a
tick]
graycode a
tick a -> a
f1 a -> a
f2 (a
x:[a]
xs) =
  a -> (a -> a) -> (a -> a) -> [a] -> [a]
forall a. a -> (a -> a) -> (a -> a) -> [a] -> [a]
graycode a
tick a -> a
f1 a -> a
f2 [a]
xs [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++
  [a -> a
f1 a
x] [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++
  [a] -> [a]
forall a. [a] -> [a]
reverse (a -> (a -> a) -> (a -> a) -> [a] -> [a]
forall a. a -> (a -> a) -> (a -> a) -> [a] -> [a]
graycode a
tick a -> a
f2 a -> a
f1 [a]
xs)

items :: [String]
items :: [String]
items =
  [ String
"cake"
  , String
"sand"
  , String
"asterisk"
  , String
"ornament"
  , String
"festive hat"
  , String
"food ration"
  , String
"space heater"
  , String
"semiconductor"
  ]

{-
direct :: [String]
direct =
  [north, north, take_ "space heater",
   east, take_ "semiconductor",
   west, south, south, east, take_ "ornament",
   south, take_ "festive hat",
   north, west, west, north, north, west]
-}

north, south, east, west :: String
north :: String
north = String
"north"
south :: String
south = String
"south"
east :: String
east  = String
"east"
west :: String
west  = String
"west"

take_ :: String -> String
take_ :: String -> String
take_ String
x = String
"take " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
x

drop_ :: String -> String
drop_ :: String -> String
drop_ String
x = String
"drop " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
x