Просмотр исходного кода

day 6 incomplete attempt, day 5 part 2

master
red 4 лет назад
Родитель
Сommit
f5e4b74624
4 измененных файлов: 200 добавлений и 43 удалений
  1. +2
    -1
      CMakeLists.txt
  2. +1
    -1
      day5.c
  3. +91
    -0
      day6.c
  4. +106
    -41
      intcode.c

+ 2
- 1
CMakeLists.txt Просмотреть файл

@@ -7,4 +7,5 @@ add_executable(day1 day1.c)
add_executable(day2 day2.c)
add_executable(day3 day3.c)
add_executable(day4 day4.c)
add_executable(day5 day5.c intcode.c)
add_executable(day5 day5.c intcode.c)
add_executable(day6 day6.c)

+ 1
- 1
day5.c Просмотреть файл

@@ -9,7 +9,7 @@
int main(int argc, char **argv) {
char* filename = argv[1];
intcode* v = read_file(filename, 2048);
int input[1] = { 1 };
int input[1] = { 5 };
v->input_tape = input;
run(v);
}

+ 91
- 0
day6.c Просмотреть файл

@@ -0,0 +1,91 @@
//
// Created by red on 07/12/19.
//

#include <stdio.h>
#include <stdlib.h>

#define CHUNK_SIZE 16
typedef struct node {
int label;
struct node** children;
size_t num_children;
} node;

typedef struct forest {
int* list_labels; // list of all node labels that exist somewhere in the tree
size_t num_nodes; // amount of nodes
struct node** trees;
size_t num_trees;
} forest;

//return a zero-initialized node
node* init_node(int label) {
node* v = malloc(sizeof(node));
v->num_children = 0;
v->children = calloc(CHUNK_SIZE, sizeof(node*));
v->label = label;
return v;
}

void add(node* head, node* child, int label_parent) {
if (head->label == label_parent) {
if (head->num_children >= CHUNK_SIZE) printf("Max number of children reached, array reallocation not implemented\n");
head->children[head->num_children] = child;
head->num_children++;
} else for (size_t i = 0; i < head->num_children; i++) {
add(head->children[i], child, label_parent);
}
}

void print_tree(node* head) {
if (head->num_children == 0) {
printf("Node %x, no children\n", head->label); return;
}
printf("Children of node %x:", head->label);
for (size_t i = 0; i < head->num_children; i++) {
printf(" %x", head->children[i]->label);
}
printf("\n");
for (size_t i = 0; i < head->num_children; i++) {
print_tree(head->children[i]);
}
}

node* read_file(char* filename) {
FILE* file = fopen(filename, "r");
char desc_str[7];
fscanf(file, "%s", desc_str);
int label_parent = (desc_str[0] << 16) + (desc_str[1] << 8) + desc_str[2];
int label = (desc_str[4] << 16) + (desc_str[5] << 8) + desc_str[6];
node* head = init_node(label_parent);
add(head, init_node(label), label_parent);
for (;;) {
if (fscanf(file, "%s", desc_str) == EOF) break;
label_parent = (desc_str[0] << 16) + (desc_str[1] << 8) + desc_str[2];
label = (desc_str[4] << 16) + (desc_str[5] << 8) + desc_str[6];
add(head, init_node(label), label_parent);
if (head->label == label) {
node* nhead = init_node(label_parent);
add(nhead, head, label_parent);
head = nhead;
}
}
return head;
}

int count_nodes(node* head, int depth) {
int sum = depth;
for (size_t i = 0; i < head->num_children; i++) {
sum += count_nodes(head->children[i], depth+1);
}
return sum;
}

int main(int argc, char **argv) {
char* filename = argv[1];
node* head = read_file(filename);
int orbits = count_nodes(head, 0);
print_tree(head);
printf("no. orbits: %d\n", orbits);
}

+ 106
- 41
intcode.c Просмотреть файл

@@ -49,57 +49,122 @@ void ival_print(ival v) {
}
}

int power (int base, int pow) {
if (pow <= 0) return 1;
else return base*power(base,pow-1);
}

int* get_operands (intcode* m, size_t num_operands) {
int* operands = calloc(num_operands, sizeof(int));
int opcode = m->tape[m->index] / 100;
for (size_t i = 0; i < num_operands; i++) {
int addr_mode = opcode % 10;
opcode = opcode / 10;
int v = 0;
if (addr_mode == 0) {
v = m->tape[m->tape[m->index+i+1]];
}
else v = m->tape[m->index+i+1];
operands[i] = v;
}
return operands;
}

ival op_add (intcode* m) {
int* operands = get_operands(m, 2);
m->tape[m->tape[m->index+3]] = operands[0] + operands[1];
m->index += 4;
free((void*) operands);
return cont_val();
}

ival op_mul (intcode* m) {
int* operands = get_operands(m, 2);
m->tape[m->tape[m->index+3]] = operands[0] * operands[1];
m->index += 4;
free((void*) operands);
return cont_val();
}

ival op_in (intcode* m) {
int i = m->tape[m->index+1];
m->index += 2;
m->tape[i] = m->input_tape[0];
m->input_tape = m->input_tape+1;
return cont_val();
}

ival op_out (intcode* m) {
int* operands = get_operands(m, 1);
m->index += 2;
int v = operands[0];
free((void*) operands);
return out_val(v);
}

ival op_jnz (intcode* m) {
int* operands = get_operands(m, 2);
if (operands[0] != 0) {
m->index = (size_t) operands[1];
} else {
m->index += 3;
}
return cont_val();
}

ival op_jez (intcode* m) {
int* operands = get_operands(m, 2);
if (operands[0] == 0) {
m->index = (size_t) operands[1];
} else {
m->index += 3;
}
return cont_val();
}

ival op_lt (intcode* m) {
int* operands = get_operands(m,2);
int result;
if (operands[0] < operands[1]) {
result = 1;
} else result = 0;
m->tape[m->tape[m->index+3]] = result;
m->index += 4;
return cont_val();
}

ival op_eq (intcode* m) {
int* operands = get_operands(m,2);
int result;
if (operands[0] == operands[1]) {
result = 1;
} else result = 0;
m->tape[m->tape[m->index+3]] = result;
m->index += 4;
return cont_val();
}

ival step (intcode* m) {
int opcode = m->tape[m->index];
int addr_mode[2];
addr_mode[0] = (opcode / 100) % 10;
addr_mode[1] = (opcode / 1000) % 10;
opcode = opcode % 100;
switch (opcode) {
case 99: return end_val();
case 4: {
int v;
if (addr_mode[0] == 0) { v = m->tape[m->tape[m->index+1]]; }
else { v = m->tape[m->index+1]; }
m->index += 2;
return out_val(v);
}
case 3: {
int i = m->tape[m->index+1];
m->index += 2;
m->tape[i] = m->input_tape[0];
m->input_tape = m->input_tape+1;
return cont_val();
}
default: {
int a;
int b;
if (opcode != 1 && opcode != 2) return err_val(IERR_BAD_OP);
if (addr_mode[0] == 0) { a = m->tape[m->tape[m->index+1]]; }
else { a = m->tape[m->index+1]; }
if (addr_mode[1] == 0) { b = m->tape[m->tape[m->index+2]]; }
else { b = m->tape[m->index+2]; }
switch (opcode) {
case 1: {
m->tape[m->tape[m->index+3]] = a+b;
m->index += 4;
break;
}
case 2: {
m->tape[m->tape[m->index+3]] = a*b;
m->index += 4;
break;
}
}
}
return cont_val();
case 1: return op_add(m);
case 2: return op_mul(m);
case 3: return op_in(m);
case 4: return op_out(m);
case 5: return op_jnz(m);
case 6: return op_jez(m);
case 7: return op_lt(m);
case 8: return op_eq(m);
default: return err_val(IERR_BAD_OP);
}
}

ival run (intcode* m) {
for (;;) {
size_t i = m->index;
printf("DEBUG: next 4 values: %d %d %d %d\n", m->tape[i], m->tape[i+1], m->tape[i+2], m->tape[i+3]);
//size_t i = m->index;
//printf("DEBUG: next 4 values: %d %d %d %d\n", m->tape[i], m->tape[i+1], m->tape[i+2], m->tape[i+3]);
ival v = step(m);
switch (v.type) {
case IVAL_ERR:

Загрузка…
Отмена
Сохранить