1
1
mirror of https://github.com/theoludwig/programming-challenges.git synced 2024-12-08 00:45:29 +01:00

fix(solutions): fix: more memory issues thanks to -fsanitize=address flag with gcc

This commit is contained in:
Théo LUDWIG 2023-08-21 21:37:54 +02:00
parent 395cd142b8
commit d73ae4dd07
Signed by: theoludwig
GPG Key ID: ADFE5A563D718F3B
14 changed files with 1020 additions and 851 deletions

View File

@ -6,6 +6,8 @@ Created by [@theoludwig](https://github.com/theoludwig) on 8 November 2021.
Write a program that generates all possible unique permutations of a string. Write a program that generates all possible unique permutations of a string.
The order of the generated permutations is important, see the example below.
## Source ## Source
- [Heap's Algorithm - Wikipedia](https://en.wikipedia.org/wiki/Heap%27s_algorithm) - [Heap's Algorithm - Wikipedia](https://en.wikipedia.org/wiki/Heap%27s_algorithm)
@ -25,10 +27,10 @@ abc
```txt ```txt
abc abc
bac bac
cba
bca
cab cab
acb acb
bca
cba
``` ```
See the `test` folder for examples of input/output. See the `test` folder for examples of input/output.

View File

@ -5,34 +5,21 @@
#include "input.h" #include "input.h"
char *swap(char *string, size_t index_from, size_t index_target) { void swap(char *string, size_t index_from, size_t index_target) {
size_t string_length = strlen(string); char temporary = string[index_from];
char *result = malloc(sizeof(char *) * (string_length)); string[index_from] = string[index_target];
for (size_t index = 0; index < string_length; index++) { string[index_target] = temporary;
if (index == index_from) {
result[index] = string[index_target];
} else if (index == index_target) {
result[index] = string[index_from];
} else {
result[index] = string[index];
}
}
return result;
} }
void heap_algorithm(unsigned long number_of_elements_to_operate, char *string) { void heap_algorithm(char *string, size_t number_of_elements_to_operate) {
if (number_of_elements_to_operate == 1) { if (number_of_elements_to_operate == 1) {
printf("%s\n", string); printf("%s\n", string);
} else { } else {
heap_algorithm(number_of_elements_to_operate - 1, string); heap_algorithm(string, number_of_elements_to_operate - 1);
for (size_t index = 0; index < number_of_elements_to_operate - 1; index++) { for (size_t index = 0; index < number_of_elements_to_operate - 1; index++) {
bool is_even = number_of_elements_to_operate % 2 == 0; bool is_even = number_of_elements_to_operate % 2 == 0;
if (!is_even) { swap(string, is_even ? index : 0, number_of_elements_to_operate - 1);
string = swap(string, index, number_of_elements_to_operate - 1); heap_algorithm(string, number_of_elements_to_operate - 1);
} else {
string = swap(string, 0, number_of_elements_to_operate - 1);
}
heap_algorithm(number_of_elements_to_operate - 1, string);
} }
} }
} }
@ -40,6 +27,7 @@ void heap_algorithm(unsigned long number_of_elements_to_operate, char *string) {
int main() { int main() {
char *string = input(); char *string = input();
size_t string_length = strlen(string); size_t string_length = strlen(string);
heap_algorithm(string_length, string); heap_algorithm(string, string_length);
free(string);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@ -1,6 +1,6 @@
abc abc
bac bac
cba
bca
cab cab
acb acb
bca
cba

View File

@ -1,24 +1,24 @@
cool cool
ocol ocol
oocl
oocl
ocol ocol
cool cool
oocl
oocl
loco
olco
cloo
lcoo
oclo
colo
colo
oclo
lcoo
cloo
olco
loco
looc looc
oloc oloc
oolc
oolc
oloc oloc
looc looc
cool
ocol
oocl
oocl
ocol
cool
looc
oloc
oolc oolc
oolc oolc
oloc
looc

View File

@ -1,120 +1,120 @@
kayak kayak
akyak akyak
yakak
aykak
ykaak ykaak
kyaak kyaak
aaykk aykak
aaykk yakak
yaakk aakyk
ayakk aakyk
yaakk kaayk
ayakk akayk
kayak akayk
kaayk
kyaak
ykaak
akyak akyak
yakak
aykak
ykaak
kyaak
aaykk
aaykk
yaakk
ayakk
yaakk
ayakk
kayak kayak
akyak
yakak yakak
aykak aykak
ykaak ayakk
kyaak yaakk
aaykk aaykk
aaykk aaykk
yaakk yaakk
ayakk ayakk
yaakk kyaka
ayakk ykaka
kayak
akyak
yakak
aykak
ykaak
kyaak
aaykk
aaykk
yaakk
ayakk
yaakk
ayakk
kkyaa
kkyaa
ykkaa
kykaa
ykkaa
kykaa
akyka akyka
kayka kayka
ykaka
kyaka
yakka yakka
aykka aykka
kykaa
ykkaa
kkyaa kkyaa
kkyaa kkyaa
ykkaa ykkaa
kykaa kykaa
kakya
akkya
kkaya
kkaya
akkya
kakya
kayka
akyka
ykaka
kyaka
aykka
yakka
aakky
aakky
kaaky
akaky
akaky
kaaky
kaaky
akaky
akaky
kaaky
aakky
aakky
akkay
kakay
kakay
akkay
kkaay
kkaay
kkaay
kkaay
akkay
kakay
kakay
akkay
ykkaa ykkaa
kykaa kykaa
kykaa
ykkaa
kkyaa
kkyaa
akyka akyka
kayka kayka
ykaka
kyaka
yakka yakka
aykka aykka
kkaay kyaka
kkaay ykaka
akkay
kakay
akkay
kakay
akaky
kaaky
akaky
kaaky
aakky
aakky
kkaay
kkaay
akkay
kakay
akkay
kakay
akaky
kaaky
akaky
kaaky
aakky
aakky
kkaya
kkaya
akkya
kakya
akkya
kakya
ykaka ykaka
kyaka kyaka
akyka
kayka
aykka aykka
yakka yakka
kkaya
kkaya
akkya
kakya
akkya
kakya
ykaka
kyaka
akyka
kayka kayka
aykka akyka
yakka akkya
kakya
kakya
akkya
kkaya
kkaya
akayk
kaayk
aakyk
aakyk
kaayk
akayk
ykaak
kyaak
aykak
yakak
kayak
akyak
aaykk
aaykk
yaakk
ayakk
ayakk
yaakk
yakak
aykak
kyaak
ykaak
akyak
kayak

File diff suppressed because it is too large Load Diff

View File

@ -5,10 +5,3 @@ void character_append(char* string, char character) {
string[length] = character; string[length] = character;
string[length + 1] = '\0'; string[length + 1] = '\0';
} }
void character_append_many(char* string, char* characters) {
size_t characters_length = strlen(characters);
for (size_t index = 0; index < characters_length; index++) {
character_append(string, characters[index]);
}
}

View File

@ -13,13 +13,4 @@
*/ */
void character_append(char* string, char character); void character_append(char* string, char character);
/**
* @brief Append many characters to a string, assuming string points to an array
* with enough space.
*
* @param string
* @param characters
*/
void character_append_many(char* string, char* characters);
#endif #endif

View File

@ -1,3 +1,4 @@
#include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -5,22 +6,129 @@
#include "character.h" #include "character.h"
#include "input.h" #include "input.h"
size_t string_get_length(const char* string) {
size_t length = 0;
while (string[length] != '\0') {
length++;
}
return length;
}
char* string_copy(const char* string) {
size_t source_length = string_get_length(string);
char* copy = malloc(sizeof(char) * (source_length + 1));
if (copy == NULL) {
perror("Error (string_copy)");
exit(EXIT_FAILURE);
}
size_t index;
for (index = 0; index < source_length; index++) {
copy[index] = string[index];
}
copy[index] = '\0';
return copy;
}
unsigned long long mathematics_absolute_value(const long long number) {
if (number >= 0) {
return number;
}
return -number;
}
void string_reverse(char* string) {
size_t string_length = string_get_length(string);
size_t index_start = 0;
size_t index_end = string_length - 1;
while (index_start < index_end) {
char temporary = string[index_start];
string[index_start] = string[index_end];
string[index_end] = temporary;
index_start++;
index_end--;
}
}
char* convert_character_to_string(const char character) {
char* string = malloc(sizeof(char) * 2);
if (string == NULL) {
perror("Error (convert_character_to_string)");
exit(EXIT_FAILURE);
}
string[0] = character;
string[1] = '\0';
return string;
}
char convert_digit_to_character(const char digit) {
return digit + '0';
}
void string_concatenate(char** destination, char* source) {
size_t destination_length = string_get_length(*destination);
size_t source_length = string_get_length(source);
size_t new_length = destination_length + source_length;
*destination = realloc(*destination, sizeof(char) * (new_length + 1));
if (*destination == NULL) {
perror("Error (string_concatenate)");
exit(EXIT_FAILURE);
}
size_t index_destination = destination_length;
for (size_t index_source = 0; index_source < source_length; index_source++) {
(*destination)[index_destination++] = source[index_source];
}
(*destination)[index_destination] = '\0';
}
char* convert_number_to_string(const long long integer) {
if (integer == 0) {
return convert_character_to_string('0');
}
bool is_negative = integer < 0;
size_t length = 1;
long long current = mathematics_absolute_value(integer);
while (current != 0) {
current = current / 10;
length++;
}
if (is_negative) {
length++;
}
char* string = malloc(sizeof(char) * length);
if (string == NULL) {
perror("Error (convert_number_to_string)");
exit(EXIT_FAILURE);
}
current = mathematics_absolute_value(integer);
size_t index = 0;
while (current != 0) {
string[index++] = convert_digit_to_character(current % 10);
current = current / 10;
}
if (is_negative) {
string[index++] = '-';
}
string[index] = '\0';
string_reverse(string);
return string;
}
int main() { int main() {
char* string = input(); char* string = input();
size_t string_length = strlen(string); size_t string_length = string_get_length(string);
char* result = malloc(sizeof(char) * (string_length + 1)); char* result = string_copy("");
for (size_t index = 0; index < string_length; index++) { for (size_t index = 0; index < string_length; index++) {
unsigned char number_of_appearances = 0; long long number_of_appearances = 0;
char value_to_search = string[index]; char value_to_search = string[index];
size_t iteration = index; while (number_of_appearances + index < string_length && string[number_of_appearances + index] == value_to_search) {
while (iteration < string_length && string[iteration] == value_to_search) {
number_of_appearances++; number_of_appearances++;
iteration++;
} }
char* number_of_appearances_string = malloc(sizeof(char) * (string_length + 1)); char* number_of_appearances_string = convert_number_to_string(number_of_appearances);
snprintf(number_of_appearances_string, sizeof(result), "%hhu", number_of_appearances); string_concatenate(&result, number_of_appearances_string);
character_append_many(result, number_of_appearances_string); char* value_string = convert_character_to_string(value_to_search);
character_append(result, value_to_search); string_concatenate(&result, value_string);
free(number_of_appearances_string);
free(value_string);
index += number_of_appearances - 1; index += number_of_appearances - 1;
} }
printf("%s\n", result); printf("%s\n", result);

View File

@ -13,48 +13,29 @@ void array_2D_int_print(int **array, size_t number_of_rows, size_t number_of_col
} }
int **array_2D_int_input(size_t *number_of_rows, size_t *number_of_columns) { int **array_2D_int_input(size_t *number_of_rows, size_t *number_of_columns) {
int **array = malloc(sizeof(int) * 2); *number_of_rows = 0;
*number_of_rows = 1; *number_of_columns = 0;
*number_of_columns = 1; int **array = malloc(sizeof(int *));
array[0] = malloc(*number_of_columns * sizeof(int)); char *line = input();
array[0][0] = 0; while (string_get_length(line) != 0) {
char character; char **integers_string = string_split(line, ' ', number_of_columns);
size_t length = 1; array[*number_of_rows] = malloc(*number_of_columns * sizeof(int));
char *string = malloc(length * sizeof(char)); for (size_t column = 0; column < *number_of_columns; column++) {
*string = '\0'; array[*number_of_rows][column] = atoi(integers_string[column]);
while ((character = getchar()) != EOF) { free(integers_string[column]);
if (character == '\n') {
int number = atoi(string);
array[*number_of_rows - 1][*number_of_columns - 1] = number;
length = 1;
memset(string, 0, length * sizeof(char));
*string = '\0';
*number_of_rows = *number_of_rows + 1;
*number_of_columns = 1;
array = realloc(array, *number_of_rows * sizeof(int *));
array[*number_of_rows - 1] = malloc(*number_of_columns * sizeof(int));
} else {
if (character == ' ') {
int number = atoi(string);
array[*number_of_rows - 1][*number_of_columns - 1] = number;
length = 1;
memset(string, 0, length * sizeof(char));
*string = '\0';
*number_of_columns = *number_of_columns + 1;
} else {
length++;
string = realloc(string, length * sizeof(char));
character_append(string, character);
}
} }
free(integers_string);
free(line);
line = input();
*number_of_rows += 1;
array = realloc(array, (*number_of_rows + 1) * sizeof(int *));
} }
int number = atoi(string); free(line);
array[*number_of_rows - 1][*number_of_columns - 1] = number;
return array; return array;
} }
int **array_2D_int_reverse_rows(int **array, size_t *number_of_rows, size_t *number_of_columns) { int **array_2D_int_reverse_rows(int **array, size_t *number_of_rows, size_t *number_of_columns) {
int **rotated_array = malloc(*number_of_rows * sizeof(int)); int **rotated_array = malloc(*number_of_rows * sizeof(int *));
for (size_t row = 0; row < *number_of_rows; row++) { for (size_t row = 0; row < *number_of_rows; row++) {
rotated_array[row] = malloc(*number_of_columns * sizeof(int)); rotated_array[row] = malloc(*number_of_columns * sizeof(int));
} }

View File

@ -6,6 +6,8 @@
#include <string.h> #include <string.h>
#include "character.h" #include "character.h"
#include "input.h"
#include "string.h"
/** /**
* @brief Prints a 2D array of integers. * @brief Prints a 2D array of integers.

View File

@ -9,6 +9,7 @@ int main() {
size_t number_of_columns = 0; size_t number_of_columns = 0;
char *direction = input(); char *direction = input();
int **array_input = array_2D_int_input(&number_of_rows, &number_of_columns); int **array_input = array_2D_int_input(&number_of_rows, &number_of_columns);
size_t initial_number_of_rows = number_of_rows;
int **array; int **array;
if (strcmp(direction, "clockwise") == 0) { if (strcmp(direction, "clockwise") == 0) {
@ -19,6 +20,10 @@ int main() {
array_2D_int_print(array, number_of_rows, number_of_columns); array_2D_int_print(array, number_of_rows, number_of_columns);
free(direction); free(direction);
for (size_t row = 0; row < initial_number_of_rows; row++) {
free(array_input[row]);
}
free(array_input);
for (size_t row = 0; row < number_of_rows; row++) { for (size_t row = 0; row < number_of_rows; row++) {
free(array[row]); free(array[row]);
} }

View File

@ -0,0 +1,64 @@
#include "string.h"
size_t string_get_length(const char* string) {
size_t length = 0;
while (string[length] != '\0') {
length++;
}
return length;
}
char* string_copy(const char* string) {
size_t source_length = string_get_length(string);
char* copy = malloc(sizeof(char) * (source_length + 1));
if (copy == NULL) {
perror("Error (string_copy)");
exit(EXIT_FAILURE);
}
size_t index;
for (index = 0; index < source_length; index++) {
copy[index] = string[index];
}
copy[index] = '\0';
return copy;
}
char** string_split(const char* string, char separator, size_t* result_size) {
size_t string_length = string_get_length(string);
size_t index_string = 0;
size_t index_current = 0;
size_t index_result = 0;
char* current = malloc(sizeof(char) * (string_length + 1));
char** result = NULL;
if (current == NULL) {
perror("Error (string_split)");
exit(EXIT_FAILURE);
}
while (index_string < string_length) {
if (string[index_string] == separator) {
current[index_current] = '\0';
result = realloc(result, sizeof(char*) * (index_result + 1));
if (result == NULL) {
perror("Error (string_split)");
exit(EXIT_FAILURE);
}
result[index_result] = string_copy(current);
index_result++;
index_current = 0;
} else {
current[index_current] = string[index_string];
index_current++;
}
index_string++;
}
current[index_current] = '\0';
result = realloc(result, sizeof(char*) * (index_result + 1));
if (result == NULL) {
perror("Error (string_split)");
exit(EXIT_FAILURE);
}
result[index_result] = string_copy(current);
free(current);
*result_size = index_result + 1;
return result;
}

View File

@ -0,0 +1,35 @@
#ifndef __STRING__
#define __STRING__
#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
/**
* @brief Return the length of a string (excluding '\0').
*
* @param string
* @return size_t
*/
size_t string_get_length(const char* string);
/**
* @brief Return the copy of a string.
*
* @param string
* @return string_t
*/
char* string_copy(const char* string);
/**
* @brief Split a string into substrings using the specified separator and return them as an array and update the pointer `result_size` to the resulting size of the created array.
*
* @param string
* @param separator
* @param result_size
* @return string_t*
*/
char** string_split(const char* string, char separator, size_t* result_size);
#endif