From 5f20c4799398878a455f64d7b81aadc4a1774dd1 Mon Sep 17 00:00:00 2001 From: Neil Smith Date: Fri, 29 Nov 2019 16:30:39 +0000 Subject: [PATCH 1/1] Initial file structure set up. --- .gitignore | 46 ++ README.md | 111 +++++ Setup.hs | 2 + advent01/package.yaml | 16 + advent01/src/advent01.hs | 55 +++ data/advent01.txt | 1000 ++++++++++++++++++++++++++++++++++++++ modest.css | 219 +++++++++ src/Main.hs | 5 + stack.yaml | 75 +++ 9 files changed, 1529 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 Setup.hs create mode 100644 advent01/package.yaml create mode 100644 advent01/src/advent01.hs create mode 100644 data/advent01.txt create mode 100644 modest.css create mode 100644 src/Main.hs create mode 100644 stack.yaml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..071d799 --- /dev/null +++ b/.gitignore @@ -0,0 +1,46 @@ +# 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 +.stack-work/ +cabal.project.local +stack.yaml.lock +.HTF/ + +# Haskell Stack cabal files: they're automatically generated. +*.cabal + +# IPython / IHaskell notebook checkpoints +.ipynb* + +# Sublime text +*.sublime-workspace + +# Logs +*.log + +# Profile exports +*.ps + +# KDE +.directory + diff --git a/README.md b/README.md new file mode 100644 index 0000000..aa3689e --- /dev/null +++ b/README.md @@ -0,0 +1,111 @@ +--- +title: "Advent of Code 2018" +output: html_document +css: modest.css +--- +Code to solve the [Advent of Code](http://adventofcode.com/2019/) puzzles. This year, I'm using the puzzles to develop my skills in [Haskell](https://wiki.haskell.org/Haskell). + +[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 [Stack documentation](https://docs.haskellstack.org/en/stable/README/) and [How I Start: Haskell](http://howistart.org/posts/haskell/1/) are good sources of using the tools. + +# Toolchain + +I'm using the basic Haskell Platform installation, together with `stack` to manage the packages and dependencies (install with +``` +$ sudo aptitude install haskell-platform haskell-stack +``` +), then updgrade with +``` + stack upgrade --binary-only +``` +as the version in the Ubuntu repos is too old to work with current Haskell Stack package sets. +## + +## 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 just one package, with the code in sub-directories of the `src` directory. Each day will generate one (or more) entries in the `adventofcode17.cabal` file. + +Create the basic `stack` project. This will create a new directory. Note that this new directory name can't have a hyphen-delimited word that's just digits, so the project will have to be `advent-of-code` + +``` +stack new advent-of-code --bare simple +``` + +Modify the `stack.yaml` file as needed, such as adding the `ghc-options` stanza. + +## Creating subsequent days + +Each day lives in a separate directory within the `src` directory. It will also need it's own stanza in `advent-of-code.cabal`. + +Compile with +``` +stack build +``` +or +``` +stack build advent01 +``` + +Run with +``` +stack exec advent01 +``` + +If you want to pass in additional RTS parameters, do it like this: +``` +stack exec -- advent01 +RTS -K0 -RTS +``` + +Run interactively with +``` +stack ghci advent-of-code:exe:advent01 +``` + +To profile, use +``` +stack build --executable-profiling --library-profiling --ghc-options="-fprof-auto -rtsopts" +``` +then run with +``` +stack exec -- advent01 +RTS -p -hy +``` +Generate the profile graph with +``` +stack exec hp2ps advent01.hp +``` + +# Packages + +Stack is using the [14.16-lts resolver](https://www.stackage.org/lts-14.16) for packages, so make sure you read the [correct documentation for the packages included in it](https://www.stackage.org/lts-14.16/docs). + +When you use a new package, use + +``` +stack solver +``` +to see how the `stack.yaml` file needs to change, and +``` +stack solver --update-yaml +``` +to implement the changes. + +# IHaskell + +Install following the [IHaskell instructions](https://github.com/gibiansky/IHaskell). + +Run it with + +``` +stack exec jupyter -- notebook +``` + +# Readme + +Build this readme file wth +``` +pandoc -s README.md > README.html +``` + +(Using the [Modest style](https://github.com/markdowncss/modest).) diff --git a/Setup.hs b/Setup.hs new file mode 100644 index 0000000..9a994af --- /dev/null +++ b/Setup.hs @@ -0,0 +1,2 @@ +import Distribution.Simple +main = defaultMain diff --git a/advent01/package.yaml b/advent01/package.yaml new file mode 100644 index 0000000..3002417 --- /dev/null +++ b/advent01/package.yaml @@ -0,0 +1,16 @@ +# 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: . + +name: advent01 +synopsis: Advent of Code +version: '0.0.1' +executables: + advent01: + main: advent01.hs + source-dirs: src + dependencies: + - base >= 2 && < 6 + - text + - megaparsec + - containers diff --git a/advent01/src/advent01.hs b/advent01/src/advent01.hs new file mode 100644 index 0000000..e1935f4 --- /dev/null +++ b/advent01/src/advent01.hs @@ -0,0 +1,55 @@ +{-# LANGUAGE NegativeLiterals #-} +{-# LANGUAGE OverloadedStrings #-} + +import Data.Text (Text) +import qualified Data.Text.IO as TIO + +import Data.Void (Void) + +import Text.Megaparsec +import Text.Megaparsec.Char +import qualified Text.Megaparsec.Char.Lexer as L +import qualified Control.Applicative as CA + +import Data.IntSet (IntSet) +import qualified Data.IntSet as S + +main :: IO () +main = do + text <- TIO.readFile "data/advent01.txt" + let changes = successfulParse text + print $ part1 changes + print $ part2 changes + + +part1 :: [Int] -> Int +part1 = sum + +part2 :: [Int] -> Int +part2 = snd . head . dropWhile unRepeated . scanl merge (S.empty, 0) . cycle + +merge :: (IntSet, Int) -> Int -> (IntSet, Int) +merge (frequencies, frequency) change = (S.insert frequency frequencies, frequency + change) + +unRepeated :: (IntSet, Int) -> Bool +unRepeated (frequencies, frequency) = frequency `S.notMember` frequencies + +-- 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 + +changesP = many signedInteger + +successfulParse :: Text -> [Int] +successfulParse input = + case parse changesP "input" input of + Left _err -> [] -- TIO.putStr $ T.pack $ parseErrorPretty err + Right changes -> changes \ No newline at end of file diff --git a/data/advent01.txt b/data/advent01.txt new file mode 100644 index 0000000..f907f85 --- /dev/null +++ b/data/advent01.txt @@ -0,0 +1,1000 @@ +-16 ++12 +-18 +-1 ++5 +-8 ++9 +-15 ++12 ++6 ++11 ++7 +-9 ++13 ++5 +-4 +-4 +-2 +-5 ++19 ++4 ++14 ++7 ++8 +-16 +-9 ++16 ++8 +-11 +-7 ++12 ++8 ++13 ++11 ++12 +-19 ++11 ++7 ++9 +-7 +-16 +-5 ++11 +-1 ++8 ++5 ++12 +-1 +-1 ++6 +-2 +-12 ++6 +-18 ++11 ++5 ++13 +-12 +-15 +-8 +-13 ++2 +-11 ++1 +-14 +-6 ++11 +-15 ++11 ++8 ++18 +-8 ++18 +-7 +-9 +-24 +-12 ++2 ++20 +-9 +-5 +-14 +-6 ++16 +-1 +-12 +-16 ++8 ++9 +-15 +-8 +-2 +-4 +-16 +-18 +-8 ++10 ++10 ++2 ++3 +-8 +-10 +-1 +-2 ++20 +-5 +-4 +-13 ++10 ++9 +-12 +-19 ++15 +-4 +-13 +-11 +-9 +-4 +-12 ++3 +-7 +-4 ++13 ++8 +-5 ++10 +-11 ++7 ++10 ++13 ++10 +-17 +-21 ++11 ++3 ++9 +-15 +-11 ++15 ++10 +-3 ++17 ++6 ++11 ++16 ++19 ++8 ++8 ++4 ++9 ++7 ++15 ++2 ++15 ++22 ++19 ++11 ++3 ++19 ++9 +-4 ++9 +-19 +-16 ++6 ++2 +-3 ++5 ++5 +-18 ++1 +-14 +-6 +-20 ++10 +-13 ++19 +-18 +-17 ++5 +-39 ++2 ++33 ++2 ++24 +-16 ++45 ++9 ++21 ++6 ++20 ++4 +-12 +-7 +-3 ++8 ++12 ++5 +-1 ++8 ++18 +-13 +-9 ++3 ++16 +-4 ++15 ++13 +-10 +-8 +-13 +-21 ++15 ++17 ++13 +-4 +-18 +-15 ++3 ++11 ++5 ++3 ++10 +-11 ++9 ++19 +-2 ++9 ++3 +-13 ++2 +-7 +-14 +-2 +-7 +-19 ++7 ++3 +-13 ++6 ++10 ++5 +-9 +-20 +-8 ++5 +-17 ++11 +-12 ++17 +-12 +-14 ++24 +-22 +-13 ++15 ++15 ++1 +-4 ++13 +-30 ++12 ++17 ++8 ++45 ++4 +-3 +-5 ++3 +-9 ++13 ++8 ++14 ++2 +-12 +-3 ++9 ++20 ++7 ++1 ++1 +-17 +-10 ++3 +-2 ++4 +-6 ++16 +-8 ++15 ++16 ++8 +-11 +-14 +-4 ++2 ++15 ++19 ++12 ++14 ++17 +-18 +-18 +-18 +-1 +-1 +-7 +-17 +-2 +-18 ++15 +-3 ++5 +-20 ++39 +-1 ++6 ++8 ++10 ++16 +-19 ++11 ++19 ++15 +-6 ++19 +-8 ++6 ++1 +-2 +-20 +-4 ++18 ++2 +-17 +-10 +-10 +-12 ++18 ++2 +-16 +-8 ++14 +-15 ++12 +-14 +-19 +-16 +-21 +-17 ++21 +-12 +-34 +-22 +-25 +-15 ++14 +-12 +-10 ++11 +-20 ++4 +-6 +-11 ++14 ++21 ++74 ++40 ++3 ++15 +-4 ++16 ++12 ++3 ++6 ++2 ++11 ++10 +-3 ++17 +-5 ++10 ++13 ++5 +-13 +-4 ++13 +-8 ++17 +-2 ++6 +-12 ++7 ++2 ++13 +-2 +-9 ++18 ++15 +-11 ++4 ++3 +-21 +-17 ++3 ++12 +-1 +-12 +-3 +-20 +-10 ++13 +-6 +-4 +-20 ++7 ++15 +-6 +-15 +-26 ++13 ++6 +-23 +-9 +-1 ++44 ++8 +-14 ++26 ++13 ++5 ++31 ++24 ++7 +-2 ++7 +-4 ++17 +-16 +-3 ++36 +-10 +-22 +-11 ++62 +-7 ++21 +-17 +-10 +-18 ++11 ++4 ++5 +-23 +-26 +-40 ++2 ++32 ++62 ++23 ++45 ++109 +-37 +-10 +-99 +-210 +-21 +-33 ++379 ++262 ++66 ++66407 ++13 +-8 +-14 +-16 +-6 +-19 ++12 ++15 +-10 +-19 +-8 ++12 ++13 +-11 ++18 ++7 +-11 ++14 +-12 +-11 +-2 ++4 +-19 +-9 ++3 +-5 ++7 +-4 ++9 +-19 ++20 ++7 +-14 +-2 +-7 +-8 +-2 +-16 ++8 +-10 ++1 +-4 +-16 ++2 ++1 +-13 +-2 +-3 +-16 ++5 +-6 +-17 ++3 ++9 ++14 ++1 +-11 ++6 +-2 +-12 +-10 ++11 ++19 +-9 ++5 +-11 +-8 +-17 +-19 ++8 +-3 +-17 ++13 ++14 +-16 +-8 ++19 ++17 +-16 +-16 +-13 +-11 ++9 +-19 ++6 ++12 ++5 +-12 +-12 +-16 +-14 +-6 ++7 ++8 +-12 +-18 ++12 ++13 +-17 ++3 +-5 ++1 ++6 +-4 +-18 ++1 ++11 ++2 +-8 +-15 +-17 ++16 +-10 +-12 ++16 +-14 +-1 +-11 ++5 ++14 ++20 ++16 +-18 ++16 ++17 ++13 +-9 +-6 +-16 ++19 ++13 ++8 +-13 ++1 ++19 +-12 +-20 +-20 +-11 +-12 ++4 ++12 ++6 +-17 +-9 +-3 +-18 +-15 +-2 +-5 ++17 ++12 +-8 ++4 +-12 +-7 +-18 +-4 +-1 +-19 ++1 +-7 +-8 ++5 ++1 ++19 +-7 +-19 ++18 ++12 ++6 ++19 ++8 +-1 ++20 +-17 +-16 +-5 +-1 +-3 ++6 +-13 +-2 ++6 +-8 ++12 +-13 +-3 +-13 ++8 ++4 +-16 ++19 ++18 ++16 +-13 +-1 ++3 ++9 ++18 ++1 ++3 ++14 ++10 ++3 ++1 +-8 ++18 ++4 ++26 ++22 ++13 +-12 +-7 +-3 ++6 +-17 ++5 ++14 +-7 ++12 ++10 +-7 ++8 +-7 ++18 ++17 +-6 ++12 ++17 ++2 ++3 +-9 ++18 ++10 +-17 +-10 +-2 +-13 ++6 ++4 ++17 ++12 ++14 +-15 ++5 ++17 ++4 +-1 +-14 +-19 +-1 ++5 +-15 +-16 ++1 +-11 +-13 +-5 ++15 +-4 +-15 ++1 ++22 ++17 +-20 +-21 ++13 ++1 +-2 ++17 ++23 +-35 +-14 +-18 ++6 ++1 ++1 +-13 +-10 ++34 ++35 ++8 ++4 ++14 ++24 ++16 +-5 +-2 ++10 ++16 +-10 +-11 ++1 +-2 +-3 ++7 ++5 ++20 +-14 ++2 ++2 +-5 ++14 +-18 ++23 +-3 ++2 ++4 ++2 ++7 ++8 ++3 +-16 +-5 ++4 ++12 +-20 +-15 +-22 ++5 +-10 ++31 +-2 ++9 ++10 +-14 ++18 ++6 ++3 ++19 +-15 ++9 ++7 ++18 +-1 +-8 ++19 ++12 ++1 ++16 +-5 +-4 +-9 ++16 ++13 ++2 ++7 ++5 +-3 +-19 ++12 ++9 ++2 ++9 ++16 +-17 +-13 ++12 +-5 ++11 ++4 +-1 ++2 +-6 ++18 ++19 +-10 ++3 +-19 +-19 +-13 +-16 +-2 +-13 ++8 ++18 ++6 +-11 ++2 +-16 ++11 ++12 +-20 ++18 ++17 ++14 +-13 ++26 +-1 ++20 +-1 +-17 +-11 +-8 ++13 +-7 +-5 +-5 +-7 ++18 +-20 +-4 ++29 +-2 ++21 ++21 ++16 ++15 ++14 ++21 +-15 +-14 ++17 ++5 +-10 +-27 +-18 ++10 +-20 ++34 +-13 ++18 ++17 +-21 ++32 ++13 ++6 ++6 ++28 +-37 ++20 ++29 +-25 +-69 +-57 +-3 +-59 ++3 +-21 +-9 ++14 +-19 +-18 ++20 +-5 ++15 ++5 +-9 +-24 ++20 +-14 +-10 +-15 ++30 ++21 +-9 +-34 ++4 +-31 ++25 +-85 ++25 ++38 +-36 +-28 ++58 ++121 +-31 ++13 ++202 ++66221 +-5 +-19 +-10 +-7 +-8 +-2 ++6 +-5 +-6 ++8 +-17 ++10 ++18 ++16 ++3 +-12 +-2 +-11 ++14 ++7 ++11 +-1 +-5 ++10 ++9 +-5 +-3 +-3 +-11 +-13 ++18 +-8 +-5 ++18 ++17 +-6 ++3 ++19 +-18 ++5 ++5 +-4 +-12 ++7 ++14 ++19 +-6 ++10 +-8 +-11 ++10 +-17 ++9 ++11 ++7 +-133358 diff --git a/modest.css b/modest.css new file mode 100644 index 0000000..947a9ea --- /dev/null +++ b/modest.css @@ -0,0 +1,219 @@ +@media print { + *, + *:before, + *:after { + background: transparent !important; + color: #000 !important; + box-shadow: none !important; + text-shadow: none !important; + } + + a, + a:visited { + text-decoration: underline; + } + + a[href]:after { + content: " (" attr(href) ")"; + } + + abbr[title]:after { + content: " (" attr(title) ")"; + } + + a[href^="#"]:after, + a[href^="javascript:"]:after { + content: ""; + } + + pre, + blockquote { + border: 1px solid #999; + page-break-inside: avoid; + } + + thead { + display: table-header-group; + } + + tr, + img { + page-break-inside: avoid; + } + + img { + max-width: 100% !important; + } + + p, + h2, + h3 { + orphans: 3; + widows: 3; + } + + h2, + h3 { + page-break-after: avoid; + } +} + +pre, +code { + font-family: Menlo, Monaco, "Courier New", monospace; +} + +pre { + padding: .5rem; + line-height: 1.25; + overflow-x: scroll; +} + +a, +a:visited { + color: #3498db; +} + +a:hover, +a:focus, +a:active { + color: #2980b9; +} + +.modest-no-decoration { + text-decoration: none; +} + +html { + font-size: 12px; +} + +@media screen and (min-width: 32rem) and (max-width: 48rem) { + html { + font-size: 15px; + } +} + +@media screen and (min-width: 48rem) { + html { + font-size: 16px; + } +} + +body { + line-height: 1.85; +} + +p, +.modest-p { + font-size: 1rem; + margin-bottom: 1.3rem; +} + +h1, +.modest-h1, +h2, +.modest-h2, +h3, +.modest-h3, +h4, +.modest-h4 { + margin: 1.414rem 0 .5rem; + font-weight: inherit; + line-height: 1.42; +} + +h1, +.modest-h1 { + margin-top: 0; + font-size: 3.998rem; +} + +h2, +.modest-h2 { + font-size: 2.827rem; +} + +h3, +.modest-h3 { + font-size: 1.999rem; +} + +h4, +.modest-h4 { + font-size: 1.414rem; +} + +h5, +.modest-h5 { + font-size: 1.121rem; +} + +h6, +.modest-h6 { + font-size: .88rem; +} + +small, +.modest-small { + font-size: .707em; +} + +/* https://github.com/mrmrs/fluidity */ + +img, +canvas, +iframe, +video, +svg, +select, +textarea { + max-width: 100%; +} + +@import url(http://fonts.googleapis.com/css?family=Open+Sans+Condensed:300,300italic,700); + +@import url(http://fonts.googleapis.com/css?family=Arimo:700,700italic); + +html { + font-size: 18px; + max-width: 100%; +} + +body { + color: #444; + font-family: 'Open Sans Condensed', sans-serif; + font-weight: 300; + margin: 0 auto; + max-width: 48rem; + line-height: 1.45; + padding: .25rem; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: Arimo, Helvetica, sans-serif; +} + +h1, +h2, +h3 { + border-bottom: 2px solid #fafafa; + margin-bottom: 1.15rem; + padding-bottom: .5rem; + text-align: center; +} + +blockquote { + border-left: 8px solid #fafafa; + padding: 1rem; +} + +pre, +code { + background-color: #fafafa; +} \ No newline at end of file diff --git a/src/Main.hs b/src/Main.hs new file mode 100644 index 0000000..9cd992d --- /dev/null +++ b/src/Main.hs @@ -0,0 +1,5 @@ +module Main where + +main :: IO () +main = do + putStrLn "hello world" diff --git a/stack.yaml b/stack.yaml new file mode 100644 index 0000000..c341fe3 --- /dev/null +++ b/stack.yaml @@ -0,0 +1,75 @@ +# This file was automatically generated by 'stack init' +# +# Some commonly used options have been documented as comments in this file. +# For advanced use and comprehensive documentation of the format, please see: +# https://docs.haskellstack.org/en/stable/yaml_configuration/ + +# Resolver to choose a 'specific' stackage snapshot or a compiler version. +# A snapshot resolver dictates the compiler version and the set of packages +# to be used for project dependencies. For example: +# +# resolver: lts-3.5 +# resolver: nightly-2015-09-21 +# resolver: ghc-7.10.2 +# +# The location of a snapshot can be provided as a file or url. Stack assumes +# a snapshot provided as a file might change, whereas a url resource does not. +# +# resolver: ./custom-snapshot.yaml +# resolver: https://example.com/snapshots/2018-01-01.yaml +resolver: lts-14.16 + + +ghc-options: + $locals: -O2 -Wall -Wno-missing-signatures -threaded -rtsopts -with-rtsopts=-N + + +# User packages to be built. +# Various formats can be used as shown in the example below. +# +# packages: +# - some-directory +# - https://example.com/foo/bar/baz-0.0.2.tar.gz +# subdirs: +# - auto-update +# - wai + +packages: +# - . +- advent01 + + +# Dependency packages to be pulled from upstream that are not in the resolver. +# These entries can reference officially published versions as well as +# forks / in-progress versions pinned to a git hash. For example: +# +# extra-deps: +# - acme-missiles-0.3 +# - git: https://github.com/commercialhaskell/stack.git +# commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a +# +# extra-deps: [] + +# Override default flag values for local packages and extra-deps +# flags: {} + +# Extra package databases containing global packages +# extra-package-dbs: [] + +# Control whether we use the GHC we find on the path +# system-ghc: true +# +# Require a specific version of stack, using version ranges +# require-stack-version: -any # Default +# require-stack-version: ">=2.1" +# +# Override the architecture used by stack, especially useful on Windows +# arch: i386 +# arch: x86_64 +# +# Extra directories used by stack for building +# extra-include-dirs: [/path/to/dir] +# extra-lib-dirs: [/path/to/dir] +# +# Allow a newer minor version of GHC than the snapshot specifies +# compiler-check: newer-minor -- 2.34.1