Skip to content
Snippets Groups Projects
Commit 760975a9 authored by orestis.malaspin's avatar orestis.malaspin
Browse files

Adds a min_i32 fucntion to C and Rust codes

parent e45fb298
No related branches found
No related tags found
No related merge requests found
#include <errno.h> #include <errno.h>
#include <inttypes.h>
#include <limits.h> #include <limits.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
...@@ -14,34 +15,34 @@ const char *usage_msg = ...@@ -14,34 +15,34 @@ const char *usage_msg =
// Copies the value of the smallest value in the tab array in the min variable. // Copies the value of the smallest value in the tab array in the min variable.
// Returns the pointer to a newly allocated value of the minimum value of the // Returns the pointer to a newly allocated value of the minimum value of the
// array if everything went fine. Returns NULL otherwise // array if everything went fine. Returns NULL otherwise
int *list_find_min(int *tab, int size); int *list_find_min(int32_t *tab, int size);
// Prints all the element in the tab array. // Prints all the element in the tab array.
// Returns -1 if size <= 0 // Returns -1 if size <= 0
// Returns -2 if tab is NULL // Returns -2 if tab is NULL
// Any other value means that everything went fine // Any other value means that everything went fine
int list_print(int *tab, int size); int list_print(int32_t *tab, int size);
// Exits if the error code shows invalidity // Exits if the error code shows invalidity
void error_handling(int error_code, int **tab); void error_handling(int error_code, int32_t **tab);
// Parses a string to an integer. // Parses a string to an integer.
// Returns a pointer to newly allocated data. // Returns a pointer to newly allocated data.
// Returns NULL if conversion failed. // Returns NULL if conversion failed.
int *parse_int(char *arg_to_transform); int *parse_int32(char *arg_to_transform);
// Reads the command line inputs and stores them // Reads the command line inputs and stores them
// in a newly allocated array. // in a newly allocated array.
// Returns the array with the parsed numbers or NULL if allocation failed or an // Returns the array with the parsed numbers or NULL if allocation failed or an
// invalid number was parsed. // invalid number was parsed.
int *read_input(int size, char *char_num[]) { int *read_input(int size, char *char_num[]) {
int *tab = malloc(size * sizeof(*tab)); int32_t *tab = malloc(size * sizeof(*tab));
if (NULL == tab) { if (NULL == tab) {
fprintf(stderr, "Memory allocation failed\n"); fprintf(stderr, "Memory allocation failed\n");
return NULL; return NULL;
} }
for (int i = 0; i < size; ++i) { for (int i = 0; i < size; ++i) {
int *num = parse_int(char_num[i]); int *num = parse_int32(char_num[i]);
if (NULL == num) { if (NULL == num) {
free(tab); free(tab);
fprintf(stderr, "Tried to parse %s which is not a valid integer.\n", fprintf(stderr, "Tried to parse %s which is not a valid integer.\n",
...@@ -64,7 +65,7 @@ int main(int argc, char *argv[]) { ...@@ -64,7 +65,7 @@ int main(int argc, char *argv[]) {
} }
int size = argc - 1; int size = argc - 1;
int *tab = read_input(size, &argv[1]); int32_t *tab = read_input(size, &argv[1]);
if (NULL == tab) { if (NULL == tab) {
fprintf(stderr, "Failure during argument parsing.\n"); fprintf(stderr, "Failure during argument parsing.\n");
return EXIT_FAILURE; return EXIT_FAILURE;
...@@ -88,8 +89,16 @@ int main(int argc, char *argv[]) { ...@@ -88,8 +89,16 @@ int main(int argc, char *argv[]) {
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
int min_i32(int32_t lhs, int32_t rhs) {
if (lhs < rhs) {
return lhs;
} else {
return rhs;
}
}
// Checks if size is valid and tab is not NULL // Checks if size is valid and tab is not NULL
int list_is_valid(int *tab, int size) { int list_is_valid(int32_t *tab, int size) {
if (size <= 0) { if (size <= 0) {
return -1; return -1;
} }
...@@ -99,7 +108,7 @@ int list_is_valid(int *tab, int size) { ...@@ -99,7 +108,7 @@ int list_is_valid(int *tab, int size) {
return 0; return 0;
} }
int list_print(int *tab, int size) { int list_print(int32_t *tab, int size) {
int code = list_is_valid(tab, size); int code = list_is_valid(tab, size);
if (code < 0) { if (code < 0) {
return code; return code;
...@@ -112,23 +121,21 @@ int list_print(int *tab, int size) { ...@@ -112,23 +121,21 @@ int list_print(int *tab, int size) {
return code; return code;
} }
int *list_find_min(int *tab, int size) { int32_t *list_find_min(int32_t *tab, int size) {
int code = list_is_valid(tab, size); int code = list_is_valid(tab, size);
if (code < 0) { if (code < 0) {
return NULL; return NULL;
} }
int *min = malloc(sizeof(*min)); int32_t *min = malloc(sizeof(*min));
*min = tab[0]; *min = tab[0];
for (int i = 1; i < size; ++i) { for (int i = 1; i < size; ++i) {
if (tab[i] < *min) { *min = min_i32(*min, tab[i]);
*min = tab[i];
}
} }
return min; return min;
} }
void error_handling(int error_code, int **tab) { void error_handling(int error_code, int32_t **tab) {
switch (error_code) { switch (error_code) {
case -1: case -1:
fprintf(stderr, "Return value, %d. Size is <= 0.\n", error_code); fprintf(stderr, "Return value, %d. Size is <= 0.\n", error_code);
...@@ -147,7 +154,7 @@ void error_handling(int error_code, int **tab) { ...@@ -147,7 +154,7 @@ void error_handling(int error_code, int **tab) {
} }
} }
int *parse_int(char *arg_to_transform) { int32_t *parse_int32(char *arg_to_transform) {
if (strlen(arg_to_transform) == 0) { if (strlen(arg_to_transform) == 0) {
return NULL; // empty string to parse return NULL; // empty string to parse
} }
...@@ -156,13 +163,13 @@ int *parse_int(char *arg_to_transform) { ...@@ -156,13 +163,13 @@ int *parse_int(char *arg_to_transform) {
long arg = strtol(arg_to_transform, &remaining, long arg = strtol(arg_to_transform, &remaining,
10); // number is parsed in base 10 10); // number is parsed in base 10
if (*remaining != '\0' || errno != 0) { if (*remaining != '\0' || errno != 0) {
return NULL; // Empty string parsed or an error occurred return NULL; // Empty string parsed or an error occurred
} }
if (arg < INT_MIN || arg > INT_MAX) { if (arg < INT_MIN || arg > INT_MAX) {
return NULL; // Not within the limits of an int return NULL; // Not within the limits of an int
} }
int *num = malloc(sizeof(*num)); int32_t *num = malloc(sizeof(*num));
*num = (int)arg; *num = (int32_t)arg;
return num; return num;
} }
File moved
[package]
name = "part01"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
/// Rust basics:
/// - Functions
/// - Arguments are "moved"
/// - if is an expression
/// - Tuples
/// - Destructuring
const SIZE: usize = 9;
fn read_command_line() -> [i32; SIZE] {
[10, 32, 12, 43, 52, 53, 83, 2, 9]
}
// Check if the size is large enough (more that 1 element)
fn check_size(size: usize) {
if size == 0 {
panic!("Size is of tab = 0.");
}
}
// Prints tab and returns tab.
// Tab would be destructed at the end of the function otherwise.
fn print_tab(tab: [i32; SIZE], size: usize) -> [i32; SIZE] {
check_size(size);
for i in 0..size {
print!("{} ", tab[i]);
}
println!();
tab
}
fn min_i32(lhs: i32, rhs: i32) -> i32 {
if lhs < rhs {
lhs
} else {
rhs
}
}
fn find_min(tab: [i32; SIZE], size: usize) -> ([i32; SIZE], i32) {
check_size(size);
let mut min = tab[0];
for i in 1..size {
min = min_i32(min, tab[i]);
}
(tab, min)
}
fn main() {
let tab = read_command_line();
println!("Among the numbers in the list:");
let tab = print_tab(tab, SIZE);
// There are alternatives to access fields of tuples
let (_, min) = find_min(tab, SIZE);
// The first field is not used therefore we can replace it with "_"
println!("The minimal value is: {}", min);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment