Skip to content

Instantly share code, notes, and snippets.

@PurpleMyst
Created February 21, 2018 17:22
Show Gist options
  • Save PurpleMyst/37476e5885548b6dd789cb0456b83b24 to your computer and use it in GitHub Desktop.
Save PurpleMyst/37476e5885548b6dd789cb0456b83b24 to your computer and use it in GitHub Desktop.
Solution to DailyProgrammer Day 351 [Intermediate]
#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