Kaynağa Gözat

moving stuff, day 3

master
red 4 yıl önce
ebeveyn
işleme
aaafbc8018
4 değiştirilmiş dosya ile 144 ekleme ve 2 silme
  1. +3
    -2
      CMakeLists.txt
  2. +0
    -0
      day1.c
  3. +0
    -0
      day2.c
  4. +141
    -0
      day3.c

+ 3
- 2
CMakeLists.txt Dosyayı Görüntüle

@@ -3,5 +3,6 @@ project(aoc2019 C)

set(CMAKE_C_STANDARD 99)

add_executable(day1 day1/day1.c)
add_executable(day2 day2/day2.c)
add_executable(day1 day1.c)
add_executable(day2 day2.c)
add_executable(day3 day3.c)

day1/day1.c → day1.c Dosyayı Görüntüle


day2/day2.c → day2.c Dosyayı Görüntüle


+ 141
- 0
day3.c Dosyayı Görüntüle

@@ -0,0 +1,141 @@
//
// Created by red on 03/12/19.
//

#include <stdio.h>
#include <stdlib.h>
#include <zconf.h>
#include <string.h>
#include <stdbool.h>

struct Point {
int x;
int y;
};

#ifndef ORIGIN
#define ORIGIN (struct Point){.x=0,.y=0,}
#endif

//given a point, a direction and a distance, return the point that's that distance in the given direction
struct Point get_pt(char dir, int delta, struct Point loc) {
struct Point dloc;
switch(dir) {
case 'R': dloc = (struct Point){
.x = loc.x + delta,
.y = loc.y,
}; break;
case 'L': dloc = (struct Point){
.x = loc.x - delta,
.y = loc.y,
}; break;
case 'U': dloc = (struct Point){
.x = loc.x,
.y = loc.y + delta,
}; break;
case 'D': dloc = (struct Point){
.x = loc.x,
.y = loc.y - delta,
}; break;
default: dloc = loc;
}
return dloc;
}

//takes four points, checks if the line a1 - a2 intersects b1 - b2, returns intersection point if yes, origin otherwise
struct Point intersects(struct Point a1, struct Point a2, struct Point b1, struct Point b2) {
bool a_isvert = (a1.x == a2.x);
bool b_isvert = (b1.x == b2.x);
if (a_isvert == b_isvert) { //no collision if lines are both vertical or both horizontal
return ORIGIN;
}
// if b is vertical, call the function again with the operands reversed. we want to assume a is vertical
if (b_isvert) {
return intersects(b1, b2, a1, a2);
}
// determine the smaller and bigger x-coord of b1 & b2. same for y-coord of a1 & a2
int b_lx = (b1.x < b2.x) ? b1.x : b2.x;
int b_gx = (b1.x < b2.x) ? b2.x : b1.x;
int a_ly = (a1.y < a2.y) ? a1.y : a2.y;
int a_gy = (a1.y < a2.y) ? a2.y : a1.y;
// if the x-coord of a1 is somewhere between b1 and b2, and the y-coord of b1 is somewhere between a1 and a2
// then the lines must intersect.
if (a1.x > b_lx && a1.x < b_gx && b1.y > a_ly && b1.y < a_gy) {
//return the manhattan distance of the intersection
return (struct Point){
.x = a1.x,
.y = b1.y,
};
}
//if the end of the function is reached, the lines don't intersect.
return ORIGIN;
}

//returns the manhattan distance between two points
int manhattan(struct Point a, struct Point b) {
return (abs(a.x - b.x) + abs(a.y - b.y));
}

int main() {
//allocate an input string, and two arrays for input points
//we don't know the exact length of the arrays but we know it's smaller than 400
char* input_raw = calloc(1500,sizeof(char));
scanf("%s", input_raw);
struct Point* a = calloc(400, sizeof(struct Point**));
struct Point* b = calloc(400, sizeof(struct Point**));
//Both a and b should start at the origin.
a[0] = ORIGIN;
b[0] = ORIGIN;
size_t a_index = 1;
size_t b_index = 1;
char* ptr = input_raw;
while (*ptr != 0) { //read till null
char dir;
int delta;
int num_read;
sscanf(ptr, "%c%d%n", &dir, &delta, &num_read);
a[a_index] = get_pt(dir, delta, a[a_index-1]);
a_index++;
ptr += num_read + 1; // skip the number we just read, and the separator
}
//clear the input buffer
memset((void*) input_raw, 0, sizeof(char)*1500);
//scan the second input sequence, reset var ptr to the beginning of the string, reset location to the origin
scanf("%s", input_raw);
ptr = input_raw;
while (*ptr != 0) { //read until null
char dir;
int delta;
int num_read;
sscanf(ptr, "%c%d%n", &dir, &delta, &num_read);
b[b_index] = get_pt(dir, delta, b[b_index-1]);
b_index++;
ptr += num_read + 1; // skip the number we just read and the separator
}
free((void*) input_raw); // we don't need the int dist = 0;raw input anymore
int min = INT_MAX;
int min_delay = INT_MAX;
int a_delay = 0;
for (size_t i = 0; i < a_index; i++) {
}
for (size_t i = 0; i < b_index; i++) {
}
//iterate over each combination of two edges in array of points a and b
for (size_t i = 1; i < a_index; i++) {
int b_delay = 0;
for (size_t j = 1; j < b_index; j++) {
struct Point pt = intersects(a[i-1], a[i], b[j-1], b[j]);
int dist = manhattan(ORIGIN, pt);
if (dist > 0) {
if (dist < min) min = dist;
int delay = a_delay + b_delay + manhattan(pt, a[i-1]) + manhattan(pt, b[j-1]);
if (delay < min_delay) min_delay = delay;
}
b_delay += manhattan(b[j-1], b[j]);
}
a_delay += manhattan(a[i-1], a[i]);
}
printf("Min. intersection distance from origin: %d\n"
"Min. intersection distance on lines: %d\n", min, min_delay);
return EXIT_SUCCESS;
}

Yükleniyor…
İptal
Kaydet