Kumite (ko͞omiˌtā) is the practice of taking techniques learned from Kata and applying them through the act of freestyle sparring.
You can create a new kumite by providing some initial code and optionally some test cases. From there other warriors can spar with you, by enhancing, refactoring and translating your code. There is no limit to how many warriors you can spar with.
A great use for kumite is to begin an idea for a kata as one. You can collaborate with other code warriors until you have it right, then you can convert it to a kata.
Description is not accurate: if you pass by value, you cannot return both a bool (whether the vector is ordered or not) and a sorted vector ????
#include <vector> #include <algorithm> #include <utility> bool Ordering(const std::vector<int> &num) { if (num.size()<=1) return true; return std::none_of(std::next(num.cbegin()),num.end(), [prev=num[0]](int val) mutable { return val<std::exchange(prev,val); }); }
using namespace std;int Ordering(vector<int> num) //1,0,3{vector <int> result;for(int i = 0 ; i < num.size() ; i++){sort(num.begin() , num.end());result.push_back(num[i]);}return result;}- #include <vector>
- #include <algorithm>
- #include <utility>
- bool Ordering(const std::vector<int> &num) {
- if (num.size()<=1) return true;
- return std::none_of(std::next(num.cbegin()),num.end(),
- [prev=num[0]](int val) mutable {
- return val<std::exchange(prev,val);
- });
- }
// TODO: Replace examples and use TDD by writing your own tests #include <limits> Describe(Ordering_) // Cannot have the same name as the function ??!! { It(Order_To_Greatest) { Assert::That(Ordering({1,2,3,4,5}), Equals(true)); Assert::That(Ordering({2,1,3,4,5}), Equals(false)); Assert::That(Ordering({}), Equals(true)); Assert::That(Ordering({1}), Equals(true)); Assert::That(Ordering({1,1,1,1,1,1,1,1,0,1,1,1,1,1,1}), Equals(false)); Assert::That(Ordering({1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}), Equals(true)); const auto maxint=std::numeric_limits<int>::max(); Assert::That(Ordering({1,1,1,1,1,1,maxint,maxint,maxint}), Equals(true)); } };
- // TODO: Replace examples and use TDD by writing your own tests
Describe(Ordering)- #include <limits>
- Describe(Ordering_) // Cannot have the same name as the function ??!!
- {
- It(Order_To_Greatest)
- {
Assert::That({1,2,3,4,5}, Equals({1,2,3,4,5}));Assert::That({2,1,3,4,5}, Equals({1,2,3,4,5})- Assert::That(Ordering({1,2,3,4,5}), Equals(true));
- Assert::That(Ordering({2,1,3,4,5}), Equals(false));
- Assert::That(Ordering({}), Equals(true));
- Assert::That(Ordering({1}), Equals(true));
- Assert::That(Ordering({1,1,1,1,1,1,1,1,0,1,1,1,1,1,1}), Equals(false));
- Assert::That(Ordering({1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}), Equals(true));
- const auto maxint=std::numeric_limits<int>::max();
- Assert::That(Ordering({1,1,1,1,1,1,maxint,maxint,maxint}), Equals(true));
- }
- };
#include <string> #include <string_view> #include <vector> #include <numeric> std::string Jointup(const std::vector<std::string> &name , const std::string_view delim = " , "){ if (name.empty()) return ""; return std::accumulate(std::next(name.begin()),name.end(), name.front(), [&](auto &s, auto &n){return s.append(delim).append(n);}); }
using namespace std;string Jointup(vector<string> name , char symbol = ", "){string result;for(int i = 0 ; i < name.size() ; i++ ){result += name[i];if(i != name.size() - 1){result+= symbol;}}return result;- #include <string>
- #include <string_view>
- #include <vector>
- #include <numeric>
- std::string Jointup(const std::vector<std::string> &name , const std::string_view delim = " , "){
- if (name.empty()) return "";
- return std::accumulate(std::next(name.begin()),name.end(),
- name.front(),
- [&](auto &s, auto &n){return s.append(delim).append(n);});
- }
Describe(JointUp) { It(Should_Join_Up) { Assert::That(Jointup({"Adam","The" , "Best"}), Equals("Adam , The , Best")); Assert::That(Jointup({"Adam"}), Equals("Adam")); Assert::That(Jointup({}), Equals("")); Assert::That(Jointup({"Codewars","is" , "ideal", "for","young","practitioners"}," "), Equals("Codewars is ideal for young practitioners")); Assert::That(Jointup({"C++23","has" , "nice","extensions","for","this","type","of","problem..."},"--"), Equals("C++23--has--nice--extensions--for--this--type--of--problem...")); } };
- Describe(JointUp)
- {
- It(Should_Join_Up)
- {
Assert::That({"Adam","The" , "Best"}, Equals({"Adam , The , Best"}));- Assert::That(Jointup({"Adam","The" , "Best"}), Equals("Adam , The , Best"));
- Assert::That(Jointup({"Adam"}), Equals("Adam"));
- Assert::That(Jointup({}), Equals(""));
- Assert::That(Jointup({"Codewars","is" , "ideal", "for","young","practitioners"}," "), Equals("Codewars is ideal for young practitioners"));
- Assert::That(Jointup({"C++23","has" , "nice","extensions","for","this","type","of","problem..."},"--"), Equals("C++23--has--nice--extensions--for--this--type--of--problem..."));
- }
- };
local function find_squares_in_array(arr) local sum = 0 for _, v in ipairs(arr) do sum = sum + v ^ 2 end return sum end return find_squares_in_array
from numpy import square- local function find_squares_in_array(arr)
- local sum = 0
- for _, v in ipairs(arr) do
- sum = sum + v ^ 2
- end
- return sum
- end
def find_squares_in_array(arr):return sum(map(square, arr))- return find_squares_in_array
local find_squares_in_array = require "solution" it("Sample Tests", function() assert.are.same(0, find_squares_in_array {}) assert.are.same(55, find_squares_in_array { 1, 2, 3, 4, 5 }) assert.are.same(16, find_squares_in_array { 4 }) assert.are.same(0, find_squares_in_array { 0, 0, 0, 0 }) end)
from solution import find_squares_in_arrayimport codewars_test as test- local find_squares_in_array = require "solution"
@test.describe("find_squares_in_array")def sample_tests():@test.it('Sample Tests')def sample_tests():test.assert_equals(find_squares_in_array([]), 0)test.assert_equals(find_squares_in_array([1, 2, 3, 4, 5]), 55)test.assert_equals(find_squares_in_array([4]), 16)test.assert_equals(find_squares_in_array([0, 0, 0, 0]), 0)- it("Sample Tests", function()
- assert.are.same(0, find_squares_in_array {})
- assert.are.same(55, find_squares_in_array { 1, 2, 3, 4, 5 })
- assert.are.same(16, find_squares_in_array { 4 })
- assert.are.same(0, find_squares_in_array { 0, 0, 0, 0 })
- end)
def Complicated_Greetings(name): h=["H","e","l","l","o"] c="," w=["W","o","r","l","d"] e="!" k="" for i in h: k+=i if name=="": k+=c k+=" " for i in w: k+=i k=k+e+e else: k+=" " k+=name return k
- def Complicated_Greetings(name):
Hello = f'{chr(72)}{chr(101)}{2 * chr(108)}{chr(111)}'comma = f'{chr(44)}{chr(32)}'World = f'{chr(87)}{chr(111)}{chr(114)}{chr(108)}{chr(100)}{2 * chr(33)}'return Hello + " "+ name if name else Hello+comma+World- h=["H","e","l","l","o"]
- c=","
- w=["W","o","r","l","d"]
- e="!"
- k=""
- for i in h:
- k+=i
- if name=="":
- k+=c
- k+=" "
- for i in w:
- k+=i
- k=k+e+e
- else:
- k+=" "
- k+=name
- return k
Background
This task assumes familiarity with template metaprogramming and std::ratio
.
Overview
In this task, you’ll represent and manipulate polynomials through C++'s type system by means of template metaprogramming and the std::ratio
type. The key idea is to define a Polynomial
class template, where each term in the polynomial is represented by a coefficient using std::ratio
.
Polynomial Structure
Create a class Polynomial
that takes, as a parameter pack, a series of std::ratio
s representing the coefficients. Each ratio corresponds to the coefficient of a term, starting from the highest degree on the left and down to the constant term on the right.
For example, the polynomial
$ 10x^3 + 2.5x^2 + 5x + 0.5 $
Is represented by the type
Polynomial<std::ratio<10>, std::ratio<5, 2>, std::ratio<5>, std::ratio<1, 2>>
Each std::ratio represents a coefficient (e.g., std::ratio<5, 2>
represents 2.5
).
The rightmost ratio is the constant term (degree 0), and the terms to the left represent higher degree terms (e.g., the std::ratio<10>
stands for $ 10x^3 $
here).
One important rule: your Polynomial
s shouldn't have leading zero coefficients. After all, $ 0x^4 + 0x^3 + x^2 + x $
is simply $ x^2 + x $
. The only exception is the degree 0 polynomial (i.e., constant), where a lone zero is valid and is represented as Polynomial<std::ratio<0>>
.
Objective
You'll implement three main operations (as type aliases) for this compile-time polynomial class: differentiation, integration, and addition.
-
Polynomial<...>::differentiated
Type alias to the polynomial type representing the result of differentiating the current.
Example:
Polynomial<std::ratio<30>, std::ratio<20>, std::ratio<10>>::differentiated // Differentiating 30x^2 + 20x + 10. Alias for type Polynomial<std::ratio<60>, std::ratio<20>>. Polynomial<std::ratio<60>, std::ratio<20>>::differentiated // Differentiating 60x + 20. Alias for type Polynomial<std::ratio<60>>. Polynomial<std::ratio<60>>::differentiated // Differentiating 60. Alias for type Polynomial<std::ratio<0>> (i.e., constant term 0).
-
Polynomial<...>::integrated<std::ratio<...>>
Type alias to the polynomial type representing the result of integrating the current, including an integration constant (a
std::ratio
passed as a template argument).Example:
Polynomial<std::ratio<10>>::integrated<std::ratio<20>> // 20 is the integration constant. // Alias for type Polynomial<std::ratio<10>, std::ratio<20>>. Polynomial<std::ratio<10>, std::ratio<20>>::integrated<std::ratio<5, 2>> // 2.5 is the integration constant. // Alias for type Polynomial<std::ratio<5>, std::ratio<20>, std::ratio<5, 2>>.
You may assume that that the template argument provided to
integrated
by the tests will always be astd::ratio
. Hence, there is no need to validate the type. -
Polynomial<...>::add<Polynomial<...>>
Type alias template that accepts, as a template argument, another
Polynomial
, and represents the polynomial type resulting from adding the two together.The polynomials may possibly be of different degrees.
Example:
Polynomial<std::ratio<7>, std::ratio<5>>::add<Polynomial<std::ratio<3>, std::ratio<1>>> // (7x + 5) + (3x + 1). Alias for type Polynomial<std::ratio<10>, std::ratio<6>>. Polynomial<std::ratio<10>, std::ratio<20>>::add<Polynomial<std::ratio<30>>> // (10x + 20) + (30). Alias for type Polynomial<std::ratio<10>, std::ratio<50>>. Polynomial<std::ratio<25>, std::ratio<3>>::add<Polynomial<std::ratio<-25>, std::ratio<10>>> // (25x + 3) + (-25x + 10). Alias for type Polynomial<std::ratio<13>>. // (NOT Polynomial<std::ratio<0>, std::ratio<13>>)!
Remember, the coefficients can be negative, and it is your responsibility to ensure your resulting polynomial doesn't have leading zeroes after addition.
Assumptions
- Single-variable polynomials: All polynomials involve only one variable (x).
-
No omitted terms: All coefficients are explicitly represented, even if zero. A polynomial of degree
n
will have alln + 1
coefficients embedded in the type. However, there should be no unnecessary leading zeroes.
Note
The tests are forgiving in the sense that unimplemented parts of your solution will be registered as a failed test rather than a compilation error. Also, any two std::ratio
s representing the same quantity will be marked as correct. So, std::ratio<3>
and std::ratio<6, 2>
are equivalent when testing. If the tests time out, it's likely because your solution contains unintendeed infinite recursion.
#include <ratio> #include <utility> #include <cstddef> #include <tuple> #include <type_traits> template <typename... Coeffs> struct Polynomial; // Helpers to help "trim" Polynomials of leading zeroes. template<typename...> struct trim_impl; template<> struct trim_impl<> : std::common_type<Polynomial<>> {}; template<typename R1, typename... Rs> struct trim_impl<R1, Rs...> : std::conditional<sizeof...(Rs) and std::is_same_v<R1, std::ratio<0>>, typename trim_impl<Rs...>::type, Polynomial<R1, Rs...>> {}; template <typename... Coeffs> struct Polynomial { // Degree of Polynomial. static constexpr auto degree = sizeof...(Coeffs) - 1; // Alias for type of i-th std::ratio in the parameter pack. Pre-C++26 workaround for pack indexing. template <std::size_t I> using at = std::tuple_element_t<I, std::tuple<Coeffs...>>; // Alias for Polynomial type with leading zeroes removed. using trim = typename trim_impl<Coeffs...>::type; // Pads by adding leading zeroes until the parameter pack becomes of size I. template <std::size_t... Is> static constexpr auto pad_impl(std::index_sequence<Is...> seq) -> Polynomial<std::ratio<Is & 0>..., Coeffs...>; template <std::size_t I> static constexpr auto pad = decltype(pad_impl(std::make_index_sequence<std::max(I, degree) - degree>{})){}; // Private (but not really) helpers: template <typename... R1, typename... Rs> static constexpr auto add_impl(Polynomial<R1...>, Polynomial<Rs...>) -> Polynomial<std::ratio_add<R1, Rs>...>; template <typename... Rs, std::size_t... Is> static constexpr auto diff_impl(std::index_sequence<Is...>) -> Polynomial<std::ratio_multiply<at<Is>, std::ratio<degree - Is>>...>; template <typename C, std::size_t... Is> static constexpr auto integrate_impl(std::index_sequence<Is...>) -> Polynomial<std::ratio_divide<Coeffs, std::ratio<degree + 1 - Is>>..., C>; // Public aliases. template <typename Other> using add = typename decltype(add_impl(pad<Other::degree>, Other::template pad<degree>))::trim; using differentiated = decltype(diff_impl(std::make_index_sequence<degree + not degree>{})); template<typename C> using integrated = typename decltype(integrate_impl<C>(std::make_index_sequence<degree + 1>{}))::trim; };
- #include <ratio>
- #include <utility>
- #include <cstddef>
- #include <tuple>
- #include <type_traits>
// INTIAL SOLUTION TEMPLATE:- template <typename... Coeffs>
- struct Polynomial;
- // Helpers to help "trim" Polynomials of leading zeroes.
- template<typename...> struct trim_impl;
- template<> struct trim_impl<> : std::common_type<Polynomial<>> {};
- template<typename R1, typename... Rs> struct trim_impl<R1, Rs...> : std::conditional<sizeof...(Rs) and std::is_same_v<R1, std::ratio<0>>, typename trim_impl<Rs...>::type, Polynomial<R1, Rs...>> {};
- template <typename... Coeffs>
- struct Polynomial {
// using differentiated = ???;// template <???> using add = ???;// template <???> using integrated = ???;};- // Degree of Polynomial.
- static constexpr auto degree = sizeof...(Coeffs) - 1;
- // Alias for type of i-th std::ratio in the parameter pack. Pre-C++26 workaround for pack indexing.
- template <std::size_t I> using at = std::tuple_element_t<I, std::tuple<Coeffs...>>;
- // Alias for Polynomial type with leading zeroes removed.
- using trim = typename trim_impl<Coeffs...>::type;
- // Pads by adding leading zeroes until the parameter pack becomes of size I.
- template <std::size_t... Is> static constexpr auto pad_impl(std::index_sequence<Is...> seq) -> Polynomial<std::ratio<Is & 0>..., Coeffs...>;
- template <std::size_t I> static constexpr auto pad = decltype(pad_impl(std::make_index_sequence<std::max(I, degree) - degree>{})){};
- // Private (but not really) helpers:
- template <typename... R1, typename... Rs> static constexpr auto add_impl(Polynomial<R1...>, Polynomial<Rs...>)
- -> Polynomial<std::ratio_add<R1, Rs>...>;
- template <typename... Rs, std::size_t... Is> static constexpr auto diff_impl(std::index_sequence<Is...>)
- -> Polynomial<std::ratio_multiply<at<Is>, std::ratio<degree - Is>>...>;
- template <typename C, std::size_t... Is> static constexpr auto integrate_impl(std::index_sequence<Is...>)
- -> Polynomial<std::ratio_divide<Coeffs, std::ratio<degree + 1 - Is>>..., C>;
- // Public aliases.
- template <typename Other> using add = typename decltype(add_impl(pad<Other::degree>, Other::template pad<degree>))::trim;
- using differentiated = decltype(diff_impl(std::make_index_sequence<degree + not degree>{}));
- template<typename C> using integrated = typename decltype(integrate_impl<C>(std::make_index_sequence<degree + 1>{}))::trim;
- };
Return the prime factorisation of a number.
def count_prime(n, prime, factors): count = 0 while n % prime == 0: count += 1 n //= prime if count: factors.append((prime, count)) return n, factors def is_prime(n): for i in range(7, int(n ** 0.5) + 1, 2): if n % i == 0: return False return True def prime_factorization(n): factors = [] n, factors = count_prime(n, 2, factors) prime = 3 while prime * prime <= n: n, factors = count_prime(n, prime, factors) prime += 2 while not is_prime(prime): prime += 2 if n > 1: factors.append((n, 1)) return factors
- def count_prime(n, prime, factors):
- count = 0
- while n % prime == 0:
- count += 1
- n //= prime
- if count:
- factors.append((prime, count))
- return n, factors
- def is_prime(n):
- for i in range(7, int(n ** 0.5) + 1, 2):
- if n % i == 0:
- return False
- return True
- def prime_factorization(n):
- factors = []
- n, factors = count_prime(n, 2, factors)
- prime = 3
- while prime * prime <= n:
- n, factors = count_prime(n, prime, factors)
- prime += 2
- while not is_prime(prime):
- prime += 2
- if n > 1:
- factors.append((n, 1))
- return factors
Solucion con lambdas
import java.util.Arrays; import java.util.Comparator; import java.util.stream.Collectors; import java.math.BigInteger; public class MaxNumber { public static BigInteger print(long number) { String numeroMaximo = Long.toString(number) .chars() .mapToObj(Character::toString) .sorted((a, b) -> b.compareTo(a)) .collect(Collectors.joining()); return new BigInteger(numeroMaximo); } }
- import java.util.Arrays;
- import java.util.Comparator;
- import java.util.stream.Collectors;
- import java.math.BigInteger;
- public class MaxNumber {
- public static BigInteger print(long number) {
int[] digits = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};for (char digit : Long.toString(number).toCharArray()) {digits[digit - '0']++;}BigInteger sum = BigInteger.ZERO;int i = 9;while(i >= 0) {if (digits[i] == 0) {i--;} else {digits[i]--;sum = sum.multiply(BigInteger.TEN).add(BigInteger.valueOf(i));}}return sum;- String numeroMaximo = Long.toString(number)
- .chars()
- .mapToObj(Character::toString)
- .sorted((a, b) -> b.compareTo(a))
- .collect(Collectors.joining());
- return new BigInteger(numeroMaximo);
- }
- }
def m(a, b): # Did you know? This is an implementation of Long Multiplacation negative_result = (a < 0) ^ (b < 0) a, b = abs(a), abs(b) a_str = str(a)[::-1] b_str = str(b)[::-1] result_length = len(a_str) + len(b_str) result = [0] * result_length for i in range(len(a_str)): for j in range(len(b_str)): digit_a = int(a_str[i]) digit_b = int(b_str[j]) product = digit_a * digit_b result[i + j] += product carry = result[i + j] // 10 result[i + j] %= 10 result[i + j + 1] += carry while len(result) > 1 and result[-1] == 0: result.pop() result_str = ''.join(map(str, result[::-1])) final_result = int(result_str) return -final_result if negative_result else final_result # test me pls
m = __import__('operator').mul- def m(a, b):
- # Did you know? This is an implementation of Long Multiplacation
- negative_result = (a < 0) ^ (b < 0)
- a, b = abs(a), abs(b)
- a_str = str(a)[::-1]
- b_str = str(b)[::-1]
- result_length = len(a_str) + len(b_str)
- result = [0] * result_length
- for i in range(len(a_str)):
- for j in range(len(b_str)):
- digit_a = int(a_str[i])
- digit_b = int(b_str[j])
- product = digit_a * digit_b
- result[i + j] += product
- carry = result[i + j] // 10
- result[i + j] %= 10
- result[i + j + 1] += carry
- while len(result) > 1 and result[-1] == 0:
- result.pop()
- result_str = ''.join(map(str, result[::-1]))
- final_result = int(result_str)
- return -final_result if negative_result else final_result
- # test me pls
#include <fmt/format.h> #include <iostream> #include <cstdlib> #include <ctime> #include <vector> #include <bitset> #include <algorithm> #include <cmath> #include <cctype> #include <random> using namespace std; static const string msgs[]={ "Enter your guess (a 4-digit number with non-repeating digits): ", "Correct numbers: {} Correct position: {}", "Congratulations! You guessed the number {} correctly in {} attempts!", "Oups.. You could not guess the number in {} attempts!", "Invalid input. Please enter a 4-digit number with non-repeating digits." }; // Initialize random number generator outside functions static random_device rd; // Obtain a random number from hardware static mt19937 g(rd()); // Seed the generator string generateRandomNumber() { static string base{"0123456789"}; // Shuffle digits shuffle(base.begin(), base.end(), g); // Return the first 4 digits as a string return base.substr(0,4); } bool hasDuplicateDigits(const string &number) { return accumulate(number.cbegin(),number.cend(), bitset<10>{0}, [](auto &bs,auto c) {return bs.set(c-'0');} ).count()!=number.size(); } bool isNumeric(const string &s) { return all_of(s.begin(), s.end(), ::isdigit); } string getUserGuess(istream &in = cin, ostream &out = cout) { string guess; out << msgs[0]; in >> guess; return guess; } pair<int, int> checkGuess(const string &randomNumber, const string &userGuess) { pair<int, int> ret {0,0}; for (int i = 0; i < 4; ++i) { if (randomNumber[i] == userGuess[i]) { ++get<0>(ret), ++get<1>(ret); } else if (count(randomNumber.begin(), randomNumber.end(), userGuess[i])) { ++get<0>(ret); } } return ret; } int acceptGuess(const string &expected, istream &in = cin, std::ostream &out = std::cout, int maxattempts=20) { int attempts = 0; std::pair status{0,0}; do { std::string userGuess = getUserGuess(in, out); if (userGuess.length() != 4 || hasDuplicateDigits(userGuess) || !isNumeric(userGuess)) { out << msgs[4] << std::endl; } else { status = checkGuess(expected, userGuess); out << fmt::format(msgs[1],status.first,status.second) << std::endl; } attempts++; } while (status.second!=4 && attempts<maxattempts); if (attempts==maxattempts) out << fmt::format(msgs[3],attempts)<< std::endl; else out << fmt::format(msgs[2],expected,attempts)<< std::endl; return attempts; } int _main(std::istream &in = std::cin, std::ostream &out = std::cout) { // Seed rand since random_shuffle _probably_ uses it. srand(static_cast<unsigned>(time(0))); std::string randomNumber = generateRandomNumber(); acceptGuess(randomNumber, in, out); return 0; }
- #include <fmt/format.h>
- #include <iostream>
- #include <cstdlib>
- #include <ctime>
- #include <vector>
- #include <bitset>
- #include <algorithm>
- #include <cmath>
- #include <cctype>
- #include <random>
- using namespace std;
static const std::string msgs[]={- static const string msgs[]={
- "Enter your guess (a 4-digit number with non-repeating digits): ",
- "Correct numbers: {} Correct position: {}",
- "Congratulations! You guessed the number {} correctly in {} attempts!",
- "Oups.. You could not guess the number in {} attempts!",
- "Invalid input. Please enter a 4-digit number with non-repeating digits."
- };
- // Initialize random number generator outside functions
static std::random_device rd; // Obtain a random number from hardwarestatic std::mt19937 g(rd()); // Seed the generator- static random_device rd; // Obtain a random number from hardware
- static mt19937 g(rd()); // Seed the generator
std::string generateRandomNumber() {static std::string base{"0123456789"};- string generateRandomNumber() {
- static string base{"0123456789"};
- // Shuffle digits
std::shuffle(base.begin(), base.end(), g);- shuffle(base.begin(), base.end(), g);
- // Return the first 4 digits as a string
- return base.substr(0,4);
- }
bool hasDuplicateDigits(const std::string &number) {return std::accumulate(number.cbegin(),number.cend(), std::bitset<10>{0},- bool hasDuplicateDigits(const string &number) {
- return accumulate(number.cbegin(),number.cend(), bitset<10>{0},
- [](auto &bs,auto c) {return bs.set(c-'0');}
- ).count()!=number.size();
- }
bool isNumeric(const std::string &s) {return std::all_of(s.begin(), s.end(), ::isdigit);- bool isNumeric(const string &s) {
- return all_of(s.begin(), s.end(), ::isdigit);
- }
std::string getUserGuess(std::istream &in = std::cin, std::ostream &out = std::cout) {std::string guess;- string getUserGuess(istream &in = cin, ostream &out = cout) {
- string guess;
- out << msgs[0];
- in >> guess;
- return guess;
- }
std::pair<int, int> checkGuess(const std::string &randomNumber, const std::string &userGuess) {std::pair<int, int> ret {0,0};- pair<int, int> checkGuess(const string &randomNumber, const string &userGuess) {
- pair<int, int> ret {0,0};
- for (int i = 0; i < 4; ++i) {
- if (randomNumber[i] == userGuess[i]) {
++std::get<0>(ret), ++std::get<1>(ret);} else if (std::count(randomNumber.begin(), randomNumber.end(), userGuess[i])) {++std::get<0>(ret);- ++get<0>(ret), ++get<1>(ret);
- } else if (count(randomNumber.begin(), randomNumber.end(), userGuess[i])) {
- ++get<0>(ret);
- }
- }
- return ret;
- }
int acceptGuess(const std::string &expected, std::istream &in = std::cin, std::ostream &out = std::cout, int maxattempts=20) {- int acceptGuess(const string &expected, istream &in = cin, std::ostream &out = std::cout, int maxattempts=20) {
- int attempts = 0;
- std::pair status{0,0};
- do {
- std::string userGuess = getUserGuess(in, out);
- if (userGuess.length() != 4 || hasDuplicateDigits(userGuess) || !isNumeric(userGuess)) {
- out << msgs[4] << std::endl;
- } else {
- status = checkGuess(expected, userGuess);
- out << fmt::format(msgs[1],status.first,status.second) << std::endl;
- }
- attempts++;
- } while (status.second!=4 && attempts<maxattempts);
- if (attempts==maxattempts)
- out << fmt::format(msgs[3],attempts)<< std::endl;
- else
- out << fmt::format(msgs[2],expected,attempts)<< std::endl;
- return attempts;
- }
- int _main(std::istream &in = std::cin, std::ostream &out = std::cout) {
- // Seed rand since random_shuffle _probably_ uses it.
- srand(static_cast<unsigned>(time(0)));
- std::string randomNumber = generateRandomNumber();
- acceptGuess(randomNumber, in, out);
- return 0;
- }