You are on page 1of 8

main.

c

// instructions are in the end of the file #include <stdio.h> #include <stdlib.h> #include "func.h" int main(void) { //input: no input (void) // output: performs a unique task according to the user input int magic_cube[10][10][6], length; int vars[6]; //the magic_square variables chars int vars_value[6]; //the magic square variables value int option_num; int sequence_arr[15], sequence_sum, i, is_magic_cube; while (1) { //the loop is breaked when 3 is inserted // aksing for an option code according to which a task will be performed printf("please enter your option, to exit enter 3\n"); scanf("%i", &option_num); // not-in-range validation while (!isInRange(option_num, 1, 3)) { printf("wrong option\n"); scanf("%i", &option_num); } // exit option if (option_num == 3) { printf("\nGOOD BYE\n"); break; } // search of a subset in an array if (option_num == 1) { printf("please insert 16 numbers:\n"); // getting set of 15 number into sequence_arr for (i = 0; i < 15; i++) { scanf("%i", &sequence_arr[i]); } // getting a sum of a possible subset in sequence_arr scanf("%i", &sequence_sum); //initalizations print_shortest_subset(sequence_arr, sequence_sum); } else if (option_num == 2) { //magic square task length = get_magic_cube(magic_cube, vars); is_magic_cube = check_magic_cube(magic_cube, length, vars_value); if (is_magic_cube) { printf("true\n"); print_vars(vars, vars_value); } else printf("false\n"); } } return (1); }

func.h
#ifndef HI #define HI int int int int char void int int int void int void #endif isInRange(int x, int min, int max); get_length() ; what_is_the_ch_type(char ch) ; is_var_already_in_vars_array(char ch, int vars[], int latest_var_index) ; expected_char(int side, int row, int col, int length); print_magic_cube(int magic_cube[][10][6], int len); check_square_value(int cube[][10][6], int side, int length); check_magic_square(int cube[][10][6], int side, int length, int vars[], int vars_last_index); check_magic_cube(int magic_cube[][10][6], int length, int vars[]); print_vars(int vars_chars[], int vars_values[]); get_magic_cube(int magic_cube[][10][6], int vars[]); print_shortest_subset(int set[], int sum);

func.c

#include <stdio.h> #include <stdlib.h> #include "func.h" int isInRange(int x, int min, int max) { //input: three integers x, min and max //output: returns 1 if min<=x<=max and 0 otherwise return x >= min && x <= max; } int get_length() { //input: no input //output: asks for an integer between 1 and 10 and returns it (validations are performed) int length; printf("please insert length\n"); scanf("%i", &length); while (!isInRange(length, 1, 10)) { //validation for wrong input printf("input error\nplease insert length\n"); scanf("%i", &length); } return length; } int what_is_the_ch_type(char ch) { //input: a char //output: returns -1 if the char is a small english letter. Returns the numeral value of the number if the char represents a digit and -2 otherwise int value = (int) ch - (int) '0'; if (isInRange(value, 0, 9)) { //digit return value; } else if (isInRange(ch, (int) 'a', (int) 'z')) { //variable (a small english letter) return -1; } else { //invalid char return -2; } } int is_var_already_in_vars_array (char ch, int vars[], int latest_var_index) { //input: a char, 1-d array and the latest index to check in it //output: if the char was found inside the array (from 0 to latest_var_index) the function returns the index of the found item and -1 otherwise int i; ch = (int) ch; for (i = 0; i <= latest_var_index; i++) { if (vars[i] == ch) { return i; } } return -1; } char expected_char(int side, int row, int col, int length) { //input: the integers "side", "row" and "col" (representing the current indexes of the magic cube input) ,and the length of the magic cube //output: returns the char ' ', if it's not the last input (the last side AND the last row AND the last column) of the magic cube and '/n' otherwise if (side == 5 && row == length - 1 && col == length - 1) { return '\n'; } else { return ' '; } } void print_magic_cube(int magic_cube[][10][6], int len) { //input: magic cube array and its length //output: prints the magic cube (used for debugging) int i, j, k; printf("\n\n"); for (i = 0; i < 6; i++) { for (j = 0; j < len; j++) { for (k = 0; k < len; k++) { printf("%i ", magic_cube[k][j][i]); } printf("\n"); } printf("\n\n"); } } int check_square_value(int cube[][10][6], int side, int length) { //input: cube, side index and the length of the cube's sides //output: returns the value of one of the rows of the square (row with no variables) int i, sum = 0; for (i = 0; i < length; i++) { if (cube[i][0][side] > 0) { sum += cube[i][0][side]; } else { //in case a variable was found in the first row sum = 0; for (i = 0; i < length; i++) { sum += cube[i][1][side]; } break; //breaking from the first row loop } } return sum; }

int check_magic_square(int cube[][10][6], int side, int length, int vars[], int vars_last_index) {

of this array

//input: cube, side index to check for being magic square, the length of the cube's sides, the vars array (where the cube calculated-already vars are) and the last index //output: -2 if the side of cube is not a magic square. Otherwise, the function returns the index of var array (that can be changed because a new var may be assigned) int i, j, sum, var_passed = 0, is_new_var = 0, value = check_square_value(cube, side, length); //par_passed denotes whether the loop passed on the variable of the side (if exists). value is the "magic value" of this side according to the first (or second) row //checking rows for (j = 0; j < length; j++) { sum = 0; if (var_passed) { //variable of the side was checked for (i = 0; i < length; i++) sum += cube[j][i][side]; //suming without checking positive numbers if (sum != value) return -2; //checking the summed value is the "magic value" } else { //variable wasn't found yet for (i = 0; i < length; i++) { if (cube[j][i][side] > 0) { //means the value is not a variable sum += cube[j][i][side]; } else { //the value is variable var_passed = 1; is_new_var = 1; //default if (vars_last_index >= -cube[j][i][side]) { //means that the variables was calculated in the previous sides sum += vars[-cube[j][i][side]]; is_new_var = 0; } } } if (var_passed && is_new_var) { //assaigning new var vars_last_index++; vars[vars_last_index] = value - sum; //complement of the row sum to the magic sum } else if (sum != value) return -2; } } //checking columns var_passed = 0; for (i = 0; i < length; i++) { sum = 0; if (var_passed) { //variable of the side was checked for (j = 0; j < length; j++) sum += cube[j][i][side]; if (sum != value) return -2; } else { for (j = 0; j < length; j++) { if (cube[j][i][side] > 0) { sum += cube[j][i][side]; } else { var_passed = 1; is_new_var = 1; if (vars_last_index >= -cube[j][i][side]) { sum += vars[-cube[j][i][side]]; is_new_var = 0; } } } if (var_passed && is_new_var) { vars_last_index++; vars[vars_last_index] = value - sum; } else if (sum != value) return -2; } } return vars_last_index;

}

int check_magic_cube(int magic_cube[][10][6], int length, int vars[]) { //input: cube array, its length and array of its variables (this array is blank and will be filled in the function) //output: 1 if it's a magic cube and 0 otherwise int vars_last_index = -1, i; for (i = 0; i < 6; i++) { //looping the sides vars_last_index = check_magic_square(magic_cube, i, length, vars, vars_last_index); if (vars_last_index == -2) { //means the side is not of a magic cube return 0; } } return 1; } void print_vars(int vars_chars[], int vars_values[]) { //input: the arrays of the magic square chars and values and the last index of them //output: prints the variables chars and their value (x=1,y=2 etc...) int i = 0; while (vars_chars[i] != 0 && i < 6) { //vars_chars is filled with zeros after the place of the last variable printf("%c=%i\n", vars_chars[i], vars_values[i]); i++; } }

int get_magic_cube(int magic_cube[][10][6], int vars[]) { //input: magic square array and variables array (the array that will contain the chars of the variables) //output: asks the user to enter the length of the square and gets the magic square data while performing validations (at the end of the function the data will be valid) static int variables_length, temp_val, ch_type, current_expected_char; static int i, j, k, one_var_flag, valid_flag, temp_var_pos;

static char ch; //the char that is used for getting the input int length; //length of the magic square length = get_length(); //asks for cube length valid_flag = 0; //for first iteration getchar(); //handle the last "enter" while (!valid_flag) { valid_flag = 1; for (i = 0; i < 6; i++) vars[i] = 0; //resets variables array variables_length = -1; //resets variables index printf("please enter %i numbers\n", 6 * length * length); for (i = 0; i < 6; i++) { //sides loop one_var_flag = 0; //initializing the flag denoting that there is a var in this side for (j = 0; j < length; j++) { //rows loop for (k = 0; k < length; k++) {//columns loop ch = getchar(); current_expected_char = expected_char(i, j, k, length); //the expected char after the input. "space" if it's not the last input and "enter" otherwise ch_type = what_is_the_ch_type(ch); //digit, var or invalid switch (ch_type) { case -2 : //invalid char valid_flag = 0; break; case -1 : //var char if (!one_var_flag) { //checks if one var was already inserted in this side one_var_flag = 1; temp_var_pos = is_var_already_in_vars_array(ch, vars, variables_length); //to check if it's new variable if (temp_var_pos == -1) { //that's means no such var was inserted before variables_length++; vars[variables_length] = (int) ch; magic_cube[k][j][i] = -variables_length; //var is indicated by the negative value of its index in vars array } else {//that var was inserted already magic_cube[k][j][i] = -temp_var_pos; //"temp_var_pos" is the index where "ch" is } ch = getchar(); if (ch != current_expected_char) valid_flag = 0; //unsuitable char after the var } else valid_flag = 0; //more than one var for this side break; default: temp_val = 0; //initialization of the total sum do { temp_val *= 10; //pushing the number to the left temp_val += ch_type; //"ch_type" is the value of the digit from the input ch = getchar(); ch_type = what_is_the_ch_type(ch); } while (ch_type >= 0); if (ch != current_expected_char) { //invalid char after the end of the number valid_flag = 0; } else { //a valid end of input was inserted magic_cube[k][j][i] = temp_val; //inserts the total number to the cube } break; } if (!valid_flag) {//breaks the loop if an invalid input was recognized break; } } if (!valid_flag) {//breaks the loop if the internal loop recognized an invalid input break; } } if (!valid_flag) {//breaks the loop if the internal loop recognized an invalid input break; } } if (!valid_flag) { //the input is invalid independent of what is the continuation of the input while (ch != '\n') { //tells the user that the input is invalid after "enter" ch = getchar(); } printf("input error\n"); } else { //print_magic_cube(magic_cube, length); //debug } } return length; }

void print_shortest_subset(int set[], int sum) { //input: 1-d array "set" of 15 items and an integer "sum" // output: prints the shortest and latest (priority in accordance to order of writing) subset in "set" which its items' sum equals to "sum". If no such subset exists in "set" then "no sequense" is printed. int minimal_length = 15, // the length of the shortest subset found so far subset_start_index = -1, // the index of the begining of the shortest subset found so far start_pos_index, //beginning index of the checked subset temp_pos, // the last index of the subset checked now temp_sum, // the current sum of the checked subset temp_length // the current length of the checked subset , i; //looping the array items to check each to be the first item in the searched subset for (start_pos_index = 0; start_pos_index < 15; start_pos_index++) { //initalizations temp_sum = 0; temp_pos = start_pos_index; temp_length = 0; //increasing temp_pos while [start_pos_index, temp_pos] is a possible begining of the required subset do { temp_length++; temp_sum += set[temp_pos]; temp_pos++; } while (temp_length < minimal_length && temp_pos < 15 && temp_sum < sum); //conditions that the subset [start_pos_index, temp_pos] is the shortest required subset if (temp_sum == sum && temp_length <= minimal_length) { // crowning a new subset and assaigning the variables as needed minimal_length = temp_length; subset_start_index = start_pos_index; }

} // prints the requird subset (if found) if (subset_start_index != -1) { i = subset_start_index; temp_length = 0; while (temp_length < minimal_length) {

} else { } }

} printf("\n\n");

printf("%i ", set[i]); i++; temp_length++;

printf("no sequense\n");

Makefile.c
a.out: func.o main.o gcc func.o main.o functions.o: func.c gcc -c func.c main.o: main.c gcc -c main.c