diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..177f7cb --- /dev/null +++ b/.editorconfig @@ -0,0 +1,11 @@ +root = true + +[*] +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +max_line_length = 90 + +[{*.c,*.go}] +indent_style = tab +indent_size = 4 diff --git a/modernc/01.1/.gitignore b/modernc/01/.gitignore similarity index 100% rename from modernc/01.1/.gitignore rename to modernc/01/.gitignore diff --git a/modernc/01.1/bad.c b/modernc/01/bad.c similarity index 100% rename from modernc/01.1/bad.c rename to modernc/01/bad.c diff --git a/modernc/01.1/getting-started.c b/modernc/01/getting-started.c similarity index 100% rename from modernc/01.1/getting-started.c rename to modernc/01/getting-started.c diff --git a/modernc/03/.gitignore b/modernc/03/.gitignore new file mode 100644 index 0000000..946b089 --- /dev/null +++ b/modernc/03/.gitignore @@ -0,0 +1 @@ +challenge-1 diff --git a/modernc/03/array.c b/modernc/03/array.c new file mode 100644 index 0000000..2918b4b --- /dev/null +++ b/modernc/03/array.c @@ -0,0 +1,90 @@ +#include +#include "array.h" + +void IntArray_new(IntArray* a, size_t size) { + a->arr = malloc(size * sizeof(int)); + a->used = 0; + a->size = size; +} + +int IntArray_append(IntArray* a, int el) { + if (a->used == a->size) { + a->size *= 2; + a->arr = realloc(a->arr, a->size * sizeof(int)); + } + + a->used++; + + a->arr[a->used] = el; + return a->used; +} + +int IntArray_get(IntArray* a, int idx, int dflt) { + if (idx > a->used) { + return dflt; + } + + return a->arr[idx]; +} + +int IntArray_length(IntArray* a) { + return a->used; +} + +void IntArray_mergesort(IntArray* a) { + IntArray left_side; + IntArray right_side; + + size_t split = a->used / 2; + + IntArray_new(&left_side, split); + IntArray_new(&right_side, split); + + for (int i = 0; i < split; ++i) { + IntArray_append(&left_side, IntArray_get(a, i, 0)); + } + + for (int i = split; i < a->used; ++i) { + IntArray_append(&right_side, IntArray_get(a, i, 0)); + } + + IntArray_mergesort(&left_side); + IntArray_mergesort(&right_side); + + IntArray_mergesort_merge(a, &left_side, &right_side); +} + +void IntArray_mergesort_merge(IntArray* a, IntArray* left_side, IntArray* right_side) { + IntArray_free(a); + + size_t i = 0; + size_t j = 0; + + while (i < left_side->used && j < right_side->used) { + if (left_side->arr[i] <= right_side->arr[j]) { + IntArray_append(a, left_side->arr[i]); + i++; + } else { + IntArray_append(a, right_side->arr[j]); + j++; + } + } + + for (size_t li = 0; li < left_side->used; ++li) { + IntArray_append(a, left_side->arr[li]); + } + + for (size_t ri = 0; ri < right_side->used; ++ri) { + IntArray_append(a, right_side->arr[ri]); + } +} + +void IntArray_quicksort(IntArray* a) { + return; +} + +void IntArray_free(IntArray* a) { + free(a->arr); + a->arr = NULL; + a->used = a->size = 0; +} diff --git a/modernc/03/array.h b/modernc/03/array.h new file mode 100644 index 0000000..35e05d7 --- /dev/null +++ b/modernc/03/array.h @@ -0,0 +1,22 @@ +#ifndef INCLUDED_ARRAY_H +#include + +typedef struct { + int *arr; + size_t used; + size_t size; +} IntArray; + +void IntArray_new(IntArray*, size_t); + +int IntArray_append(IntArray*, int); +int IntArray_get(IntArray*, int, int); +int IntArray_length(IntArray*); +void IntArray_mergesort(IntArray*); +void IntArray_mergesort_merge(IntArray*, IntArray*, IntArray*); +void IntArray_quicksort(IntArray*); + +void IntArray_free(IntArray*); + +#define INCLUDED_ARRAY_H 1 +#endif diff --git a/modernc/03/challenge-1.c b/modernc/03/challenge-1.c new file mode 100644 index 0000000..2918027 --- /dev/null +++ b/modernc/03/challenge-1.c @@ -0,0 +1,114 @@ +#include +#include +#include +#include + +#include "array.h" + +#define IODASH "-" + +void usage(char* prog) { + fprintf(stderr, "Usage: %s [-f|--input-file ] [-o|--output-file ]\n", prog); +} + +int main(int argc, char **argv) { + char* input_file = IODASH; + char* output_file = IODASH; + + int c = 0; + + while (1) { + static struct option long_options[] = { + {"input-file", required_argument, 0, 'f'}, + {"output-file", required_argument, 0, 'o'}, + }; + + int option_index = 0; + + c = getopt_long(argc, argv, "f:o:", long_options, &option_index); + + if (c == -1) { + break; + } + + switch (c) { + case 'f': + input_file = optarg; + break; + case 'o': + output_file = optarg; + break; + default: + usage(argv[0]); + return 1; + } + } + + if (strcmp(input_file, IODASH) == 0) { + fprintf(stderr, "(reading from stdin)\n"); + } + + if (strcmp(output_file, IODASH) == 0) { + fprintf(stderr, "(writing to stdout)\n"); + } + + printf("input_file='%s' output_file='%s'\n", input_file, output_file); + + FILE* instream; + + instream = stdin; + if (strcmp(input_file, IODASH) != 0) { + instream = fopen(input_file, "r"); + } + + if (instream == NULL) { + perror("opening input file"); + return EXIT_FAILURE; + } + + FILE* outstream; + + outstream = stdout; + if (strcmp(output_file, IODASH) != 0) { + outstream = fopen(output_file, "r"); + } + + if (outstream == NULL) { + perror("opening output file"); + return EXIT_FAILURE; + } + + int line_int; + ssize_t nread; + + char* endptr = NULL; + char* line = NULL; + size_t len = 0; + + IntArray accum; + IntArray_new(&accum, 100); + + while ((nread = getline(&line, &len, instream)) != -1) { + IntArray_append(&accum, atoi(line)); + } + + printf("Accumulated %i ints\n", IntArray_length(&accum)); + + IntArray_mergesort(&accum); + + printf("Merge sorted:\n"); + + for (int i = 0; i < accum.used; ++i) { + printf("%i: %i\n", i, IntArray_get(&accum, i, 0)); + } + + if (strcmp(input_file, IODASH) != 0) { + fclose(instream); + } + + if (strcmp(output_file, IODASH) != 0) { + fclose(outstream); + } + + return EXIT_SUCCESS; +}