Created
February 21, 2018 17:22
-
-
Save PurpleMyst/37476e5885548b6dd789cb0456b83b24 to your computer and use it in GitHub Desktop.
Solution to DailyProgrammer Day 351 [Intermediate]
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define _GNU_SOURCE | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#define ever (;;) | |
typedef struct { | |
size_t size; | |
char *names; | |
size_t *positions; | |
} Programs; | |
static Programs *programs_new(char *names) { | |
Programs *programs = malloc(sizeof(Programs)); | |
programs->size = strlen(names); | |
programs->names = names; | |
programs->positions = calloc(programs->size, sizeof(size_t)); | |
for (size_t i = 0; i < programs->size; ++i) programs->positions[i] = i; | |
return programs; | |
} | |
static void programs_free(Programs *programs) { | |
free(programs->names); | |
free(programs->positions); | |
free(programs); | |
} | |
static void programs_print(const Programs *programs) { | |
char *result = calloc(programs->size + 1, sizeof(char)); | |
for (size_t i = 0, l = programs->size; i < l; ++i) { | |
result[programs->positions[i]] = programs->names[i]; | |
} | |
printf("%s\n", result); | |
free(result); | |
} | |
static void programs_spin(Programs *programs, size_t n) { | |
for (size_t i = 0, l = programs->size; i < l; ++i) { | |
programs->positions[i] = (programs->positions[i] + n) % l; | |
} | |
} | |
static void programs_exchange(Programs *programs, size_t a, size_t b) { | |
size_t a_index = programs->size, | |
b_index = programs->size; | |
for (size_t i = 0, l = programs->size; i < l; ++i) { | |
size_t position = programs->positions[i]; | |
if (position == a) { | |
a_index = i; | |
} | |
if (position == b) { | |
b_index = i; | |
} | |
if (a_index < l && b_index < l) { | |
size_t temp = programs->positions[a_index]; | |
programs->positions[a_index] = programs->positions[b_index]; | |
programs->positions[b_index] = temp; | |
return; | |
} | |
} | |
fputs("Wrongful exchange.", stderr); | |
exit(EXIT_FAILURE); | |
} | |
static void programs_partner(Programs *programs, size_t a, size_t b) { | |
size_t temp = programs->positions[a]; | |
programs->positions[a] = programs->positions[b]; | |
programs->positions[b] = temp; | |
} | |
int main(/*int argc, char *argv[]*/) { | |
char *line = NULL; | |
size_t _n = 0; | |
if (getline(&line, &_n, stdin) == -1) { | |
perror("Error reading program names."); | |
exit(EXIT_FAILURE); | |
} | |
const size_t line_length = strlen(line); | |
if (line[line_length - 1] == '\n') { | |
line[line_length - 1] = 0; | |
} | |
Programs *programs = programs_new(line); | |
for ever { | |
int c = getchar(); | |
size_t a, b; | |
switch(c) { | |
case 's': | |
scanf("%lu,", &a); | |
programs_spin(programs, a); | |
break; | |
case 'x': | |
scanf("%lu/%lu,", &a, &b); | |
programs_exchange(programs, a, b); | |
break; | |
case 'p': | |
scanf("%lu/%lu,", &a, &b); | |
programs_partner(programs, a, b); | |
break; | |
case EOF: | |
goto cleanup; | |
case '\n': | |
break; | |
default: | |
fprintf(stderr, "Unknown dance move '%c'\n", c); | |
exit(EXIT_FAILURE); | |
} | |
} | |
cleanup: | |
programs_print(programs); | |
programs_free(programs); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment