diff options
-rw-r--r-- | CMakeLists.txt | 5 | ||||
-rw-r--r-- | justify.cc | 33 | ||||
-rw-r--r-- | src/random.cc | 29 | ||||
-rw-r--r-- | src/random.h | 34 |
4 files changed, 84 insertions, 17 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index deddd48..f9b9fdc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,12 @@ set( "${CMAKE_CXX_FLAGS} -std=c++14 -W -Wall -Wextra -Winline -pedantic" ) +include_directories( + src/ +) + add_executable( justify justify.cc + src/random.cc ) @@ -1,26 +1,24 @@ #include <iostream> #include <string> #include <vector> -#include <random> -#include <algorithm> -#include <cassert> -class LineAccumulator { - static const std::size_t MAX_LENGTH = 60; +#include "random.h" +class LineAccumulator { public: - LineAccumulator(): - device_(), - length_(0), - tokens_(), - spaces_() { } + LineAccumulator(const std::size_t max_length): + max_length_{max_length}, + random_{}, + length_{0}, + tokens_{}, + spaces_{} { } ~LineAccumulator() { this->discharge(false); } void operator()(const std::string& word) { - if ( ( this->length_ + word.length() + 1 ) > MAX_LENGTH ) { + if ( ( this->length_ + word.length() + 1 ) > this->max_length_ ) { this->pop_trailing_token(); this->discharge(true); } @@ -30,7 +28,9 @@ class LineAccumulator { } private: - std::random_device device_; + const std::size_t max_length_; + + utility::Random random_; std::size_t length_; std::vector<std::string> tokens_; std::vector<std::size_t> spaces_; @@ -58,11 +58,10 @@ class LineAccumulator { void discharge(const bool full) { if ( full ) { - std::mt19937 generator(this->device_()); - std::uniform_int_distribution<> random(0, this->spaces_.size()-1); + auto range = this->random_.makeRange(0, this->spaces_.size()-1); - while ( this->length_ < MAX_LENGTH ) { - this->increase_space_at(random(generator)); + while ( this->length_ < this->max_length_ ) { + this->increase_space_at(range.get()); } } @@ -83,7 +82,7 @@ int main() { std::cout.sync_with_stdio(false); std::cin.sync_with_stdio(false); - LineAccumulator acc; + LineAccumulator acc{60}; std::string word; while ( std::cin >> word ) { diff --git a/src/random.cc b/src/random.cc new file mode 100644 index 0000000..dba3647 --- /dev/null +++ b/src/random.cc @@ -0,0 +1,29 @@ +#include "random.h" + +namespace utility { + +std::size_t Random::Range::get() { + return this->distribution_(*(this->generator_)); +} + +Random::Range::Range( + std::mt19937* const generator, + const std::size_t a, + const std::size_t b +): + generator_(generator), + distribution_(a, b) { } + +Random::Random(): + device_{}, + generator_{device_()} { } + +Random::Range Random::makeRange( + const std::size_t a, + const std::size_t b) { + this->generator_.seed(this->device_()); + + return Range{&(this->generator_), a, b}; +} + +} diff --git a/src/random.h b/src/random.h new file mode 100644 index 0000000..386dc21 --- /dev/null +++ b/src/random.h @@ -0,0 +1,34 @@ +#pragma once + +#include <random> + +namespace utility { + +class Random { + public: + class Range { + public: + std::size_t get(); + + protected: + friend class Random; + + Range(std::mt19937* const, const std::size_t, const std::size_t); + + private: + std::mt19937* const generator_; + std::uniform_int_distribution<std::size_t> distribution_; + }; + + Random(); + + Range makeRange(const std::size_t, const std::size_t); + + private: + std::random_device device_; + std::mt19937 generator_; + +}; + + +} |