Too many more things about ModernC

This commit is contained in:
Dan Buch 2024-04-14 22:08:23 -04:00
parent 8424a6836a
commit f6ac67a6a6
Signed by: meatballhat
GPG Key ID: A12F782281063434
8 changed files with 238 additions and 0 deletions

11
.editorconfig Normal file
View File

@ -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

1
modernc/03/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
challenge-1

90
modernc/03/array.c Normal file
View File

@ -0,0 +1,90 @@
#include <stdlib.h>
#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;
}

22
modernc/03/array.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef INCLUDED_ARRAY_H
#include <stdlib.h>
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

114
modernc/03/challenge-1.c Normal file
View File

@ -0,0 +1,114 @@
#include <stdlib.h>
#include <stdio.h>
#include <getopt.h>
#include <string.h>
#include "array.h"
#define IODASH "-"
void usage(char* prog) {
fprintf(stderr, "Usage: %s [-f|--input-file <input-file>] [-o|--output-file <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;
}