aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/line_accumulator.cc57
-rw-r--r--src/line_accumulator.h15
2 files changed, 34 insertions, 38 deletions
diff --git a/src/line_accumulator.cc b/src/line_accumulator.cc
index cf25c0c..b2facab 100644
--- a/src/line_accumulator.cc
+++ b/src/line_accumulator.cc
@@ -1,65 +1,64 @@
#include "line_accumulator.h"
#include <iostream>
+#include <algorithm>
LineAccumulator::LineAccumulator(const std::size_t max_length):
max_length_{max_length},
random_{},
length_{0},
- tokens_{},
- spaces_{} { }
+ tokens_{} { }
LineAccumulator::~LineAccumulator() {
this->discharge(false);
}
void LineAccumulator::operator()(const std::string& word) {
- if ( ( this->length_ + word.length() + 1 ) > this->max_length_ ) {
- this->pop_trailing_token();
+ if ( ( this->length_ + word.length() ) > this->max_length_ ) {
this->discharge(true);
}
- this->add_token(word);
- this->add_space();
-}
+ this->tokens_.emplace_back(word, 0);
+ this->length_ += word.length();
-void LineAccumulator::add_token(const std::string& token) {
- this->length_ += token.length();
- this->tokens_.emplace_back(token);
+ if ( this->length_ < this->max_length_ ) {
+ this->tokens_.back().second += 1;
+ this->length_ += 1;
+ }
}
-void LineAccumulator::add_space() {
- this->add_token(" ");
- this->spaces_.emplace_back(this->tokens_.size() - 1);
-}
+void LineAccumulator::discharge(const bool full) {
+ if ( full ) {
+ this->length_ -= this->tokens_.back().second;
+ this->tokens_.back().second = 0;
-void LineAccumulator::increase_space_at(const std::size_t index) {
- this->tokens_.at(this->spaces_[index]).append(" ");
- ++this->length_;
-}
+ const std::size_t missing = this->max_length_ - this->length_;
+ const std::size_t base = missing / (this->tokens_.size()-1);
-void LineAccumulator::pop_trailing_token() {
- this->length_ -= this->tokens_.back().length();
- this->tokens_.pop_back();
- this->spaces_.pop_back();
-}
+ std::for_each(
+ this->tokens_.begin(),
+ this->tokens_.end()-2,
+ [base, this](auto& token) {
+ token.second += base;
+ this->length_ += base;
+ }
+ );
-void LineAccumulator::discharge(const bool full) {
- if ( full ) {
- auto range = this->random_.makeRange(0, this->spaces_.size()-1);
+ auto range = this->random_.makeRange(0, this->tokens_.size()-2);
while ( this->length_ < this->max_length_ ) {
- this->increase_space_at(range.get());
+ this->tokens_[range.get()].second += 1;
+ this->length_ += 1;
}
}
for ( const auto& token : this->tokens_ ) {
- std::cout << token;
+ std::cout << token.first
+ << std::string(token.second, ' ');
}
std::cout << '\n';
this->length_ = 0;
this->tokens_.clear();
- this->spaces_.clear();
}
diff --git a/src/line_accumulator.h b/src/line_accumulator.h
index ea813a9..b3e78de 100644
--- a/src/line_accumulator.h
+++ b/src/line_accumulator.h
@@ -1,5 +1,6 @@
#pragma once
+#include <tuple>
#include <string>
#include <vector>
@@ -15,16 +16,12 @@ class LineAccumulator {
private:
const std::size_t max_length_;
- utility::Random random_;
- std::size_t length_;
- std::vector<std::string> tokens_;
- std::vector<std::size_t> spaces_;
+ utility::Random random_;
+ std::size_t length_;
- void add_token(const std::string& token);
- void add_space();
-
- void increase_space_at(const std::size_t index);
- void pop_trailing_token();
+ std::vector<
+ std::pair<std::string, std::uint8_t>
+ > tokens_;
void discharge(const bool full);