87 lines
2.4 KiB
C
87 lines
2.4 KiB
C
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <float.h>
|
||
|
|
||
|
#define MAX_SAMPLES 1000000
|
||
|
|
||
|
int main(int argc, char *argv[]) {
|
||
|
if (argc < 2) {
|
||
|
fprintf(stderr, "Usage: %s number_of_bins\n", argv[0]);
|
||
|
exit(EXIT_FAILURE);
|
||
|
}
|
||
|
|
||
|
int num_bins = atoi(argv[1]);
|
||
|
if (num_bins <= 0) {
|
||
|
fprintf(stderr, "Number of bins must be a positive integer.\n");
|
||
|
exit(EXIT_FAILURE);
|
||
|
}
|
||
|
|
||
|
int *bins = calloc(num_bins, sizeof(int));
|
||
|
double *samples = malloc(MAX_SAMPLES * sizeof(double));
|
||
|
if (bins == NULL || samples == NULL) {
|
||
|
fprintf(stderr, "Memory allocation failed.\n");
|
||
|
exit(EXIT_FAILURE);
|
||
|
}
|
||
|
|
||
|
double value, min_value = DBL_MAX, max_value = -DBL_MAX;
|
||
|
int sample_count = 0;
|
||
|
|
||
|
// Read numbers from stdin and store them into the samples array
|
||
|
while (sample_count < MAX_SAMPLES && scanf("%lf", &value) != EOF) {
|
||
|
samples[sample_count++] = value;
|
||
|
if (value < min_value) {
|
||
|
min_value = value;
|
||
|
}
|
||
|
if (value > max_value) {
|
||
|
max_value = value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Avoid division by zero for a single unique value
|
||
|
if (min_value == max_value) {
|
||
|
max_value++;
|
||
|
}
|
||
|
|
||
|
// Calculate bin width
|
||
|
double range = max_value - min_value;
|
||
|
double bin_width = range / num_bins;
|
||
|
|
||
|
// Fill the bins with sample counts
|
||
|
for (int i = 0; i < sample_count; i++) {
|
||
|
int bin_index = (int)((samples[i] - min_value) / bin_width);
|
||
|
if (bin_index == num_bins) {
|
||
|
bin_index--; // Last bin includes max_value
|
||
|
}
|
||
|
bins[bin_index]++;
|
||
|
}
|
||
|
|
||
|
// Calculate the scaling factor based on the maximum bin count
|
||
|
int max_bin_count = 0;
|
||
|
for (int i = 0; i < num_bins; i++) {
|
||
|
if (bins[i] > max_bin_count) {
|
||
|
max_bin_count = bins[i];
|
||
|
}
|
||
|
}
|
||
|
const int MAX_WIDTH = 50; // Adjust this to your terminal width
|
||
|
double scale = max_bin_count > MAX_WIDTH ? (double)MAX_WIDTH / max_bin_count : 1.0;
|
||
|
|
||
|
// Print the histogram
|
||
|
for (int i = 0; i < num_bins; i++) {
|
||
|
double bin_start = min_value + i * bin_width;
|
||
|
double bin_end = bin_start + bin_width;
|
||
|
printf(" [%4.1f, %4.1f): ", bin_start, bin_end);
|
||
|
|
||
|
int marks = (int)(bins[i] * scale);
|
||
|
for (int j = 0; j < marks; j++) {
|
||
|
printf("▇");
|
||
|
}
|
||
|
printf(" %d\n", bins[i]);
|
||
|
}
|
||
|
|
||
|
// Free the allocated memory
|
||
|
free(bins);
|
||
|
free(samples);
|
||
|
|
||
|
return 0;
|
||
|
}
|