How to blur a .pgm file? - c

I've written this code, which is supposed to blur a .pgm file. Works perfectly on Linux, but it gives a wrong result on Windows. The program should be run like this: "filter.exe enb.pgm enb_filtered.pgm qs 3", where the 4th argument can be qs/cnt/ins, depending on what sorting algorithm wants the user to use, while the 5th one it's an odd number and gives the width of the blurring window (it should go at least until 21). 1st argument is our .exe, the 2nd one is the initial image, while the 3rd one is the final image. On Linux, the result is the expected one, while on Windows the enb.filtered.pgm file is all black and it has wrong dimensions. Can you, guys, help me?
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
#define HI(num) (((num) & 0x0000FF00) >> 8)
#define LO(num) ((num) & 0x000000FF)
typedef struct _PGMData {
int row;
int col;
int max_gray;
int **matrix;
} PGMData;
void quick_sort (int *a, int n) {
int i, j, p, t;
if (n < 2)
return;
p = a[n / 2];
for (i = 0, j = n - 1;; i++, j--) {
while (a[i] < p)
i++;
while (p < a[j])
j--;
if (i >= j)
break;
t = a[i];
a[i] = a[j];
a[j] = t;
}
quick_sort(a, i);
quick_sort(a + i, n - i);
}
void insertion_sort (int *a, int n) {
int i, j, t;
for (i = 1; i < n; i++) {
t = a[i];
for (j = i; j > 0 && t < a[j - 1]; j--) {
a[j] = a[j - 1];
}
a[j] = t;
}
}
void counting_sort(int *array, int n)
{
int i, j, k, min, max, *count;
min = max = array[0];
for(i=1; i < n; i++) {
if ( array[i] < min ) {
min = array[i];
}
else if ( array[i] > max ) {
max = array[i];
}
}
count = (int *)calloc(max - min + 1, sizeof(int));
for(i = 0, k = 0; i < n; i++) {
count[array[i] - min]++;
}
for(i = min; i <= max; i++) {
for(j = 0; j < count[i - min]; j++) {
array[k++] = i;
}
}
free(count);
}
int **allocate_dynamic_matrix(int row, int col)
{
int **ret_val;
int i;
ret_val = (int **)malloc(sizeof(int *) * row);
if (ret_val == NULL) {
perror("memory allocation failure");
exit(EXIT_FAILURE);
}
for (i = 0; i < row; ++i) {
ret_val[i] = (int *)malloc(sizeof(int) * col);
if (ret_val[i] == NULL) {
perror("memory allocation failure");
exit(EXIT_FAILURE);
}
}
return ret_val;
}
void deallocate_dynamic_matrix(int **matrix, int row)
{
int i;
for (i = 0; i < row; ++i)
free(matrix[i]);
free(matrix);
}
void SkipComments(FILE *fp)
{
int ch;
char line[100];
while ((ch = fgetc(fp)) != EOF && isspace(ch))
;
if (ch == '#') {
fgets(line, sizeof(line), fp);
SkipComments(fp);
} else
fseek(fp, -1, SEEK_CUR);
}
PGMData* readPGM(FILE *pgmFile, PGMData *data)
{
char version[3];
int i, j;
int lo, hi;
fgets(version, sizeof(version), pgmFile);
if (strcmp(version, "P5")) {
fprintf(stderr, "Wrong file type!\n");
exit(EXIT_FAILURE);
}
SkipComments(pgmFile);
fscanf(pgmFile, "%d", &(data->col));
SkipComments(pgmFile);
fscanf(pgmFile, "%d", &(data->row));
SkipComments(pgmFile);
fscanf(pgmFile, "%d", &(data->max_gray));
fgetc(pgmFile);
data->matrix = allocate_dynamic_matrix(data->row, data->col);
if (data->max_gray > 255)
for (i = 0; i < data->row; ++i)
for (j = 0; j < data->col; ++j) {
hi = fgetc(pgmFile);
lo = fgetc(pgmFile);
data->matrix[i][j] = (hi << 8) + lo;
}
else
for (i = 0; i < data->row; ++i)
for (j = 0; j < data->col; ++j) {
lo = fgetc(pgmFile);
data->matrix[i][j] = lo;
}
fclose(pgmFile);
return data;
}
/*and for writing*/
void writePGM(const char *filename, const PGMData *data)
{
FILE *pgmFile;
int i, j;
int hi, lo;
pgmFile = fopen(filename, "wb");
if (pgmFile == NULL) {
perror("cannot open file to write");
exit(EXIT_FAILURE);
}
fprintf(pgmFile, "P5 ");
fprintf(pgmFile, "%d %d ", data->col, data->row);
fprintf(pgmFile, "%d ", data->max_gray);
if (data->max_gray > 255) {
for (i = 0; i < data->row; ++i) {
for (j = 0; j < data->col; ++j) {
hi = HI(data->matrix[i][j]);
lo = LO(data->matrix[i][j]);
fputc(hi, pgmFile);
fputc(lo, pgmFile);
}
}
} else {
for (i = 0; i < data->row; ++i)
for (j = 0; j < data->col; ++j) {
lo = LO(data->matrix[i][j]);
fputc(lo, pgmFile);
}
}
fclose(pgmFile);
deallocate_dynamic_matrix(data->matrix, data->row);
}
int main ( int argc, char *argv[] )
{
PGMData *initialImage, *finalImage;
int **initialMatrix=NULL, **finalMatrix=NULL;
int n=atoi(argv[4]);
int i, j, k, l, counter;
int *buffer=NULL;
//Time count
clock_t start, end;
double cpu_time_used;
start = clock();
if ( argc != 5 ) /* argc should be 5 for correct execution */
{
/* We print argv[0] assuming it is the program name */
printf( "usage: %s filename", argv[0] );
}
else
{
// We assume argv[1] is a filename to open
FILE *file = fopen( argv[1], "r" );
/* fopen returns 0, the NULL pointer, on failure */
if ( !file )
{
printf( "Could not open file\n" );
}
else
{ initialImage = (PGMData *)malloc(1 * sizeof(PGMData));
initialImage = readPGM (file, initialImage);
initialMatrix = (int **)malloc(initialImage->row * sizeof(int*));
for(i = 0; i < initialImage->row; i++) {
initialMatrix[i] = (int *)malloc(initialImage->col * sizeof(int));
}
finalMatrix = (int **)malloc(initialImage->row * sizeof(int*));
for(i = 0; i < initialImage->row; i++) {
finalMatrix[i] = (int *)malloc(initialImage->col * sizeof(int));
}
if (initialMatrix == NULL || finalMatrix == NULL) {
puts ("Unable to allocate memory for matrix");
}
for (i = 0; i < initialImage->row; i++){
for (j = 0; j < initialImage->col; j++){
initialMatrix[i][j] = initialImage->matrix[i][j];
}
}
buffer = (int *) malloc(n * n * sizeof (int));
if (buffer == NULL) {
puts ("Unable to allocate memory for buffer");
}
for (i = 0; i < initialImage->row; i++){
for (j = 0; j < initialImage->col; j++){
counter = 0;
for (k = -(n/2); k <= n/2; k++){
for (l = -(n/2); l <= n/2; l++){
/*top left corner*/ if (i-k <= 0 && j-l <= 0) {
buffer[counter]=initialMatrix[0][0];
}
/*left side*/ else if (i-k <= 0 && j-l >= 0 && j-l <= initialImage->col-1) {
buffer[counter]=initialMatrix[0][j-l];
}
/*top side*/ else if (j-l <= 0 && i-k >= 0 && i-k <= initialImage->row-1) {
buffer[counter]=initialMatrix[i-k][0];
}
/*bottom left corner*/ else if (j-l <= 0 && i-k >= initialImage->row-1) {
buffer[counter]=initialMatrix[initialImage->row-1][0];
}
/*top right corner*/ else if (i-k <= 0 && j-l >= initialImage->col-1) {
buffer[counter]=initialMatrix[0][initialImage->col-1];
}
/*bottom side*/ else if (i-k >= initialImage->row-1 && j-l >= 0 && j-l <=initialImage->col-1) {
buffer[counter]=initialMatrix[initialImage->row-1][j-l];
}
/*right side*/ else if (j-l >= initialImage->col-1 && i-k >= 0 && i-k <=initialImage->row-1) {
buffer[counter]=initialMatrix[i-k][initialImage->col-1];
}
/*bottom right corner*/ else if (j-l >= initialImage->col-1 && i-k >= initialImage->row-1) {
buffer[counter]=initialMatrix[initialImage->row-1][initialImage->col-1];
}
/*rest*/ else {
buffer[counter]=initialMatrix[i-k][j-l];
}
counter++;
}
}
if(!strcmp(argv[3], "ins")) {
insertion_sort (buffer, n*n);
}
else if(!strcmp(argv[3], "qs")) {
quick_sort (buffer, n*n);
}
else if(!strcmp(argv[3], "cnt")) {
counting_sort (buffer, n*n);
}
else {
puts ("Unknown sorting algorithm");
}
finalMatrix[i][j] = buffer [n * n/2];
}
}
finalImage = (PGMData *)malloc(1 * sizeof(PGMData));
finalImage->col=initialImage->col;
finalImage->row=initialImage->row;
finalImage->max_gray = initialImage->max_gray;
finalImage->matrix = finalMatrix;
writePGM (argv[2], finalImage);
deallocate_dynamic_matrix(initialMatrix, initialImage->row);
deallocate_dynamic_matrix(initialImage->matrix, initialImage->row);
free(buffer);
free(initialImage);
free(finalImage);
}
}
end = clock();
cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
printf ("Execution time: %f seconds\n", cpu_time_used);
}

Related

Backtracking crossword algorithm in c

So i made a backtracking algorithm in c, where i get a txt file filled with words in each line and another txt file just has coordinates for the black squares of a square crossword. I know my implementation is extremelly simple, but i just want to have the barebones algorithm, to make it much faster later on with constraint satisfaction, forward checking etc.
However i have no idea how to get the basic code to work without segmentation faults and wrong solutions! Ant advice would be very helpful!
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_WORDS 150000
#define MAX_DIMENSION 200
#define MAX_BLACK_SQUARES 250
int is_valid_word(char *word, int dimension, char crossword[MAX_DIMENSION][MAX_DIMENSION])
{
int i, j, k;
int word_length = strlen(word);
// check if word is too long
if (word_length > dimension)
{
return 0;
}
// check if word overlaps existing letters
for (i = 0; i < dimension; i++)
{
for (j = 0; j < dimension; j++)
{
if (crossword[i][j] != '_')
{
for (k = 0; k < word_length; k++)
{
if ((i + k < dimension && crossword[i + k][j] != '_' && crossword[i + k][j] != word[k]) ||
(j + k < dimension && crossword[i][j + k] != '_' && crossword[i][j + k] != word[k]))
{
return 0;
}
}
}
}
}
return 1;
}
int solve_crossword(int dimension, char crossword[MAX_DIMENSION][MAX_DIMENSION], char words[MAX_WORDS][30], int num_words, int word_index)
{
int i, j, k;
if (word_index >= num_words)
{
// all words have been placed, so return true
return 1;
}
// try placing the current word horizontally
for (i = 0; i < dimension; i++)
{
for (j = 0; j < dimension - strlen(words[word_index]); j++)
{
if (crossword[i][j] != '#')
{
// try placing the word here
int is_valid = 1;
for (k = 0; k < strlen(words[word_index]); k++)
{
if (crossword[i][j + k] != '_' && crossword[i][j + k] != words[word_index][k])
{
is_valid = 0;
break;
}
}
if (is_valid)
{
// place the word
for (k = 0; k < strlen(words[word_index]); k++)
{
crossword[i][j + k] = words[word_index][k];
}
// recursive call to place the next word
if (solve_crossword(dimension, crossword, words, num_words, word_index + 1))
{
return 1;
}
// backtrack by removing the word
for (k = 0; k < strlen(words[word_index]); k++)
{
crossword[i][j + k] = '_';
}
}
}
}
}
// try placing the current word vertically
for (i = 0; i < dimension - strlen(words[word_index]); i++)
{
for (j = 0; j < dimension; j++)
{
if (crossword[i][j] != '#')
{
// try placing the word here
int is_valid = 1;
for (k = 0; k < strlen(words[word_index]); k++)
{
if (crossword[i + k][j] != '_' && crossword[i + k][j] != words[word_index][k])
{
is_valid = 0;
break;
}
}
if (is_valid)
{
// place the word
for (k = 0; k < strlen(words[word_index]); k++)
{
crossword[i + k][j] = words[word_index][k];
}
// recursive call to place the next word
if (solve_crossword(dimension, crossword, words, num_words,word_index + 1))
{
return 1;
}
// backtrack by removing the word
for (k = 0; k < strlen(words[word_index]); k++)
{
crossword[i + k][j] = '_';
}
}
}
}
}
// if we get here, we were unable to place the word in either direction
return 0;
}
int main()
{
// open dictionary file
FILE *dict_file = fopen("dicts/EvenMoreWords.txt", "r");
if (dict_file == NULL)
{
printf("Unable to open dict.txt\n");
return 1;
}
// read dictionary into array
char words[MAX_WORDS][30];
int num_words = 0;
char buffer[30];
while (fgets(buffer, 30, dict_file) != NULL)
{
int word_length = strlen(buffer);
if (buffer[word_length - 1] == '\n')
{
buffer[word_length - 1] = '\0';
}
strcpy(words[num_words], buffer);
num_words++;
}
fclose(dict_file);
// open crossword file
FILE *crossword_file = fopen("crosswords/c1.txt", "r");
if (crossword_file == NULL)
{
printf("Unable to open crossword.txt\n");
return 1;
}
// read dimensions and black squares
int dimension, i, j, width, height;
fscanf(crossword_file, "%d", &dimension);
// initialize crossword
char crossword[MAX_DIMENSION][MAX_DIMENSION];
while (fscanf(crossword_file, "%d %d", &width, &height) != EOF)
{
crossword[width - 1][height - 1] = '#';
}
printf("\n\n\n");
for (i = 0; i < dimension; i++)
{
for (j = 0; j < dimension; j++)
{
if (crossword[i][j] != '#')
{
crossword[i][j] = '_';
printf("%c ", crossword[i][j]);
}
else
{
printf("%c ", crossword[i][j]);
}
}
printf("\n");
}
printf("\n\n\n");
// solve crossword
if (solve_crossword(dimension, crossword, words, num_words, 0))
{
// print solution
for (i = 0; i < dimension; i++)
{
for (j = 0; j < dimension; j++)
{
printf("%c ", crossword[i][j]);
}
printf("\n");
}
}
else
{
printf("Unable to find a solution\n");
}
return 0;
}

Finding Median of an Array

I am trying to write a C program to find the median of an array, but the task requires to not sort the array. The current code I have works, but fails when there is a repeated number. I am struggling to find a way to account for this case. Any help would be appreciated.
#include <stdio.h>
#include <stdlib.h>
int median_finder(int size, int* data) {
int n1, n2;
int count = 0;
for (int t = 0; t < size; t ++) {
int piv = data[t];
int higher = 0;
int lower = 0;
int median;
if (size % 2 != 0) {
for (int j = 0; j < size; j++) {
if (piv < data[j]) {
higher++;
} else if (piv > data[j]) {
lower++;
}
}
if (higher != 0 && lower == higher) {
printf("MEDIAN: %d\n", piv);
return 0;
}
} else {
//int num = 0;
for (int j = 0; j < size; j++) {
if (piv < data[j]) {
higher++;
} else if (piv > data[j]) {
lower++;
}
}
if (higher != 0 && (lower == size/2 || higher == size/2)) {
count++;
if (count == 1) {
n1 = piv;
} if (count == 2) {
n2 = piv;
}
}
} if (count == 2) {
if (n1 > n2) {
median = n2;
} else {
median = n1;
}
printf("Median: %d\n", median);
return 0;
}
}
}
int main(int argc, char** argv) {
int size = atoi(argv[1]);
argv++;
argv++;
int data[size];
for (int i = 0; i < size; i++) {
data[i] = atoi(argv[i]);
}
median_finder(size, data);
}
The median for an unsorted array with possible duplicate values a of length n is the element with the value a[i] where half of the remaining elements (n-1)/2 (rounded down) are between less than (lt) or less than and equal (lt + eq) to a[i]:
#include <assert.h>
#include <stdio.h>
int median(size_t n, int *a) {
assert(n > 0);
for(size_t i = 0; i < n; i++) {
size_t lt = 0;
size_t eq = 0;
for(size_t j = 0; j < n; j++) {
if(i == j) continue;
if(a[j] < a[i]) lt++;
else if(a[j] == a[i]) eq++;
}
if((n-1)/2 >= lt && (n-1)/2 <= lt + eq)
return a[i];
}
assert(!"BUG");
}
// tap-like
void test(size_t test, int got, int expected) {
printf("%sok %zu\n", got == expected ? "" : "not ", test);
if(got != expected) {
printf(" --\n"
" got: %d\n"
" expected: %d\n"
" ...\n", got, expected);
}
}
int main(void) {
struct {
size_t n;
int *a;
} tests[] = {
{1, (int []) {0}},
{2, (int []) {0, 1}},
{3, (int []) {-1, 0, 1}},
{4, (int []) {-1, 0, 0, 1}},
};
for(int i = 0; i < sizeof tests / sizeof *tests; i++) {
test(i+1, median(tests[i].n, tests[i].a), 0);
}
}

fprintf in a while loop will only print my data 10 times to a file

ran into a problem regarding fprintf, we want to write a double array into our file for every loop in our main's while loop, however when this loop goes higher than 10 it simply stops fprintf'ing.
The function in question is "store_trash_file". Also the program is controlled by a few defines at top.
Day_max = controls the amount of loops in our while loop
SIZE = with higher SIZE it seems it will fprintf less, and with a smaller it will fprintf more lines.
Ill be putting up the entire code, so u can run it, perhaps keep an eye on the create directories function, as it will make folders and some txts
Any help is much appreciated
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <conio.h>
#include <io.h>
#include <process.h>
#define MARGIN 70
#define MARGIN2 30
#define NAREA 4
#define NSUBAREA 4
#define SIZE 20
#define DAY_MAX 20
#define AREAS_PER_TRUCK 4
#define LOWER1 6
#define LOWER2 8
#define LOWER3 10
#define UPPER1 8
#define UPPER2 10
#define UPPER3 12
typedef struct subarea
{
int co2_cost, time, emptied_subarea_counter, lower_random, upper_random, activity_level;
double average, total_trash_subarea_avg, sensorData[SIZE], sensorDataTotal[SIZE];
} subarea;
typedef struct area
{
subarea *subarea_array[NAREA + 1];
double average, total_trash_area_avg;
int emptied_area_counter;
} area;
void simulated_days(area *area_dynamic, area *area_static);
void average_trash(area *area);
void sensor_data_start(area *area, double start_var);
void compare_trash_to_empty(area *area_array[NAREA + 1], int *area_number_p);
void empty_trash(area *area, int *co2_counter_p, int *time_counter_p);
void store_trash_file(area *area_array[NAREA + 1]);
void create_areas(area *area_array[NAREA + 1]);
void empty_trash_static(area *area, int *co2_counter_static_p, int *time_counter_static_p);
void create_directories();
void make_txt_file(char file_name[30], char file_name2[30]);
int main(void)
{
int co2_counter = 0, time_counter = 0;
int co2_counter_static = 0, time_counter_static = 0;
int day_counter = 0;
int area_number;
int garbage_truck_amount = 0;
double *area_array_avg[DAY_MAX][NAREA];
double *subarea_array_avg[DAY_MAX][NAREA * NSUBAREA];
double *trashcan_array_avg[DAY_MAX][NAREA * NSUBAREA * SIZE];
area *area_array[NAREA + 1];
area *area_array_static[NAREA + 1];
srand(time(NULL));
for (int i = NAREA; i > 0; i -= AREAS_PER_TRUCK)
{
garbage_truck_amount++;
}
printf("Garbage trucks: %d\n", garbage_truck_amount);
create_areas(area_array);
create_areas(area_array_static);
create_directories();
int running = 1;
while (running)
{
for (int i = 1; i < NAREA + 1; i++)
{
simulated_days(area_array[i], area_array_static[i]);
average_trash(area_array[i]);
average_trash(area_array_static[i]);
}
for (int i = 1; i < NAREA + 1; i++)
{
for (int j = 0; j < NSUBAREA; j++)
{
printf("area array: %lf\n", area_array[i]->subarea_array[j]->average);
printf("area array static: %lf\n", area_array_static[i]->subarea_array[j]->average);
}
}
for (int i = 0; i < garbage_truck_amount; i++)
{
compare_trash_to_empty(area_array, &area_number);
empty_trash(area_array[area_number], &co2_counter, &time_counter);
for (int j = 1; j < NAREA + 1; j++)
{
average_trash(area_array[j]);
}
}
if (day_counter > 1 && day_counter % 14 == 0)
{
for (int i = 1; i < NAREA + 1; i++)
{
empty_trash_static(area_array_static[i], &co2_counter_static, &time_counter_static);
average_trash(area_array_static[i]);
}
}
store_trash_file(area_array);
printf("Day: %d\n", day_counter + 1);
for (int i = 0; i < NSUBAREA; i++)
{
for (int j = 1; j < NAREA + 1; j++)
{
printf("%lf\t", area_array[j]->subarea_array[i]->average);
printf("%lf\t", area_array_static[j]->subarea_array[i]->average);
}
printf("\n");
}
printf("\n");
day_counter++;
if(day_counter == DAY_MAX)
{
running = 0;
}
}
}
void simulated_days(area *area_dynamic, area *area_static)
{
for (int i = 0; i < NSUBAREA; i++)
{
for (int j = 0; j < SIZE; j++)
{
int x = ((rand() % (area_dynamic->subarea_array[i]->upper_random - area_dynamic->subarea_array[i]->lower_random + 1)) + area_dynamic->subarea_array[i]->lower_random);
area_dynamic->subarea_array[i]->sensorData[j] += x;
area_dynamic->subarea_array[i]->sensorDataTotal[j] += x;
area_static->subarea_array[i]->sensorData[j] += x;
area_static->subarea_array[i]->sensorDataTotal[j] += x;
}
}
}
void average_trash(area *area)
{
double sum[NSUBAREA];
double sum_total[NSUBAREA];
double area_trash_sum = 0;
double area_trash_sum_total = 0;
for (int i = 0; i < NSUBAREA; i++)
{
sum[i] = 0;
sum_total[i] = 0;
}
for (int i = 0; i < NSUBAREA; i++)
{
for (int j = 0; j < SIZE; j++)
{
sum[i] += area->subarea_array[i]->sensorData[j];
sum_total[i] += area->subarea_array[i]->sensorDataTotal[j];
}
area->subarea_array[i]->average = sum[i] / SIZE;
area->subarea_array[i]->total_trash_subarea_avg = sum_total[i] / SIZE;
}
for (int i = 0; i < NSUBAREA; i++)
{
area_trash_sum += area->subarea_array[i]->average;
area_trash_sum_total += area->subarea_array[i]->total_trash_subarea_avg;
}
area->average = area_trash_sum / NSUBAREA;
area->total_trash_area_avg = area_trash_sum_total / NSUBAREA;
}
void sensor_data_start(area *area, double start_var)
{
for (int i = 0; i < NSUBAREA; i++)
{
for (int j = 0; j < SIZE; j++)
{
area->subarea_array[i]->sensorData[j] = start_var;
area->subarea_array[i]->sensorDataTotal[j] = start_var;
}
}
}
void compare_trash_to_empty(area *area_array[NAREA + 1], int *area_number_p)
{
int highBlock = 0;
for (int i = 1; i < NAREA + 1; i++)
{
if (area_array[i]->average >= MARGIN)
{
if (area_array[i]->average > area_array[highBlock]->average)
{
highBlock = i;
}
}
}
*area_number_p = highBlock;
printf("\nhighblock %d\n", highBlock);
}
void empty_trash(area *area, int *co2_counter_p, int *time_counter_p)
{
for (int i = 0; i < NSUBAREA; i++)
{
if (area->subarea_array[i]->average > MARGIN2)
{
*co2_counter_p += area->subarea_array[i]->co2_cost;
*time_counter_p += area->subarea_array[i]->time;
area->subarea_array[i]->average = 0;
area->subarea_array[i]->emptied_subarea_counter++;
for (int j = 0; j < SIZE; j++)
{
if (area->subarea_array[i]->sensorData[j] <= 100)
{
area->subarea_array[i]->sensorData[j] = 0;
}
else if (area->subarea_array[i]->sensorData[j] > 100)
{
area->subarea_array[i]->sensorData[j] -= 100;
}
}
}
}
area->emptied_area_counter++;
}
void store_trash_file(area *area_array[NAREA + 1])
{
// int xcount = 0;
// int ycount = 0;
// double area_array_avg[NAREA];
// double subarea_array_avg[NAREA * NSUBAREA];
// double trashcan_array_avg[NAREA * NSUBAREA * SIZE];
FILE *output_filepointer;
char *dirname2 = "C:\\Users\\jacob\\Documents\\software\\projekter\\p1\\kode\\intelligenttrash\\data\\area";
char newdirname[150];
char newdirname2[150];
char newdirname3[150];
for (int i = 1; i < NAREA + 1; i++)
{
// area_array_avg[i - 1] = (area_array[i]->total_trash_area_avg);
snprintf(newdirname, 150, "%s%d\\area_average_total.txt", dirname2, i);
output_filepointer = fopen(newdirname, "a");
fprintf(output_filepointer, "%lf ", area_array[i]->total_trash_area_avg);
for (int j = 0; j < NSUBAREA; j++)
{
// subarea_array_avg[j + (ycount * NSUBAREA)] = (area_array[i]->subarea_array[j]->total_trash_subarea_avg);
snprintf(newdirname2, 150, "%s%d%s%d\\subarea_average_total.txt", dirname2, i, "\\subarea", j);
output_filepointer = fopen(newdirname2, "a");
fprintf(output_filepointer, "%lf ", area_array[i]->subarea_array[j]->total_trash_subarea_avg);
for (int z = 0; z < SIZE; z++)
{
// trashcan_array_avg[z + (xcount * SIZE)] = (area_array[i]->subarea_array[j]->sensorDataTotal[z]);
snprintf(newdirname3, 150, "%s%d%s%d\\trashcan_trash.txt", dirname2, i, "\\subarea", j);
output_filepointer = fopen(newdirname3, "a");
fprintf(output_filepointer, "%lf ", area_array[i]->subarea_array[j]->sensorDataTotal[z]);
}
// xcount++;
fprintf(output_filepointer, "\n");
output_filepointer = fopen(newdirname2, "a");
fprintf(output_filepointer, "\n");
}
// ycount++;
output_filepointer = fopen(newdirname, "a");
fprintf(output_filepointer, "\n");
}
fclose(output_filepointer);
}
void create_areas(area *area_array[NAREA + 1])
{
int percentage_added[3][2] = {{LOWER1, UPPER1}, {LOWER2, UPPER2}, {LOWER3, UPPER3}};
int activity_level;
for (int i = 0; i < NAREA + 1; i++)
{
area_array[i] = malloc(sizeof(area));
for (int j = 0; j < NSUBAREA; j++)
{
activity_level = (rand() % 3);
area_array[i]->subarea_array[j] = malloc(sizeof(subarea));
area_array[i]->subarea_array[j]->co2_cost = 50;
area_array[i]->subarea_array[j]->time = 50;
area_array[i]->subarea_array[j]->average = 0;
area_array[i]->subarea_array[j]->emptied_subarea_counter = 0;
area_array[i]->subarea_array[j]->total_trash_subarea_avg = 0;
area_array[i]->subarea_array[j]->lower_random = percentage_added[activity_level][0];
area_array[i]->subarea_array[j]->upper_random = percentage_added[activity_level][1];
area_array[i]->subarea_array[j]->activity_level = activity_level;
}
sensor_data_start(area_array[i], 0);
area_array[i]->average = 0;
area_array[i]->total_trash_area_avg = 0;
area_array[i]->emptied_area_counter = 0;
}
}
void empty_trash_static(area *area, int *co2_counter_static_p, int *time_counter_static_p)
{
for (int i = 0; i < NSUBAREA; i++)
{
*co2_counter_static_p += area->subarea_array[i]->co2_cost;
*time_counter_static_p += area->subarea_array[i]->time;
area->subarea_array[i]->average = 0;
area->subarea_array[i]->emptied_subarea_counter++;
for (int j = 0; j < SIZE; j++)
{
if (area->subarea_array[i]->sensorData[j] <= 100)
{
area->subarea_array[i]->sensorData[j] = 0;
}
else if (area->subarea_array[i]->sensorData[j] > 100)
{
area->subarea_array[i]->sensorData[j] -= 100;
}
}
}
area->emptied_area_counter++;
}
void create_directories()
{
int check;
char *dirname1 = "C:\\Users\\jacob\\Documents\\software\\projekter\\p1\\kode\\intelligenttrash\\data";
char *dirname2 = "C:\\Users\\jacob\\Documents\\software\\projekter\\p1\\kode\\intelligenttrash\\data\\area";
mkdir(dirname1);
for (int i = 1; i < NAREA + 1; i++)
{
char newdirname[100];
char newdirname2[100];
snprintf(newdirname, 100, "%s%d", dirname2, i);
mkdir(newdirname);
for (int j = 1; j < NSUBAREA + 1; j++)
{
snprintf(newdirname2, 100, "%s%d%s%d", dirname2, i, "\\subarea", j);
mkdir(newdirname2);
}
}
}
void make_txt_file(char file_name[30], char file_name2[30])
{
FILE *output_filepointer;
char *dirname2 = "C:\\Users\\jacob\\Documents\\software\\projekter\\p1\\kode\\intelligenttrash\\data\\area";
char newdirname[100];
char newdirname2[100];
for (int i = 1; i < NAREA + 1; i++)
{
if (file_name != "none")
{
snprintf(newdirname, 100, "%s%d\\%s.txt", dirname2, i, file_name);
output_filepointer = fopen(newdirname, "a");
}
for (int j = 1; j < NSUBAREA + 1; j++)
{
if (file_name2 != "none")
{
snprintf(newdirname2, 100, "%s%d%s%d\\%s.txt", dirname2, i, "\\subarea", j, file_name2);
output_filepointer = fopen(newdirname2, "a");
}
}
}
fclose(output_filepointer);
}

Not sure why int value is not what it is supposed to be

I'm solving this problem : https://www.hackerrank.com/challenges/structuring-the-document/problem
When I run my program on my IDE (XCode) I can see that word_count int 7428912 is not what it is supposed to be for any input. I am not sure why. I know that I am accessing out of bounds array index but I need someone to show me where exactly. The program outputs correctly and then gives an error. Thread 1: EXC_BAD_ACCESS (code=1, address=0x73696870)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#define MAX_CHARACTERS 1005
#define MAX_PARAGRAPHS 5
struct word {
char* data;
};
struct sentence {
struct word* data;
int word_count;//denotes number of words in a sentence
};
struct paragraph {
struct sentence* data ;
int sentence_count;//denotes number of sentences in a paragraph
};
struct document {
struct paragraph* data;
int paragraph_count;//denotes number of paragraphs in a document
};
#include <ctype.h>
struct document get_document(char* text) {
int spaces = 0, periods = 0, newlines = 0;
for(int i = 0; i < strlen(text); i++)
if(text[i] == ' ')
spaces++;
else if(text[i] == '.')
periods++;
else if(text[i] == '\n')
newlines++;
struct document doc;
doc.paragraph_count = newlines + 1;
doc.data = malloc((newlines + 1) * sizeof(struct paragraph));
int inBetweenPeriods = 0, j = 0;
struct paragraph para[doc.paragraph_count];
for(int i = 0; i < doc.paragraph_count; i++) {
for(; j < strlen(text); )
if(text[j] == '.') {
inBetweenPeriods++;
j++;
}
else if(text[j] == '\n' || j == strlen(text) - 1) {
para[i].sentence_count = inBetweenPeriods;
j++;
break;
}
else
j++;
para[i].data = malloc((inBetweenPeriods) * sizeof(struct sentence));
inBetweenPeriods = 0;
}
struct sentence sen[periods];
int sp[periods];
for(int j = 0; j < periods; j++)
sp[j] = 0;
int beg = 0;
int ij = 0;
for(int j = 0; j < strlen(text); j++) {
if(text[j] == '.') {
for(int k = beg; k < j; k++)
if(text[k] == ' ')
sp[ij]++;
ij++;
beg = j + 1;
}
}
for(int i = 0; i < periods; i++) {
sen[i].word_count = sp[i] + 1;//spaces + 1;
sen[i].data = malloc((sp[i] + 1) * sizeof(struct word));
}
struct word word[spaces + periods];
int start = 0, k = 0, wordsub = 0, sensub = 0, parasub = 0, docsub = 0, wordno = 0, parano = 0;
for(int i = 0; i < strlen(text); i++) {
if(text[i] == ' ' || text[i] == '.') {
word[wordsub].data = malloc((i - start) * sizeof(char) + 1);
for(int j = start; j < i; j++)
word[wordsub].data[k++] = text[j];
word[wordsub].data[k++] = '\0';
k = 0;
if(i < strlen(text) - 1 && text[i + 1] == '\n')
start = i + 2;
else
start = i + 1;
if(text[i] == ' ') {
sen[sensub].data[wordno] = word[wordsub];
wordno++; //wordno can be 0 or 1
}
if(i != strlen(text) - 1 && isalpha(text[i + 1]) && text[i] == '.') {
sen[sensub].data[wordno] = word[wordsub];
wordno = 0;
para[parasub].data[parano] = sen[sensub];
sensub++;
parano++;
}
if( (i != strlen(text) - 1 && text[i + 1] == '\n') || i == strlen(text) - 1) {
sen[sensub].data[wordno] = word[wordsub];
wordno = 0;
para[parasub].data[parano++] = sen[sensub];
parano = 0;
doc.data[docsub++] = para[parasub];
parasub++;
sensub++;
}
wordsub++;
}
}
return doc;
}
struct word kth_word_in_mth_sentence_of_nth_paragraph(struct document Doc, int k, int m, int n) {
return Doc.data[n - 1].data[m - 1].data[k - 1];
}
struct sentence kth_sentence_in_mth_paragraph(struct document Doc, int k, int m) {
return Doc.data[m - 1].data[k - 1];
}
struct paragraph kth_paragraph(struct document Doc, int k) {
return Doc.data[k - 1];
}
void print_word(struct word w) {
printf("%s", w.data);
}
void print_sentence(struct sentence sen) {
for(int i = 0; i < sen.word_count; i++) {
print_word(sen.data[i]);
if (i != sen.word_count - 1) {
printf(" ");
}
}
}
void print_paragraph(struct paragraph para) {
for(int i = 0; i < para.sentence_count; i++){
print_sentence(para.data[i]);
printf(".");
}
}
void print_document(struct document doc) {
for(int i = 0; i < doc.paragraph_count; i++) {
print_paragraph(doc.data[i]);
if (i != doc.paragraph_count - 1)
printf("\n");
}
}
char* get_input_text() {
int paragraph_count;
scanf("%d", &paragraph_count);
char p[MAX_PARAGRAPHS][MAX_CHARACTERS], doc[MAX_CHARACTERS];
memset(doc, 0, sizeof(doc));
getchar();
for (int i = 0; i < paragraph_count; i++) {
scanf("%[^\n]%*c", p[i]);
strcat(doc, p[i]);
if (i != paragraph_count - 1)
strcat(doc, "\n");
}
char* returnDoc = (char*)malloc((strlen (doc)+1) * (sizeof(char)));
strcpy(returnDoc, doc);
return returnDoc;
}
int main()
{
char* text = get_input_text();
struct document Doc = get_document(text);
int q;
scanf("%d", &q);
while (q--) {
int type;
scanf("%d", &type);
if (type == 3){
int k, m, n;
scanf("%d %d %d", &k, &m, &n);
struct word w = kth_word_in_mth_sentence_of_nth_paragraph(Doc, k, m, n);
print_word(w);
}
else if (type == 2) {
int k, m;
scanf("%d %d", &k, &m);
struct sentence sen= kth_sentence_in_mth_paragraph(Doc, k, m);
print_sentence(sen);
}
else{
int k;
scanf("%d", &k);
struct paragraph para = kth_paragraph(Doc, k);
print_paragraph(para);
}
printf("\n");
}
}
I solved it like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#define MAX_CHARACTERS 1005
#define MAX_PARAGRAPHS 5
struct word {
char* data;
};
struct sentence {
struct word* data;
int word_count;//denotes number of words in a sentence
};
struct paragraph {
struct sentence* data ;
int sentence_count;//denotes number of sentences in a paragraph
};
struct document {
struct paragraph* data;
int paragraph_count;//denotes number of paragraphs in a document
};
#include <ctype.h>
struct document get_document(char* text) {
int spaces = 0, periods = 0, newlines = 0;
for(int i = 0; i < strlen(text); i++)
if(text[i] == ' ')
spaces++;
else if(text[i] == '.')
periods++;
else if(text[i] == '\n')
newlines++;
struct document doc;
doc.paragraph_count = newlines + 1;
doc.data = malloc((newlines + 1) * sizeof(struct paragraph));
int inBetweenPeriods = 0, j = 0;
struct paragraph para[doc.paragraph_count];
for(int i = 0; i < doc.paragraph_count; i++) {
for(; j < strlen(text);)
if(text[j] == '.')
{ inBetweenPeriods++;j++;}
else if(text[j] == '\n' || j == strlen(text) - 1)
{j++;break;}else j++;
para[i].sentence_count = inBetweenPeriods;
para[i].data = malloc((inBetweenPeriods) * sizeof(struct sentence));
inBetweenPeriods = 0;
}
struct sentence sen[periods];
int sp[periods];
for(int j = 0; j < periods; j++)
sp[j] = 0;
int beg = 0;
int ij = 0;
for(int j = 0; j < strlen(text); j++) {
if(text[j] == '.') {
for(int k = beg; k < j; k++)
if(text[k] == ' ')
sp[ij]++;
ij++;
beg = j + 1;
}
}
for(int i = 0; i < periods; i++) {
sen[i].word_count = sp[i] + 1;//spaces + 1;
sen[i].data = malloc((sp[i] + 1) * sizeof(struct word));
}
struct word word[spaces + periods];
int start = 0, k = 0, wordsub = 0, sensub = 0, parasub = 0, docsub = 0, wordno = 0, parano = 0;
for(int i = 0; i < strlen(text); i++) {
if(text[i] == ' ' || text[i] == '.') {
word[wordsub].data = malloc((i - start) * sizeof(char) + 1);
for(int j = start; j < i; j++)
word[wordsub].data[k++] = text[j];
word[wordsub].data[k++] = '\0';
k = 0;
if(i < strlen(text) - 1 && text[i + 1] == '\n')
start = i + 2;
else
start = i + 1;
if(text[i] == ' ') {
sen[sensub].data[wordno] = word[wordsub];
wordno++; //wordno can be 0 or 1
}
if(i != strlen(text) - 1 && isalpha(text[i + 1]) && text[i] == '.') {
sen[sensub].data[wordno] = word[wordsub];
wordno = 0;
para[parasub].data[parano] = sen[sensub];
sensub++;
parano++;
}
if( (i != strlen(text) - 1 && text[i + 1] == '\n') || i == strlen(text) - 1) {
sen[sensub].data[wordno] = word[wordsub];
wordno = 0;
para[parasub].data[parano++] = sen[sensub];
parano = 0;
doc.data[docsub++] = para[parasub];
parasub++;
sensub++;
}
wordsub++;
}
}
return doc;
}
struct word kth_word_in_mth_sentence_of_nth_paragraph(struct document Doc, int k, int m, int n) {
return Doc.data[n - 1].data[m - 1].data[k - 1];
}
struct sentence kth_sentence_in_mth_paragraph(struct document Doc, int k, int m) {
return Doc.data[m - 1].data[k - 1];
}
struct paragraph kth_paragraph(struct document Doc, int k) {
return Doc.data[k - 1];
}
void print_word(struct word w) {
printf("%s", w.data);
}
void print_sentence(struct sentence sen) {
for(int i = 0; i < sen.word_count; i++) {
print_word(sen.data[i]);
if (i != sen.word_count - 1) {
printf(" ");
}
}
}
void print_paragraph(struct paragraph para) {
for(int i = 0; i < para.sentence_count; i++){
print_sentence(para.data[i]);
printf(".");
}
}
void print_document(struct document doc) {
for(int i = 0; i < doc.paragraph_count; i++) {
print_paragraph(doc.data[i]);
if (i != doc.paragraph_count - 1)
printf("\n");
}
}
char* get_input_text() {
int paragraph_count;
scanf("%d", &paragraph_count);
char p[MAX_PARAGRAPHS][MAX_CHARACTERS], doc[MAX_CHARACTERS];
memset(doc, 0, sizeof(doc));
getchar();
for (int i = 0; i < paragraph_count; i++) {
scanf("%[^\n]%*c", p[i]);
strcat(doc, p[i]);
if (i != paragraph_count - 1)
strcat(doc, "\n");
}
char* returnDoc = (char*)malloc((strlen (doc)+1) * (sizeof(char)));
strcpy(returnDoc, doc);
return returnDoc;
}
int main()
{
char* text = get_input_text();
struct document Doc = get_document(text);
int q;
scanf("%d", &q);
while (q--) {
int type;
scanf("%d", &type);
if (type == 3){
int k, m, n;
scanf("%d %d %d", &k, &m, &n);
struct word w = kth_word_in_mth_sentence_of_nth_paragraph(Doc, k, m, n);
print_word(w);
}
else if (type == 2) {
int k, m;
scanf("%d %d", &k, &m);
struct sentence sen= kth_sentence_in_mth_paragraph(Doc, k, m);
print_sentence(sen);
}
else{
int k;
scanf("%d", &k);
struct paragraph para = kth_paragraph(Doc, k);
print_paragraph(para);
}
printf("\n");
}
}

Possible mode error

I've made this program that computes the mean, the median and the mode from an array. Although I've tested with some examples, I found out there might be a case that I have forgotten as for many of the inputs I've tested it works but the testing program that my teacher is using gave me an error for a certain test, but I was not presented with its input. Maybe someone can have a look and see if I am making a mistake at the mode point of the code:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
void *safeMalloc(int n) {
void *p = malloc(n);
if (p == NULL) {
printf("Error: malloc(%d) failed. Out of memory?\n", n);
exit(EXIT_FAILURE);
}
return p;
}
int main(int argc, char *argv[]) {
int n, i;
scanf("%d", &n);
int *array = safeMalloc(n * sizeof(int));
for (i = 0; i < n; i++) {
int value;
scanf("%d", &value);
array[i] = value;
}
//mean
double mean;
double sum = 0;
for (i = 0; i < n; i++) {
sum = sum + (double)array[i];
}
mean = sum / n;
printf("mean: %.2f\n", mean);
//median
float temp;
int j;
for (i = 0; i < n; i++)
for (j = i + 1; j < n; j++) {
if (array[i] > array[j]) {
temp = array[j];
array[j] = array[i];
array[i] = temp;
}
}
printf("median: %d\n", array[n / 2]);
//mode
int val = array[0], noOfRepetitions = 1, valMax = array[0], maxRepetitions = 1, possibleMax = 1;
for (i = 1; i < n; i++) {
if (array[i] == val) {
noOfRepetitions++;
}
if (array[i] != val) {
val = array[i];
noOfRepetitions = 1;
}
if (noOfRepetitions == possibleMax) {
maxRepetitions = 1;
continue;
}
if (noOfRepetitions > maxRepetitions) {
valMax = val;
maxRepetitions = noOfRepetitions;
possibleMax = maxRepetitions;
}
}
if (maxRepetitions > 1) {
printf("mode: %d\n", valMax);
} else {
printf("mode: NONE\n");
}
return 0;
}
My idea for mode was because the numbers are sorted when just transverse it. If the next element is the same as the previous one, increase the noOfRepetitions. If the noOfRepetition is bigger than the maxRepetitions until now, replace with that. Also store the last maximum val needed if we have for example more than 2 numbers with the same number of repetitions.
EDIT: The mode of an array should return the number with the maximum number of occurrences in the array.If we have 2 or more number with the same number of maximum occurrences , there isn't a mode on that array.
I've discovered my mistake. I didn't think of the case when I have numbers with same maximum frequency and after that came one with lower frequency but still bigger than others. For example : 1 1 1 2 2 2 3 3 4 5 6.With my code , the result would have been 3 . I just needed to change the comparison of noOfRepetitions with oldMaxRepetition.
There seems to be no purpose for the variable possibleMax. You should just remove these lines:
if(noOfRepetitions==possibleMax){
maxRepetitions=1;
continue;
}
They cause maxRepetitions to be reset erroneously.
You could detect if the distribution is multimodal and print all mode values:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
void *safeMalloc(int n) {
void *p = malloc(n);
if (p == NULL) {
printf("Error: malloc(%d) failed. Out of memory?\n", n);
exit(EXIT_FAILURE);
}
return p;
}
int main(int argc, char *argv[]) {
int n, i;
if (scanf("%d", &n) != 1 || n <= 0)
return 1;
int *array = safeMalloc(n * sizeof(int));
for (i = 0; i < n; i++) {
if (scanf("%d", &array[i]) != 1)
return 1;
}
//mean
double sum = 0;
for (i = 0; i < n; i++) {
sum = sum + (double)array[i];
}
printf("mean: %.2f\n", sum / n);
//median
int j;
for (i = 0; i < n; i++) {
for (j = i + 1; j < n; j++) {
if (array[i] > array[j]) {
int temp = array[j];
array[j] = array[i];
array[i] = temp;
}
}
}
printf("median: %d\n", array[n / 2]);
//mode
int val = array[0], noOfRepetitions = 1, valMax = array[0], maxRepetitions = 1;
for (i = 1; i < n; i++) {
if (array[i] == val) {
noOfRepetitions++;
if (noOfRepetitions > maxRepetitions) {
valMax = val;
maxRepetitions = noOfRepetitions;
}
} else {
val = array[i];
noOfRepetitions = 1;
}
}
if (maxRepetitions == 1) {
printf("mode: NONE\n");
} else {
printf("mode: %d", valMax);
val = array[0];
noOfRepetitions = 1;
for (i = 1; i < n; i++) {
if (array[i] == val) {
noOfRepetitions++;
} else {
if (noOfRepetition == maxRepetitions && val != valMax) {
printf(", %d", val);
}
val = array[i];
noOfRepetitions = 1;
}
}
if (noOfRepetition == maxRepetitions && val != valMax) {
printf(", %d", val);
}
printf("\n");
}
return 0;
}
Your code to search a mode seems too complicated. Compare this:
//mode
int val = array[0], noOfRepetitions = 1,
valMax = array[0], maxRepetitions = 1;
for (i = 1; i < n; i++) {
if (array[i] == val) {
if (++noOfRepetitions > maxRepetitions) {
valMax = val;
maxRepetitions = noOfRepetitions;
}
}
else
{
val = array[i];
noOfRepetitions = 1;
}
}
It's probably the simplest code to do what you need, but it overwrites maxVal and maxRepetitions much too often.
The following version overwrites the two 'max' variables only once per each new maximum found – at the cost of duplicating some part of code:
//mode
int val = array[0], noOfRepetitions = 1,
valMax = array[0], maxRepetitions = 1;
for (i = 1; i < n; i++) {
if (array[i] == val) {
++noOfRepetitions;
}
else
{
if (noOfRepetitions > maxRepetitions) {
valMax = val;
maxRepetitions = noOfRepetitions;
}
val = array[i];
noOfRepetitions = 1;
}
}
if (noOfRepetitions > maxRepetitions) {
valMax = val;
maxRepetitions = noOfRepetitions;
}

Resources