Skip to content

Instantly share code, notes, and snippets.

@pv2b

pv2b/day5.c Secret

Created December 5, 2020 14:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pv2b/900d35020ea06a280d4e0bcd601f9b99 to your computer and use it in GitHub Desktop.
Save pv2b/900d35020ea06a280d4e0bcd601f9b99 to your computer and use it in GitHub Desktop.
/* 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