Adding files for DSA
This commit is contained in:
parent
ac8d1be38c
commit
b2e5d19c66
3 changed files with 10486 additions and 0 deletions
10000
extra/DSA/hw1data
Normal file
10000
extra/DSA/hw1data
Normal file
File diff suppressed because it is too large
Load diff
246
extra/DSA/matrix-cube.c
Normal file
246
extra/DSA/matrix-cube.c
Normal file
|
@ -0,0 +1,246 @@
|
|||
/*
|
||||
Created by Fry.
|
||||
Date: 10.12.2016
|
||||
https://www.ryoko-rpg.ro
|
||||
https://github.com/Metonimie
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define VISITED_MASK ( (unsigned) 1 << 4)
|
||||
#define DEATH_MASK ( (unsigned) 1 << 5)
|
||||
#define EXIT_MASK ( (unsigned) 1 << 6)
|
||||
#define WALL_MASK ( (unsigned) 1 << 7)
|
||||
#define NUMBER_MASK ~( (unsigned) ~0 << 4)
|
||||
|
||||
#define ISVISITED(x) ((x) & VISITED_MASK)
|
||||
#define ISDEATH(x) ((x) & DEATH_MASK)
|
||||
#define ISEXIT(x) ((x) & EXIT_MASK)
|
||||
#define ISWALL(x) ((x) & WALL_MASK)
|
||||
#define GETNUMBER(x) ((x) & NUMBER_MASK)
|
||||
|
||||
unsigned rows = 4;
|
||||
unsigned cols = 4;
|
||||
|
||||
unsigned testM[4][4] = {
|
||||
{0, 0, 0, 0},
|
||||
{0, 0, 0, 0},
|
||||
{0, 0, 0, 0},
|
||||
{0, 0, 0, 0},
|
||||
};
|
||||
|
||||
// The number will represent the death time, when it reaches 0, the cell
|
||||
// becomes a death wall.
|
||||
|
||||
void make_visited_cell(unsigned * x) { *x |= VISITED_MASK; }
|
||||
void unmake_visited_cell(unsigned * x) { *x &= ~VISITED_MASK; }
|
||||
|
||||
void make_death_cell(unsigned * x) { *x |= DEATH_MASK; }
|
||||
void unmake_death_cell(unsigned * x) { *x &= ~DEATH_MASK; }
|
||||
|
||||
void make_exit_cell(unsigned * x) { *x |= EXIT_MASK; }
|
||||
void unmake_exit_cell(unsigned * x) { *x &= ~EXIT_MASK; }
|
||||
|
||||
void make_wall_cell(unsigned * x) { *x |= WALL_MASK; }
|
||||
void unmake_wall_cell(unsigned * x) { *x &= ~WALL_MASK; }
|
||||
|
||||
void increment_cell(unsigned * x) {
|
||||
// We don't want to mess with walls or the exit cell.
|
||||
if ( ISWALL(*x) || ISEXIT(*x)) {
|
||||
return;
|
||||
}
|
||||
// check the timmer is not bigget than 15, the maximum value for a timmer.
|
||||
if ( GETNUMBER(*x) < 16 ) {
|
||||
*x = *x + 1;
|
||||
}
|
||||
}
|
||||
|
||||
void decrement_cell(unsigned * x) {
|
||||
// We don't want to mess with walls or the exit cell.
|
||||
if ( ISWALL(*x) || ISEXIT(*x)) {
|
||||
return;
|
||||
}
|
||||
// We need to make sure the cell is always greater than 0.
|
||||
if ( GETNUMBER(*x) > 0 ) {
|
||||
*x = *x - 1;
|
||||
}
|
||||
}
|
||||
|
||||
// This should be called when updating the timmers of a cell that's not a
|
||||
// death cell.
|
||||
void update_cell_mechanism() {
|
||||
for (unsigned i = 0; i < rows; ++i) {
|
||||
for (unsigned j = 0; j < cols; ++j) {
|
||||
// We don't update the walls or exit cells.
|
||||
if ( ISWALL(testM[i][j]) || ISEXIT(testM[i][j])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// We update the cell.
|
||||
if ( ISDEATH(testM[i][j]) ) {
|
||||
increment_cell(&testM[i][j]);
|
||||
} else if ( !ISDEATH(testM[i][j]) ) {
|
||||
decrement_cell(&testM[i][j]);
|
||||
}
|
||||
|
||||
// We have a cell that is going to turn.
|
||||
if ( GETNUMBER(testM[i][j] == 0) ) {
|
||||
// We turn the cell.
|
||||
testM[i][j] = testM[i][j] ^ DEATH_MASK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This should be called when backtracking, cheater.
|
||||
void reverse_update_cell_mechanism() {
|
||||
for (unsigned i = 0; i < rows; ++i) {
|
||||
for (unsigned j = 0; j < cols; ++j) {
|
||||
// We don't update the walls or exit cells.
|
||||
if ( ISWALL(testM[i][j]) || ISEXIT(testM[i][j])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// We update the cell.
|
||||
if ( !ISDEATH(testM[i][j]) ) {
|
||||
increment_cell(&testM[i][j]);
|
||||
} else if ( ISDEATH(testM[i][j]) ) {
|
||||
decrement_cell(&testM[i][j]);
|
||||
}
|
||||
|
||||
// We have a cell that is going to turn.
|
||||
if ( GETNUMBER(testM[i][j] == 0) ) {
|
||||
// We turn the cell. Death doesn't wait.
|
||||
testM[i][j] = testM[i][j] ^ DEATH_MASK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void set_timmer(unsigned row, unsigned col, unsigned timer) {
|
||||
// If the timer is correct, we set it. If not, thou shall get blessed.
|
||||
// We don't mess with walls or the exit.
|
||||
if ( ISWALL(testM[row][col]) || ISEXIT(testM[row][col]) ) {
|
||||
return;
|
||||
}
|
||||
if ( timer > 0 && timer < 16) {
|
||||
testM[row][col] += timer;
|
||||
} else {
|
||||
testM[row][col] += (15 - GETNUMBER(testM[row][col]));
|
||||
}
|
||||
}
|
||||
|
||||
void print_matrix2(unsigned m[4][4], unsigned row, unsigned col) {
|
||||
for (unsigned i = 0; i < row; ++i) {
|
||||
for (unsigned j = 0; j < col; ++j) {
|
||||
printf(" ");
|
||||
if ( ISEXIT(testM[i][j])) {
|
||||
printf("E ");
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( ISWALL(testM[i][j])) {
|
||||
printf("W ");
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( ISVISITED(testM[i][j]) ) {
|
||||
printf("V");
|
||||
}
|
||||
|
||||
if ( ISDEATH(testM[i][j]) ) {
|
||||
printf("D");
|
||||
}
|
||||
|
||||
printf("%d ", GETNUMBER(testM[i][j]));
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
unsigned ** new_matrix(unsigned row, unsigned col) {
|
||||
unsigned ** mat = (unsigned **) calloc(row, sizeof(unsigned *));
|
||||
for (unsigned i = 0; i < col; ++i) {
|
||||
mat[i] = (unsigned *) calloc(col, sizeof(unsigned) * col);
|
||||
}
|
||||
return mat;
|
||||
}
|
||||
|
||||
// This function will be called with the initial position from where the player
|
||||
// will start the labyrinth.
|
||||
unsigned solve_mat(unsigned c, unsigned r) {
|
||||
// Make sure we check that everything is safe before accessing memory.
|
||||
if ( !( (c < cols) && (r < rows)) ) {
|
||||
return 0;
|
||||
}
|
||||
// check if we're on a wall or on a visited path or a deathcell.
|
||||
else if ( (ISWALL(testM[r][c])) || ISVISITED(testM[r][c])
|
||||
|| ISDEATH(testM[r][c]) )
|
||||
{
|
||||
return 0;
|
||||
} // check for deathcell.
|
||||
|
||||
// Check if we found the exit.
|
||||
if ( ISEXIT(testM[r][c]) ) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
update_cell_mechanism();
|
||||
make_visited_cell(&testM[r][c]);
|
||||
|
||||
if ( solve_mat(c + 1, r) == 1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( solve_mat(c, r + 1) == 1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( solve_mat(c - 1, r) == 1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( solve_mat(c, r - 1) == 1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
reverse_update_cell_mechanism();
|
||||
unmake_visited_cell(&testM[r][c]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void skip_lines(FILE * fd, unsigned num) {
|
||||
for (unsigned i = 0; i < num; ++i) {
|
||||
fscanf(fd, "%*[^\n]\n", NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void fatal(const char * msg) {
|
||||
fprintf(stderr, "%s\n", msg);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
|
||||
make_exit_cell(&testM[3][3]);
|
||||
make_wall_cell(&testM[0][3]);
|
||||
make_wall_cell(&testM[1][1]);
|
||||
make_wall_cell(&testM[2][1]);
|
||||
make_wall_cell(&testM[2][2]);
|
||||
make_wall_cell(&testM[2][3]);
|
||||
|
||||
for (unsigned i = 0; i < rows; ++i) {
|
||||
for (unsigned j = 0; j < cols; ++j) {
|
||||
set_timmer(i, j, 6);
|
||||
}
|
||||
}
|
||||
|
||||
print_matrix2(testM, 4, 4);
|
||||
unsigned x = solve_mat(0, 0);
|
||||
printf("Solved: %d\n", x);
|
||||
print_matrix2(testM, 4, 4);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
240
extra/DSA/product-browser.c
Normal file
240
extra/DSA/product-browser.c
Normal file
|
@ -0,0 +1,240 @@
|
|||
//razvan.cioarga@cs.upt.ro
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
struct record_t {
|
||||
char product_name[35];
|
||||
int product_code;
|
||||
};
|
||||
|
||||
typedef struct record_t Record;
|
||||
|
||||
Record * records;
|
||||
Record * sorted_by_code;
|
||||
int number_of_records;
|
||||
FILE * input_file;
|
||||
|
||||
int load_records(const char * file_name) {
|
||||
size_t size = 500;
|
||||
input_file = fopen(file_name, "r");
|
||||
if ( !input_file ) {
|
||||
printf("Can't open file: %s \n", file_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int counter = 0;
|
||||
|
||||
records = malloc ( size * sizeof(struct record_t));
|
||||
if ( records == NULL ) {
|
||||
printf("Not enough memory!\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
while (
|
||||
(fscanf(input_file, "%s\n", records[counter].product_name) != EOF ) &&
|
||||
(fscanf(input_file, "%d\n", &records[counter].product_code) != EOF )
|
||||
) {
|
||||
if ( counter > size - 100 ) {
|
||||
size = size + 100;
|
||||
records = realloc(records, size * sizeof(struct record_t));
|
||||
if ( records == NULL ) {
|
||||
printf("Reallocation failed!\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
++counter;
|
||||
}
|
||||
|
||||
number_of_records = counter;
|
||||
|
||||
sorted_by_code = malloc(number_of_records * sizeof(struct record_t));
|
||||
if ( sorted_by_code == NULL ) {
|
||||
printf("Not enough memory!\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
printf("Loaded %d records! \n", counter);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void display() {
|
||||
int const collumns = 3;
|
||||
int tab = 0;
|
||||
printf("FORMAT: PRODUCT NAME - PRODUCT CODE\n");
|
||||
for (int i = 0; i < number_of_records; ++i) {
|
||||
if ( tab % collumns == 0) {
|
||||
printf("\t");
|
||||
}
|
||||
printf("%s - %d ", records[i].product_name,
|
||||
records[i].product_code);
|
||||
if ( tab % collumns == 0) {
|
||||
printf("\n");
|
||||
}
|
||||
++tab;
|
||||
}
|
||||
}
|
||||
|
||||
void sort_ascending(Record * array, int n) {
|
||||
int i, j, min;
|
||||
Record temp;
|
||||
for( i= 0; i <= n-2; i ++)
|
||||
{
|
||||
min= i; temp= array[i];
|
||||
for( j= i+1; j < n; j ++)
|
||||
if ( tolower(array[j].product_name[0]) < tolower(temp.product_name[0]) )
|
||||
{
|
||||
min= j; temp= array[j];
|
||||
} /*FOR*/
|
||||
array[min]= array[i]; array[i]= temp; /*interschimbarea*/
|
||||
} /*FOR*/
|
||||
}
|
||||
|
||||
void sort_ascending_by_code(Record * array, int n) {
|
||||
int i, j, min;
|
||||
Record temp;
|
||||
for( i= 0; i <= n-2; i ++)
|
||||
{
|
||||
min= i; temp= array[i];
|
||||
for( j= i+1; j < n; j ++)
|
||||
if ( array[j].product_code < temp.product_code )
|
||||
{
|
||||
min= j; temp= array[j];
|
||||
} /*FOR*/
|
||||
array[min]= array[i]; array[i]= temp; /*interschimbarea*/
|
||||
} /*FOR*/
|
||||
}
|
||||
|
||||
Record * search_by_code(Record * a, int n, int x) {
|
||||
int s, d, gasit, m;
|
||||
s=0; d=n; gasit=0;
|
||||
while(s<d)
|
||||
{
|
||||
m=(s+d)/2; /*sau orice valoare cuprinsă între s şi d*/
|
||||
if(a[m].product_code<x)
|
||||
s=m+1;
|
||||
else
|
||||
d=m;
|
||||
}
|
||||
if(d>=n)
|
||||
{ /*elementul cautat nu exista*/
|
||||
}
|
||||
else
|
||||
if (a[d].product_code==x) {/*avem o coincidenta la indicele d */
|
||||
return &a[d];
|
||||
}
|
||||
else
|
||||
{/*elementul cautat nu exista*/
|
||||
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void sort_odd_by_product_code(Record * array, int n) {
|
||||
int i, j, min;
|
||||
Record temp;
|
||||
for( i= 0; i <= n-2; i ++)
|
||||
{
|
||||
min= i; temp= array[i];
|
||||
for( j= i+1; j < n; j ++)
|
||||
if ( array[j].product_code > temp.product_code &&
|
||||
(array[j].product_code % 2 != 0) &&
|
||||
(temp.product_code) % 2 != 0
|
||||
)
|
||||
{
|
||||
min= j; temp= array[j];
|
||||
} /*FOR*/
|
||||
array[min]= array[i]; array[i]= temp; /*interschimbarea*/
|
||||
} /*FOR*/
|
||||
|
||||
}
|
||||
|
||||
void show_menu() {
|
||||
printf("1. Display\n");
|
||||
printf("2. Sort asscending\n");
|
||||
printf("3. Search by product code\n");
|
||||
printf("4. Sord desc-odd by product code\n");
|
||||
printf("5. Exit\n");
|
||||
}
|
||||
|
||||
void invalid_choice(char * message) {
|
||||
printf("%s\n", message);
|
||||
}
|
||||
|
||||
void clear() {
|
||||
fflush(stdin);
|
||||
int c = getchar();
|
||||
while ( c != '\n') {
|
||||
c = getchar();
|
||||
};
|
||||
}
|
||||
|
||||
enum choices { c_display = 1, c_sort, c_search, c_psort, c_exit, c_quit = 65 };
|
||||
void make_choice() {
|
||||
show_menu();
|
||||
|
||||
printf("Enter choice: ");
|
||||
int choice = getchar() - '0';
|
||||
clear();
|
||||
|
||||
int product_code;
|
||||
|
||||
switch (choice) {
|
||||
case c_display:
|
||||
display();
|
||||
clear();
|
||||
break;
|
||||
case c_sort:
|
||||
sort_ascending(records, number_of_records);
|
||||
printf("Records sorted successfully!\n");
|
||||
break;
|
||||
case c_search:
|
||||
printf("Enter the product code: ");
|
||||
int valid = scanf("%d", &product_code);
|
||||
if (!valid) {
|
||||
invalid_choice("Invalid product_code");
|
||||
clear();
|
||||
make_choice();
|
||||
}
|
||||
memcpy(sorted_by_code, records, number_of_records * sizeof(struct record_t));
|
||||
sort_ascending_by_code(sorted_by_code, number_of_records);
|
||||
char * product = search_by_code(sorted_by_code, number_of_records, product_code)->product_name;
|
||||
if (product) {
|
||||
printf("Product: %s\n", product);
|
||||
} else {
|
||||
printf("No product found for the following code %d\n", product_code);
|
||||
}
|
||||
|
||||
clear();
|
||||
break;
|
||||
case c_psort:
|
||||
sort_odd_by_product_code(records, number_of_records);
|
||||
printf("Records sorted successfully!\n");
|
||||
break;
|
||||
case c_exit:
|
||||
case c_quit:
|
||||
exit(0);
|
||||
default:
|
||||
invalid_choice("Choice is invalid! Please make a valid choice!");
|
||||
break;
|
||||
}
|
||||
make_choice();
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
if (argc < 2) {
|
||||
printf("Usage:\n");
|
||||
printf("%s filename\n", argv[0]);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (!load_records(argv[1])) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
make_choice();
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in a new issue