diff --git a/histogram.cpp b/histogram.cpp new file mode 100644 index 0000000..663a6d3 --- /dev/null +++ b/histogram.cpp @@ -0,0 +1,77 @@ +#include <iostream> +#include <vector> +#include <cmath> +#include "histogram.h" + +using namespace std; + +void +find_minmax(const vector<double>& numbers, double& min1, double& max1) +{ + max1 = numbers[0]; + min1 = numbers[0]; + for(size_t i = 0; i < numbers.size(); i++) + { + if (numbers[i] > max1) max1 = numbers[i]; + if (numbers[i] < min1) min1 = numbers[i]; + } + return; +} + +vector<double> +make_histogram(const vector<double>& numbers, size_t bin_count) +{ + double min1, max1; + find_minmax(numbers, min1, max1); + + vector<double> bins; + bins.resize(bin_count); + + size_t cor_size = (max1 - min1)/bin_count; + + for (size_t i = 0; i < numbers.size(); i++) + { + bool flag = false; + for (size_t j = 0; (j < bin_count) && !flag; j++) + { + auto L = min1 + j*cor_size; + auto H = min1 + (j+1)*cor_size; + if ((L <= numbers[i]) && (numbers[i] <= H)) + { + flag = true; + bins[j]++; + } + } + if (!flag) bins[bin_count-1]++; + } + + return bins; +} + +void +show_histogram_text(vector<double> bins, const vector<double>& numbers, size_t bin_count) +{ + const size_t MAX_ASTERISK = 76; + size_t maxb = bins[0]; + size_t H, j; + + for (j = 1; j < bin_count; j++) + { + if (bins[j] > maxb) maxb = bins[j]; + } + + for (j = 0; j < bin_count; j++) + { + if (maxb > MAX_ASTERISK) + { + H = MAX_ASTERISK * (static_cast<double>(bins[j]) / maxb); + } + else H = bins[j]; + if (bins[j] < 100) cout << " "; + if (bins[j] < 10) cout << " "; + cout << bins[j] << "|"; + for (size_t i = 0; i < H; i++) cout << "*"; + cout << endl; + } + return; +} diff --git a/histogram.h b/histogram.h new file mode 100644 index 0000000..e629077 --- /dev/null +++ b/histogram.h @@ -0,0 +1,7 @@ +#pragma once +#include <vector> + +std::vector<double> +make_histogram(const std::vector<double>& numbers, size_t bin_count); +void +show_histogram_text(std::vector<double> bins, const std::vector<double>& numbers, size_t bin_count); diff --git a/histogram_internal.h b/histogram_internal.h new file mode 100644 index 0000000..627b9f6 --- /dev/null +++ b/histogram_internal.h @@ -0,0 +1,5 @@ +#pragma once +#include <vector> + +void +find_minmax(const std::vector<double>& numbers, double& min1, double& max1); diff --git a/unittest.cbp b/unittest.cbp new file mode 100644 index 0000000..6da4486 --- /dev/null +++ b/unittest.cbp @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> +<CodeBlocks_project_file> + <FileVersion major="1" minor="6" /> + <Project> + <Option title="unittest" /> + <Option pch_mode="2" /> + <Option compiler="gcc" /> + <Build> + <Target title="Debug"> + <Option output="bin/Debug/unittest" prefix_auto="1" extension_auto="1" /> + <Option object_output="obj/Debug/" /> + <Option type="1" /> + <Option compiler="gcc" /> + <Compiler> + <Add option="-g" /> + </Compiler> + </Target> + <Target title="Release"> + <Option output="bin/Release/unittest" prefix_auto="1" extension_auto="1" /> + <Option object_output="obj/Release/" /> + <Option type="1" /> + <Option compiler="gcc" /> + <Compiler> + <Add option="-O2" /> + </Compiler> + <Linker> + <Add option="-s" /> + </Linker> + </Target> + </Build> + <Compiler> + <Add option="-Wall" /> + </Compiler> + <Extensions /> + </Project> +</CodeBlocks_project_file> diff --git a/unittest.cpp b/unittest.cpp new file mode 100644 index 0000000..981aa6f --- /dev/null +++ b/unittest.cpp @@ -0,0 +1,36 @@ +#define DOCTEST_CONFIG_NO_MULTITHREADING +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#include "doctest.h" +#include "histogram_internal.h" + +TEST_CASE("distinct positive numbers") { + double min = 0; + double max = 0; + find_minmax({1, 2}, min, max); + CHECK(min == 1); + CHECK(max == 2); +} + +TEST_CASE("distinct identical numbers") { + double min = 0; + double max = 0; + find_minmax({5, 5}, min, max); + CHECK(min == 5); + CHECK(max == 5); +} + +TEST_CASE("distinct one number") { + double min = 0; + double max = 0; + find_minmax({3}, min, max); + CHECK(min == 3); + CHECK(max == 3); +} + +TEST_CASE("distinct negative numbers") { + double min = 0; + double max = 0; + find_minmax({-3, -1}, min, max); + CHECK(min == -3); + CHECK(max == -1); +}