소스 검색

Day 8

main
Jens Kadenbach 2 년 전
부모
커밋
b9df0aa858
7개의 변경된 파일265개의 추가작업 그리고 1개의 파일을 삭제
  1. 11
    0
      aoc2022.cabal
  2. 3
    0
      package.yaml
  3. 99
    0
      ressources/day08-input
  4. 84
    0
      src/Day8.hs
  5. 3
    0
      src/Lib.hs
  6. 0
    1
      test/Day6Spec.hs
  7. 65
    0
      test/Day8Spec.hs

+ 11
- 0
aoc2022.cabal 파일 보기

@@ -47,6 +47,7 @@ library
47 47
       Day7
48 48
       Day7.Interpreter
49 49
       Day7.Parser
50
+      Day8
50 51
       Lib
51 52
       Shared
52 53
   other-modules:
@@ -61,9 +62,12 @@ library
61 62
     , heredoc
62 63
     , hspec
63 64
     , lens
65
+    , matrix
66
+    , megaparsec
64 67
     , parsec
65 68
     , split
66 69
     , text
70
+    , vector
67 71
   default-language: Haskell2010
68 72
 
69 73
 executable aoc2022-exe
@@ -81,9 +85,12 @@ executable aoc2022-exe
81 85
     , heredoc
82 86
     , hspec
83 87
     , lens
88
+    , matrix
89
+    , megaparsec
84 90
     , parsec
85 91
     , split
86 92
     , text
93
+    , vector
87 94
   default-language: Haskell2010
88 95
 
89 96
 test-suite aoc2022-test
@@ -97,6 +104,7 @@ test-suite aoc2022-test
97 104
       Day5Spec
98 105
       Day6Spec
99 106
       Day7Spec
107
+      Day8Spec
100 108
       Paths_aoc2022
101 109
   hs-source-dirs:
102 110
       test
@@ -109,7 +117,10 @@ test-suite aoc2022-test
109 117
     , heredoc
110 118
     , hspec
111 119
     , lens
120
+    , matrix
121
+    , megaparsec
112 122
     , parsec
113 123
     , split
114 124
     , text
125
+    , vector
115 126
   default-language: Haskell2010

+ 3
- 0
package.yaml 파일 보기

@@ -30,6 +30,9 @@ dependencies:
30 30
 - lens
31 31
 - Ranged-sets
32 32
 - parsec
33
+- matrix
34
+- vector
35
+- megaparsec
33 36
 
34 37
 ghc-options:
35 38
 - -Wall

+ 99
- 0
ressources/day08-input 파일 보기

@@ -0,0 +1,99 @@
1
+002100030222341303232115221524311502200403234452204125251345024423544443305142410110142101223120110
2
+102030322341143330244233013052025453422005415304655426206452251310214055314024034341233110302320003
3
+003012203404011430120134554314552441635001641050211406204621114102021543144514102510421243314102033
4
+330313423002034140035001210441156554545625042262651356556544202500446121455112434243313013430141203
5
+331203121131230002055113430244610062654034520106363462155201210355601153542301323442223310134324300
6
+232201231021003254355411402310326206625011564114125202263504451451212600155351424154310240411213431
7
+033033333301011523544023206136145505304224325606020360006206455564513553512054354124523232201230441
8
+132201032234334044251334220345360402456541662253556375754662323265201641514121105025300453041111234
9
+314322341322104402235020206565044225363527617767574524475421763504341061551154250344125514014234344
10
+101323043023430543342440532324326413655657527215661116623455613664321005134300223542510253102211310
11
+320404242514122111525043444530625417656773117247512712444315767422412130351505513231104322032421303
12
+221204123205133142044056245654205231734371546616753217321556472223654044043612554152141554333102034
13
+340310155225452152216635634352712541366312326272262143522347111166646736001360102010220214000133002
14
+012404003515002416422500163244271366252711531615333437352461454777311142132000140205630042305222013
15
+332434552302203445503543424523327464362526657251687634745536521746523154717531643250132300541053000
16
+020130312425316362611130462217125425435545265467725256332777233137141524314631100051153314314343032
17
+112115124512002346011342433146124542356845483862756322785545283652723747276776403131622540014001524
18
+332354013101003031053022245431274627654677343638672643442563448782737464337546541546630431125021330
19
+220315320142064161406534365262377268373743527784575246325564676238816733767331345114363612344051535
20
+102041153526000601402325625766534543527882476653366727573448727775677146365732431425225562043130034
21
+350054114310533002426654125166575285757827422257872378766383267543484865317252532765440216543555512
22
+222440404353016144747347457368562668586285847553578732435887584463446862116134751240360645225435344
23
+554234546163262630313431762248876668663352436888374587856263343842526635237314231451062036605442520
24
+525531324662660356256614344438373575732699988366775989976447384338336827686445577222030363631240512
25
+055541261042533424177375756738443482846986979788978997559377679255463858237757327464422026230510130
26
+514123221240250442457744728347386637684953574546455344754548333793233865436751231314653541223102202
27
+355454250661114645144551785724753237378345375493453967559796675839837444334776625552412552302431302
28
+202445234333206767744653874724276586973668878949653473947686567565487325864733735677672241416513452
29
+445415223211061633767433865252483574744685974593334963668983745643354885658423263536531213102544202
30
+201405464251164654177385783224666473975674643767946648464678958969336335638578275154116223152222102
31
+401423140356441654745572266848965593553995667644648964747884544439493545472454437715336645303346422
32
+154440323240741427732867467564957336394985859766644495658985963583496399736552632162756445212536404
33
+441663663062661372122867364584655388977474857585778686889578799644949733463423826715534215154065204
34
+422036122016243651174663588693898583374968974778579585977478599643389537573534354622377452555411315
35
+430412403362272513348763673566578945645997454758694486758844958569786758359475575577532661126532300
36
+503653020441267422765353469867998339764449596776968996449777464644846938866332635583727771665263026
37
+006252631541331635768754753357384754988659585857956567666645975599653466655333342485345762600032403
38
+215205542775713732868842389885585646884858449858579777975997584997463698339932263363162431251615251
39
+342224450731115175762626546538955447796468885776778879697695699945446388444478355347827635732006646
40
+045011110226211633623658548365544498466468766878699597655897586488555435934935526883851537736604133
41
+440352212243431376382869634434568447654566895897796875679759667598898849334873844583742271767024403
42
+566632367121414762272448784755746799985759966559657989697977677955455754549393784586875275341562621
43
+004131167135757426882464486773699786789959957795985595559587775554479945637849747667752242212324244
44
+022411031432724262533554794664597446479869568767598899669969588984864457535986725263473577457413134
45
+036415005331162527346577487593798458668976888776888766856699598847776567686579476836656723623111342
46
+504001302331545267684439554776894957999788577876688969865558955547965687556849786463457244355044511
47
+464266074264126575276833864784546697885788878967966988678696686685576789843676844576623242451411411
48
+660130573642326366362654785549676574587876888769689696798799988678648554635745724364273772474666502
49
+413511521313437652422664948645649566979966676679778669968777776786958464356797545247763267365643645
50
+455033174473274564484285387995879595555686569997977698868769855686564847593489668858847744131410225
51
+560316675532344635443349663994499869866598568889798868967976679655597494679336978524332246567265361
52
+121053163342234352453837754569968465557968697766766888969966667796479457384444468264837376474515455
53
+604062313527642634768255846899648545559665886668966887999959659769978495794795825775373713613231451
54
+041031112622754332842439776736966994677888699898679988967779696758849589365579766676242256227420364
55
+630161363126476778455475799658545955598576568877768698668579988799596866465635488284555252726211044
56
+455563641427127283364758796475975894658677688789777769876667978747955677573575525588444241765111511
57
+256420063532645225542863884958844496596759999769769687678888788875449888945958948378756476127155054
58
+523256165217547362636325547686549767698957967985968987897777685866576744344388256886854362647342110
59
+205224606764556763544234874676659474468968576879668558856675855668779847849738247387744421321145610
60
+022651355615653552468486676459694744747575877656886776677858584988944678787576556747724125467333305
61
+526313424324717126486746644643397589664468865599858886996669788566489473798387676766873216657521426
62
+426530404522411762572567697375959747975669667958685679878659587764977658398697353283563215312244014
63
+023510245741131775436864579684699874979976567776557765866775469587757498544476554753722641656303654
64
+211341433442225414565332887899363678699495567888998675657659688744458493387343842346747477252626250
65
+406543152154335614758277748595836896786654948759999978569588555764838686653647362854723163226456101
66
+333640633617315535456525364849458558744656899855554897897568844446533866457545654847562377442214226
67
+040003053246534354438748723933365934878485997458955574785966996653353969666867276761661111124104550
68
+405602516206264365157378627495546935658594587869579958969686766986836687348285865231616336232000100
69
+304131030254233641578272475868953446545577766644956989679964489688554398956223433417637732661500540
70
+131164662225325441733366324345477954639475997658684766465487974699579665344326248136151472051130445
71
+452312154206174654138684277376889449945746954689646875777596486949365968888456226732332263263420000
72
+003010154551246223274282454345355673349967689986885795449989359633496728553885221437611730454554455
73
+131435126460017635544785754344874379695379366384573934357795398633967475353836864461424146264354142
74
+350154544045013352533173566257757787385448697484997454578735937499665628425542376452563635450224022
75
+302420224365163651765264446875287359533637498445639443969586466433384346337722662774436566624454214
76
+415242456321105173655733744886343826548944666338683876383973497998744488687446541256724244661531431
77
+155303206134314124372553618623857237346567857564464797593393675563536467777317174625640132203003240
78
+335521544652523624641575451785635352333587957647598535633948867838652636686573137515062356442045153
79
+235314500244636615342325346277256685653838226755493858683465683736283367654226655456541546644313125
80
+252520511531061305614364671212856473625642477732845278766573642425286572562373137446456005011330433
81
+241525455120116046543737642325543677623243884242534423327827446383376441727657314343125403632434002
82
+301045223551220356167117621755325772252845222546246588464784874685774676163655131632622146412415515
83
+011150133311336614251435416453632383454327534367288242328746537673543714263674263262001132354544412
84
+314104033000306256531666256433553535833538337463847277453476563227672715617272601302551120422305504
85
+104211442013141664402363645617163435245556228235337864656673626354151416721375243323635625100210424
86
+413422313502535362615054171511431775335574748526574728747453724472157632635263350024552502052340024
87
+131225301023304456424150404525765416565572272321835377167235317312551645334432406536160545434122120
88
+342131052232413325301451041516716541737346252413667115612642227312572433104525003114240240141232002
89
+244421101354005430232434420344323273421374225635551363463245561271743411452116466311034334101231020
90
+232404402304311415164151401553463731147111147752141732625152553615361046133341313265525232544143442
91
+201321033520133414312301326330253041267251614477322566645472656414545035321106361434351501123314104
92
+211232034442524242313453325046331353174352335422752364775746537513333534355120322320404054014303124
93
+224032233240430510135541652065052415154147565656231651653327511443424113100543020223335130010141400
94
+004110101133543440511523265424013341433043655022512172622140322434116104552043413352211021312421433
95
+000304433232402410151205333526613043463556021413402141634154404530112303306244402221312522221004042
96
+200204441020135232033032541516232550445221141520665016336536052063115335040344025054213324400312303
97
+300211022440310123055510053251505226452265556365100101014044645236505213550201425252404100302413231
98
+310312413210032422053242024243343060135340422313312403505631104430120233112324204414021331012401232
99
+132020341330304022053503522313342026211133610000020554213662244142551253124302245242110111033101203

+ 84
- 0
src/Day8.hs 파일 보기

@@ -0,0 +1,84 @@
1
+module Day8 (
2
+  Forest,
3
+  Visibillity,
4
+  parseForest,
5
+  checkVisibility,
6
+  countVisible,
7
+  findMaxScenicScore,
8
+  viewingDistance,
9
+  day8
10
+)where
11
+
12
+import qualified Data.Matrix as M
13
+import Data.Matrix ((!))
14
+import Data.Char (isDigit)
15
+import qualified Data.Vector as V
16
+import Data.Monoid (Sum (..), getSum, Product (..), getProduct)
17
+import Control.Arrow ((>>>))
18
+
19
+type Forest = M.Matrix Int
20
+type Visibillity = M.Matrix Bool
21
+
22
+parseForest :: String -> Forest
23
+parseForest input = M.fromList rows cols asNumbers
24
+                     where
25
+                       ls = lines input
26
+                       cols = length (head ls)
27
+                       rows = length ls
28
+                       asNumbers :: [Int]
29
+                       asNumbers = map (read . (: [])) . filter isDigit $ input
30
+
31
+checkAgainstNeighbours :: (Int -> [V.Vector Int] -> a) -> Forest -> M.Matrix a
32
+checkAgainstNeighbours f forest  = M.matrix (M.nrows forest) (M.ncols forest) check
33
+  where
34
+    check(x, y) =
35
+      let row = M.getRow x forest
36
+          col = M.getCol y forest
37
+          -- left and top are reversed to order the as seen from (x,y)
38
+          left   = V.reverse $ V.take (y - 1) row 
39
+          right  = V.drop y row
40
+          top    = V.reverse $ V.take (x - 1) col 
41
+          bottom = V.drop x col
42
+          v = forest ! (x,y)
43
+      in f v [left, right, top, bottom]
44
+
45
+checkVisibility :: Forest -> Visibillity
46
+checkVisibility = checkAgainstNeighbours isVisible
47
+  where
48
+    isVisible v = any (all (< v))
49
+
50
+countVisible :: Visibillity -> Int
51
+countVisible vis = getSum $ foldMap (Sum . isTrue) vis
52
+  where
53
+    isTrue True = 1
54
+    isTrue False = 0
55
+
56
+checkScenicScores :: Forest -> M.Matrix Int
57
+checkScenicScores = checkAgainstNeighbours allDistances
58
+  where
59
+    allDistances tree neighbors = getProduct $ foldMap (Product . viewingDistance tree) neighbors
60
+
61
+viewingDistance :: Int -> V.Vector Int -> Int
62
+viewingDistance treeHeight neighbors
63
+  | V.length neighbors == 0 = 0
64
+  | V.head neighbors >= treeHeight = 1
65
+  | V.head neighbors < treeHeight = 1 + viewingDistance treeHeight (V.tail neighbors)
66
+  | otherwise = 0
67
+
68
+findMaxScenicScore :: Forest -> Int
69
+findMaxScenicScore forest = maximum $ M.toList scores
70
+  where
71
+    scores = checkScenicScores forest
72
+
73
+day8 :: IO ()
74
+day8 = do
75
+   input <- readFile "ressources/day08-input"
76
+   putStrLn "Day8"
77
+   let forest = parseForest input
78
+   let visibleTrees = checkVisibility >>>
79
+                      countVisible $ forest
80
+   putStrLn ("Number of visible trees is " ++ show visibleTrees)
81
+   let highestScenicScore = findMaxScenicScore forest
82
+   putStrLn ("Highest scenic score is " ++ show highestScenicScore)
83
+   
84
+

+ 3
- 0
src/Lib.hs 파일 보기

@@ -9,6 +9,7 @@ import Day4
9 9
 import Day5
10 10
 import Day6
11 11
 import Day7
12
+import Day8
12 13
 
13 14
 someFunc :: IO ()
14 15
 someFunc = do
@@ -25,5 +26,7 @@ someFunc = do
25 26
   day6
26 27
   putStrLn "-----------"
27 28
   day7
29
+  putStrLn "-----------"
30
+  day8
28 31
   
29 32
 

+ 0
- 1
test/Day6Spec.hs 파일 보기

@@ -2,7 +2,6 @@ module Day6Spec (spec) where
2 2
 
3 3
 import Test.Hspec
4 4
 import Day6
5
-import qualified Data.Sequence as S
6 5
 
7 6
 spec :: Spec
8 7
 spec =

+ 65
- 0
test/Day8Spec.hs 파일 보기

@@ -0,0 +1,65 @@
1
+{-# LANGUAGE QuasiQuotes #-}
2
+module Day8Spec (spec) where
3
+
4
+import Test.Hspec
5
+import Text.Heredoc
6
+import Control.Arrow ((>>>))
7
+
8
+import qualified Data.Matrix as M
9
+import qualified Data.Vector as V
10
+import Day8
11
+
12
+testInput :: String
13
+testInput = [str|30373
14
+                |25512
15
+                |65332
16
+                |33549
17
+                |35390
18
+                |]
19
+
20
+testVisibility :: Visibillity
21
+testVisibility = M.fromList 5 5
22
+  [x,x,x,x,x,
23
+   x,x,x,o,x,
24
+   x,x,o,x,x,
25
+   x,o,x,o,x,
26
+   x,x,x,x,x
27
+  ]
28
+  where
29
+    x = True
30
+    o = False
31
+
32
+smallForest :: String
33
+smallForest = [str|1234
34
+                  |5678
35
+                  |9012
36
+                  |]
37
+
38
+parsedSmallForest :: Forest
39
+parsedSmallForest = M.fromList 3 4 $ [1..9] ++ [0,1,2]
40
+
41
+spec :: Spec
42
+spec =
43
+  describe "Day8" $ do
44
+    describe "Part1" $ do
45
+      it "parses a forest" $ do
46
+        parseForest smallForest `shouldBe` parsedSmallForest
47
+      it "checks visibility" $ do
48
+        let forest = parseForest testInput
49
+        checkVisibility forest `shouldBe` testVisibility
50
+      it "counts visible things" $ do
51
+        let v = parseForest >>>
52
+                checkVisibility >>>
53
+                countVisible $ testInput
54
+        v `shouldBe` 21
55
+    describe "Part2" $ do
56
+      it "calculates viewing distance from height" $ do
57
+        viewingDistance 5 (V.fromList [3]) `shouldBe` 1
58
+        viewingDistance 5 (V.fromList [5,2]) `shouldBe` 1
59
+        viewingDistance 5 (V.fromList [1,2]) `shouldBe` 2
60
+        viewingDistance 5 (V.fromList [3,5,3]) `shouldBe` 2
61
+      it "calculates the scenic score" $ do
62
+        let s = parseForest >>>
63
+                findMaxScenicScore $ testInput
64
+        s `shouldBe` 8
65
+

Loading…
취소
저장