This commit is contained in:
ctsk
2023-09-07 08:20:07 +02:00
parent 4ea7c5329c
commit 89c9c622d1
8 changed files with 442 additions and 3 deletions

View File

@@ -23,8 +23,10 @@ common defaults
library library
import: warnings, defaults import: warnings, defaults
hs-source-dirs: src hs-source-dirs: src
c-sources:
src/Days/D08.c
exposed-modules: exposed-modules:
Lib Lib
other-modules: other-modules:
@@ -39,8 +41,11 @@ library
Days.D05 Days.D05
Days.D06 Days.D06
Days.D07 Days.D07
Days.D08
build-depends: build-depends:
megaparsec ^>=9.4.0 bytestring
, megaparsec ^>=9.4.0
, mtl
, text , text
, vector ^>=0.13.0.0 , vector ^>=0.13.0.0

View File

@@ -15,6 +15,7 @@ paths =
, "./data/05.in" , "./data/05.in"
, "./data/06.in" , "./data/06.in"
, "./data/07.in" , "./data/07.in"
, "./data/08.in"
] ]
solutions :: [(Int, Day, FilePath)] solutions :: [(Int, Day, FilePath)]

View File

@@ -14,6 +14,7 @@ paths =
, "./data/05.in" , "./data/05.in"
, "./data/06.in" , "./data/06.in"
, "./data/07.in" , "./data/07.in"
, "./data/08.in"
] ]
solutions :: [(Integer, [Day], FilePath)] solutions :: [(Integer, [Day], FilePath)]

99
data/08.in Normal file
View File

@@ -0,0 +1,99 @@
233221301103014030101125554304512450101014416563016614544451211503551012024530301031123411303012023
223110030312032004315232020021044351226566053525520014161014365133524241052505310020040430140233233
011200302423421402534302350042313154065514525565225306335602432332241151015242024200402140133220003
002023323144303045350514551440115531356512252026625440355250226333224214343231500124312340334341321
101232243140312024142320204214244464231230062354016652136653240513255431333204040044401030434211030
303102413102435311532052555553031040461010416520354404000202101125240056131215011352334200032434223
300241124021350440235305305265064502252664355653052603103661022335154654350220253343535411223334123
323220243322044313554114210145156005441001520353563754330342212516625242341151024213335041414342201
130013214244243213502220216324363535110135412126721426711575535566050222160040010533452035332043122
331223042334244550504551605434252666266354232461526253225234277303623553352605022424451300442404244
143244011302242550040222126526005533526344773247731442766312662452542641101604655543134141230441332
034223223341140140532440622100244276224772513433354277525736136616624533125062164113454025403423402
011112421331125444541545223116743735215125731334727642366151131753355120223064024615410235002330044
444010415251333360424226054325525134356261352627756142635246277134767675144662506365541424215011331
413332441252412114024404002455175464551226722723787467136522723675716526677621400405145404044353224
320023231445523665546426443713561726276471685736846476656864427621276566267641152263152434551423142
422032340150053016434505315234157333716363573868457334788332525157426143532125060004414202214323541
242005523130100156466605122446724637245547256767534536377384663686265165314726542344260140135454002
103103100333045134543342647715363346722727472345762338564544728683817742222663435161452411314342331
201030531455612563214136716421674265273685246232774787758444882758632623271232544645026655130050015
202410214152634604632242257725843782468462487534886844242326842632565746616656433140433335243531333
411504054613063251425672131267466665352547345346773883344377237255874782366375362434624660051354302
332334051660432424365534664438257225352566448464768647749842833862366527525737563310450154222212201
554551232162023652377415617576326426634334486439834956749789862277657783246672677312135325021125400
215415462453165534715474435345677326623944368587786448463733938422325377247253142625766166441124240
152520042445420426271164156224232558995394389979447796564968436496783742374537144266754145665133551
310343406536261745732663877434357763897657757483567998955333735485732743685642167713461503241410413
415444100156265263661412857434726837394473488968699838749578938837968847383432226374617610220601131
044000262650372413555472572764488366353877587334555968745383837543935447883323412334776255334201434
331416641562174551317778768486783555676634548677966894448878499783948688878478273164216565456622432
542264115512434233272343848478748567383875668797597769875598699635845682727422684656425363423254043
551355050443331327358343724746553849357476979686844488954889849539839345668335624531411166014406004
440110124312163373442478475539635686795987575554687897645498659549998653645848866855143417411221612
452416661044376754553536384443537367449997689768555695778848587859646763666787267355113376652032403
351650106612733643567234479567838574545748547654959748898496787978857448387838556761311434621161600
423164215452426775346873528893488499859748486797964668784868787959578553965536576733115232412150350
534520345555146763236633735798347448877599674655978795974786569666444749477557576225721371326555454
015012041533642333262638456553667977664659486997665867556895587645795864896923458222123716546104604
541314543717441134768334438436398575674499788867858879958994567865657958799965467265822753444305130
104150434751234164255836339363688675667479889896798557658668974494587453947337235834446644234104263
441420243111137557568749494995774879487597588968889595759978549788648695757684634223416656462645003
103125155224727172844574993843955848657566577796675586566789686649665879655957838554322354612552424
505004515272455856668623737796989468458856966956698758978866957467864653369358663825786774354323034
326033654574774366385288876634649479797795567779796665896955776488686574458935627685483456547506432
562103324543744324365346453468648558597657599588698696999885595968976978794937464456581432613140136
612345424446172733285699787374567874598678685688686687688767588585457545587555947527286555311050000
433411414626376543244244867987484948587678658966766789796877855698467447859563357883485375475406354
341253451334125875245373685564955887589966866989999997797598978974475468594857484258484136127120100
200303433735745237766747834544658696999686799768686786879887875664657758359549937282838247626231056
654646336644158883684285846734695969585558766799679888677899877697994746768685758885425753311261306
201036034452128372763239763585657697767668999996887978766987796754969494978755372858433115131334025
462060556445627753535893495377649878766655988798977997687789856658474747668868444568545643714431066
140254534612124588745669733384686669655659556969687669686697565594784896454757723723424377574253611
663516371646244454853456894595497944586665977899987888798588768965477846974987562747644153757513141
332452315233616328522297938878564899968667857886976687688787756767865449986797765827526215346700510
452645155542553755722737576437966959876669857879789679679787668766866869639497732582262262346206605
320451305651771656358773668459579474577589978577787666868787685797884496985453478287843557752540326
221005405577667683824287895575588785589656888856599685876586776546856449569557225537381525443546515
522610412447146737554357965736564875845999676767786957776689658558947465783965388637347135733214120
365113041743772247648369688588766659447876857788787989999588676755655643654457223588345215763342145
331365662344244275766538468557895994865886687597975599897895679569494793355738562445371761445154350
560416605723667182485224784988455577468866555569569998585787896485878847338535683462264111470251530
146413604243275425265736458655756558556566768798968887777776464554786797466795526262563147715263426
130226503774252443838523787457458487445798576575789687898599777444996674896557665832754766151211114
410644160416465516265472763685956655947554997997988985664549867944667645963837585338271746120020623
234400444353735614367346473777975359676584465486444488547785859567944686978722843764714117506664600
330546341222173232268777444964336537946884947578646848754969987868489857574783625523627515745012632
215510460313351411647234366638389773845747847598579897894889788546944863985342457275663675614025645
342210213545727234368434488693363487985575464755897758657759859343755599343477752464125277503536454
231114156421261576175655857464745369897476648997688859877754445379957697253653436731667713060354010
453164662623171156214662327873474686336654745997449564568896584576355868652768524545755363354252620
554300025316031736125826485383344339936569454949855764487789637389535733242664787511565362326423031
320445466330572672647677445385687357347484433584587359664737845658463728375235815264547445451141050
504233423002631313542617237333654646344836534888493885796453743989575826863727171225235343520331515
550051466325245352321661255742284479457798358753587476535783987374576533832831166254212101342043215
103404063140042663267711668752435245443665533849666834674565479747865765884433262127324024133412453
502210250335356312253437134837433475579479784957983873846397955424332238453171177325245310426631521
120423203425443325251472236253442864547699839844889568449833836538346875574334244366660066111410500
150153024014651445361655446722526662223434754345497966369358272744777533661277677616351264143044333
305043020534516555723625613757836647243434758546652236833432766363745648575252765670636334423020131
324341410350233006414762746234734427762582565426887263285227484572273665714572114134636106013020003
024200410445454521665127625215755832276547667754345246823835628624425272357333436355205213141023411
042531434220205431213215417464652274557872486753652854725522264725447146417737544341305620021332442
000344203054303414332247511552441765344484233633274753688646745444375155547363223656046623541021312
112201101440051650123666552763751174414522522454367622586846738672455255341233213141313644302203534
033034235541206026565611331557477413635332243334866483233646131427363516527746640130053324105441343
440432235524015324224620641631111436575761766437865557653265414665227132272123041536221402525004420
424204415025304344210144511336126171352733234257647414163555255776662313512445124614512541552311403
201203443413331044112643006546676731362454147415613675324315222135154622450034424105110224345204424
404032420045400044052565515162401326262664123571333131356225636421142014511240160465543201054014314
140044001322251045503043151635126675576646522245367527254755444572343462466066233105323133200240324
142132040345344121403506604160454253277156425274151762712352543305563111025002305104214312140031443
320411133024401404323432063135406654433363161345315713341411244554233022526116153323002505144044210
131230124111314340101354024335060425100312345444175716433135323021551435425313124554012321023300324
030420114021215402121303133114546220214604202332136022350260462606446502430052002150144444321104203
300211414243414500044050104102034525462355366652523204163624026443102203551513331414101143310403023
110211230343204114142500240353200434243156554215023430233064610531316015110202440241003231234113202
100202013233034314540220440222252066451465203542453535611346001146526045342142013305331421411410013
213120202203131334354133550411130050063060344561426462151351261236123301315415324404100140403211313

View File

@@ -3,6 +3,7 @@
module Common where module Common where
import Data.ByteString.Char8 (ByteString)
import Data.Text qualified as T import Data.Text qualified as T
data Answer where data Answer where
@@ -25,4 +26,5 @@ type DayResult = Either String (Result, Result)
data Day data Day
= TextDay (T.Text -> DayResult) = TextDay (T.Text -> DayResult)
| StringDay (String -> DayResult) | StringDay (String -> DayResult)
| ByteStringDay (ByteString -> DayResult)
| ParsecDay (FilePath -> T.Text -> DayResult) | ParsecDay (FilePath -> T.Text -> DayResult)

195
src/Days/D08.c Normal file
View File

@@ -0,0 +1,195 @@
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
struct result_cell
{
int32_t fst;
int32_t snd;
};
struct stack_cell
{
char c;
int32_t p;
};
struct stack
{
struct stack_cell stk[10];
int32_t height;
};
struct stack init_stack()
{
struct stack result;
result.height = 0;
return result;
}
void stack_push(struct stack* stk, struct stack_cell v)
{
stk->stk[stk->height] = v;
stk->height++;
}
void stack_pop(struct stack *stk)
{
stk->height--;
}
struct stack_cell stack_top(struct stack *stk)
{
return stk->stk[stk->height - 1];
}
bool stack_empty(struct stack *stk)
{
return stk->height == 0;
}
void analyze_row(
char grid[],
bool result_visible[],
int32_t result_fwd[],
int32_t result_bwd[],
int32_t row,
int32_t w,
int32_t xs,
int32_t ys)
{
struct stack stk = init_stack();
struct stack_cell top;
int32_t j = 0;
char cur;
size_t pos;
stack_push(&stk, (struct stack_cell) { '9' + 1, 0}); //sentinel
for (; j < w; j++) {
pos = row*xs+j*ys;
cur = grid[pos];
while (stk.height > 0
&& (top = stack_top(&stk)).c < cur) {
result_fwd[row*xs+(top.p)*ys] = j - top.p;
stack_pop(&stk);
}
if (stk.height == 1) {
result_visible[row*xs+j*ys] = true;
}
result_bwd[pos] = j - top.p;
if (top.c == cur) {
result_fwd[row*xs+(top.p)*ys] = j - top.p;
stack_pop(&stk);
}
stack_push(&stk, (struct stack_cell) { cur, j});
}
while (stk.height > 1) {
top = stack_top(&stk);
result_fwd[row*xs+(top.p)*ys] = w - top.p - 1;
result_visible[row*xs+(top.p)*ys] = true;
stack_pop(&stk);
}
}
void analyze(
char grid[],
bool result_visible[],
int32_t result_fwd[],
int32_t result_bwd[],
int32_t h,
int32_t w,
int32_t xs,
int32_t ys)
{
for (int32_t i = 0; i < h; i++) {
analyze_row(grid, result_visible, result_fwd, result_bwd, i, w, xs, ys);
}
}
// void analyze_horizontal(char grid[], int32_t result_fwd[], int32_t result_bwd[], int32_t height, int32_t width)
// {
// analyze(grid, result_fwd, result_bwd, height, width, width, 1);
// }
// void analyze_vertical(char grid[], int32_t result_fwd[], int32_t result_bwd[], int32_t height, int32_t width)
// {
// analyze(grid, result_fwd, result_bwd, height, width, 1, height);
// }
// void print_grid(char grid[], int h, int w) {
// for (int i = 0; i < h; i++) {
// for (int j = 0; j < w; j++) {
// putchar(grid[i*w + j]);
// putchar(' ');
// }
// putchar('\n');
// }
// }
// void print_result(int grid[], int h, int w) {
// for (int i = 0; i < h; i++) {
// for (int j = 0; j < w; j++) {
// printf("%d ", grid[i*w+j]);
// }
// putchar('\n');
// }
// }
// int main()
// {
// FILE *fp = fopen("./data/08.in", "r");
// // Determine file size
// fseek(fp, 0L, SEEK_END);
// int fpsize = ftell(fp);
// fseek(fp, 0L, SEEK_SET);
// rewind(fp);
// char *buf = malloc(fpsize);
// char *grid = malloc(fpsize);
// fread(buf, 1, fpsize, fp);
// char *grid_ptr = grid;
// for (int i = 0; i < fpsize; i++) {
// *grid_ptr = buf[i];
// if (buf[i] != '\n') {
// grid_ptr++;
// }
// }
// int H = 5;
// int W = 5;
// print_grid(grid, H, W);
// int* result_fwd = malloc(fpsize * sizeof(int));
// int* result_bwd = malloc(fpsize * sizeof(int));
// analyze_vertical(grid, result_fwd, result_bwd, H, W);
// printf("\n D \n");
// print_result(result_fwd, H, W);
// printf("\n U \n");
// print_result(result_bwd, H, W);
// analyze_horizontal(grid, result_fwd, result_bwd, H, W);
// printf("\n R \n");
// print_result(result_fwd, H, W);
// printf("\n L \n");
// print_result(result_bwd, H, W);
// }

132
src/Days/D08.hs Normal file
View File

@@ -0,0 +1,132 @@
{-# LANGUAGE ImportQualifiedPost #-}
{-# LANGUAGE NamedFieldPuns #-}
module Days.D08 where
import Common
import Data.ByteString.Char8 qualified as BS
import Data.ByteString.Unsafe qualified as BS
import Data.Int
import Data.Maybe (fromMaybe)
import Data.Vector.Storable qualified as VS
import Data.Vector.Storable.Mutable qualified as VSM
import Foreign qualified as F
import Foreign.C qualified as FT
import GHC.IO (unsafePerformIO)
foreign import ccall unsafe "analyze"
cAnalyze ::
-- | grid
FT.CString ->
-- | result_visible
F.Ptr FT.CBool ->
-- | result_fwd
F.Ptr Int32 ->
-- | result_bwd
F.Ptr Int32 ->
-- | h
Int32 ->
-- | w
Int32 ->
-- | x_stride
Int32 ->
-- | y_stride
Int32 ->
IO ()
analyzeHorizontal :: FT.CString -> F.Ptr FT.CBool -> F.Ptr Int32 -> F.Ptr Int32 -> Int32 -> Int32 -> IO ()
analyzeHorizontal grid vis fwd bwd h w = cAnalyze grid vis fwd bwd h w w 1
analyzeVertical :: FT.CString -> F.Ptr FT.CBool -> F.Ptr Int32 -> F.Ptr Int32 -> Int32 -> Int32 -> IO ()
analyzeVertical grid vis fwd bwd h w = cAnalyze grid vis fwd bwd h w 1 h
data Intermediate = Intermediate
{ h :: Int
, w :: Int
, v :: VS.Vector FT.CBool
, u :: VS.Vector Int32
, d :: VS.Vector Int32
, l :: VS.Vector Int32
, r :: VS.Vector Int32
}
deriving (Show)
process :: BS.ByteString -> Intermediate
process bs =
let
w = fromMaybe 0 (BS.elemIndex '\n' bs)
h = (BS.length bs + 1) `div` (w + 1)
grid = BS.filter (/= '\n') bs
gridLen = h * w
in
unsafePerformIO $ do
v <- VSM.new gridLen
l <- VSM.unsafeNew gridLen
r <- VSM.unsafeNew gridLen
u <- VSM.unsafeNew gridLen
d <- VSM.unsafeNew gridLen
BS.unsafeUseAsCString
grid
( \gridptr ->
VSM.unsafeWith
v
( \vptr -> do
VSM.unsafeWith
l
( \lptr ->
VSM.unsafeWith
r
( \rptr ->
analyzeHorizontal
gridptr
vptr
rptr
lptr
(fromIntegral h)
(fromIntegral w)
)
)
VSM.unsafeWith
d
( \dptr ->
VSM.unsafeWith
u
( \uptr ->
analyzeVertical
gridptr
vptr
dptr
uptr
(fromIntegral h)
(fromIntegral w)
)
)
)
)
lf <- VS.freeze l
rf <- VS.freeze r
uf <- VS.freeze u
df <- VS.freeze d
vf <- VS.freeze v
return (Intermediate{h = h, w = w, u = uf, d = df, l = lf, r = rf, v = vf})
part1 :: Intermediate -> Int
part1 (Intermediate{v}) = VS.sum $ VS.map fromIntegral v
part2 :: Intermediate -> Int
part2 (Intermediate{u, d, l, r}) =
fromIntegral
. VS.maximum
$ VS.zipWith4 (\a1 a2 a3 a4 -> a1 * a2 * a3 * a4) u d l r
day :: Day
day =
ByteStringDay
( \bs ->
let ffiResult = process bs
in Right (definitive $ part1 ffiResult, definitive $ part2 ffiResult)
)

View File

@@ -18,12 +18,15 @@ import Days.D04 qualified as D04
import Days.D05 qualified as D05 import Days.D05 qualified as D05
import Days.D06 qualified as D06 import Days.D06 qualified as D06
import Days.D07 qualified as D07 import Days.D07 qualified as D07
import Days.D08 qualified as D08
import Data.ByteString.Char8 qualified as BS
import Data.Text.IO qualified as T import Data.Text.IO qualified as T
run :: Day -> FilePath -> IO DayResult run :: Day -> FilePath -> IO DayResult
run (TextDay f) = fmap f . T.readFile run (TextDay f) = fmap f . T.readFile
run (StringDay f) = fmap f . readFile run (StringDay f) = fmap f . readFile
run (ByteStringDay f) = fmap f . BS.readFile
run (ParsecDay f) = \path -> f path <$> T.readFile path run (ParsecDay f) = \path -> f path <$> T.readFile path
days :: [[Day]] days :: [[Day]]
@@ -35,4 +38,5 @@ days =
, [D05.day] , [D05.day]
, [D06.day] , [D06.day]
, [D07.day] , [D07.day]
, [D08.day]
] ]