This is a Purescript starter kit for Advent of Code solutions.
Example of a repo that uses this starter kit.
Clone the repo and build and run the CLI. This repo will use npm to install the latest purescript compiler and spago build tool in your local directory.
git clone https://github.com/fpindia/purescript-adventofcode
cd purescript-adventofcode
npm install
npx spago build
npx spago runIf this prints a brief help message then you are all set with the dev tools!
This is needed if you want to be able to automatically download your puzzle input.
- First login to Advent of Code.
- Then with Firefox:
- Or with Chrome:
- Right-click, inspect, to open developer tools.
- Go to «Network» tab, refresh the page to see all the network requests
- In the left «name» pane, Click on the HTML request. click «Cookies» tab on the right page, and grab the value for «session» cookie.
- Copy the
.env.templatefile into.env. - Paste the cookie in the AOC_COOKIE variable. The
.envfile should look like this:
AOC_COOKIE="536…"
AOC_INPUT_DIRECTORY="input"
You are done ! You should now be able to download the input file by running the aoc command.
We recommend one of the following editor setups -
Spacemacs is a user friendly emacs distribution with excellent inbuilt support for Purescript.
Enable the purescript layer by putting the following in your $HOME/.spacemacs file, in the dotspacemacs-configuration-layers section -
(purescript :variables
node-add-modules-path t
psc-ide-use-npm-bin t
)Restart spacemacs with <space>-q-R.
Then open src/Main.purs in the editor, and run <space>-m-m-s to run the purescript ide server.
VSCode is a lightweight editor/ide from microsoft.
Install the purescript-ide plugin by Nicholas Wolverson.
Then open src/Main.purs in the editor.
Use aoc bootstrap to immediately start coding for a given day.
It downloads the input file, creates a sample module for that day.
Example - To bootstrap the solution for the 5th puzzle in 2020, run ./aoc bootstrap 2020 5
It will create the following files -``
purescript-adventofcode
├── input
│ └── 2020
│ └── 05
└── src
└── Year2020
└── Day05.purs
The src/Year2020/Day05.purs is simple but it contains all you need: 2 methods, part1 and part2, that take as parameter the content of the input file, and return the expected value.
module Year2020.Day05 where
...
--------------------------------------------------------------------------------
-- Write your solutions here
part1 :: String -> Effect Unit
part1 input = do
let result = "<TODO>"
log $ "Part 1 ==> " <> result
part2 :: String -> Effect Unit
part2 = do
let result = "<TODO>"
log $ "Part 2 ==> " <> result
...Use aoc run to quickly run your current solution and measure the execution time.
./aoc run 2020 5
Part 1 ==> ...
Obtained in: 0.296ms
Part 2 ==> ...
Obtained in: 0.3i9ms
You can also run only a specific part with the --part flag.
./aoc run 2020 5 --part1
Part 1 ==> ...
Obtained in: 0.297ms
Use aoc download to quickly download your puzzle input and put it in the correct location.
./aoc download 2020 5
This will download the input into a file called inputs/year2020/day5.
This project includes the following libraries -
- Bignumber. For dealing with arbitrarily large integers that don't fit in 64 bits.
- Parsing. Parsec style parsing for Purescript.
- Free. Useful to build interpreters and automatons.
Also included are a bunch of helper functions in AOC.Lib.
-
iterate :: forall a. Int -> (a -> a) -> a -> aApply a function repeatedly a specified number of times
-
pipeline :: forall a. a -> Array (a -> a) -> aSuccessively run an array of functions on a value
-
eitherToMaybe :: forall e a. Either e a -> Maybe aConvert an either into a maybe
-
intToBigNumber :: Int -> BigNumberConvert an integer into a bignumber
-
spanMap :: forall a b. (a -> Maybe b) -> Array a -> {init :: Array b, rest :: Array a}Split an array into two parts: 1. the longest initial subarray for which all elements return a Just value for the supplied function, and returns the values mapped to the Just values 2. the remaining elements
-
splitFirst :: Pattern -> String -> Maybe {left::String, right::String}Split by a pattern once and return left and right params To make multiple splits, use
Data.String.split -
chunk :: Int -> String -> Array StringSplit a string into chunks of fixed length
NOTE: Normally you won't need to use the below functions, since the input is automatically passed to the part1 and part2 functions.
-
inputFileLocation :: Int -> Int -> StringThe location of the input file
-
readInput :: Int -> Int -> Effect StringRead the entire input file into a single string
-
preventNaN :: Number -> Maybe NumberTurn NaN's into Nothing
-
parseIntBaseN :: Int -> String -> Maybe IntParse an integer in specified base
-
parseInt10 :: String -> Maybe IntParse an integer
-
parseFloat :: String -> Maybe NumberParse a float
