Add solution for day 8
This commit is contained in:
parent
441e0f327b
commit
c93d336e90
4 changed files with 438 additions and 0 deletions
3
day_8/Makefile
Normal file
3
day_8/Makefile
Normal file
|
@ -0,0 +1,3 @@
|
|||
TARGET := day_8
|
||||
|
||||
include ../Makefile.common.mk
|
100
day_8/input.txt
Normal file
100
day_8/input.txt
Normal file
|
@ -0,0 +1,100 @@
|
|||
102212110110302230012132130441442043243242145112422525112333344240121120342411110001231112222021211
|
||||
222101001302011022124443303121322323142224235123233315215333545242421321241403143213333101310210211
|
||||
200201223122002022301310313414224443253123231515151513541254251131310343344222040320023211301320200
|
||||
200010213032223103230132143412204353411323525332513442523314324332413034422122304413120211230122212
|
||||
010211000332000340422300132032513533513115523254315325423242433353351244232123121111220123121333221
|
||||
200122303232310323111312343413321244422555551325423211253434511531321144403333313021201212232131220
|
||||
000212003210330240303442205443113542544534111314155152232435243131155352422402104202123433111201232
|
||||
103312101101443020314140255354241134315242455146454323625133153413235312512313332430221300331131100
|
||||
010220000301314241214335313133422432322123354664326463436444322422342554355225140334421002113133121
|
||||
323101132001123022243353315252233331435562622453564455524652525652244413142424222440021003003130221
|
||||
311311300011420441113315524451532135232526456634245324454325625255644144511435413342301130211231301
|
||||
122330114303143110342335214315243456332354435254662545365545352556636544332142113343020330142302023
|
||||
022120000403423231542555223312544433353262526636242665353354342624542223253541435144031113311431220
|
||||
210013131013443325232155555522255445233525524424425466462465252544334662211253135515414212121223103
|
||||
122130234323200111421534352526522446635243456643673475346653325362454362443421552412233011444032132
|
||||
330230413401024335441342264233664326224445367753634776764473243636265344556415445523524224043114211
|
||||
020342003212232435413445263654334245243765543345436537434453757662242253666363442422244144403424000
|
||||
200102231042423341434316352256242653765564636564563755363577363456266625662553514113422123403421132
|
||||
313204040243524231344465644555626363733665445433637447335677545646763646633226445435325125112213414
|
||||
314103222004445425153443435336445733737355475744355366644536666633436334423645665121453234041020422
|
||||
241224100115215322523535566553547766677645474354634357364574375657645546622424324323251244433440201
|
||||
022222042544545521533326245235374365344376774543443767376646565377535776236535264522124353322203234
|
||||
422222135434133533655352463473735556656745548755787857555356377355447565365456463664354434453044312
|
||||
304324242134435426624362552443745545463386458858447758455754543677463336472433462334512421444332223
|
||||
341414135242433442655442346556355346658767857767584647675766884536373667347366462552211223152411402
|
||||
322422011132511352664233364365653466744454566746588468655774844685736565337465223255264314431430230
|
||||
230422221453335454423325334433457458687888455486757548466746647544834643335672463455634151341522302
|
||||
234004552353522225535427357745555646855484747845567786675574858868655476475453443665223324353452113
|
||||
020135314133142653352266355334757758775757788848887684458858675874884637537467525625364253131211244
|
||||
414342423551254236456446367655347867476487576757978699668748774646468564677435372565356631415154301
|
||||
402224514555445234247373353744455587885585976595966767878796785855864485334466564262266452143444311
|
||||
322114434454542333646465444736668764744886688767569596959858556668754886535574755434322662442212133
|
||||
121324243324423343546763375477766585857886776859668579795978997478645686674366773535335522313423220
|
||||
133542124333622654643366436564658876577978579997657798669999767568447887467776367522435455533321443
|
||||
023413415133262422437473376558558855786797675666795779995686567865485584745545375742263662533555543
|
||||
141153353554563662677655657576756468676875598877958956899955978897446555748753563362626454221131125
|
||||
325353321363522257537756588466744857658697678559699997698595865765578845586445367745536633643312255
|
||||
423213544666625365635544655675458885666985859697786876896858858797786874566466456657466442525434421
|
||||
111454444524556247634754788885848856779676996689987686878899758967589455644666556534542332454425232
|
||||
113454234223324274556335586767549686998856766879779799897977886877798476548873366444323624534235512
|
||||
413111246643442463347377577668885588996599677886898888866767856868795965878475573774545255562121514
|
||||
033322552545543547534354548647668766698879698968876698988768678695558875847754474335753623445451141
|
||||
033335136263443377434448478688978869869678786967679698969669778569788867674444636373445324354533414
|
||||
234114125435462653577777876855756557856867678669979986768879699797765796588455677467665646523542244
|
||||
315515242442526536477764768685998958898698776897898777978978889975778988546787635537642445246521555
|
||||
321543542424553344445665648775695579876967767799989797989877898976866779658748865436436245526532153
|
||||
214442166263264436546368554888589767787766679977779878789696679785859879648657647656345336454331514
|
||||
534225433653422444656547767677967556776977788979899998877878867678798578885766845756635543235613324
|
||||
451252264522467473463764566489668785797977788978898788799896886865858766846568667573775654463254212
|
||||
142243545346537474556565585866986596889698977988978988797896887869755867746847846457535246243622521
|
||||
314533543366656735447764644785876759686776988887899987977868668886569975674466755746757543333613415
|
||||
423155324556563534544657846546998786988679877979797897977866789679597759764485834747537363422511525
|
||||
111123232243256547763345885669578779768699999987898779978667968776659685647547563666543566442343212
|
||||
153351242236666565346454875568986796797687677988888979789886768978999686477777536735573656352555412
|
||||
323332424652563666766546867459698977996778977989988888888788678879875896444874453373545246666243111
|
||||
135523512363264534676375878685595968577686668988899788976766699895667985668547534554755246336443443
|
||||
532252346635325565376768676458557777667966786898889778979967688766768868568846557747445423253133325
|
||||
021423433266355547435457658778656599566767767766877768698699878975689884477647674353546424463554451
|
||||
143143223365543567635335747757587977786897796676679778966786689768589657474877567637754423223422312
|
||||
042415253643232575556737767785757788676996887999678977967666877589856675557885677334454634555223453
|
||||
234134135655336276745375664665486567958579869999988689769887997756966947584657365476724435655111251
|
||||
042425212462644477445435755454677877597667699897769689877689755868578567458576456463552232355231414
|
||||
354513445446645356573335466767579577676958688689866686776999686878859666766855753737445265524242214
|
||||
233154124332425336374475485444574569589885768789686679877995988778897787557646674666625354631424244
|
||||
242554311144536267576756377488488867896687566758869688757566767878568654674856637746343532221224535
|
||||
031352533424343666353537635778657888979797968869596858555897765778484557476745657576565652351431515
|
||||
244111523123546656444743447588484547797769687556999759895965969964878878867565456634442462655533330
|
||||
101154321124235234634644573645444776899979778958586696559589578574766767767776545323635556543324520
|
||||
230453243413346443656346633655876856466765588966595989676877687676564857856756335622566465554243444
|
||||
400115531525436425435363466676884457554568997656888965766988578885546646566546575455244664152151421
|
||||
121244523334642663334357574375756475655847758985795997565974854847688754735474744655256243422233523
|
||||
442124553352143426554554663364376844777584585568578895884475557584464677453543662566322652421252333
|
||||
121445542333545553333233367636337576575784548858744665868786757667467367567665363332432223545423200
|
||||
020321333225342646522423376435557446777478648478548458845546545678744437577337244622534425211350022
|
||||
041332232423124342256245433633577566478865647545565685666764666787764767576462433566522451433113043
|
||||
014424132244453224234546334667567447876654868784855884886878754645547664773756545644453424241524312
|
||||
414311054242342142224533466634464356437556445785767567866777856766576577644556443654324531342222310
|
||||
310322213415213433425552662577476354776577788877577647884464577437343437336643223244511135242014011
|
||||
300241033122121121456356264344335565375647366774864774858553747547334674624355256434534221515041124
|
||||
244113020144235342335234634564444633644736357543455335653765466354354346565443633362331511132134132
|
||||
143133204011342551536234336443376364333444577754334556634356574777657644433624432451425543542044012
|
||||
124214441344114214133244352626436376363654365447576564735347353654435326246226356243423532004304101
|
||||
101243244443555155315534544462433463654377635665747456733666473757525254363464365544115552421213312
|
||||
220422144420114253554354265345456453344337374375545645445347674334436455364526444454513431401002123
|
||||
313223311020451432455413454445642422634537364635666546754656735345535652356322545145325423121103202
|
||||
331004402420123535413315226646464442326356744477434645574333466622343266264444114525225333122240311
|
||||
112302121222114254552233452266654536466263462644653436655626223464363536324452444455541022040211131
|
||||
212012013423120023144244325334534664552523526224436442254665635246443333635121151334524401320433130
|
||||
001121341442114243125433441523554465523535244533322625264462365223623553532133143211423424102210003
|
||||
223220023212441130233151252342414632544243253526323465544536453355466344221452532544441122243331202
|
||||
312121212403143043222224331132453532666642654664652655433535463465343224212113542013034330243203021
|
||||
202012103340130001242425435444222111424542356345243653462563232352212415345354221301440242321032000
|
||||
212202110121021140441443523243344241514332562652664256563344623454345255222133212212024343023301122
|
||||
021010131200334014423400143154151315325512332544243346551323121315214235513143134101443433302011002
|
||||
122302321231131322434420345125245413215132313112255444513255422341524133353314114412224230231302110
|
||||
110111100102010040122344032453213533213254233521331414232113423512123251530432223244441332003202300
|
||||
200023022231020232023042313022141535414442413511535352414333413345343120402340033343211011203223002
|
||||
001120213231313130220231100314421411535333234424124253354254335222245404210032440401122303031121122
|
||||
011011030023132123022011022032214014533223521512511221453113132215230244324434210342210100311021222
|
||||
|
45
day_8/lexer.l
Normal file
45
day_8/lexer.l
Normal file
|
@ -0,0 +1,45 @@
|
|||
%{
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "parser.h"
|
||||
|
||||
%}
|
||||
|
||||
%option warn nodefault
|
||||
|
||||
/* makes the scanner terminate after reaching <<EOF>> instead of assuming a new input was provided */
|
||||
%option noyywrap
|
||||
/* disable some unused functionality, add scanner tracking */
|
||||
%option nounput noinput batch debug
|
||||
|
||||
/* gimme a reentrant parser (overkill but more pure) */
|
||||
%option reentrant
|
||||
|
||||
%option bison-bridge
|
||||
|
||||
|
||||
NL [\n]
|
||||
|
||||
/*general definitions*/
|
||||
NUM [0-9]
|
||||
|
||||
%%
|
||||
|
||||
{NL} { return NEWLINE; }
|
||||
|
||||
{NUM} {
|
||||
unsigned long num = strtoul(yytext, NULL, 10);
|
||||
yylval->num = num;
|
||||
return NUM;
|
||||
}
|
||||
|
||||
<<EOF>> {
|
||||
return END_OF_FILE;
|
||||
}
|
||||
. {
|
||||
printf("[error] Encountered unexpected token %s\n", yytext);
|
||||
return 0;
|
||||
}
|
||||
|
||||
%%
|
290
day_8/parser.y
Normal file
290
day_8/parser.y
Normal file
|
@ -0,0 +1,290 @@
|
|||
/* Require bison minimal version */
|
||||
%require "3.2"
|
||||
|
||||
/* write out a header file containing the token defines */
|
||||
%header
|
||||
|
||||
// Code for the header file generated by bison
|
||||
%code requires {
|
||||
typedef void* yyscan_t;
|
||||
|
||||
struct parser_state {
|
||||
/// Layout of the data: forest[row][col]
|
||||
unsigned short **forest;
|
||||
size_t rows;
|
||||
size_t cols;
|
||||
|
||||
unsigned short *current_line;
|
||||
/// for tracking the current position in a line during parsing
|
||||
size_t pos;
|
||||
size_t allocated;
|
||||
};
|
||||
}
|
||||
|
||||
// Code for the c file
|
||||
%{
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include "parser.h"
|
||||
#include "lexer.h"
|
||||
|
||||
void yyerror(struct parser_state* state, yyscan_t scanner, const char* msg) {
|
||||
(void)state;
|
||||
(void)scanner;
|
||||
fprintf(stderr, "\033[93mSyntax Error: %s\033[0m\n", msg);
|
||||
}
|
||||
%}
|
||||
|
||||
// define a reentrant parser
|
||||
%define api.pure
|
||||
|
||||
// enable parser tracing and detailed error messages (plus Lookahead Correction)
|
||||
%define parse.trace
|
||||
%define parse.error detailed
|
||||
%define parse.lac full
|
||||
|
||||
%lex-param { yyscan_t scanner }
|
||||
%parse-param { struct parser_state* state }
|
||||
%parse-param { yyscan_t scanner }
|
||||
|
||||
%union {
|
||||
unsigned long num;
|
||||
}
|
||||
|
||||
%start input
|
||||
%token NEWLINE
|
||||
%token <num> NUM
|
||||
%term END_OF_FILE
|
||||
|
||||
%%
|
||||
|
||||
input
|
||||
: treerow input
|
||||
| END_OF_FILE { return 0; }
|
||||
;
|
||||
|
||||
treerow
|
||||
: NUM treerow {
|
||||
if (state->pos >= state->allocated) {
|
||||
state->allocated += 10;
|
||||
state->current_line = realloc(state->current_line, state->allocated * sizeof(unsigned short));
|
||||
if (!state->current_line) {
|
||||
fprintf(stderr, "\033[91m[error] Ran out of memory\033[0m\n");
|
||||
YYABORT;
|
||||
}
|
||||
}
|
||||
|
||||
state->current_line[state->pos] = $1;
|
||||
state->pos++;
|
||||
}
|
||||
| NEWLINE {
|
||||
if (state->pos != 0) {
|
||||
state->forest = realloc(state->forest, (state->rows + 1) * sizeof(unsigned short *));
|
||||
if (!state->forest) {
|
||||
fprintf(stderr, "\033[91m[error] Ran out of memory\033[0m\n");
|
||||
YYABORT;
|
||||
}
|
||||
|
||||
// resize the current line if necessary
|
||||
if (state->allocated > state->pos) {
|
||||
state->current_line = realloc(state->current_line, state->pos * sizeof(unsigned short));
|
||||
// cannot really fail but oh well
|
||||
if (!state->current_line) {
|
||||
fprintf(stderr, "\033[91m[error] Ran out of memory\033[0m\n");
|
||||
YYABORT;
|
||||
}
|
||||
}
|
||||
|
||||
if (state->pos != state->cols) {
|
||||
if (state->cols != 0) {
|
||||
fprintf(stderr, "\033[91m[error] Column size has changed mid-parse\033[0m\n");
|
||||
YYERROR;
|
||||
}
|
||||
|
||||
state->cols = state->pos;
|
||||
}
|
||||
|
||||
// write the current line to the forest
|
||||
state->forest[state->rows] = state->current_line;
|
||||
state->rows++;
|
||||
|
||||
// initialize a new row
|
||||
state->allocated = state->cols;
|
||||
state->pos = 0;
|
||||
state->current_line = calloc(state->allocated, sizeof(unsigned short));
|
||||
|
||||
if (!state->current_line) {
|
||||
fprintf(stderr, "\033[91m[error] Ran out of memory\033[0m\n");
|
||||
YYABORT;
|
||||
}
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
%%
|
||||
|
||||
|
||||
unsigned long compute_scenic_score(struct parser_state *state, size_t row, size_t col) {
|
||||
unsigned short height = state->forest[row][col];
|
||||
|
||||
unsigned long up = 0;
|
||||
for (int r = row - 1; r >= 0; r--) {
|
||||
up++;
|
||||
if (state->forest[r][col] >= height) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long down = 0;
|
||||
for (size_t r = row + 1; r < state->rows; r++) {
|
||||
down++;
|
||||
if (state->forest[r][col] >= height) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long left = 0;
|
||||
for (int c = col - 1; c >= 0; c--) {
|
||||
left++;
|
||||
if (state->forest[row][c] >= height) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long right = 0;
|
||||
for (size_t c = col + 1; c < state->cols; c++) {
|
||||
right++;
|
||||
if (state->forest[row][c] >= height) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return up * down * left * right;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
struct parser_state *state = calloc(1, sizeof(struct parser_state));
|
||||
if (!state) {
|
||||
fprintf(stderr, "\033[91m[error] Ran out of memory\033[0m\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
state->allocated = 100;
|
||||
state->current_line = calloc(state->allocated, sizeof(unsigned short));
|
||||
if (!state->current_line) {
|
||||
fprintf(stderr, "\033[91m[error] Ran out of memory\033[0m\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
yyscan_t scanner;
|
||||
if (yylex_init(&scanner)) {
|
||||
fprintf(stderr, "\033[91m[error] Could not initialize lexer\033[0m\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (yyparse(state, scanner)) {
|
||||
// TODO: Error handling https://www.gnu.org/software/bison/manual/html_node/Parser-Function.html
|
||||
// error during parse occured
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
yylex_destroy(scanner);
|
||||
|
||||
// task 1
|
||||
// create a bitmap marking counted visible trees
|
||||
bool **bitmap = calloc(state->rows, sizeof(bool *));
|
||||
if (!bitmap) {
|
||||
fprintf(stderr, "\033[91m[error] Ran out of memory\033[0m\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
for (size_t i = 0; i < state->rows; i++) {
|
||||
bitmap[i] = calloc(state->cols, sizeof(bool));
|
||||
if (!bitmap[i]) {
|
||||
fprintf(stderr, "\033[91m[error] Ran out of memory\033[0m\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
// count all outer rows and cols as visible
|
||||
unsigned long visible = 0;
|
||||
|
||||
for (size_t c = 0; c < state->cols; c++) {
|
||||
unsigned short tallest = state->forest[0][c];
|
||||
bitmap[0][c] = true;
|
||||
visible++;
|
||||
// top->down
|
||||
for (size_t r = 0; r < (state->rows - 1); r++) {
|
||||
if (state->forest[r][c] > tallest) {
|
||||
tallest = state->forest[r][c];
|
||||
if (!bitmap[r][c]) {
|
||||
visible++;
|
||||
bitmap[r][c] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// bottom->up
|
||||
tallest = state->forest[state->rows - 1][c];
|
||||
visible++;
|
||||
bitmap[state->rows - 1][c] = true;
|
||||
for (size_t r = state->rows - 1; r > 0; r--) {
|
||||
if (state->forest[r][c] > tallest) {
|
||||
tallest = state->forest[r][c];
|
||||
if (!bitmap[r][c]) {
|
||||
visible++;
|
||||
bitmap[r][c] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// move through individual rows
|
||||
for (size_t r = 0; r < state->rows; r++) {
|
||||
unsigned short tallest = state->forest[r][0];
|
||||
if (!bitmap[r][0]) {
|
||||
bitmap[r][0] = true;
|
||||
visible++;
|
||||
}
|
||||
// left->right
|
||||
for (size_t c = 0; c < (state->cols - 1); c++) {
|
||||
if (state->forest[r][c] > tallest) {
|
||||
tallest = state->forest[r][c];
|
||||
if (!bitmap[r][c]) {
|
||||
visible++;
|
||||
bitmap[r][c] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// right->left
|
||||
tallest = state->forest[r][state->cols - 1];
|
||||
if (!bitmap[r][state->cols - 1]) {
|
||||
bitmap[r][state->cols - 1] = true;
|
||||
visible++;
|
||||
}
|
||||
for (size_t c = state->cols - 1; c > 0; c--) {
|
||||
if (state->forest[r][c] > tallest) {
|
||||
tallest = state->forest[r][c];
|
||||
if (!bitmap[r][c]) {
|
||||
visible++;
|
||||
bitmap[r][c] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("Visible trees: %zu\n", visible);
|
||||
|
||||
unsigned long best = 0;
|
||||
for (size_t r = 0; r < state->rows; r++) {
|
||||
for (size_t c = 0; c < state->cols; c++) {
|
||||
unsigned long tmp = compute_scenic_score(state, r, c);
|
||||
if (tmp > best) {
|
||||
best = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("Best scenic score: %zu\n", best);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in a new issue