This commit is contained in:
Jens Kadenbach
2022-12-01 15:57:27 +01:00
commit c104561d8b
16 changed files with 2670 additions and 0 deletions

5
.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
.stack-work/
*~
.idea/
aoc2022.iml
out/

11
CHANGELOG.md Normal file
View File

@@ -0,0 +1,11 @@
# Changelog for `aoc2022`
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to the
[Haskell Package Versioning Policy](https://pvp.haskell.org/).
## Unreleased
## 0.1.0.0 - YYYY-MM-DD

30
LICENSE Normal file
View File

@@ -0,0 +1,30 @@
Copyright Jens Kadenbach (c) 2022
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of Jens Kadenbach nor the names of other
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

1
README.md Normal file
View File

@@ -0,0 +1 @@
# aoc2022

2
Setup.hs Normal file
View File

@@ -0,0 +1,2 @@
import Distribution.Simple
main = defaultMain

75
aoc2022.cabal Normal file
View File

@@ -0,0 +1,75 @@
cabal-version: 1.12
-- This file has been generated from package.yaml by hpack version 0.35.0.
--
-- see: https://github.com/sol/hpack
name: aoc2022
version: 0.1.0.0
description: Please see the README on GitHub at <https://github.com/audax/aoc2022#readme>
homepage: https://github.com/audax/aoc2022#readme
bug-reports: https://github.com/audax/aoc2022/issues
author: Jens Kadenbach
maintainer: jens.kadenbach@smartsteuer.de
copyright: 2022 Jens Kadenbach
license: BSD3
license-file: LICENSE
build-type: Simple
extra-source-files:
README.md
CHANGELOG.md
source-repository head
type: git
location: https://github.com/audax/aoc2022
library
exposed-modules:
Day1
Day1.Internal
Lib
other-modules:
Paths_aoc2022
hs-source-dirs:
src
ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-export-lists -Wmissing-home-modules -Wpartial-fields -Wredundant-constraints
build-depends:
QuickCheck
, base >=4.7 && <5
, hspec
, split
, text
default-language: Haskell2010
executable aoc2022-exe
main-is: Main.hs
other-modules:
Paths_aoc2022
hs-source-dirs:
app
ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-export-lists -Wmissing-home-modules -Wpartial-fields -Wredundant-constraints -threaded -rtsopts -with-rtsopts=-N
build-depends:
QuickCheck
, aoc2022
, base >=4.7 && <5
, hspec
, split
, text
default-language: Haskell2010
test-suite aoc2022-test
type: exitcode-stdio-1.0
main-is: Spec.hs
other-modules:
Paths_aoc2022
hs-source-dirs:
test
ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-export-lists -Wmissing-home-modules -Wpartial-fields -Wredundant-constraints -threaded -rtsopts -with-rtsopts=-N
build-depends:
QuickCheck
, aoc2022
, base >=4.7 && <5
, hspec
, split
, text
default-language: Haskell2010

6
app/Main.hs Normal file
View File

@@ -0,0 +1,6 @@
module Main (main) where
import Lib
main :: IO ()
main = someFunc

63
package.yaml Normal file
View File

@@ -0,0 +1,63 @@
name: aoc2022
version: 0.1.0.0
github: "audax/aoc2022"
license: BSD3
author: "Jens Kadenbach"
maintainer: "jens.kadenbach@smartsteuer.de"
copyright: "2022 Jens Kadenbach"
extra-source-files:
- README.md
- CHANGELOG.md
# Metadata used when publishing your package
# synopsis: Short description of your package
# category: Web
# To avoid duplicated efforts in documentation and dealing with the
# complications of embedding Haddock markup inside cabal files, it is
# common to point users to the README.md file.
description: Please see the README on GitHub at <https://github.com/audax/aoc2022#readme>
dependencies:
- base >= 4.7 && < 5
- hspec
- QuickCheck
- text
- split
ghc-options:
- -Wall
- -Wcompat
- -Widentities
- -Wincomplete-record-updates
- -Wincomplete-uni-patterns
- -Wmissing-export-lists
- -Wmissing-home-modules
- -Wpartial-fields
- -Wredundant-constraints
library:
source-dirs: src
executables:
aoc2022-exe:
main: Main.hs
source-dirs: app
ghc-options:
- -threaded
- -rtsopts
- -with-rtsopts=-N
dependencies:
- aoc2022
tests:
aoc2022-test:
main: Spec.hs
source-dirs: test
ghc-options:
- -threaded
- -rtsopts
- -with-rtsopts=-N
dependencies:
- aoc2022

2244
ressources/day01-input Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,14 @@
1000
2000
3000
4000
5000
6000
7000
8000
9000
10000

39
src/Day1.hs Normal file
View File

@@ -0,0 +1,39 @@
module Day1 (
day1,
findElfWithHighestCalorieCount,
findCaloriesOfTop3Elves
) where
import qualified Data.Text as T
import Day1.Internal
day1 :: IO ()
day1 = do
putStrLn "Day1"
calorieCount <- day1_1
putStrLn ("Highest calorie count = " ++ calorieCount)
caloriesOfTop3Elves <- day1_2
putStrLn ("Calories of top 3 elves = " ++ caloriesOfTop3Elves)
putStrLn "-----------"
day1_1 :: IO String
day1_1 = do
input <- readFile "ressources/day01-input"
return (show $ findElfWithHighestCalorieCount $ T.pack input)
day1_2 :: IO String
day1_2 = do
input <- readFile "ressources/day01-input"
return (show $ findCaloriesOfTop3Elves $ T.pack input)
findCaloriesOfTop3Elves :: T.Text -> CalorieCount
findCaloriesOfTop3Elves =
calories . sumCalories . take 3 . sortElves . elfToCalories
where
sumCalories :: [Elf] -> Int
sumCalories = sum . map caloriesOf
findElfWithHighestCalorieCount :: T.Text -> Elf
findElfWithHighestCalorieCount = head .sortElves . elfToCalories

66
src/Day1/Internal.hs Normal file
View File

@@ -0,0 +1,66 @@
{-# LANGUAGE OverloadedStrings #-}
module Day1.Internal (
elfToCalories,
Elf,
CalorieCount,
calories,
elf,
parseElfGroups,
intOrZero,
sortElves,
caloriesOf
) where
import qualified Data.Text as T
import qualified Data.Text.Read as R
import Data.List.Split
import qualified Data.List as L
import Data.Either
newtype CalorieCount = CalorieCount Int
newtype Elf = Elf CalorieCount
instance Show CalorieCount where
show (CalorieCount c) = "Calories[" ++ show c ++ "]"
instance Show Elf where
show (Elf (CalorieCount c)) = "Elf[" ++ show c ++ "]"
instance Eq CalorieCount where
(==) (CalorieCount c1) (CalorieCount c2) = c1 == c2
instance Eq Elf where
(==) (Elf (CalorieCount c1)) (Elf (CalorieCount c2)) = c1 == c2
instance Ord Elf where
compare (Elf (CalorieCount c1)) (Elf (CalorieCount c2)) = compare c1 c2
elf :: Int -> Elf
elf c = Elf (CalorieCount c)
calories :: Int -> CalorieCount
calories = CalorieCount
caloriesOf :: Elf -> Int
caloriesOf (Elf (CalorieCount c)) = c
sortElves :: [Elf] -> [Elf]
sortElves = L.reverse . L.sort
elfToCalories :: T.Text -> [Elf]
elfToCalories input = map elf sums
where
groups = parseElfGroups input
sums = map sum groups
parseElfGroups :: T.Text -> [[Int]]
parseElfGroups input = map (map intOrZero) groups
where
groups = splitWhen (== "") $ T.lines input
intOrZero:: T.Text -> Int
intOrZero text = val
where
(val, _) = fromRight (0, "") $ R.decimal text

9
src/Lib.hs Normal file
View File

@@ -0,0 +1,9 @@
module Lib
( someFunc
) where
import Day1
someFunc :: IO ()
someFunc = day1

67
stack.yaml Normal file
View File

@@ -0,0 +1,67 @@
# 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:
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/20/2.yaml
# 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:
- .
# 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.9"
#
# 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

13
stack.yaml.lock Normal file
View File

@@ -0,0 +1,13 @@
# This file was autogenerated by Stack.
# You should not edit this file by hand.
# For more information, please see the documentation at:
# https://docs.haskellstack.org/en/stable/lock_files
packages: []
snapshots:
- completed:
sha256: fc39d8afc97531d53d87b10abdef593bce503c0c1e46c2e9a84ebcbc78bf8470
size: 648432
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/20/2.yaml
original:
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/20/2.yaml

25
test/Spec.hs Normal file
View File

@@ -0,0 +1,25 @@
{-# LANGUAGE OverloadedStrings #-}
import Test.Hspec
import Day1
import Day1.Internal
import qualified Data.Text as T
main :: IO ()
main = hspec $ do
describe "Day1" $ do
it "sorts elves" $ do
let input = [ elf 6000, elf 4000, elf 11000]
sortElves input `shouldBe` [ elf 11000, elf 6000, elf 4000]
it "converts a list of strings to a list of either int or caloriecount" $ do
input <- readFile "ressources/day01-input-test"
elfToCalories (T.pack input) `shouldBe`
[ elf 6000, elf 4000, elf 11000, elf 24000, elf 10000 ]
it "parser text to int" $ do
intOrZero "1000" `shouldBe` 1000
it "finds the elf with the highest calorie count" $ do
input <- readFile "ressources/day01-input-test"
findElfWithHighestCalorieCount (T.pack input) `shouldBe` elf 24000
it "sums the calorie counts" $ do
input <- readFile "ressources/day01-input-test"
findCaloriesOfTop3Elves (T.pack input) `shouldBe` calories 45000