Skip to content

Instantly share code, notes, and snippets.

@paulsmith
Last active December 2, 2016 04:58
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 paulsmith/6f0fab3e995d667b707f37efb7b9dcfc to your computer and use it in GitHub Desktop.
Save paulsmith/6f0fab3e995d667b707f37efb7b9dcfc to your computer and use it in GitHub Desktop.
day 1 of 2016 advent of code solution, parts 1 & 2
for http://adventofcode.com/2016/day/1
$ # copy day 1 puzzle input to file
$ make day1
$ ./day1 < day1.input
# part 1 output
$ touch day1.c && make CFLAGS=-DPART2 day1
$ ./day1 < day1.input
# part 2 output
/* Copyright (c) 2016 Paul Smith <paulsmith@pobox.com> */
/* Permission is hereby granted, free of charge, to any person obtaining a copy */
/* of this software and associated documentation files (the "Software"), to deal */
/* in the Software without restriction, including without limitation the rights */
/* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell */
/* copies of the Software, and to permit persons to whom the Software is */
/* furnished to do so, subject to the following conditions: */
/* The above copyright notice and this permission notice shall be included in all */
/* copies or substantial portions of the Software. */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR */
/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, */
/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE */
/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER */
/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, */
/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */
/* SOFTWARE. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void die(char *msg)
{
fprintf(stderr, "ERROR: %s", msg);
exit(1);
}
typedef struct coord {
int x;
int y;
} coord;
typedef enum dir {
NORTH,
EAST,
SOUTH,
WEST
} dir;
typedef struct player {
coord coord;
dir dir;
} player;
void init_player(player *p)
{
p->dir = NORTH;
p->coord.x = 0;
p->coord.y = 0;
}
typedef enum turn {
LEFT = -1,
RIGHT = 1
} turn;
typedef struct seq {
turn turn;
int blocks;
} seq;
typedef struct sequences {
seq *seqs;
int len;
int cap;
} sequences;
void init_sequences(sequences *s)
{
s->seqs = malloc(sizeof(seq));
s->len = 0;
s->cap = 1;
}
void print_sequences(sequences *s)
{
for (int i = 0; i < s->len; i++) {
char turn;
switch (s->seqs[i].turn) {
case LEFT: turn = 'L'; break;
case RIGHT: turn = 'R'; break;
}
printf("TURN: %c BLOCKS: %d\n", turn, s->seqs[i].blocks);
}
}
void parse_seq(char *s, seq *seq)
{
switch (s[0]) {
case 'L': seq->turn = LEFT; break;
case 'R': seq->turn = RIGHT; break;
}
seq->blocks = atoi(s+1);
}
char *get_line()
{
char *line = NULL;
size_t linecap = 0;
ssize_t linelen;
if ((linelen = getline(&line, &linecap, stdin)) == -1) {
die("getting line from stdin");
}
line[linelen] = '\0'; // trim off newline
return line;
}
void make_sequences(char *input, sequences *s)
{
char *seqstr;
while ((seqstr = strsep(&input, ", ")) != NULL) {
if (strcmp(seqstr, "") != 0) {
if (s->len == s->cap) {
s->seqs = realloc(s->seqs, sizeof(seq) * (s->cap *= 2));
}
parse_seq(seqstr, &s->seqs[s->len++]);
}
}
}
#ifdef DEBUG
#define debug_print_player_seq(player, seq) \
printf("TURN: %2d BLOCKS: %3d FACING: %d X: %3d Y: %3d\n", \
seq.turn, seq.blocks, \
p->dir, p->coord.x, p->coord.y)
#else
#define debug_print_player_seq(player, seq)
#endif
#define MAXCOORD 1000
char visited[MAXCOORD][MAXCOORD];
void move_player(player *p, sequences *s)
{
for (int i = 0; i < s->len; i++) {
seq seq = s->seqs[i];
p->dir = (p->dir + seq.turn) % 4;
int *c; // coord to update
char sign;
switch (p->dir) {
case NORTH:
c = &p->coord.y;
sign = 1;
break;
case EAST:
c = &p->coord.x;
sign = 1;
break;
case SOUTH:
c = &p->coord.y;
sign = -1;
break;
case WEST:
c = &p->coord.x;
sign = -1;
break;
}
for (int j = 0; j < seq.blocks; j++) {
*c = *c + sign;
visited[p->coord.x+(MAXCOORD/2)][p->coord.y+(MAXCOORD/2)]++;
#ifdef PART2
if (visited[p->coord.x+(MAXCOORD/2)][p->coord.y+(MAXCOORD/2)] == 2) {
printf("VISITED %d/%d TWICE\n", p->coord.x, p->coord.y);
return;
}
#endif
}
debug_print_player_seq(p, seq);
}
}
int taxicab_dist(coord c)
{
return abs(c.x) + abs(c.y);
}
void init_visited()
{
for (int i = 0; i < MAXCOORD; i++) {
for (int j = 0; j < MAXCOORD; j++) {
visited[i][j] = 0;
}
}
}
int main(int argc, char **argv)
{
sequences s;
player p;
char *line = get_line();
init_visited();
init_sequences(&s);
make_sequences(line, &s);
free(line);
init_player(&p);
move_player(&p, &s);
int blocks_away = taxicab_dist(p.coord);
printf("blocks away: %d\n", blocks_away);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment