Add TP 7 correction.
authorJérôme Benoit <jerome.benoit@piment-noir.org>
Mon, 27 Feb 2017 18:15:11 +0000 (19:15 +0100)
committerJérôme Benoit <jerome.benoit@piment-noir.org>
Mon, 27 Feb 2017 18:15:11 +0000 (19:15 +0100)
Signed-off-by: Jérôme Benoit <jerome.benoit@piment-noir.org>
TP_7_C/Makefile [new file with mode: 0644]
TP_7_C/README [new file with mode: 0644]
TP_7_C/exo1-base.c [new file with mode: 0644]
TP_7_C/exo1-extra.c [new file with mode: 0644]
TP_7_C/exo1-full.c [new file with mode: 0644]
TP_7_C/exo2-base.c [new file with mode: 0644]
TP_7_C/exo2-extra.c [new file with mode: 0644]
TP_7_C/exo2-full.c [new file with mode: 0644]
TP_7_C/exo3-base.c [new file with mode: 0644]
TP_7_C/exo3-extra.c [new file with mode: 0644]
TP_7_C/exo3-full.c [new file with mode: 0644]

diff --git a/TP_7_C/Makefile b/TP_7_C/Makefile
new file mode 100644 (file)
index 0000000..57d5b7b
--- /dev/null
@@ -0,0 +1,15 @@
+all: \
+       exo1-base \
+       exo1-full \
+       exo1-extra \
+       exo2-base \
+       exo2-full \
+       exo2-extra \
+       exo3-base \
+       exo3-full \
+       exo3-extra \
+
+
+%:%.c
+       gcc $< -std=c99 -Wall -g -o $@
+
diff --git a/TP_7_C/README b/TP_7_C/README
new file mode 100644 (file)
index 0000000..e452c5b
--- /dev/null
@@ -0,0 +1,9 @@
+Correction du TP noté de C
+
+Pour compiler, utiliser make directement:
+
+$ make
+
+Les fichiers -base contiennent l'exercice de base, les fichiers -full contiennent les points optionels.
+
+Les fichiers -extra contiennent une version alternative. Cette version n'est pas nécessairement plus efficace (voir elle est parfois moins efficace!) et n'est pas non plus aussi lisible; de manière générale les "astuces" utilisées ne sont pas conseillées quand elles réduisent la lisibilité sans apporter d'avantage réel.
diff --git a/TP_7_C/exo1-base.c b/TP_7_C/exo1-base.c
new file mode 100644 (file)
index 0000000..a30362c
--- /dev/null
@@ -0,0 +1,44 @@
+#include <stdio.h>
+#include <stdbool.h>
+
+void swap(int* v1, int* v2) {
+    int tempValue = *v1;
+    *v1 = *v2;
+    *v2 = tempValue;
+}
+
+/** Display the array on standard output. */
+void displayArray(int* array, int count) {
+    for (int tabIndex = 0; tabIndex < count; ++tabIndex) {
+        printf("array[%d] = %d\n", tabIndex, array[tabIndex]);
+    }
+}
+
+/** Perform one swap on the first two values not in increasing order.
+ *
+ * @return true if a swap was performed, false if the whole array is ordered.
+ */
+bool sortFirst(int* array, int length) {
+    for (int tabIndex = 0; tabIndex < (length - 1); ++tabIndex) {
+        if (array[tabIndex] > array[tabIndex + 1]) {
+            swap(&array[tabIndex], &array[tabIndex + 1]);
+            return true;
+        }
+    }
+
+    return false;
+}
+
+void sortArray(int* array, int length) {
+    bool swappedValues;
+
+    do {
+        swappedValues = sortFirst(array, length);
+    } while (swappedValues);
+}
+
+int main() {
+    int arr[10] = {23, 2, 0, 4, 56, 3, 7, 8, 98, 1};
+    sortArray(arr, 10);
+    displayArray(arr, 10);
+}
diff --git a/TP_7_C/exo1-extra.c b/TP_7_C/exo1-extra.c
new file mode 100644 (file)
index 0000000..3d191f0
--- /dev/null
@@ -0,0 +1,54 @@
+#include <stdio.h>
+#include <stdbool.h>
+
+void swap(int* v1, int* v2) {
+    int tempValue = *v1;
+    *v1 = *v2;
+    *v2 = tempValue;
+}
+
+/** Display the array on standard output. */
+void displayArray(int* array, int count) {
+    for (int tabIndex = 0; tabIndex < count; ++tabIndex) {
+        printf("array[%d] = %d\n", tabIndex, *(array++));
+    }
+}
+
+/** Swap every out-of-order cells at most once.
+ *
+ * @return true if a swap was performed, false if the whole array is ordered.
+ */
+bool sortFirst(int* array, int length) {
+    bool swappedValues = false;
+    int* cursor = array;
+
+    while (--length) {
+        if (*cursor > *(cursor + 1)) {
+            swap(cursor, cursor + 1);
+            swappedValues = true;
+        }
+
+        ++cursor;
+    }
+
+    return swappedValues;
+}
+
+void sortArray(int* array, int length) {
+    while (sortFirst(array, length));
+}
+
+/** Fill the array with user input. */
+void promptArray(int* array, int length) {
+    for (int tabIndex = 0; tabIndex < length; ++tabIndex) {
+        printf("Enter value for index %d:\n", tabIndex);
+        scanf("%d", array++);
+    }
+}
+
+int main() {
+    int arr[10];
+    promptArray(arr, 10);
+    sortArray(arr, 10);
+    displayArray(arr, 10);
+}
diff --git a/TP_7_C/exo1-full.c b/TP_7_C/exo1-full.c
new file mode 100644 (file)
index 0000000..451816b
--- /dev/null
@@ -0,0 +1,55 @@
+#include <stdio.h>
+#include <stdbool.h>
+
+void swap(int* v1, int* v2) {
+    int tempValue = *v1;
+    *v1 = *v2;
+    *v2 = tempValue;
+}
+
+/** Display the array on standard output. */
+void displayArray(int* array, int count) {
+    for (int tabIndex = 0; tabIndex < count; ++tabIndex) {
+        printf("array[%d] = %d\n", tabIndex, array[tabIndex]);
+    }
+}
+
+/** Swap every out-of-order cells at most once.
+ *
+ * @return true if a swap was performed, false if the whole array is ordered.
+ */
+bool sortFirst(int* array, int length) {
+    bool swappedValues = false;
+
+    for (int tabIndex = 0; tabIndex < (length - 1); ++tabIndex) {
+        if (array[tabIndex] > array[tabIndex + 1]) {
+            swap(&array[tabIndex], &array[tabIndex + 1]);
+            swappedValues = true;
+        }
+    }
+
+    return swappedValues;
+}
+
+void sortArray(int* array, int length) {
+    bool swappedValues;
+
+    do {
+        swappedValues = sortFirst(array, length);
+    } while (swappedValues);
+}
+
+/** Fill the array with user input. */
+void promptArray(int* array, int length) {
+    for (int tabIndex = 0; tabIndex < length; ++tabIndex) {
+        printf("Enter value for index %d:\n", tabIndex);
+        scanf("%d", &array[tabIndex]);
+    }
+}
+
+int main() {
+    int arr[10];
+    promptArray(arr, 10);
+    sortArray(arr, 10);
+    displayArray(arr, 10);
+}
diff --git a/TP_7_C/exo2-base.c b/TP_7_C/exo2-base.c
new file mode 100644 (file)
index 0000000..7212cfc
--- /dev/null
@@ -0,0 +1,79 @@
+#include <stdio.h>
+#include <stdbool.h>
+
+/** Display a prompt to the user then wait for an integer input. */
+int promptValue(const char* prompt) {
+    printf("%s:\n", prompt);
+    int result;
+    scanf("%d", &result);
+    return result;
+}
+
+void displayMenuEntry(int index, const char* label) {
+    printf("%d | %s\n", index, label);
+}
+
+void displayMenu() {
+    displayMenuEntry(1, "Addition");
+    displayMenuEntry(2, "Substraction");
+    displayMenuEntry(3, "Multiplication");
+    displayMenuEntry(4, "Exit");
+}
+
+/** Prompt the user for his operation choice.
+ *
+ * @return The selected operation. No invalid value can be returned.
+ */
+int promptOperation() {
+    displayMenu();
+    int result;
+
+    do {
+        result = promptValue("Choose an option");
+
+        if (result >= 1 && result <= 4) {
+            break;
+        }
+
+        puts("Please choose a valid option (1-4)");
+    } while (true);
+
+    return result;
+}
+
+int main() {
+    int operation = promptOperation();
+
+    if (operation == 4) {
+        return 0;
+    }
+
+    int initialValue = promptValue("Initial value");
+
+    do {
+        int nextValue = promptValue("Next value");
+
+        if (nextValue == 0) {
+            break;
+        }
+
+        switch (operation) {
+        // Addition
+        case 1:
+            initialValue += nextValue;
+            break;
+
+        // Substraction
+        case 2:
+            initialValue -= nextValue;
+            break;
+
+        // Multiplication
+        case 3:
+            initialValue *= nextValue;
+            break;
+        }
+
+        printf("Result: %d\n", initialValue);
+    } while (true);
+}
diff --git a/TP_7_C/exo2-extra.c b/TP_7_C/exo2-extra.c
new file mode 100644 (file)
index 0000000..2250cfd
--- /dev/null
@@ -0,0 +1,119 @@
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+/** Pointer to a function with this profile */
+typedef int(*operation_cb)(int v1, int v2);
+
+/** Describe a single operation */
+typedef struct {
+    const char* label;
+    operation_cb cb;
+} operation_t;
+
+int doAddition(int v1, int v2);
+int doSubstraction(int v1, int v2);
+int doMultiplication(int v1, int v2);
+int doXOR(int v1, int v2);
+
+/** All available operations */
+operation_t operations[4] = {
+    {
+        "Addition",
+        doAddition
+    },
+    {
+        "Substraction",
+        doSubstraction
+    },
+    {
+        "Multiplication",
+        doMultiplication
+    },
+    {
+        "XOR",
+        doXOR
+    }
+};
+#define operations_count ((int) (sizeof(operations) / sizeof(operations[0])))
+
+/** Display a prompt to the user then wait for an integer input. */
+void promptValue(const char* prompt, int* value) {
+    printf("%s:\n", prompt);
+    scanf("%d", value);
+}
+
+void displayMenuEntry(int index, const char* label) {
+    printf("%d | %s\n", index, label);
+}
+
+/** Display all available operations and an EXIT option. */
+void displayMenu() {
+    for (int menuIndex = 0; menuIndex < operations_count; ++menuIndex) {
+        displayMenuEntry(menuIndex + 1, operations[menuIndex].label);
+    }
+
+    displayMenuEntry(operations_count + 1, "Exit");
+}
+
+/** Prompt the user for his operation choice.
+ *
+ * @return The selected operation. If the exit option is chosen, return NULL
+ */
+operation_t* promptOperation() {
+    displayMenu();
+
+    do {
+        int result;
+        promptValue("Choose an option", &result);
+
+        if (result == (operations_count + 1)) {
+            return NULL;
+        }
+
+        if (result >= 1 && result <= operations_count) {
+            return &operations[result - 1];
+        }
+
+        printf("Please choose a valid option (1-%d)\n", operations_count);
+    } while (true);
+}
+
+int doAddition(int v1, int v2) {
+    return v1 + v2;
+}
+
+int doSubstraction(int v1, int v2) {
+    return v1 - v2;
+}
+
+int doMultiplication(int v1, int v2) {
+    return v1 * v2;
+}
+
+int doXOR(int v1, int v2) {
+    return v1 ^ v2;
+}
+
+int main() {
+    operation_t* operation = promptOperation();
+
+    if (operation == NULL) {
+        return 0;
+    }
+
+    int initialValue;
+    promptValue("Initial value", &initialValue);
+
+    do {
+        int nextValue;
+        promptValue("Next value", &nextValue);
+
+        if (nextValue == 0) {
+            break;
+        }
+
+        initialValue = operation->cb(initialValue, nextValue);
+        printf("Result: %d\n", initialValue);
+    } while (true);
+}
diff --git a/TP_7_C/exo2-full.c b/TP_7_C/exo2-full.c
new file mode 100644 (file)
index 0000000..acbe4a3
--- /dev/null
@@ -0,0 +1,85 @@
+#include <stdio.h>
+#include <stdbool.h>
+
+/** Display a prompt to the user then wait for an integer input. */
+int promptValue(const char* prompt) {
+    printf("%s:\n", prompt);
+    int result;
+    scanf("%d", &result);
+    return result;
+}
+
+void displayMenuEntry(int index, const char* label) {
+    printf("%d | %s\n", index, label);
+}
+
+void displayMenu() {
+    displayMenuEntry(1, "Addition");
+    displayMenuEntry(2, "Substraction");
+    displayMenuEntry(3, "Multiplication");
+    displayMenuEntry(4, "XOR");
+    displayMenuEntry(5, "Exit");
+}
+
+/** Prompt the user for his operation choice.
+ *
+ * @return The selected operation. No invalid value can be returned.
+ */
+int promptOperation() {
+    displayMenu();
+    int result;
+
+    do {
+        result = promptValue("Choose an option");
+
+        if (result >= 1 && result <= 5) {
+            break;
+        }
+
+        puts("Please choose a valid option (1-5)");
+    } while (true);
+
+    return result;
+}
+
+int main() {
+    int operation = promptOperation();
+
+    if (operation == 5) {
+        return 0;
+    }
+
+    int initialValue = promptValue("Initial value");
+
+    do {
+        int nextValue = promptValue("Next value");
+
+        if (nextValue == 0) {
+            break;
+        }
+
+        switch (operation) {
+        // Addition
+        case 1:
+            initialValue += nextValue;
+            break;
+
+        // Substraction
+        case 2:
+            initialValue -= nextValue;
+            break;
+
+        // Multiplication
+        case 3:
+            initialValue *= nextValue;
+            break;
+
+        // XOR
+        case 4:
+            initialValue ^= nextValue;
+            break;
+        }
+
+        printf("Result: %d\n", initialValue);
+    } while (true);
+}
diff --git a/TP_7_C/exo3-base.c b/TP_7_C/exo3-base.c
new file mode 100644 (file)
index 0000000..c50753c
--- /dev/null
@@ -0,0 +1,33 @@
+#include <stdio.h>
+
+int stringLength(const char* str) {
+    int result = 0;
+
+    while (str[result] != '\0') {
+        ++result;
+    }
+
+    return result;
+}
+
+void swap(char* v1, char* v2) {
+    char temp = *v1;
+    *v1 = *v2;
+    *v2 = temp;
+}
+
+void reverseString(char* str) {
+    int length = stringLength(str);
+    int halfLength = length / 2;
+
+    for (int charId = 0; charId < halfLength; ++charId) {
+        swap(&str[charId], &str[length - charId - 1]);
+    }
+}
+
+int main() {
+    char msg[] = "Votre message";
+    printf("Initial value: \"%s\"\n", msg);
+    reverseString(msg);
+    printf("Reversed     : \"%s\"\n", msg);
+}
diff --git a/TP_7_C/exo3-extra.c b/TP_7_C/exo3-extra.c
new file mode 100644 (file)
index 0000000..36fdb64
--- /dev/null
@@ -0,0 +1,60 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+int stringLength(const char* str) {
+    int result = 0;
+
+    for (; str[result]; ++result);
+
+    return result;
+}
+
+void swap(char* v1, char* v2) {
+    char temp = *v1;
+    *v1 = *v2;
+    *v2 = temp;
+}
+
+void reverseString(char* str) {
+    char* begin = str;
+    char* end = str + stringLength(str) - 1;
+
+    while (begin < end) {
+        swap(begin++, end--);
+    }
+}
+
+/** Perform a classical ROT13 permutation in-place */
+void rot13(char* str) {
+    char* cursor = str;
+    char* end = str + stringLength(str);
+
+    while (cursor < end) {
+        if (*cursor >= 'a' && *cursor <= 'z') {
+            *cursor = (*cursor - 'a' + 13) % 26 + 'a';
+        } else if (*cursor >= 'A' && *cursor <= 'Z') {
+            *cursor = (*cursor - 'A' + 13) % 26 + 'A';
+        }
+
+        ++cursor;
+    }
+}
+
+int main() {
+    char* msg;
+    puts("Enter your message:");
+    int readValue = scanf("%ms", &msg);
+
+    if (readValue == 0) {
+        puts("oops");
+        return 0;
+    }
+
+    printf("Initial value: \"%s\"\n", msg);
+    reverseString(msg);
+    printf("Reversed     : \"%s\"\n", msg);
+    reverseString(msg); // Restore the original message
+    rot13(msg);
+    printf("ROT13        : \"%s\"\n", msg);
+    free(msg); // scanf("%ms") allocate dynamic memory
+}
diff --git a/TP_7_C/exo3-full.c b/TP_7_C/exo3-full.c
new file mode 100644 (file)
index 0000000..4f6eca0
--- /dev/null
@@ -0,0 +1,55 @@
+#include <stdio.h>
+
+int stringLength(const char* str) {
+    int result = 0;
+
+    while (str[result] != '\0') {
+        ++result;
+    }
+
+    return result;
+}
+
+void swap(char* v1, char* v2) {
+    char temp = *v1;
+    *v1 = *v2;
+    *v2 = temp;
+}
+
+void reverseString(char* str) {
+    int length = stringLength(str);
+    int halfLength = length / 2;
+
+    for (int charId = 0; charId < halfLength; ++charId) {
+        swap(&str[charId], &str[length - charId - 1]);
+    }
+}
+
+/** Perform a classical ROT13 permutation in-place */
+void rot13(char* str) {
+    int length = stringLength(str);
+
+    for (int charId = 0; charId < length; ++charId) {
+        char chrValue = str[charId];
+
+        if (chrValue >= 'a' && chrValue <= 'z') {
+            str[charId] =
+                (chrValue - 'a' // Translate chrValue from 'a'-'z' to 0-25
+                 + 13) // Add 13
+                % 26 // Rotate in 0-25
+                + 'a'; // Translate the value from 0-25 to 'a'-'z'
+        } else if (chrValue >= 'A' && chrValue <= 'Z') {
+            str[charId] = (chrValue - 'A' + 13) % 26 + 'A';
+        }
+    }
+}
+
+int main() {
+    char msg[] = "Votre message";
+    printf("Initial value: \"%s\"\n", msg);
+    reverseString(msg);
+    printf("Reversed     : \"%s\"\n", msg);
+    reverseString(msg); // Restore the original message
+    rot13(msg);
+    printf("ROT13        : \"%s\"\n", msg);
+}