-
-
Save pv2b/900d35020ea06a280d4e0bcd601f9b99 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* solution to advent of code 2020, day 5, by pv2b */ | |
#include <stdio.h> | |
#include <string.h> | |
#include <limits.h> | |
/* based on the seat codes, we know there are a maximum of 1024 rows */ | |
#define NUM_ROWS 1024 | |
/* gets the row from a seatID */ | |
#define ROW(id) ((id) >> 3) | |
/* gets the column from a seatID */ | |
#define COL(id) ((id) & 0x07) | |
/* constructs a seatID from a row and column */ | |
#define SEAT_ID(r, c) (((r) << 3) | ((c) & 0x07)) | |
/* reads and decodes a single seat ID from STDIN, | |
* or returns -1 if EOF or error | |
*/ | |
int read_one_seat(void) { | |
int seatID = 0; | |
for (int bit = 0x200; bit != 0x04; bit >>= 1) { | |
switch (getchar()) { | |
case 'F': break; | |
case 'B': seatID |= bit; break; | |
default: return -1; | |
} | |
} | |
for (int bit = 0x04; bit != 0x00; bit >>= 1) { | |
switch (getchar()) { | |
case 'L': break; | |
case 'R': seatID |= bit; break; | |
default: return -1; | |
} | |
} | |
if (getchar() != '\n') return -1; | |
return seatID; | |
} | |
int main (int argc, char *argv[]) { | |
/* based on the seat codes, we know there are exactly 8 seats per row. | |
* So every char represents a row, with each bit in thie char | |
* representing one seat, with 1 for occupied, and 0 for free. | |
*/ | |
char seatMap[NUM_ROWS]; | |
int seatID; | |
int minSeatID = INT_MAX; | |
int maxSeatID = INT_MIN; | |
int emptySeatID; | |
/* fills in seatMap after initializing it, determining the minimum | |
* and maximum seat ID as we go | |
*/ | |
memset(seatMap, 0, NUM_ROWS); | |
while ((seatID = read_one_seat()) != -1) { | |
seatMap[ROW(seatID)] |= 1 << COL(seatID); | |
if (seatID < minSeatID) minSeatID = seatID; | |
if (seatID > maxSeatID) maxSeatID = seatID; | |
} | |
printf("part 1: %d\n", maxSeatID); | |
/* the puzzle tells us that we're not sitting on the first or last | |
* occupied row. so.... let's find the first occupied row, and start | |
* looking at the first seat of the row after that. | |
*/ | |
for (int row = ROW(minSeatID) + 1; row < NUM_ROWS; row++) { | |
char currentRow = seatMap[row]; | |
/* skip this row if it's full */ | |
if (currentRow == 0xFF) continue; | |
/* look for empty seats */ | |
for (int col = 0; col < 7; col++) { | |
if ((currentRow & (1 << col)) == 0) { | |
/* found empty seat */ | |
emptySeatID = SEAT_ID(row, col); | |
printf("part 2: %d\n", emptySeatID); | |
return 0; | |
} | |
} | |
} | |
printf("No empty seat found!\n"); | |
return 1; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment