I've been reading the Rust versions of this, and just because I'm kinda tired, I thought I'd just throw together something in C.
Here's my 15 minute effort to solve the 2016 Advent of Code Day 1, Part 1 problem. The task is to follow some directions (90° turns and steps on a rectilinear grid), then state the rectilinear distance from the origin.
// http://adventofcode.com/2016/day/1
//
// "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\x86_amd64\vcvarsx86_amd64.bat" to setup
// cl day01.c to compile
// day01.exe to run
const char * input = "R4, R5, L5, L5, L3, R2, R1, R1, L5, R5, R2, L1, L3, L4, R3, L1, L1, R2, R3, R3, R1, L3, L5, R3, R1, L1, R1, R2, L1, L4, L5, R4, R2, L192, R5, L2, R53, R1, L5, R73, R5, L5, R186, L3, L2, R1, R3, L3, L3, R1, L4, L2, R3, L5, R4, R3, R1, L1, R5, R2, R1, R1, R1, R3, R2, L1, R5, R1, L5, R2, L2, L4, R3, L1, R4, L5, R4, R3, L5, L3, R4, R2, L5, L5, R2, R3, R5, R4, R2, R1, L1, L5, L2, L3, L4, L5, L4, L5, L1, R3, R4, R5, R3, L5, L4, L3, L1, L4, R2, R5, R5, R4, L2, L4, R3, R1, L2, R5, L5, R1, R1, L1, L5, L5, L2, L1, R5, R2, L4, L1, R4, R3, L3, R1, R5, L1, L4, R2, L3, R5, R3, R1, L3";
enum {N,E,S,W} direction = N;
int translate_ns[4] = {1,0,-1,0};
int translate_ew[4] = {0,1,0,-1};
int main()
{
int ns = 0;
int ew = 0;
int pos = 0;
char digit = 0;
int walk = 0;
while (input[pos]!='\0') {
char turn = input[pos++];
if (turn=='R') direction = (direction+1) % 4;
if (turn=='L') direction = (direction+3) % 4; // bwahahah
walk = 0;
while ((digit=input[pos++])!='\0' && isdigit(digit)) walk = walk*10+digit-'0';
ns += walk*translate_ns[direction];
ew += walk*translate_ew[direction];
while (input[pos] && (input[pos]==',' || input[pos]==' ')) pos++;
}
printf("Distance to Easter Bunny HQ is: %d",abs(ns)+abs(ew));
}
Output is:
C:\Workarea\AdventOfCode\Day01>day01.exe
Distance to Easter Bunny HQ is: 250
C:\Workarea\AdventOfCode\Day01>
I know it's a bit evil, and this isn't how I'd program at work, but it's nice to let my hair down occasionally. Fire away!
And here's part 2! This was harder and I had to iterate a little to get the answer to come out.
I had to add a new routine to detect a crossing over the previous route. Of course the easiest way with the in-place solution for part 1 is just to use the last added position as where we're coming from, then iterate through the previous positions and detect when we cross.
I made the passed positions pointer to int so we can update to the crossing point when needed, and still return 1 to break out of reading the routing instructions.
There's obviously a much better and shorter solution lurking in there somewhere, but at least I have something that works.
// http://adventofcode.com/2016/day/1
//
// "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\x86_amd64\vcvarsx86_amd64.bat" to setup
// cl day01.c to compile
// day01.exe to run
const char * input = "R4, R5, L5, L5, L3, R2, R1, R1, L5, R5, R2, L1, L3, L4, R3, L1, L1, R2, R3, R3, R1, L3, L5, R3, R1, L1, R1, R2, L1, L4, L5, R4, R2, L192, R5, L2, R53, R1, L5, R73, R5, L5, R186, L3, L2, R1, R3, L3, L3, R1, L4, L2, R3, L5, R4, R3, R1, L1, R5, R2, R1, R1, R1, R3, R2, L1, R5, R1, L5, R2, L2, L4, R3, L1, R4, L5, R4, R3, L5, L3, R4, R2, L5, L5, R2, R3, R5, R4, R2, R1, L1, L5, L2, L3, L4, L5, L4, L5, L1, R3, R4, R5, R3, L5, L4, L3, L1, L4, R2, R5, R5, R4, L2, L4, R3, R1, L2, R5, L5, R1, R1, L1, L5, L5, L2, L1, R5, R2, L4, L1, R4, R3, L3, R1, R5, L1, L4, R2, L3, R5, R3, R1, L3";
#define min(x,y) ((x)<(y) ? (x) : (y))
#define max(x,y) ((x)>(y) ? (x) : (y))
enum {N,E,S,W} direction = N;
int translate_ns[4] = {1,0,-1,0};
int translate_ew[4] = {0,1,0,-1};
int visited[2000];
int visited_count = 1;
int check_add_visited(int* ns, int* ew)
{
int nsp = visited[(visited_count-1)*2];
int ewp = visited[(visited_count-1)*2+1];
// start from 1 so we have a previous entry to check
int prevns = visited[0];
int prevew = visited[1];
for (int i=1;i<visited_count;++i) {
// get the prev and next ns,ew to check
int nextns = visited[i*2];
int nextew = visited[i*2+1];
if (prevns==nextns && ewp==*ew && min(*ns,nsp)<prevns && max(*ns,nsp)>prevns
&& min(prevew,nextew)<*ew && max(prevew,nextew)>*ew) {
// found a crossing at prevns,ew
*ns = prevns;
return 1;
}
if (prevew==nextew && nsp==*ns && min(*ew,ewp)<prevew && max(*ew,ewp)>prevew
&& min(prevns,nextns)<*ns && max(prevns,nextns)>*ns ) {
// found a crossing at ns,prevew
*ew = prevew;
return 1;
}
prevns = nextns;
prevew = nextew;
}
visited[visited_count*2] = *ns;
visited[visited_count*2+1] = *ew;
visited_count++;
return 0;
}
int main()
{
int ns = 0;
int ew = 0;
int pos = 0;
char digit = 0;
int walk = 0;
visited[0] = visited[1] = 0;
while (input[pos]!='\0') {
char turn = input[pos++];
if (turn=='R') direction = (direction+1) % 4;
if (turn=='L') direction = (direction+3) % 4; // bwahahah
walk = 0;
while ((digit=input[pos++])!='\0' && isdigit(digit)) walk = walk*10+digit-'0';
ns += walk*translate_ns[direction];
ew += walk*translate_ew[direction];
if (check_add_visited(&ns,&ew)) break;
while (input[pos] && (input[pos]==',' || input[pos]==' ')) pos++;
}
printf("Distance to Easter Bunny HQ is: %d",abs(ns)+abs(ew));
}
The output from part 2 is:
C:\Workarea\AdventOfCode\Day01>day01.exe
Distance to Easter Bunny HQ is: 151
C:\Workarea\AdventOfCode\Day01>