3 changed files with 121 additions and 0 deletions
			
			
		@ -0,0 +1,8 @@ | 
				
			|||||
 | 
					CFLAGS := -Wall -Wextra -std=c17 -D_GNU_SOURCE | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.PHONY: all | 
				
			||||
 | 
					all: main | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.PHONY: clean | 
				
			||||
 | 
					clean: | 
				
			||||
 | 
						rm -f main | 
				
			||||
								
									
										File diff suppressed because one or more lines are too long
									
								
							
						
					@ -0,0 +1,112 @@ | 
				
			|||||
 | 
					#include <stdlib.h> | 
				
			||||
 | 
					#include <stdio.h> | 
				
			||||
 | 
					#include <string.h> | 
				
			||||
 | 
					#include <ctype.h> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					void *read_file_contents(const char *fname, size_t *len) | 
				
			||||
 | 
					{ | 
				
			||||
 | 
					    FILE *f = fopen(fname, "r"); | 
				
			||||
 | 
					    if (!f) { | 
				
			||||
 | 
					        perror(fname); | 
				
			||||
 | 
					        return NULL; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					    fseek(f, 0, SEEK_END); | 
				
			||||
 | 
					    *len = ftell(f); | 
				
			||||
 | 
					    rewind(f); | 
				
			||||
 | 
					    void *contents = malloc(*len); | 
				
			||||
 | 
					    if (!contents) { | 
				
			||||
 | 
					        perror("malloc"); | 
				
			||||
 | 
					        fclose(f); | 
				
			||||
 | 
					        return NULL; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					    fread(contents, *len, 1, f); | 
				
			||||
 | 
					    fclose(f); | 
				
			||||
 | 
					    return contents; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					void remove_dupes(char *mem, size_t len) | 
				
			||||
 | 
					{ | 
				
			||||
 | 
					    int found; | 
				
			||||
 | 
					    char last_char; | 
				
			||||
 | 
					    size_t last_char_pos; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    do { | 
				
			||||
 | 
					        found = 0; | 
				
			||||
 | 
					        last_char = '\0'; | 
				
			||||
 | 
					        last_char_pos = 0; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        for (size_t i = 0; i < len; i++) { | 
				
			||||
 | 
					            if (!mem[i]) continue; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            if (tolower(mem[i]) == tolower(last_char) && | 
				
			||||
 | 
					                    mem[i] != last_char) { | 
				
			||||
 | 
					                mem[i] = mem[last_char_pos] = '\0'; | 
				
			||||
 | 
					                found = 1; | 
				
			||||
 | 
					                last_char_pos = 0; | 
				
			||||
 | 
					                last_char = '\0'; | 
				
			||||
 | 
					            } else { | 
				
			||||
 | 
					                last_char_pos = i; | 
				
			||||
 | 
					                last_char = mem[last_char_pos]; | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    } while (found); | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					void remove_char(char *mem, size_t len, char c) | 
				
			||||
 | 
					{ | 
				
			||||
 | 
					    for (char *i = mem; i < mem + len; i++) { | 
				
			||||
 | 
					        if (tolower(*i) == c) *i = '\0'; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					size_t strip_zeroes(char *mem, size_t len) | 
				
			||||
 | 
					{ | 
				
			||||
 | 
					    size_t new_len = len; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    char *current = mem + len - 1; | 
				
			||||
 | 
					    while (len) { | 
				
			||||
 | 
					        while (len && *current) {len--; current--;} | 
				
			||||
 | 
					        if (!len) break; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        char *start = current; | 
				
			||||
 | 
					        while (len && !*current) {len--; current--;} | 
				
			||||
 | 
					        size_t diff = new_len - len - (start - current); | 
				
			||||
 | 
					        memmove(current + 1, start + 1, diff); | 
				
			||||
 | 
					        new_len = len + diff; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    return new_len; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					int main() | 
				
			||||
 | 
					{ | 
				
			||||
 | 
					    size_t string_len; | 
				
			||||
 | 
					    char *string = read_file_contents("input", &string_len); | 
				
			||||
 | 
					    if (!string) return 1; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    while (isspace(string[string_len - 1])) string[--string_len] = '\0'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    char *string_copy = malloc(string_len); | 
				
			||||
 | 
					    if (!string_copy) { | 
				
			||||
 | 
					        perror("malloc"); | 
				
			||||
 | 
					        free(string); | 
				
			||||
 | 
					        return 1; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					    size_t shortest = string_len; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    for (char x = 'a'; x <= 'z'; x++) { | 
				
			||||
 | 
					        printf("Attempting '%c'... ", x); | 
				
			||||
 | 
					        memcpy(string_copy, string, string_len); | 
				
			||||
 | 
					        remove_char(string_copy, string_len, x); | 
				
			||||
 | 
					        remove_dupes(string_copy, string_len); | 
				
			||||
 | 
					        size_t len = strip_zeroes(string_copy, string_len); | 
				
			||||
 | 
					        printf("%lu\n", len); | 
				
			||||
 | 
					        if (shortest > len) shortest = len; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    printf("Shortest: %lu\n", shortest); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    free(string_copy); | 
				
			||||
 | 
					    free(string); | 
				
			||||
 | 
					    return 0; | 
				
			||||
 | 
					} | 
				
			||||
					Loading…
					
					
				
		Reference in new issue