histogram.c (2457B)
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <float.h> 4 5 #define MAX_SAMPLES 1000000 6 7 int main(int argc, char *argv[]) { 8 if (argc < 2) { 9 fprintf(stderr, "Usage: %s number_of_bins\n", argv[0]); 10 exit(EXIT_FAILURE); 11 } 12 13 int num_bins = atoi(argv[1]); 14 if (num_bins <= 0) { 15 fprintf(stderr, "Number of bins must be a positive integer.\n"); 16 exit(EXIT_FAILURE); 17 } 18 19 int *bins = calloc(num_bins, sizeof(int)); 20 double *samples = malloc(MAX_SAMPLES * sizeof(double)); 21 if (bins == NULL || samples == NULL) { 22 fprintf(stderr, "Memory allocation failed.\n"); 23 exit(EXIT_FAILURE); 24 } 25 26 double value, min_value = DBL_MAX, max_value = -DBL_MAX; 27 int sample_count = 0; 28 29 // Read numbers from stdin and store them into the samples array 30 while (sample_count < MAX_SAMPLES && scanf("%lf", &value) != EOF) { 31 samples[sample_count++] = value; 32 if (value < min_value) { 33 min_value = value; 34 } 35 if (value > max_value) { 36 max_value = value; 37 } 38 } 39 40 // Avoid division by zero for a single unique value 41 if (min_value == max_value) { 42 max_value++; 43 } 44 45 // Calculate bin width 46 double range = max_value - min_value; 47 double bin_width = range / num_bins; 48 49 // Fill the bins with sample counts 50 for (int i = 0; i < sample_count; i++) { 51 int bin_index = (int)((samples[i] - min_value) / bin_width); 52 if (bin_index == num_bins) { 53 bin_index--; // Last bin includes max_value 54 } 55 bins[bin_index]++; 56 } 57 58 // Calculate the scaling factor based on the maximum bin count 59 int max_bin_count = 0; 60 for (int i = 0; i < num_bins; i++) { 61 if (bins[i] > max_bin_count) { 62 max_bin_count = bins[i]; 63 } 64 } 65 const int MAX_WIDTH = 50; // Adjust this to your terminal width 66 double scale = max_bin_count > MAX_WIDTH ? (double)MAX_WIDTH / max_bin_count : 1.0; 67 68 // Print the histogram 69 for (int i = 0; i < num_bins; i++) { 70 double bin_start = min_value + i * bin_width; 71 double bin_end = bin_start + bin_width; 72 printf(" [%4.1f, %4.1f): ", bin_start, bin_end); 73 74 int marks = (int)(bins[i] * scale); 75 for (int j = 0; j < marks; j++) { 76 printf("▇"); 77 } 78 printf(" %d\n", bins[i]); 79 } 80 81 // Free the allocated memory 82 free(bins); 83 free(samples); 84 85 return 0; 86 }