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 run
If 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.template
file into.env
. - Paste the cookie in the AOC_COOKIE variable. The
.env
file 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 -> a
Apply a function repeatedly a specified number of times
-
pipeline :: forall a. a -> Array (a -> a) -> a
Successively run an array of functions on a value
-
eitherToMaybe :: forall e a. Either e a -> Maybe a
Convert an either into a maybe
-
intToBigNumber :: Int -> BigNumber
Convert 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 String
Split 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 -> String
The location of the input file
-
readInput :: Int -> Int -> Effect String
Read the entire input file into a single string
-
preventNaN :: Number -> Maybe Number
Turn NaN's into Nothing
-
parseIntBaseN :: Int -> String -> Maybe Int
Parse an integer in specified base
-
parseInt10 :: String -> Maybe Int
Parse an integer
-
parseFloat :: String -> Maybe Number
Parse a float