// libsemigroups - C++ library for semigroups and monoids
// Copyright (C) 2021 James D. Mitchell + Maria Tsalakou
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
#include "libsemigroups/string.hpp"
#include <random>
// for mt19937
#include "libsemigroups/config.hpp" // for LIBSEMIGROUPS_FMT_ENABLED
#include "libsemigroups/exception.hpp" // for LIBSEMIGROUPS_EXCEPTION
#ifdef LIBSEMIGROUPS_FMT_ENABLED
#include "fmt/format.h" // for group_digits
#endif
namespace libsemigroups {
namespace detail {
std::string random_string(std::string
const& alphabet, size_t length) {
static std::random_device rd;
static std::mt19937 generator(rd());
std::uniform_int_distribution<> distribution(0, alphabet.size() - 1);
std::string result;
for (size_t i = 0; i < length; ++i) {
result += alphabet[distribution(generator)];
}
return result;
}
// Random string with random length in the range [min, max) over <alphabet>
std::string random_string(std::string
const& alphabet,
size_t min,
size_t max) {
if (min >= max) {
LIBSEMIGROUPS_EXCEPTION(
"the 2nd argument (min) must be less than the 3rd argument (max)");
}
else if (alphabet.empty() && min != 0) {
LIBSEMIGROUPS_EXCEPTION(
"expected non-empty 1st argument (alphabet)");
}
if (max == min + 1) {
return random_string(alphabet, min);
}
static std::random_device rd;
static std::mt19937 generator(rd());
std::uniform_int_distribution<> distribution(min, max - 1);
return random_string(alphabet, distribution(generator));
}
std::vector<std::string> random_strings(std::string
const& alphabet,
size_t number,
size_t min,
size_t max) {
std::vector<std::string> result;
for (size_t j = 0; j < number; ++j) {
result.push_back(random_string(alphabet, min, max));
}
return result;
}
// Returns the string s to the power N, not optimized, complexity is O(N *
// |s|)
std::string power_string(std::string
const& s, size_t N) {
std::string result = s;
for (size_t i = 0; i < N; ++i) {
result += s;
}
return result;
}
namespace {
#ifdef LIBSEMIGROUPS_FMT_ENABLED
std::string group_digits(uint64_t num) {
return fmt::to_string(fmt::group_digits(num));
}
#else
std::string group_digits(uint64_t num) {
std::string result = detail::to_string(num);
if (result.size() < 4) {
return result;
}
for (size_t i = 3; i < result.size(); i += 4) {
result.insert(result.size() - i,
",");
}
return result;
}
#endif
}
// namespace
std::string group_digits(int64_t num) {
if (num < 0) {
return "-" + group_digits(
static_cast<uint64_t>(-num));
}
return group_digits(
static_cast<uint64_t>(num));
}
}
// namespace detail
}
// namespace libsemigroups