diff --git a/challenges/caesar-cipher/solutions/c/function/README.md b/challenges/caesar-cipher/solutions/c/function/README.md new file mode 100644 index 0000000..360affe --- /dev/null +++ b/challenges/caesar-cipher/solutions/c/function/README.md @@ -0,0 +1,3 @@ +# caesar-cipher/c/function + +Created by [@Divlo](https://github.com/Divlo) on 7 October 2021. diff --git a/challenges/caesar-cipher/solutions/c/function/character.c b/challenges/caesar-cipher/solutions/c/function/character.c new file mode 100644 index 0000000..49d4f00 --- /dev/null +++ b/challenges/caesar-cipher/solutions/c/function/character.c @@ -0,0 +1,10 @@ +#include "character.h" + +#include +#include + +void character_append(char* string, char character) { + size_t length = strlen(string); + string[length] = character; + string[length + 1] = '\0'; +} diff --git a/challenges/caesar-cipher/solutions/c/function/character.h b/challenges/caesar-cipher/solutions/c/function/character.h new file mode 100644 index 0000000..1c1851b --- /dev/null +++ b/challenges/caesar-cipher/solutions/c/function/character.h @@ -0,0 +1,13 @@ +#ifndef CHARACTER_H +#define CHARACTER_H + +/** + * @brief Append a character to a string, assuming string points to an array + * with enough space. + * + * @param string + * @param character + */ +void character_append(char* string, char character); + +#endif diff --git a/challenges/caesar-cipher/solutions/c/function/input.c b/challenges/caesar-cipher/solutions/c/function/input.c new file mode 100644 index 0000000..c07bb6d --- /dev/null +++ b/challenges/caesar-cipher/solutions/c/function/input.c @@ -0,0 +1,19 @@ +#include "input.h" + +#include +#include + +#include "character.h" + +char* input() { + char character; + size_t length = 1; + char* string = malloc(length * sizeof(char)); + *string = '\0'; + while ((character = getchar()) != '\n' && character != EOF) { + length++; + string = realloc(string, length * sizeof(char)); + character_append(string, character); + } + return string; +} diff --git a/challenges/caesar-cipher/solutions/c/function/input.h b/challenges/caesar-cipher/solutions/c/function/input.h new file mode 100644 index 0000000..9cd0a22 --- /dev/null +++ b/challenges/caesar-cipher/solutions/c/function/input.h @@ -0,0 +1,11 @@ +#ifndef INPUT_H +#define INPUT_H + +/** + * @brief Read a line from stdin. + * + * @return char* + */ +char* input(); + +#endif diff --git a/challenges/caesar-cipher/solutions/c/function/solution.c b/challenges/caesar-cipher/solutions/c/function/solution.c new file mode 100644 index 0000000..89bd9e2 --- /dev/null +++ b/challenges/caesar-cipher/solutions/c/function/solution.c @@ -0,0 +1,16 @@ +#include +#include + +#include "character.h" +#include "input.h" +#include "string.h" + +int main() { + char* string = input(); + int shift; + scanf("%d", &shift); + string = string_caesar_cipher(string, shift); + printf("%s\n", string); + free(string); + return EXIT_SUCCESS; +} diff --git a/challenges/caesar-cipher/solutions/c/function/string.c b/challenges/caesar-cipher/solutions/c/function/string.c new file mode 100644 index 0000000..7144829 --- /dev/null +++ b/challenges/caesar-cipher/solutions/c/function/string.c @@ -0,0 +1,43 @@ +#include "string.h" + +#include +#include +#include + +#include "character.h" + +#define ALPHABET_LENGTH 26 + +char* string_shift_alphabet(int shift) { + char* result = malloc(sizeof(char) * (ALPHABET_LENGTH + 1)); + for (char index = 0; index < ALPHABET_LENGTH; index++) { + char letter = 'A' + index + shift; + if (letter < 'A') { + letter = 'Z' + shift + index + 1; + } else if (letter > 'Z') { + letter = letter - ALPHABET_LENGTH; + } + character_append(result, letter); + } + return result; +} + +char* string_caesar_cipher(char* string, int shift) { + size_t string_length = strlen(string); + char* result = malloc(sizeof(char) * (string_length + 1)); + char* shifted_alphabet = string_shift_alphabet(shift); + for (size_t index = 0; index < string_length; index++) { + char letter = string[index]; + if (letter != ' ') { + for (char index_alphabet = 0; index_alphabet < ALPHABET_LENGTH; index_alphabet++) { + char current_letter = 'A' + index_alphabet; + if (string[index] == current_letter) { + letter = shifted_alphabet[index_alphabet]; + break; + } + } + } + character_append(result, letter); + } + return result; +} diff --git a/challenges/caesar-cipher/solutions/c/function/string.h b/challenges/caesar-cipher/solutions/c/function/string.h new file mode 100644 index 0000000..ab9281f --- /dev/null +++ b/challenges/caesar-cipher/solutions/c/function/string.h @@ -0,0 +1,23 @@ +#ifndef STRING_H +#define STRING_H + +#define ALPHABET "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + +/** + * @brief Shift the alphabet by a given amount. + * + * @param shift + * @return char* + */ +char* string_shift_alphabet(int shift); + +/** + * @brief Encrypts a string using the Caesar cipher. + * + * @param string + * @param shift + * @return char* + */ +char* string_caesar_cipher(char* string, int shift); + +#endif