9511_workbook

solved exercises from algorithms & programming I (9511) prof. Cardozo
Index Commits Files Refs README
commit eff0d54bd42b931ca0cda7a65f5c4ef1d9b4fe7f
parent fe1cd8ff532510dfe16619027b0d57d0dc12ee57
Author: klewer-martin <martin.cachari@gmail.com>
Date:   Sat,  3 Jul 2021 01:12:37 -0300

Update

Diffstat:
A.gitignore | 1+
Mguia03/ex08.c | 6++----
Mguia06/ex02.c | 9++++++---
Aguia06/ex03.c | 28++++++++++++++++++++++++++++
Mguia08/ex11.c | 86+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------
Aguia08/ex12.c | 151++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aguia10/:w | 22++++++++++++++++++++++
Aguia10/ex01.c | 6++++++
Aguia10/ex11.c | 33+++++++++++++++++++++++++++++++++
9 files changed, 322 insertions(+), 20 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -0,0 +1 @@
+*.csv
diff --git a/guia03/ex08.c b/guia03/ex08.c
@@ -2,12 +2,10 @@
 #include <string.h>
 
 size_t str_len(const char *str) {
-    if(str == NULL)
-        return 1;
+    if(str == NULL) return 1;
 
     size_t i = 0;
-    while(str[i++])
-        ; 
+    while(str[i++]); 
 
     return i;
 }
diff --git a/guia06/ex02.c b/guia06/ex02.c
@@ -1,10 +1,10 @@
 #include <stdio.h>
 
-#define ARGS
+#define ARGS 3 /* Two strings + the program name */
 
 typedef enum {
     OK,
-    ERROR_NO_ARGUMENT,
+    ERROR_PROGRAM_INVOCATION,
     ERROR_NULL_POINTER,
 } status_t;
 
@@ -22,11 +22,14 @@ int main (int argc, char *argv[])
         cmp += ((argv[1][i]) - (argv[2][i]));
     }
 
-    printf("%s\n", cmp ? "Son distintas" : "Son iguales");
+    printf("%d\n", cmp);
     return 0;
 }
 
 status_t validate_arguments(int argc, char *argv[])
 {
+    if(!argv) return ERROR_NULL_POINTER;
+    if(argc != ARGS) return ERROR_PROGRAM_INVOCATION;
+
     return OK;
 }
diff --git a/guia06/ex03.c b/guia06/ex03.c
@@ -0,0 +1,28 @@
+#include <stdio.h>
+
+#define ARGS 2 /* Program name + one number */
+
+typedef enum {
+    OK,
+    ERROR_PROGRAM_INVOCATION,
+    ERROR_NULL_POINTER
+} status_t;
+
+status_t validate_arguments(int argc, char *argv[]);
+
+int main (int argc, char *argv[])
+{
+    size_t n, res;
+
+    n = strtol(argv[NUMBER_POS], NULL, 10);
+
+    return 0;
+}
+
+status_t validate_arguments(int argc, char *argv[])
+{
+    if(!argv) return ERROR_NULL_POINTER;
+    if(argc != ARGS) return ERROR_PROGRAM_INVOCATION;
+
+    return 0K
+}
diff --git a/guia08/ex11.c b/guia08/ex11.c
@@ -1,36 +1,98 @@
-/* guia08/ej11.c 
+/* guia08/ej11.c + CLA
  * por Martin J. Klöckner
  * github.com/klewer-martin
  */
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
+
+#define ARGS    2    /* Program name and file to read name */
+#define FILE_NAME_POS    1
+
+#define MSG_USAGE    "Usage: ./a.out <file name>"
 
 #define ARR_INIT_SIZE    3
 #define STR_INIT_SIZE    10
 
 #define GROWTH_FACTOR    2
 
+#define LOAD_FILE_BUFFER_SIZE 100
+
+typedef enum {
+    OK,
+    ERROR_PROGRAM_INVOCATION,
+    ERROR_OPENING_FILE,
+    ERROR_ALLOC_MEMORY,
+    ERROR_NULL_POINTER
+} status_t;
+
+status_t validate_arguments(int argc, char *argv[]);
+
+status_t load_file(const char *file_name, char **array);
 char **split(const char *s, char delim, size_t *fields);
 
-int main (void)
+int main (int argc, char *argv[])
 {
-    char csv[] = "Hola,Hello,Hallo,Aloha";
-    char **arr;
+    char **arr, *input;
     size_t i, len;
+    status_t st;
+
+    if((st = validate_arguments(argc, argv))) {
+        fprintf(stderr, "%s\n", MSG_USAGE);
+        return ERROR_PROGRAM_INVOCATION;
+    } 
+
+    if((st = load_file(argv[FILE_NAME_POS], &input))) return st;
 
-    if(!(arr = split(csv, ',', &len))) return 1;
+    if(!(arr = split(input, ',', &len))) return 1;
 
     for(i = 0; i <= len; i++)
-        puts(arr[i]);
+        printf("%s\n", arr[i]);
 
     while(len + 1) free(arr[len--]);
 
     free(arr);
+    free(input);
 
     return 0;
 }
 
+status_t validate_arguments(int argc, char *argv[])
+{
+    if(!argv) return ERROR_NULL_POINTER;
+    if(argc != ARGS) return ERROR_PROGRAM_INVOCATION;
+
+    return OK;
+}
+
+status_t load_file(const char *file_name, char **array)
+{
+    FILE *fp;
+    size_t alloc_size;
+
+    if(!(fp = fopen(file_name, "rt"))) return ERROR_OPENING_FILE;
+
+    alloc_size = LOAD_FILE_BUFFER_SIZE;
+    if(!(*array = calloc(sizeof(char), alloc_size))) return ERROR_ALLOC_MEMORY;
+
+    for(size_t i = 0; ((*array)[i] = fgetc(fp)) != EOF; i++) {
+        if(i == (alloc_size - 2)) {
+            alloc_size *= 2;
+            if(!(*array = realloc(*array, alloc_size))) {
+                free(*array);
+                array = NULL;
+                fclose(fp);
+                return ERROR_ALLOC_MEMORY;
+            }
+        }
+    }
+
+    fclose(fp);
+    return OK;
+}
+
+/* Recibe una cadena de caracteres de longitud desconocida, con valores separados por un caracter delimitador y los separa en cadenas de caracteres de longitud dinamica */
 char **split(const char *s, char delim, size_t *fields)
 {
     if(!s || !fields) return NULL;
@@ -44,7 +106,7 @@ char **split(const char *s, char delim, size_t *fields)
     if(!(arr = (char **)calloc(sizeof(char *), arr_size))) return NULL;
 
     if(!(*arr = (char *)calloc(sizeof(char), str_size))) {
-        free(arr)
+        free(arr);
         return NULL;
     }
 
@@ -61,9 +123,7 @@ char **split(const char *s, char delim, size_t *fields)
                 return NULL;
             }
         }
-
-        if(*s == delim) {            
-            /* Gets memory for a new string and increments arr index by one */
+        if((*s == delim) || (*s == '\n')) {    
             if(!(arr[++(*fields)] = (char *)calloc(sizeof(char), str_size))) {
                 /* If it can't get more memory then all the previous allocations gets freed */
                 while(*fields)
@@ -75,9 +135,8 @@ char **split(const char *s, char delim, size_t *fields)
             i = 0;
             s++;
         }
-        /* This makes sure that every string has available memory, if not then it gets more */
-        if(i == (str_size - 2))
-        {
+        /* This makes sure that the current string has available memory, if not then it gets more */
+        if(i == (str_size - 2)) {
             str_size *= GROWTH_FACTOR;
             if(!(arr[*fields] = (char *)realloc(arr[*fields], str_size))) {
                 /* If it can't get more memory all the previous used memmory gets freed */
@@ -92,5 +151,6 @@ char **split(const char *s, char delim, size_t *fields)
         }
         arr[*fields][i] = (*s);
     }
+    free(arr[(*fields)--]);
     return arr;
 }
diff --git a/guia08/ex12.c b/guia08/ex12.c
@@ -0,0 +1,151 @@
+/* guia08/ej12.c + CLA
+ * por Martin J. Klöckner
+ * github.com/klewer-martin
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define FILE_NAME_POS    1
+#define ARGS            2
+
+#define MSG_USAGE        "Usage: ./a.out <file name>"
+
+#define GROWTH_FACTOR    2
+
+#define ARR_INIT_SIZE    1000
+#define STR_INIT_SIZE    2
+
+#define LOAD_FILE_BUFFER_SIZE 100
+
+typedef enum {
+    OK,
+    ERROR_PROGRAM_INVOCATION,
+    ERROR_OPENING_FILE,
+    ERROR_ALLOC_MEMORY,
+    ERROR_NULL_POINTER
+} status_t;
+
+status_t validate_arguments(int argc, char *argv[]);
+
+status_t load_file(const char *file_name, char **array);
+status_t split(const char *s, char ***array, char delim, size_t *fields);
+
+int main (int argc, char *argv[])
+{
+    char **arr, *input;
+    size_t i, len;
+    status_t st;
+
+    if((st = validate_arguments(argc, argv))) {
+        fprintf(stderr, "%s\n", MSG_USAGE);
+        return ERROR_PROGRAM_INVOCATION;
+    } 
+
+    if((st = load_file(argv[FILE_NAME_POS], &input))) return st;
+
+    if((st = split(input, &arr, ',', &len))) return st;
+
+    free(input);
+
+    for(i = 0; i <= len; i++)
+        printf("%s\n", arr[i]);
+
+    while(len + 1) free(arr[len--]);
+
+    free(arr);
+
+    return 0;
+}
+
+status_t validate_arguments(int argc, char *argv[])
+{
+    if(!argv) return ERROR_NULL_POINTER;
+    if(argc != ARGS) return ERROR_PROGRAM_INVOCATION;
+
+    return OK;
+}
+
+status_t load_file(const char *file_name, char **array)
+{
+    FILE *fp;
+    size_t alloc_size;
+
+    if(!(fp = fopen(file_name, "rt"))) return ERROR_OPENING_FILE;
+
+    alloc_size = LOAD_FILE_BUFFER_SIZE;
+    if(!(*array = calloc(sizeof(char), alloc_size))) return ERROR_ALLOC_MEMORY;
+
+    for(size_t i = 0; ((*array)[i] = fgetc(fp)) != EOF; i++) {
+        if(i == (alloc_size - 2)) {
+            alloc_size *= 2;
+            if(!(*array = realloc(*array, alloc_size))) {
+                free(*array);
+                array = NULL;
+                fclose(fp);
+                return ERROR_ALLOC_MEMORY;
+            }
+        }
+    }
+
+    fclose(fp);
+    return OK;
+}
+
+/* Recibe una cadena de caracteres de longitud desconocida, con valores separados por un caracter delimitador y los separa en cadenas de caracteres de longitud dinamica */
+status_t split(const char *s, char ***array, char delim, size_t *fields)
+{
+    if(!s || !fields) return ERROR_NULL_POINTER;
+
+    size_t i, arr_size, str_size;
+
+    arr_size = ARR_INIT_SIZE;
+    str_size = STR_INIT_SIZE;
+
+    if(!(*array = (char **)calloc(sizeof(char *), arr_size))) return ERROR_ALLOC_MEMORY;
+
+    if(!(**array = (char *)calloc(sizeof(char), str_size))) { free(*array); return ERROR_ALLOC_MEMORY; }
+
+    for(*fields = i = 0; *s; i++, s++) {
+        /* If the array doesn't have any memory left then it gets more memory */
+        if(*fields == (arr_size - 1)) {
+            /* Exponential growth of the array */
+            arr_size *= GROWTH_FACTOR;
+            if(!(*array = (char **)realloc(*array, arr_size * sizeof(char *)))) {
+                /* If it can't get more memory then all the previous allocations gets freed */
+                while((*fields) + 1) free((*array)[(*fields)--]);
+                free(*array);
+                return ERROR_ALLOC_MEMORY;
+            }
+        }
+        if((*s == delim) || (*s == '\n')) {
+            str_size = STR_INIT_SIZE;
+            if(!((*array)[++(*fields)] = (char *)calloc(sizeof(char), str_size))) {
+                /* If it can't get more memory then all the previous allocations gets freed */
+                while(*fields)
+                    free((*array)[(*fields)--]);
+
+                free(*array);
+                return ERROR_ALLOC_MEMORY;
+            }
+            s++; i = 0;
+        }
+        /* This makes sure that the current string has available memory, if not then it gets more */
+        if(i == (str_size - 2)) {
+            str_size *= GROWTH_FACTOR;
+            if(!((*array)[*fields] = (char *)realloc((*array)[*fields], str_size))) {
+                /* If it can't get more memory all the previous used memmory gets freed */
+                while((*fields) + 1)
+                    free((*array)[(*fields)--]);
+
+                free(*array);
+                return ERROR_ALLOC_MEMORY;
+            }
+        }
+        (*array)[*fields][i] = (*s);
+    } /* End for loop */
+
+    free((*array)[(*fields)--]);
+    return OK;
+}
diff --git a/guia10/:w b/guia10/:w
@@ -0,0 +1,22 @@
+#include <stdio.h>
+
+int dot_product(int *v1, int *v2, size_t j);
+
+int main (void)
+{
+    int v1[3] = { 1,2,3 };
+    int v2[3] = { 1,2,3 };
+    printf("%d\n", dot_product(v1,v2,3));
+    return 0;
+}
+
+int dot_m(int *v1, int *v2, size_t index)
+{
+    if(index == 0) return v1[0] * v2[0];
+    return v1[index] * v2[index] + dot_product(v1, v2, index - 1);
+}
+
+int dot_product(int *v1, int *v2, size_t index)
+{
+    return !index ? v1[0] * v2[0]: v1[l] * v2[l] + dot_product((v1, v2, l - 1);
+}
diff --git a/guia10/ex01.c b/guia10/ex01.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+int main (void)
+{
+    return 0;
+}
diff --git a/guia10/ex11.c b/guia10/ex11.c
@@ -0,0 +1,33 @@
+#include <stdio.h>
+
+int dot_product(int *v1, int *v2, size_t l);
+
+void test(int *v1);
+
+int main (void)
+{
+    int v1[4] = { 1,2,3,4 };
+    int v2[4] = { 1,2,3,4 };
+    printf("%d\n", dot_product(v1,v2,4));
+
+    test(v1);
+
+    printf("v1 elements: %ld\n", sizeof(v1) / sizeof(int));
+    return 0;
+}
+
+/* int dot_m(int *v1, int *v2, size_t index) */
+/* { */
+/*     if(index == 0) return v1[0] * v2[0]; */
+/*     return v1[index] * v2[index] + dot_product(v1, v2, index - 1); */
+/* } */
+
+void test(int *v1)
+{
+    printf("%ld\n", sizeof(*v1));
+}
+
+int dot_product(int *v1, int *v2, size_t l)
+{
+    return l ? v1[l-1] * v2[l-1] + dot_product(v1, v2, l-1) : 0;
+}