aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--justify.cc16
-rw-r--r--src/line_accumulator.cc49
-rw-r--r--src/line_accumulator.h11
4 files changed, 46 insertions, 32 deletions
diff --git a/README.md b/README.md
index 9b6ab36..214e2b8 100644
--- a/README.md
+++ b/README.md
@@ -14,6 +14,8 @@ i.e. `echo "$the_paragraph_above" | justify --length 40 --offset 2` results in:
leading spaces may be defined using
`--offset`.
+The seed used to pseudorandomly distribute missing spaces may be customized via the `--seed` argument.
+
## Requirements
* CMake
diff --git a/justify.cc b/justify.cc
index c417dfd..9115d83 100644
--- a/justify.cc
+++ b/justify.cc
@@ -23,6 +23,11 @@ boost::optional<boost::program_options::variables_map> input(
boost::program_options::value<int>(),
"Number of spaces to be prepended on each line"
)
+ (
+ "seed",
+ boost::program_options::value<std::uint32_t>(),
+ "Seed for pseudorandomly distributing missing spaces"
+ )
;
boost::program_options::variables_map variables;
@@ -51,8 +56,9 @@ bool process(const boost::program_options::variables_map& variables) {
std::cout.sync_with_stdio(false);
std::cin.sync_with_stdio(false);
- std::uint8_t line_length = 60;
- std::uint8_t line_offset = 0;
+ std::uint8_t line_length = 60;
+ std::uint8_t line_offset = 0;
+ std::uint32_t seed = 3473018784;
if ( variables.count("length") ) {
const int user_length = variables["length"].as<int>();
@@ -78,7 +84,11 @@ bool process(const boost::program_options::variables_map& variables) {
}
}
- justify::LineAccumulator acc{line_length, line_offset};
+ if ( variables.count("seed") ) {
+ seed = variables["seed"].as<std::uint32_t>();
+ }
+
+ justify::LineAccumulator acc{line_length, line_offset, seed};
std::string token;
while ( std::cin.good() ) {
diff --git a/src/line_accumulator.cc b/src/line_accumulator.cc
index 9ce389b..a203fac 100644
--- a/src/line_accumulator.cc
+++ b/src/line_accumulator.cc
@@ -6,23 +6,17 @@
namespace {
-static std::mt19937 generator;
-
std::uint8_t getRandomIndex(
- const int seed,
+ std::mt19937& generator,
const std::uint8_t n
) {
- generator.seed(seed);
-
return std::uniform_int_distribution<std::uint8_t>{0, n}(generator);
}
std::vector<std::uint8_t> getRandomIndizes(
- const int seed,
- const std::uint8_t n
+ std::mt19937& generator,
+ const std::uint8_t n
) {
- generator.seed(seed);
-
std::vector<std::uint8_t> indizes(n);
std::iota(indizes.begin(), indizes.end(), 0);
std::shuffle(
@@ -55,11 +49,13 @@ std::size_t getCharacterLength(const std::string& token) {
namespace justify {
LineAccumulator::LineAccumulator(
- const std::uint8_t max_length,
- const std::uint8_t offset
+ const std::uint8_t max_length,
+ const std::uint8_t offset,
+ const std::uint32_t seed
):
max_length_{max_length},
offset_{offset},
+ generator_{seed},
length_{0},
tokens_{} { }
@@ -67,14 +63,6 @@ LineAccumulator::~LineAccumulator() {
this->discharge(false);
}
-std::uint8_t LineAccumulator::getMissing() const {
- if ( this->length_ < this->max_length_ ) {
- return this->max_length_ - this->length_;
- } else {
- return 0;
- }
-}
-
void LineAccumulator::operator()(const std::string& token) {
const std::size_t tokenLength = getCharacterLength(token);
@@ -91,10 +79,15 @@ void LineAccumulator::operator()(const std::string& token) {
}
}
-void LineAccumulator::justify() {
- const int seed = this->tokens_.size()
- + this->getMissing();
+std::uint8_t LineAccumulator::getMissing() const {
+ if ( this->length_ < this->max_length_ ) {
+ return this->max_length_ - this->length_;
+ } else {
+ return 0;
+ }
+}
+void LineAccumulator::justify() {
switch ( this->tokens_.size() ) {
// There is no sensible block justification of null or any single token
case 0:
@@ -137,14 +130,18 @@ void LineAccumulator::justify() {
}
// randomly distribute missing spaces
case 1: {
- this->tokens_[
- getRandomIndex(seed, this->tokens_.size() - 2)
- ].second += 1;
+ this->tokens_[getRandomIndex(
+ this->generator_,
+ this->tokens_.size() - 2
+ )].second += 1;
break;
}
default: {
- const auto indizes = getRandomIndizes(seed, this->tokens_.size() - 2);
+ const auto indizes = getRandomIndizes(
+ this->generator_,
+ this->tokens_.size() - 2
+ );
std::for_each(
indizes.begin(),
diff --git a/src/line_accumulator.h b/src/line_accumulator.h
index 69b4c74..db75c8c 100644
--- a/src/line_accumulator.h
+++ b/src/line_accumulator.h
@@ -9,23 +9,28 @@ namespace justify {
class LineAccumulator {
public:
- LineAccumulator(const std::uint8_t max_length, const std::uint8_t offset);
+ LineAccumulator(
+ const std::uint8_t max_length,
+ const std::uint8_t offset,
+ const std::uint32_t seed
+ );
~LineAccumulator();
- std::uint8_t getMissing() const;
-
void operator()(const std::string& token);
private:
const std::uint8_t max_length_;
const std::uint8_t offset_;
+ std::mt19937 generator_;
std::uint8_t length_;
std::vector<
std::pair<std::string, std::uint8_t>
> tokens_;
+ std::uint8_t getMissing() const;
+
void justify();
void discharge(const bool full);