#include <string> #include <string_view> #include <fmt/format.h> #include <cmath> #include <array> namespace{ using namespace std::literals::string_view_literals; constexpr std::array ones_map{"ZERO "sv, "ONE "sv, "TWO "sv, "THREE "sv, "FOUR "sv, "FIVE "sv, "SIX "sv, "SEVEN "sv, "EIGHT "sv, "NINE "sv}; constexpr std::array teens_map{"TEN "sv, "ELEVEN "sv, "TWELVE "sv, "THIRTEEN "sv, "FOURTEEN "sv, "FIFTEEN "sv, "SIXTEEN "sv, "SEVENTEEN "sv, "EIGHTEEN "sv, "NINETEEN "sv}; constexpr std::array tens_map{"TWENTY "sv, "THIRTY "sv, "FORTY "sv, "FIFTY "sv, "SIXTY "sv, "SEVENTY "sv, "EIGHTY "sv, "NINETY "sv}; constexpr std::string_view empty{}; } std::string checkAmount(double amount) { int totalCents = static_cast<int>( std::round(amount * 100) ); if (totalCents < 1 || totalCents > 9999) return {}; int dollars = totalCents / 100; int cents = totalCents % 100; auto tens_word = empty; auto ones_word = empty; if(dollars < 10){ ones_word = ones_map[dollars]; } else if(dollars < 20){ ones_word = teens_map[dollars - 10]; } else{ auto ones_val = dollars % 10; if(ones_val > 0){ ones_word = ones_map[ones_val]; } tens_word = tens_map[dollars / 10 - 2]; } return fmt::format("{}{}and {}/100", tens_word, ones_word, cents); }
#include <string.h>#include <stdio.h>#include <stdlib.h>- #include <string>
- #include <string_view>
- #include <fmt/format.h>
- #include <cmath>
- #include <array>
char *checkAmount(double amount) {char * return_val = NULL;// Your code here!- namespace{
- using namespace std::literals::string_view_literals;
- constexpr std::array ones_map{"ZERO "sv, "ONE "sv, "TWO "sv, "THREE "sv, "FOUR "sv, "FIVE "sv, "SIX "sv, "SEVEN "sv, "EIGHT "sv, "NINE "sv};
- constexpr std::array teens_map{"TEN "sv, "ELEVEN "sv, "TWELVE "sv, "THIRTEEN "sv, "FOURTEEN "sv, "FIFTEEN "sv, "SIXTEEN "sv, "SEVENTEEN "sv, "EIGHTEEN "sv, "NINETEEN "sv};
- constexpr std::array tens_map{"TWENTY "sv, "THIRTY "sv, "FORTY "sv, "FIFTY "sv, "SIXTY "sv, "SEVENTY "sv, "EIGHTY "sv, "NINETY "sv};
- constexpr std::string_view empty{};
- }
- std::string checkAmount(double amount) {
- int totalCents = static_cast<int>( std::round(amount * 100) );
- if (totalCents < 1 || totalCents > 9999) return {};
- int dollars = totalCents / 100;
- int cents = totalCents % 100;
- auto tens_word = empty;
- auto ones_word = empty;
- if(dollars < 10){
- ones_word = ones_map[dollars];
- } else if(dollars < 20){
- ones_word = teens_map[dollars - 10];
- } else{
- auto ones_val = dollars % 10;
- if(ones_val > 0){
- ones_word = ones_map[ones_val];
- }
- tens_word = tens_map[dollars / 10 - 2];
- }
return return_val;- return fmt::format("{}{}and {}/100", tens_word, ones_word, cents);
- }
Describe(Normal_dollar_tests) { It(zero_to_nine) { Assert::That(checkAmount(0.01), Equals("ZERO and 1/100")); Assert::That(checkAmount(1.00), Equals("ONE and 0/100")); Assert::That(checkAmount(2.00), Equals("TWO and 0/100")); Assert::That(checkAmount(3.00), Equals("THREE and 0/100")); Assert::That(checkAmount(4.00), Equals("FOUR and 0/100")); Assert::That(checkAmount(5.00), Equals("FIVE and 0/100")); Assert::That(checkAmount(6.00), Equals("SIX and 0/100")); Assert::That(checkAmount(7.00), Equals("SEVEN and 0/100")); Assert::That(checkAmount(8.00), Equals("EIGHT and 0/100")); Assert::That(checkAmount(9.00), Equals("NINE and 0/100")); } It(ten_to_nineteen) { Assert::That(checkAmount(10.00), Equals("TEN and 0/100")); Assert::That(checkAmount(11.00), Equals("ELEVEN and 0/100")); Assert::That(checkAmount(12.00), Equals("TWELVE and 0/100")); Assert::That(checkAmount(13.00), Equals("THIRTEEN and 0/100")); Assert::That(checkAmount(14.00), Equals("FOURTEEN and 0/100")); Assert::That(checkAmount(15.00), Equals("FIFTEEN and 0/100")); Assert::That(checkAmount(16.00), Equals("SIXTEEN and 0/100")); Assert::That(checkAmount(17.00), Equals("SEVENTEEN and 0/100")); Assert::That(checkAmount(18.00), Equals("EIGHTEEN and 0/100")); Assert::That(checkAmount(19.00), Equals("NINETEEN and 0/100")); } It(twenty_to_ninety_nine) { Assert::That(checkAmount(20.00), Equals("TWENTY and 0/100")); Assert::That(checkAmount(21.00), Equals("TWENTY ONE and 0/100")); Assert::That(checkAmount(30.00), Equals("THIRTY and 0/100")); Assert::That(checkAmount(32.00), Equals("THIRTY TWO and 0/100")); Assert::That(checkAmount(40.00), Equals("FORTY and 0/100")); Assert::That(checkAmount(43.00), Equals("FORTY THREE and 0/100")); Assert::That(checkAmount(50.00), Equals("FIFTY and 0/100")); Assert::That(checkAmount(54.00), Equals("FIFTY FOUR and 0/100")); Assert::That(checkAmount(60.00), Equals("SIXTY and 0/100")); Assert::That(checkAmount(65.00), Equals("SIXTY FIVE and 0/100")); Assert::That(checkAmount(70.00), Equals("SEVENTY and 0/100")); Assert::That(checkAmount(76.00), Equals("SEVENTY SIX and 0/100")); Assert::That(checkAmount(80.00), Equals("EIGHTY and 0/100")); Assert::That(checkAmount(87.00), Equals("EIGHTY SEVEN and 0/100")); Assert::That(checkAmount(90.00), Equals("NINETY and 0/100")); Assert::That(checkAmount(98.00), Equals("NINETY EIGHT and 0/100")); Assert::That(checkAmount(99.00), Equals("NINETY NINE and 0/100")); } }; Describe(Normal_cent_tests) { It(zero_to_ninety_nine_cents) { Assert::That(checkAmount(42.00), Equals("FORTY TWO and 0/100")); Assert::That(checkAmount(42.01), Equals("FORTY TWO and 1/100")); Assert::That(checkAmount(42.10), Equals("FORTY TWO and 10/100")); Assert::That(checkAmount(42.21), Equals("FORTY TWO and 21/100")); Assert::That(checkAmount(42.32), Equals("FORTY TWO and 32/100")); Assert::That(checkAmount(42.43), Equals("FORTY TWO and 43/100")); Assert::That(checkAmount(42.54), Equals("FORTY TWO and 54/100")); Assert::That(checkAmount(42.65), Equals("FORTY TWO and 65/100")); Assert::That(checkAmount(42.76), Equals("FORTY TWO and 76/100")); Assert::That(checkAmount(42.87), Equals("FORTY TWO and 87/100")); Assert::That(checkAmount(42.98), Equals("FORTY TWO and 98/100")); Assert::That(checkAmount(42.99), Equals("FORTY TWO and 99/100")); } };
#include <criterion/criterion.h>#include <string.h>#include <stdio.h>#include <stdlib.h>// functional prototypechar *checkAmount(double amount);Test(Normal_dollar_tests, zero_to_nine) {// 0-9cr_assert(strncmp("ZERO and 1/100", checkAmount((double)0.01), 1024) == 0);cr_assert(strncmp("ONE and 0/100", checkAmount((double)1.00), 1024) == 0);cr_assert(strncmp("TWO and 0/100", checkAmount((double)2.00), 1024) == 0);cr_assert(strncmp("THREE and 0/100", checkAmount((double)3.00), 1024) == 0);cr_assert(strncmp("FOUR and 0/100", checkAmount((double)4.00), 1024) == 0);cr_assert(strncmp("FIVE and 0/100", checkAmount((double)5.00), 1024) == 0);cr_assert(strncmp("SIX and 0/100", checkAmount((double)6.00), 1024) == 0);cr_assert(strncmp("SEVEN and 0/100", checkAmount((double)7.00), 1024) == 0);cr_assert(strncmp("EIGHT and 0/100", checkAmount((double)8.00), 1024) == 0);cr_assert(strncmp("NINE and 0/100", checkAmount((double)9.00), 1024) == 0);}Test(Normal_dollar_tests, ten_to_nineteen) {// 10-19cr_assert(strncmp("TEN and 0/100", checkAmount((double)10.00), 1024) == 0);cr_assert(strncmp("ELEVEN and 0/100", checkAmount((double)11.00), 1024) == 0);cr_assert(strncmp("TWELVE and 0/100", checkAmount((double)12.00), 1024) == 0);cr_assert(strncmp("THIRTEEN and 0/100", checkAmount((double)13.00), 1024) == 0);cr_assert(strncmp("FOURTEEN and 0/100", checkAmount((double)14.00), 1024) == 0);cr_assert(strncmp("FIFTEEN and 0/100", checkAmount((double)15.00), 1024) == 0);cr_assert(strncmp("SIXTEEN and 0/100", checkAmount((double)16.00), 1024) == 0);cr_assert(strncmp("SEVENTEEN and 0/100", checkAmount((double)17.00), 1024) == 0);cr_assert(strncmp("EIGHTEEN and 0/100", checkAmount((double)18.00), 1024) == 0);cr_assert(strncmp("NINETEEN and 0/100", checkAmount((double)19.00), 1024) == 0);}Test(Normal_dollar_tests, twenty_to_ninety_nine) {// These test both the 10s place and the ones placecr_assert(strncmp("TWENTY and 0/100", checkAmount((double)20.00), 1024) == 0);cr_assert(strncmp("TWENTY ONE and 0/100", checkAmount((double)21.00), 1024) == 0);cr_assert(strncmp("THIRTY and 0/100", checkAmount((double)30.00), 1024) == 0);cr_assert(strncmp("THIRTY TWO and 0/100", checkAmount((double)32.00), 1024) == 0);cr_assert(strncmp("FORTY and 0/100", checkAmount((double)40.00), 1024) == 0);cr_assert(strncmp("FORTY THREE and 0/100", checkAmount((double)43.00), 1024) == 0);cr_assert(strncmp("FIFTY and 0/100", checkAmount((double)50.00), 1024) == 0);cr_assert(strncmp("FIFTY FOUR and 0/100", checkAmount((double)54.00), 1024) == 0);cr_assert(strncmp("SIXTY and 0/100", checkAmount((double)60.00), 1024) == 0);cr_assert(strncmp("SIXTY FIVE and 0/100", checkAmount((double)65.00), 1024) == 0);cr_assert(strncmp("SEVENTY and 0/100", checkAmount((double)70.00), 1024) == 0);cr_assert(strncmp("SEVENTY SIX and 0/100", checkAmount((double)76.00), 1024) == 0);cr_assert(strncmp("EIGHTY and 0/100", checkAmount((double)80.00), 1024) == 0);cr_assert(strncmp("EIGHTY SEVEN and 0/100", checkAmount((double)87.00), 1024) == 0);cr_assert(strncmp("NINETY and 0/100", checkAmount((double)90.00), 1024) == 0);cr_assert(strncmp("NINETY EIGHT and 0/100", checkAmount((double)98.00), 1024) == 0);cr_assert(strncmp("NINETY NINE and 0/100", checkAmount((double)99.00), 1024) == 0);}Test(Normal_cent_tests, zero_to_ninety_nine) {cr_assert(strncmp("FORTY TWO and 0/100", checkAmount((double)42.00), 1024) == 0);cr_assert(strncmp("FORTY TWO and 1/100", checkAmount((double)42.01), 1024) == 0);cr_assert(strncmp("FORTY TWO and 10/100", checkAmount((double)42.10), 1024) == 0);cr_assert(strncmp("FORTY TWO and 21/100", checkAmount((double)42.21), 1024) == 0);cr_assert(strncmp("FORTY TWO and 32/100", checkAmount((double)42.32), 1024) == 0);cr_assert(strncmp("FORTY TWO and 43/100", checkAmount((double)42.43), 1024) == 0);cr_assert(strncmp("FORTY TWO and 54/100", checkAmount((double)42.54), 1024) == 0);cr_assert(strncmp("FORTY TWO and 65/100", checkAmount((double)42.65), 1024) == 0);cr_assert(strncmp("FORTY TWO and 76/100", checkAmount((double)42.76), 1024) == 0);cr_assert(strncmp("FORTY TWO and 87/100", checkAmount((double)42.87), 1024) == 0);cr_assert(strncmp("FORTY TWO and 98/100", checkAmount((double)42.98), 1024) == 0);cr_assert(strncmp("FORTY TWO and 99/100", checkAmount((double)42.99), 1024) == 0);}- Describe(Normal_dollar_tests)
- {
- It(zero_to_nine)
- {
- Assert::That(checkAmount(0.01), Equals("ZERO and 1/100"));
- Assert::That(checkAmount(1.00), Equals("ONE and 0/100"));
- Assert::That(checkAmount(2.00), Equals("TWO and 0/100"));
- Assert::That(checkAmount(3.00), Equals("THREE and 0/100"));
- Assert::That(checkAmount(4.00), Equals("FOUR and 0/100"));
- Assert::That(checkAmount(5.00), Equals("FIVE and 0/100"));
- Assert::That(checkAmount(6.00), Equals("SIX and 0/100"));
- Assert::That(checkAmount(7.00), Equals("SEVEN and 0/100"));
- Assert::That(checkAmount(8.00), Equals("EIGHT and 0/100"));
- Assert::That(checkAmount(9.00), Equals("NINE and 0/100"));
- }
- It(ten_to_nineteen)
- {
- Assert::That(checkAmount(10.00), Equals("TEN and 0/100"));
- Assert::That(checkAmount(11.00), Equals("ELEVEN and 0/100"));
- Assert::That(checkAmount(12.00), Equals("TWELVE and 0/100"));
- Assert::That(checkAmount(13.00), Equals("THIRTEEN and 0/100"));
- Assert::That(checkAmount(14.00), Equals("FOURTEEN and 0/100"));
- Assert::That(checkAmount(15.00), Equals("FIFTEEN and 0/100"));
- Assert::That(checkAmount(16.00), Equals("SIXTEEN and 0/100"));
- Assert::That(checkAmount(17.00), Equals("SEVENTEEN and 0/100"));
- Assert::That(checkAmount(18.00), Equals("EIGHTEEN and 0/100"));
- Assert::That(checkAmount(19.00), Equals("NINETEEN and 0/100"));
- }
- It(twenty_to_ninety_nine)
- {
- Assert::That(checkAmount(20.00), Equals("TWENTY and 0/100"));
- Assert::That(checkAmount(21.00), Equals("TWENTY ONE and 0/100"));
- Assert::That(checkAmount(30.00), Equals("THIRTY and 0/100"));
- Assert::That(checkAmount(32.00), Equals("THIRTY TWO and 0/100"));
- Assert::That(checkAmount(40.00), Equals("FORTY and 0/100"));
- Assert::That(checkAmount(43.00), Equals("FORTY THREE and 0/100"));
- Assert::That(checkAmount(50.00), Equals("FIFTY and 0/100"));
- Assert::That(checkAmount(54.00), Equals("FIFTY FOUR and 0/100"));
- Assert::That(checkAmount(60.00), Equals("SIXTY and 0/100"));
- Assert::That(checkAmount(65.00), Equals("SIXTY FIVE and 0/100"));
- Assert::That(checkAmount(70.00), Equals("SEVENTY and 0/100"));
- Assert::That(checkAmount(76.00), Equals("SEVENTY SIX and 0/100"));
- Assert::That(checkAmount(80.00), Equals("EIGHTY and 0/100"));
- Assert::That(checkAmount(87.00), Equals("EIGHTY SEVEN and 0/100"));
- Assert::That(checkAmount(90.00), Equals("NINETY and 0/100"));
- Assert::That(checkAmount(98.00), Equals("NINETY EIGHT and 0/100"));
- Assert::That(checkAmount(99.00), Equals("NINETY NINE and 0/100"));
- }
- };
- Describe(Normal_cent_tests)
- {
- It(zero_to_ninety_nine_cents)
- {
- Assert::That(checkAmount(42.00), Equals("FORTY TWO and 0/100"));
- Assert::That(checkAmount(42.01), Equals("FORTY TWO and 1/100"));
- Assert::That(checkAmount(42.10), Equals("FORTY TWO and 10/100"));
- Assert::That(checkAmount(42.21), Equals("FORTY TWO and 21/100"));
- Assert::That(checkAmount(42.32), Equals("FORTY TWO and 32/100"));
- Assert::That(checkAmount(42.43), Equals("FORTY TWO and 43/100"));
- Assert::That(checkAmount(42.54), Equals("FORTY TWO and 54/100"));
- Assert::That(checkAmount(42.65), Equals("FORTY TWO and 65/100"));
- Assert::That(checkAmount(42.76), Equals("FORTY TWO and 76/100"));
- Assert::That(checkAmount(42.87), Equals("FORTY TWO and 87/100"));
- Assert::That(checkAmount(42.98), Equals("FORTY TWO and 98/100"));
- Assert::That(checkAmount(42.99), Equals("FORTY TWO and 99/100"));
- }
- };
as the relative order between two equal ints does not matter (and sort would ruin it anyways), we can just use partition, instead of stable_partition.
Added a lot of tests
#include <vector> void re_arrange(std::vector<int>& data) { auto it = std::partition(data.begin(), data.end(), [](int x) { return x % 2 == 0; }); std::sort(data.begin(), it); std::sort(it, data.end()); }
- #include <vector>
- void re_arrange(std::vector<int>& data) {
auto it = std::stable_partition(data.begin(), data.end(), [](int x) { return x % 2 == 0; });- auto it = std::partition(data.begin(), data.end(), [](int x) { return x % 2 == 0; });
- std::sort(data.begin(), it);
- std::sort(it, data.end());
- }
Describe(mixed_numbers) { It(mixed_order_1) { auto data = std::vector<int>{1, 2, 5, 0, 9, 4, 7}; re_arrange(data); Assert::That(data, Equals(std::vector<int>{0, 2, 4, 1, 5, 7, 9})); } It(mixed_order_2) { auto data = std::vector<int>{2, 1, 4, 7, 9, 0, 5}; re_arrange(data); Assert::That(data, Equals(std::vector<int>{0, 2, 4, 1, 5, 7, 9})); } It(mixed_order_3) { auto data = std::vector<int>{5, 2, 3, 8, 7, 6}; re_arrange(data); Assert::That(data, Equals(std::vector<int>{2, 6, 8, 3, 5, 7})); } It(mixed_order_4) { auto data = std::vector<int>{10, 7, 2, 3, 4, 9}; re_arrange(data); Assert::That(data, Equals(std::vector<int>{2, 4, 10, 3, 7, 9})); } }; Describe(empty_vector) { It(empty_case) { auto data = std::vector<int>{}; re_arrange(data); Assert::That(data, Equals(std::vector<int>{})); } }; Describe(all_even) { It(even_numbers_1) { auto data = std::vector<int>{8, 4, 2, 10}; re_arrange(data); Assert::That(data, Equals(std::vector<int>{2, 4, 8, 10})); } It(even_numbers_2) { auto data = std::vector<int>{10, 2, 8, 4}; re_arrange(data); Assert::That(data, Equals(std::vector<int>{2, 4, 8, 10})); } }; Describe(all_odd) { It(odd_numbers_1) { auto data = std::vector<int>{9, 3, 7, 1}; re_arrange(data); Assert::That(data, Equals(std::vector<int>{1, 3, 7, 9})); } It(odd_numbers_2) { auto data = std::vector<int>{9, 7, 5, 3, 1}; re_arrange(data); Assert::That(data, Equals(std::vector<int>{1, 3, 5, 7, 9})); } }; Describe(negative_numbers) { It(negative_numbers_1) { auto data = std::vector<int>{-3, -2, -5, 0, 2, 1}; re_arrange(data); Assert::That(data, Equals(std::vector<int>{-2, 0, 2, -5, -3, 1})); } It(negative_numbers_2) { auto data = std::vector<int>{-4, -3, -2, -1}; re_arrange(data); Assert::That(data, Equals(std::vector<int>{-4, -2, -3, -1})); } }; Describe(single_element) { It(single_even) { auto data = std::vector<int>{42}; re_arrange(data); Assert::That(data, Equals(std::vector<int>{42})); } It(single_odd) { auto data = std::vector<int>{7}; re_arrange(data); Assert::That(data, Equals(std::vector<int>{7})); } }; Describe(duplicate_values) { It(duplicates_case) { auto data = std::vector<int>{4, 4, 3, 3, 2, 2}; re_arrange(data); Assert::That(data, Equals(std::vector<int>{2, 2, 4, 4, 3, 3})); } It(duplicates_non_contiguous) { auto data = std::vector<int>{3, 2, 3, 2, 4, 4}; re_arrange(data); Assert::That(data, Equals(std::vector<int>{2, 2, 4, 4, 3, 3})); } };
Describe(simple_example)- Describe(mixed_numbers)
- {
It(re_arrange_simple)- It(mixed_order_1)
- {
auto data = std::vector<int>{1,2,5,0,9,4,7};- auto data = std::vector<int>{1, 2, 5, 0, 9, 4, 7};
- re_arrange(data);
Assert::That(data, Equals(std::vector<int>{0,2,4,1,5,7,9}));- Assert::That(data, Equals(std::vector<int>{0, 2, 4, 1, 5, 7, 9}));
- }
- It(mixed_order_2)
- {
- auto data = std::vector<int>{2, 1, 4, 7, 9, 0, 5};
- re_arrange(data);
- Assert::That(data, Equals(std::vector<int>{0, 2, 4, 1, 5, 7, 9}));
- }
- It(mixed_order_3)
- {
- auto data = std::vector<int>{5, 2, 3, 8, 7, 6};
- re_arrange(data);
- Assert::That(data, Equals(std::vector<int>{2, 6, 8, 3, 5, 7}));
- }
- It(mixed_order_4)
- {
- auto data = std::vector<int>{10, 7, 2, 3, 4, 9};
- re_arrange(data);
- Assert::That(data, Equals(std::vector<int>{2, 4, 10, 3, 7, 9}));
- }
- };
- Describe(empty_vector)
- {
- It(empty_case)
- {
- auto data = std::vector<int>{};
- re_arrange(data);
- Assert::That(data, Equals(std::vector<int>{}));
- }
- };
- Describe(all_even)
- {
- It(even_numbers_1)
- {
- auto data = std::vector<int>{8, 4, 2, 10};
- re_arrange(data);
- Assert::That(data, Equals(std::vector<int>{2, 4, 8, 10}));
- }
- It(even_numbers_2)
- {
- auto data = std::vector<int>{10, 2, 8, 4};
- re_arrange(data);
- Assert::That(data, Equals(std::vector<int>{2, 4, 8, 10}));
- }
- };
- Describe(all_odd)
- {
- It(odd_numbers_1)
- {
- auto data = std::vector<int>{9, 3, 7, 1};
- re_arrange(data);
- Assert::That(data, Equals(std::vector<int>{1, 3, 7, 9}));
- }
- It(odd_numbers_2)
- {
- auto data = std::vector<int>{9, 7, 5, 3, 1};
- re_arrange(data);
- Assert::That(data, Equals(std::vector<int>{1, 3, 5, 7, 9}));
- }
- };
- Describe(negative_numbers)
- {
- It(negative_numbers_1)
- {
- auto data = std::vector<int>{-3, -2, -5, 0, 2, 1};
- re_arrange(data);
- Assert::That(data, Equals(std::vector<int>{-2, 0, 2, -5, -3, 1}));
- }
- It(negative_numbers_2)
- {
- auto data = std::vector<int>{-4, -3, -2, -1};
- re_arrange(data);
- Assert::That(data, Equals(std::vector<int>{-4, -2, -3, -1}));
- }
- };
- Describe(single_element)
- {
- It(single_even)
- {
- auto data = std::vector<int>{42};
- re_arrange(data);
- Assert::That(data, Equals(std::vector<int>{42}));
- }
- It(single_odd)
- {
- auto data = std::vector<int>{7};
- re_arrange(data);
- Assert::That(data, Equals(std::vector<int>{7}));
- }
- };
- Describe(duplicate_values)
- {
- It(duplicates_case)
- {
- auto data = std::vector<int>{4, 4, 3, 3, 2, 2};
- re_arrange(data);
- Assert::That(data, Equals(std::vector<int>{2, 2, 4, 4, 3, 3}));
- }
- It(duplicates_non_contiguous)
- {
- auto data = std::vector<int>{3, 2, 3, 2, 4, 4};
- re_arrange(data);
- Assert::That(data, Equals(std::vector<int>{2, 2, 4, 4, 3, 3}));
- }
- };
Actually makes the input greater than 2
But only if it wasn't already
template<typename T> bool above_two(T& arg){ static_assert(std::is_arithmetic<T>::value, "arg must be a arithmetic type"); if(arg <= T(2)){ arg = T(3); } return true; }
#Onelined again...def above_two(arg): return True- template<typename T>
- bool above_two(T& arg){
- static_assert(std::is_arithmetic<T>::value, "arg must be a arithmetic type");
- if(arg <= T(2)){
- arg = T(3);
- }
- return true;
- }
template<typename T> void tester(T arg){ if(arg > 2){ auto expected = arg; Assert::That(above_two(arg), Equals(true)); Assert::That(arg, Equals(expected)); }else{ Assert::That(above_two(arg), Equals(true)); Assert::That(arg, Is().GreaterThan(2)); } } Describe(example) { It(test_case_int) { tester(0); tester(1); tester(2); tester(3); tester(4); tester(5); tester(6); tester(7); tester(8); tester(9); tester(10); } It(test_case_double) { tester(0.0); tester(1.0); tester(2.0); tester(3.0); tester(4.0); tester(5.0); tester(6.0); tester(7.0); tester(8.0); tester(9.0); tester(10.0); } };
import codewars_test as test# TODO Write testsimport solution # or from solution import example- template<typename T>
- void tester(T arg){
- if(arg > 2){
- auto expected = arg;
- Assert::That(above_two(arg), Equals(true));
- Assert::That(arg, Equals(expected));
- }else{
- Assert::That(above_two(arg), Equals(true));
- Assert::That(arg, Is().GreaterThan(2));
- }
- }
# test.assert_equals(actual, expected, [optional] message)@test.describe("Example")def test_group():@test.it("test case")def test_case():test.assert_equals(above_two(0), True)test.assert_equals(above_two(1), True)test.assert_equals(above_two(2), True)test.assert_equals(above_two(3), True)test.assert_equals(above_two(4), True)test.assert_equals(above_two(5), True)- Describe(example)
- {
- It(test_case_int)
- {
- tester(0);
- tester(1);
- tester(2);
- tester(3);
- tester(4);
- tester(5);
- tester(6);
- tester(7);
- tester(8);
- tester(9);
- tester(10);
- }
- It(test_case_double)
- {
- tester(0.0);
- tester(1.0);
- tester(2.0);
- tester(3.0);
- tester(4.0);
- tester(5.0);
- tester(6.0);
- tester(7.0);
- tester(8.0);
- tester(9.0);
- tester(10.0);
- }
- };
Added memory ordering
Increment should just need relaxed, as it does not controll other states. It either keeps the potential object from being reclaimed, in which case there is no change, or the object is already reclaimed and you don't touch it anyway.
all else is more or less acq_rel to sync possible last access to an object, and it's destructor
#include <atomic> struct Counter { static constexpr uint64_t is_zero = 1ull << 63; static constexpr uint64_t helped = 1ull << 62; std::atomic<uint64_t> counter{1}; bool increment_if_not_zero(){ return (counter.fetch_add(1, std::memory_order_relaxed) & is_zero) == 0; } bool decrement(){ if(counter.fetch_sub(1, std::memory_order_acq_rel) == 1){ uint64_t e = 0; if(counter.compare_exchange_strong(e, is_zero, std::memory_order_acq_rel, std::memory_order_acquire)) return true; else if((e & helped) && (counter.exchange(is_zero, std::memory_order_acq_rel) & helped)) return true; } return false; } uint64_t read(){ auto val = counter.load(std::memory_order_acquire); if(val == 0 && counter.compare_exchange_strong(val, is_zero | helped, std::memory_order_acq_rel, std::memory_order_acquire)) return 0; return (val & is_zero) ? 0 : val; } };
- #include <atomic>
- struct Counter {
- static constexpr uint64_t is_zero = 1ull << 63;
- static constexpr uint64_t helped = 1ull << 62;
- std::atomic<uint64_t> counter{1};
- bool increment_if_not_zero(){
return (counter.fetch_add(1) & is_zero) == 0;- return (counter.fetch_add(1, std::memory_order_relaxed) & is_zero) == 0;
- }
- bool decrement(){
if(counter.fetch_sub(1) == 1){- if(counter.fetch_sub(1, std::memory_order_acq_rel) == 1){
- uint64_t e = 0;
if(counter.compare_exchange_strong(e, is_zero)) return true;else if((e & helped) && (counter.exchange(is_zero) & helped)) return true;- if(counter.compare_exchange_strong(e, is_zero, std::memory_order_acq_rel, std::memory_order_acquire)) return true;
- else if((e & helped) && (counter.exchange(is_zero, std::memory_order_acq_rel) & helped)) return true;
- }
- return false;
- }
- uint64_t read(){
auto val = counter.load();if(val == 0 && counter.compare_exchange_strong(val, is_zero | helped)) return 0;- auto val = counter.load(std::memory_order_acquire);
- if(val == 0 && counter.compare_exchange_strong(val, is_zero | helped, std::memory_order_acq_rel, std::memory_order_acquire)) return 0;
- return (val & is_zero) ? 0 : val;
- }
- };
#include <string> #include <string_view> #include <algorithm> std::string fun(std::string_view input) { std::string result; result.reserve(input.size()); std::transform(input.cbegin(), input.cend(), std::back_inserter(result), [](unsigned char c) -> char { return std::toupper(c); }); return result; }
#include <stdlib.h>#include <string.h>#include <ctype.h>- #include <string>
- #include <string_view>
- #include <algorithm>
char *fun(const char *input)- std::string fun(std::string_view input)
- {
size_t len = strlen(input);char *result = malloc(len + 1);for (size_t i = 0; input[i]; i++)result[i] = toupper(input[i]);return result[len] = '\0', result;- std::string result;
- result.reserve(input.size());
- std::transform(input.cbegin(), input.cend(), std::back_inserter(result), [](unsigned char c) -> char {
- return std::toupper(c);
- });
- return result;
- }
void tester(std::string_view input, std::string_view expected) { auto result = fun(input); Assert::That(result, Equals(expected)); } Describe(fun_tests) { It(should_upper_all_chars) { tester("Welcome", "WELCOME"); tester("hello", "HELLO"); tester("yellow", "YELLOW"); tester("blue", "BLUE"); tester("1a2b3c", "1A2B3C"); } };
#include <criterion/criterion.h>#include <stdlib.h>char *fun(const char *input);void tester(const char *input, const char *expected)- void tester(std::string_view input, std::string_view expected)
- {
char *result = fun(input);cr_assert_str_eq(result, expected);free(result);- auto result = fun(input);
- Assert::That(result, Equals(expected));
- }
Test(Example, test_case)- Describe(fun_tests)
- {
tester("Welcome", "WELCOME");tester("hello", "HELLO");tester("yellow", "YELLOW");tester("blue", "BLUE");}- It(should_upper_all_chars)
- {
- tester("Welcome", "WELCOME");
- tester("hello", "HELLO");
- tester("yellow", "YELLOW");
- tester("blue", "BLUE");
- tester("1a2b3c", "1A2B3C");
- }
- };
const correctness
#include <stdlib.h> #include <string.h> char *reverse_string(const char *word) { size_t len = strlen(word); char *res = malloc(len + 1); for (size_t i = 0; i < len; i++) res[i] = word[len - i - 1]; return res[len] = '\0', res; }
- #include <stdlib.h>
- #include <string.h>
char *reverse_string(char *word)- char *reverse_string(const char *word)
- {
- size_t len = strlen(word);
- char *res = malloc(len + 1);
- for (size_t i = 0; i < len; i++)
- res[i] = word[len - i - 1];
- return res[len] = '\0', res;
- }
#include <criterion/criterion.h> char *reverse_string(const char *word); void tester(const char *word, const char *expected) { char *res = reverse_string(word); cr_assert_str_eq(res, expected); free(res); } Test(Sample_Tests, Valid_Input_Test) { tester("monkey", "yeknom"); tester("home", "emoh"); tester("pneumonoultramicroscopicsilicovolcanoconiosis", "sisoinoconaclovociliscipocsorcimartluonomuenp"); }
- #include <criterion/criterion.h>
char *reverse_string(char *word);- char *reverse_string(const char *word);
void tester(char *word, char *expected)- void tester(const char *word, const char *expected)
- {
- char *res = reverse_string(word);
- cr_assert_str_eq(res, expected);
- free(res);
- }
- Test(Sample_Tests, Valid_Input_Test)
- {
- tester("monkey", "yeknom");
- tester("home", "emoh");
- tester("pneumonoultramicroscopicsilicovolcanoconiosis", "sisoinoconaclovociliscipocsorcimartluonomuenp");
- }
Wait free counter for use in reference counting, so you know if you are the one who needs to free the memory. Taken from Daniel Anderson - CppCon 2024
I assume you might be able to be optimised more, if you inlude more fine grained memory ordering in each atomic operation.
And it would be prudent to include concurency test, to ensure that only one thread would get a true on decrement.
#include <atomic>
struct Counter {
static constexpr uint64_t is_zero = 1ull << 63;
static constexpr uint64_t helped = 1ull << 62;
std::atomic<uint64_t> counter{1};
bool increment_if_not_zero(){
return (counter.fetch_add(1) & is_zero) == 0;
}
bool decrement(){
if(counter.fetch_sub(1) == 1){
uint64_t e = 0;
if(counter.compare_exchange_strong(e, is_zero)) return true;
else if((e & helped) && (counter.exchange(is_zero) & helped)) return true;
}
return false;
}
uint64_t read(){
auto val = counter.load();
if(val == 0 && counter.compare_exchange_strong(val, is_zero | helped)) return 0;
return (val & is_zero) ? 0 : val;
}
};
Describe(counter_tests)
{
It(single_thread_use)
{
Counter c;
Assert::That(c.read(), Equals(1ull));
Assert::That(c.increment_if_not_zero(), Equals(true));
Assert::That(c.read(), Equals(2ull));
Assert::That(c.decrement(), Equals(false));
Assert::That(c.read(), Equals(1ull));
Assert::That(c.decrement(), Equals(true));
Assert::That(c.read(), Equals(0ull));
Assert::That(c.increment_if_not_zero(), Equals(false));
}
};
#include <string> #include <string_view> std::string reverse_string(std::string_view word){ return {word.rbegin(), word.rend()}; }
public class ReverseString {public static String reverseString(String word) {return new StringBuilder(word).reverse().toString();}- #include <string>
- #include <string_view>
- std::string reverse_string(std::string_view word){
- return {word.rbegin(), word.rend()};
- }
Describe(Sample_Tests) { It(Valid_Input_Test) { Assert::That(reverse_string("monkey"), Equals("yeknom")); Assert::That(reverse_string("home"), Equals("emoh")); Assert::That(reverse_string("pneumonoultramicroscopicsilicovolcanoconiosis"), Equals("sisoinoconaclovociliscipocsorcimartluonomuenp")); } };
import org.junit.jupiter.api.Test;import static org.junit.jupiter.api.Assertions.assertEquals;class ReverseStringTest {@Testpublic void testMonkey() {assertEquals("yeknom", ReverseString.reverseString( "monkey"));- Describe(Sample_Tests)
- {
- It(Valid_Input_Test)
- {
- Assert::That(reverse_string("monkey"), Equals("yeknom"));
- Assert::That(reverse_string("home"), Equals("emoh"));
- Assert::That(reverse_string("pneumonoultramicroscopicsilicovolcanoconiosis"), Equals("sisoinoconaclovociliscipocsorcimartluonomuenp"));
- }
@Testvoid testHome() {assertEquals("emoh", ReverseString.reverseString("home"));}@Testvoid testPneumonoultramicroscopicsilicovolcanoconiosis() {assertEquals("sisoinoconaclovociliscipocsorcimartluonomuenp", ReverseString.reverseString("pneumonoultramicroscopicsilicovolcanoconiosis"));}}- };
Can also be solved with two sets
#include <vector> #include <unordered_set> #include <numeric> int unique_sum(const std::vector<int>& nums) { std::unordered_set<int> once; std::unordered_set<int> more_than_once; for(auto&& num : nums){ if(once.find(num) == once.end() && more_than_once.find(num) == more_than_once.end()){ once.insert(num); } else if(once.find(num) != once.end()){ once.erase(num); more_than_once.insert(num); } } return std::reduce(once.cbegin(), once.cend(), 0); }
#include <iostream>- #include <vector>
#include <unordered_map>#include <cassert>- #include <unordered_set>
- #include <numeric>
- int unique_sum(const std::vector<int>& nums) {
std::unordered_map<int, int> hashMap;for (int i = 0; i < nums.size(); i++) {if (hashMap.find(nums[i]) == hashMap.end()) {hashMap[nums[i]] = nums[i];} else {hashMap[nums[i]] = 0;- std::unordered_set<int> once;
- std::unordered_set<int> more_than_once;
- for(auto&& num : nums){
- if(once.find(num) == once.end() && more_than_once.find(num) == more_than_once.end()){
- once.insert(num);
- }
- else if(once.find(num) != once.end()){
- once.erase(num);
- more_than_once.insert(num);
- }
- }
int sum = 0;for (auto i: hashMap) {sum = sum + hashMap[i.first];}return sum;- return std::reduce(once.cbegin(), once.cend(), 0);
- }
why add, when we can do it our self.
#include <bitset> #include <fmt/core.h> std::bitset<64> bitwiseAdd(std::bitset<64> x, std::bitset<64> y) { while ((x & y).any()) { std::bitset<64> carry = (x & y) << 1; x = x ^ y; y = carry; } return x ^ y; } int64_t multiply(int32_t a, int32_t b) { std::bitset<64> bitsetA(static_cast<uint64_t>(a)); std::bitset<64> bitsetB(static_cast<uint64_t>(b)); std::bitset<64> result; for (int i = 0; i < 64; ++i) { if (bitsetB.test(i)) { auto shiftedA = (bitsetA << i); result = bitwiseAdd(result, shiftedA); } } return static_cast<int64_t>(result.to_ullong()); }
int just_why(int a, int b) { return b ? a + just_why(a, b - 1) : 0; }int multiply(int a, int b) { return just_why(a, b); }- #include <bitset>
- #include <fmt/core.h>
- std::bitset<64> bitwiseAdd(std::bitset<64> x, std::bitset<64> y) {
- while ((x & y).any()) {
- std::bitset<64> carry = (x & y) << 1;
- x = x ^ y;
- y = carry;
- }
- return x ^ y;
- }
- int64_t multiply(int32_t a, int32_t b) {
- std::bitset<64> bitsetA(static_cast<uint64_t>(a));
- std::bitset<64> bitsetB(static_cast<uint64_t>(b));
- std::bitset<64> result;
- for (int i = 0; i < 64; ++i) {
- if (bitsetB.test(i)) {
- auto shiftedA = (bitsetA << i);
- result = bitwiseAdd(result, shiftedA);
- }
- }
- return static_cast<int64_t>(result.to_ullong());
- }
// TODO: Replace examples and use TDD by writing your own tests. The code provided here is just a how-to example. #include <criterion/criterion.h> // replace with the actual method being tested int multiply(int a,int b); Test(the_multiply_function, should_pass_all_the_tests_provided) { cr_assert_eq(multiply(1, 1), 1); cr_assert_eq(multiply(2, 2), 4); cr_assert_eq(multiply(2, -2), -4); cr_assert_eq(multiply(-2, 2), -4); cr_assert_eq(multiply(-2, -2), 4); cr_assert_eq(multiply(3, 7), 21); cr_assert_eq(multiply(3, -7), -21); cr_assert_eq(multiply(-3, -7), 21); }
- // TODO: Replace examples and use TDD by writing your own tests. The code provided here is just a how-to example.
- #include <criterion/criterion.h>
- // replace with the actual method being tested
- int multiply(int a,int b);
- Test(the_multiply_function, should_pass_all_the_tests_provided) {
- cr_assert_eq(multiply(1, 1), 1);
- cr_assert_eq(multiply(2, 2), 4);
- cr_assert_eq(multiply(2, -2), -4);
- cr_assert_eq(multiply(-2, 2), -4);
- cr_assert_eq(multiply(-2, -2), 4);
- cr_assert_eq(multiply(3, 7), 21);
- cr_assert_eq(multiply(3, -7), -21);
- cr_assert_eq(multiply(-3, -7), 21);
- }
Might have cone a bit crazy with the tests, but hey now you should be able to pass any container that satisfy the requirement. And if it doesn't it wont compile.
#include <string> #include <vector> #include <algorithm> template<typename Container> bool containsT_Rex(const Container &things){ using ValueType = typename Container::value_type; static_assert(std::is_convertible_v<decltype(std::declval<ValueType>() == std::declval<std::string>()), bool>, "Container elements must be comparable to std::string"); static constexpr auto trex = "Tyrannosaurus"; return std::find(things.cbegin(), things.cend(), trex) != things.cend(); }
public class findT_Rex {public static boolean containsT_Rex(String[] things) {//insert code!return true;}- #include <string>
- #include <vector>
- #include <algorithm>
- template<typename Container>
- bool containsT_Rex(const Container &things){
- using ValueType = typename Container::value_type;
- static_assert(std::is_convertible_v<decltype(std::declval<ValueType>() == std::declval<std::string>()), bool>, "Container elements must be comparable to std::string");
- static constexpr auto trex = "Tyrannosaurus";
- return std::find(things.cbegin(), things.cend(), trex) != things.cend();
- }
#include <vector> #include <set> #include <array> #include <list> #include <forward_list> #include <string> #include <string_view> // Helper type for SFINAE template <typename, typename = void> struct is_comparable_to_string : std::false_type {}; // Specialization when T can be compared to std::string template <typename T> struct is_comparable_to_string< T, std::void_t<decltype(std::declval<typename T::value_type>() == std::declval<std::string>())> > : std::true_type {}; // Alias for cleaner syntax template <typename T> constexpr bool is_comparable_to_string_v = is_comparable_to_string<T>::value; Describe(containsT_Rex_string) { It(does_contains_trex) { Assert::That(containsT_Rex(std::vector<std::string>{"Jackie Chan", "Charlize Theron", "Tyrannosaurus", "Tom Hardy", "Ruby Rose"}), Equals(true)); } It(does_not_contains_trex) { Assert::That(containsT_Rex(std::vector<std::string>{"Triceratops", "Megalosaurus", "Spinosaurus", "Archaeopteryx"}), Equals(false)); Assert::That(containsT_Rex(std::vector<std::string>{}), Equals(false)); } }; Describe(containsT_Rex_char_pointer) { It(does_contains_trex) { Assert::That(containsT_Rex(std::vector<const char*>{"Jackie Chan", "Charlize Theron", "Tyrannosaurus", "Tom Hardy", "Ruby Rose"}), Equals(true)); } It(does_not_contains_trex) { Assert::That(containsT_Rex(std::vector<const char*>{"Triceratops", "Megalosaurus", "Spinosaurus", "Archaeopteryx"}), Equals(false)); Assert::That(containsT_Rex(std::vector<const char*>{}), Equals(false)); } }; Describe(containsT_Rex_string_view) { It(does_contains_trex) { Assert::That(containsT_Rex(std::vector<std::string_view>{"Jackie Chan", "Charlize Theron", "Tyrannosaurus", "Tom Hardy", "Ruby Rose"}), Equals(true)); } It(does_not_contains_trex) { Assert::That(containsT_Rex(std::vector<std::string_view>{"Triceratops", "Megalosaurus", "Spinosaurus", "Archaeopteryx"}), Equals(false)); Assert::That(containsT_Rex(std::vector<std::string_view>{}), Equals(false)); } }; Describe(container_test) { It(should_work) { Assert::That(is_comparable_to_string_v<std::vector<std::string>>, Equals(true), "vector of string should work"); Assert::That(is_comparable_to_string_v<std::list<std::string>>, Equals(true), "list of string should work"); Assert::That(is_comparable_to_string_v<std::vector<const char*>>, Equals(true), "vector of const char* should work"); Assert::That(is_comparable_to_string_v<std::list<const char*>>, Equals(true), "list of const char* should work"); Assert::That(is_comparable_to_string_v<std::deque<std::string>>, Equals(true), "deque of string should work"); Assert::That(is_comparable_to_string_v<std::vector<std::string_view>>, Equals(true), "vector of string_view should work"); } It(should_not_work) { Assert::That(is_comparable_to_string_v<std::vector<int>>, Equals(false), "vector of int should not work"); Assert::That(is_comparable_to_string_v<std::list<double>>, Equals(false), "list of double should not work"); Assert::That(is_comparable_to_string_v<std::deque<void*>>, Equals(false), "deque of void* should not work"); Assert::That(is_comparable_to_string_v<std::vector<std::nullptr_t>>, Equals(false), "vector of nullptr_t should not work"); Assert::That(is_comparable_to_string_v<std::array<int, 4>>, Equals(false), "array of int should not work"); } It(mixed_edge_cases) { Assert::That(is_comparable_to_string_v<std::vector<char*>>, Equals(true), "vector of char* should work"); Assert::That(is_comparable_to_string_v<std::list<const char*>>, Equals(true), "list of const char* should work"); Assert::That(is_comparable_to_string_v<std::deque<const char*>>, Equals(true), "deque of const char* should work"); Assert::That(is_comparable_to_string_v<std::vector<std::pair<int, std::string>>>, Equals(false), "vector of pair<int, string> should not work"); Assert::That(is_comparable_to_string_v<std::list<std::pair<const char*, const char*>>>, Equals(false), "list of pair<const char*, const char*> should not work"); } }; Describe(containsT_Rex_string_difcontainer) { It(does_contains_trex) { Assert::That(containsT_Rex(std::array<std::string, 5>{"Jackie Chan", "Charlize Theron", "Tyrannosaurus", "Tom Hardy", "Ruby Rose"}), Equals(true)); Assert::That(containsT_Rex(std::deque<std::string>{"Jackie Chan", "Charlize Theron", "Tyrannosaurus", "Tom Hardy", "Ruby Rose"}), Equals(true)); Assert::That(containsT_Rex(std::list<std::string>{"Jackie Chan", "Charlize Theron", "Tyrannosaurus", "Tom Hardy", "Ruby Rose"}), Equals(true)); Assert::That(containsT_Rex(std::set<std::string>{"Jackie Chan", "Charlize Theron", "Tyrannosaurus", "Tom Hardy", "Ruby Rose"}), Equals(true)); Assert::That(containsT_Rex(std::forward_list<std::string>{"Jackie Chan", "Charlize Theron", "Tyrannosaurus", "Tom Hardy", "Ruby Rose"}), Equals(true)); } It(does_not_contains_trex) { Assert::That(containsT_Rex(std::array<std::string, 4>{"Triceratops", "Megalosaurus", "Spinosaurus", "Archaeopteryx"}), Equals(false)); Assert::That(containsT_Rex(std::deque<std::string>{"Triceratops", "Megalosaurus", "Spinosaurus", "Archaeopteryx"}), Equals(false)); Assert::That(containsT_Rex(std::list<std::string>{"Triceratops", "Megalosaurus", "Spinosaurus", "Archaeopteryx"}), Equals(false)); Assert::That(containsT_Rex(std::set<std::string>{"Triceratops", "Megalosaurus", "Spinosaurus", "Archaeopteryx"}), Equals(false)); Assert::That(containsT_Rex(std::forward_list<std::string>{"Triceratops", "Megalosaurus", "Spinosaurus", "Archaeopteryx"}), Equals(false)); Assert::That(containsT_Rex(std::array<std::string, 0>{}), Equals(false)); Assert::That(containsT_Rex(std::deque<std::string>{}), Equals(false)); Assert::That(containsT_Rex(std::list<std::string>{}), Equals(false)); Assert::That(containsT_Rex(std::set<std::string>{}), Equals(false)); Assert::That(containsT_Rex(std::forward_list<std::string>{}), Equals(false)); } };
import org.junit.Test;import static org.junit.Assert.assertEquals;- #include <vector>
- #include <set>
- #include <array>
- #include <list>
- #include <forward_list>
- #include <string>
- #include <string_view>
// TODO: Replace examples and use TDD by writing your own testsclass SolutionTest {@Testpublic void tests() {String[] things1 = new String[] {"Triceratops", "Megalosaurus", "Spinosaurus", "Archaeopteryx"};String[] things2 = new String[] {"Jackie Chan", "Charlize Theron", "Tyrannosaurus", "Tom Hardy", "Ruby Rose"};String[] things3 = new String[] {""};- // Helper type for SFINAE
- template <typename, typename = void>
- struct is_comparable_to_string : std::false_type {};
- // Specialization when T can be compared to std::string
- template <typename T>
- struct is_comparable_to_string<
- T,
- std::void_t<decltype(std::declval<typename T::value_type>() == std::declval<std::string>())>
- > : std::true_type {};
- // Alias for cleaner syntax
- template <typename T>
- constexpr bool is_comparable_to_string_v = is_comparable_to_string<T>::value;
- Describe(containsT_Rex_string)
- {
- It(does_contains_trex)
- {
- Assert::That(containsT_Rex(std::vector<std::string>{"Jackie Chan", "Charlize Theron", "Tyrannosaurus", "Tom Hardy", "Ruby Rose"}), Equals(true));
- }
- It(does_not_contains_trex)
- {
- Assert::That(containsT_Rex(std::vector<std::string>{"Triceratops", "Megalosaurus", "Spinosaurus", "Archaeopteryx"}), Equals(false));
- Assert::That(containsT_Rex(std::vector<std::string>{}), Equals(false));
- }
- };
- Describe(containsT_Rex_char_pointer)
- {
- It(does_contains_trex)
- {
- Assert::That(containsT_Rex(std::vector<const char*>{"Jackie Chan", "Charlize Theron", "Tyrannosaurus", "Tom Hardy", "Ruby Rose"}), Equals(true));
- }
- It(does_not_contains_trex)
- {
- Assert::That(containsT_Rex(std::vector<const char*>{"Triceratops", "Megalosaurus", "Spinosaurus", "Archaeopteryx"}), Equals(false));
- Assert::That(containsT_Rex(std::vector<const char*>{}), Equals(false));
- }
- };
- Describe(containsT_Rex_string_view)
- {
- It(does_contains_trex)
- {
- Assert::That(containsT_Rex(std::vector<std::string_view>{"Jackie Chan", "Charlize Theron", "Tyrannosaurus", "Tom Hardy", "Ruby Rose"}), Equals(true));
- }
- It(does_not_contains_trex)
- {
- Assert::That(containsT_Rex(std::vector<std::string_view>{"Triceratops", "Megalosaurus", "Spinosaurus", "Archaeopteryx"}), Equals(false));
- Assert::That(containsT_Rex(std::vector<std::string_view>{}), Equals(false));
- }
- };
- Describe(container_test)
- {
- It(should_work)
- {
- Assert::That(is_comparable_to_string_v<std::vector<std::string>>, Equals(true), "vector of string should work");
- Assert::That(is_comparable_to_string_v<std::list<std::string>>, Equals(true), "list of string should work");
- Assert::That(is_comparable_to_string_v<std::vector<const char*>>, Equals(true), "vector of const char* should work");
- Assert::That(is_comparable_to_string_v<std::list<const char*>>, Equals(true), "list of const char* should work");
- Assert::That(is_comparable_to_string_v<std::deque<std::string>>, Equals(true), "deque of string should work");
- Assert::That(is_comparable_to_string_v<std::vector<std::string_view>>, Equals(true), "vector of string_view should work");
- }
- It(should_not_work)
- {
- Assert::That(is_comparable_to_string_v<std::vector<int>>, Equals(false), "vector of int should not work");
- Assert::That(is_comparable_to_string_v<std::list<double>>, Equals(false), "list of double should not work");
- Assert::That(is_comparable_to_string_v<std::deque<void*>>, Equals(false), "deque of void* should not work");
- Assert::That(is_comparable_to_string_v<std::vector<std::nullptr_t>>, Equals(false), "vector of nullptr_t should not work");
- Assert::That(is_comparable_to_string_v<std::array<int, 4>>, Equals(false), "array of int should not work");
- }
- It(mixed_edge_cases)
- {
- Assert::That(is_comparable_to_string_v<std::vector<char*>>, Equals(true), "vector of char* should work");
- Assert::That(is_comparable_to_string_v<std::list<const char*>>, Equals(true), "list of const char* should work");
- Assert::That(is_comparable_to_string_v<std::deque<const char*>>, Equals(true), "deque of const char* should work");
- Assert::That(is_comparable_to_string_v<std::vector<std::pair<int, std::string>>>, Equals(false), "vector of pair<int, string> should not work");
- Assert::That(is_comparable_to_string_v<std::list<std::pair<const char*, const char*>>>, Equals(false), "list of pair<const char*, const char*> should not work");
- }
- };
- Describe(containsT_Rex_string_difcontainer)
- {
- It(does_contains_trex)
- {
- Assert::That(containsT_Rex(std::array<std::string, 5>{"Jackie Chan", "Charlize Theron", "Tyrannosaurus", "Tom Hardy", "Ruby Rose"}), Equals(true));
- Assert::That(containsT_Rex(std::deque<std::string>{"Jackie Chan", "Charlize Theron", "Tyrannosaurus", "Tom Hardy", "Ruby Rose"}), Equals(true));
- Assert::That(containsT_Rex(std::list<std::string>{"Jackie Chan", "Charlize Theron", "Tyrannosaurus", "Tom Hardy", "Ruby Rose"}), Equals(true));
- Assert::That(containsT_Rex(std::set<std::string>{"Jackie Chan", "Charlize Theron", "Tyrannosaurus", "Tom Hardy", "Ruby Rose"}), Equals(true));
- Assert::That(containsT_Rex(std::forward_list<std::string>{"Jackie Chan", "Charlize Theron", "Tyrannosaurus", "Tom Hardy", "Ruby Rose"}), Equals(true));
- }
- It(does_not_contains_trex)
- {
- Assert::That(containsT_Rex(std::array<std::string, 4>{"Triceratops", "Megalosaurus", "Spinosaurus", "Archaeopteryx"}), Equals(false));
- Assert::That(containsT_Rex(std::deque<std::string>{"Triceratops", "Megalosaurus", "Spinosaurus", "Archaeopteryx"}), Equals(false));
- Assert::That(containsT_Rex(std::list<std::string>{"Triceratops", "Megalosaurus", "Spinosaurus", "Archaeopteryx"}), Equals(false));
- Assert::That(containsT_Rex(std::set<std::string>{"Triceratops", "Megalosaurus", "Spinosaurus", "Archaeopteryx"}), Equals(false));
- Assert::That(containsT_Rex(std::forward_list<std::string>{"Triceratops", "Megalosaurus", "Spinosaurus", "Archaeopteryx"}), Equals(false));
// assertEquals("expected", "actual");assertEquals(false, containsT_Rex(things1));assertEquals(true, containsT_Rex(things2));assertEquals(false, containsT_Rex(things3));- Assert::That(containsT_Rex(std::array<std::string, 0>{}), Equals(false));
- Assert::That(containsT_Rex(std::deque<std::string>{}), Equals(false));
- Assert::That(containsT_Rex(std::list<std::string>{}), Equals(false));
- Assert::That(containsT_Rex(std::set<std::string>{}), Equals(false));
- Assert::That(containsT_Rex(std::forward_list<std::string>{}), Equals(false));
- }
}- };
#include <type_traits> #include <limits> #include <bitset> template<typename T> constexpr bool is_more_than_2(T n){ static_assert(std::is_integral_v<T>, "T must be an integral type."); constexpr size_t numBits = std::numeric_limits<T>::digits + std::is_signed_v<T>; std::bitset<numBits> bits(n); if constexpr (std::is_unsigned_v<T>) { // For unsigned, check if more than 1 bit is set return bits.count() > 1; } else { // For signed, ensure the sign bit is unset and more than 1 bit is set bool signBitUnset = !bits[numBits - 1]; bits.reset(numBits - 1); // Mask out the sign bit return signBitUnset && bits.count() > 1; } }
def is_more_than_2(n):return n > 2- #include <type_traits>
- #include <limits>
- #include <bitset>
- template<typename T>
- constexpr bool is_more_than_2(T n){
- static_assert(std::is_integral_v<T>, "T must be an integral type.");
- constexpr size_t numBits = std::numeric_limits<T>::digits + std::is_signed_v<T>;
- std::bitset<numBits> bits(n);
- if constexpr (std::is_unsigned_v<T>) {
- // For unsigned, check if more than 1 bit is set
- return bits.count() > 1;
- } else {
- // For signed, ensure the sign bit is unset and more than 1 bit is set
- bool signBitUnset = !bits[numBits - 1];
- bits.reset(numBits - 1); // Mask out the sign bit
- return signBitUnset && bits.count() > 1;
- }
- }
#include <limits> Describe(is_more_than_2_test) { It(signed_values) { Assert::That(is_more_than_2(std::numeric_limits<int>::min()), Equals(false)); Assert::That(is_more_than_2(-3), Equals(false)); Assert::That(is_more_than_2(-2), Equals(false)); Assert::That(is_more_than_2(-1), Equals(false)); Assert::That(is_more_than_2(0), Equals(false)); Assert::That(is_more_than_2(1), Equals(false)); Assert::That(is_more_than_2(2), Equals(false)); Assert::That(is_more_than_2(3), Equals(true)); Assert::That(is_more_than_2(10), Equals(true)); Assert::That(is_more_than_2(std::numeric_limits<int>::max()), Equals(true)); } It(unsigned_values) { Assert::That(is_more_than_2(0u), Equals(false)); Assert::That(is_more_than_2(1u), Equals(false)); Assert::That(is_more_than_2(2u), Equals(false)); Assert::That(is_more_than_2(3u), Equals(true)); Assert::That(is_more_than_2(10u), Equals(true)); Assert::That(is_more_than_2(std::numeric_limits<unsigned>::max()), Equals(true)); } };
import codewars_test as testimport random# TODO Write testsimport solution # or from solution import example- #include <limits>
# test.assert_equals(actual, expected, [optional] message)@test.describe("Random test cases")def random_tests():@test.it("Random test")def test_case():for x in range(100):randomValue = random.randint(-1000, 1000)test.assert_equals(is_more_than_2(randomValue), randomValue > 2)- Describe(is_more_than_2_test)
- {
- It(signed_values)
- {
- Assert::That(is_more_than_2(std::numeric_limits<int>::min()), Equals(false));
- Assert::That(is_more_than_2(-3), Equals(false));
- Assert::That(is_more_than_2(-2), Equals(false));
- Assert::That(is_more_than_2(-1), Equals(false));
- Assert::That(is_more_than_2(0), Equals(false));
- Assert::That(is_more_than_2(1), Equals(false));
- Assert::That(is_more_than_2(2), Equals(false));
- Assert::That(is_more_than_2(3), Equals(true));
- Assert::That(is_more_than_2(10), Equals(true));
- Assert::That(is_more_than_2(std::numeric_limits<int>::max()), Equals(true));
- }
- It(unsigned_values)
- {
- Assert::That(is_more_than_2(0u), Equals(false));
- Assert::That(is_more_than_2(1u), Equals(false));
- Assert::That(is_more_than_2(2u), Equals(false));
- Assert::That(is_more_than_2(3u), Equals(true));
- Assert::That(is_more_than_2(10u), Equals(true));
- Assert::That(is_more_than_2(std::numeric_limits<unsigned>::max()), Equals(true));
- }
- };
Checked math in c++, using some buildins for gcc/clang. Translated from Rust.
Can be made without the buildins, but you would have to make your own boundary checks.
#include <optional> #include <limits> std::optional<int32_t> add_checked(int32_t a, int32_t b){ int32_t r{}; if(!__builtin_sadd_overflow(a, b, &r)){ return r; } return std::nullopt; } std::optional<int32_t> sub_checked(int32_t a, int32_t b){ int32_t r{}; if(!__builtin_ssub_overflow(a, b, &r)){ return r; } return std::nullopt; } std::optional<int32_t> mul_checked(int32_t a, int32_t b){ int32_t r{}; if(!__builtin_smul_overflow(a, b, &r)){ return r; } return std::nullopt; } std::optional<int32_t> div_checked(int32_t a, int32_t b){ if(b == 0 || (a == std::numeric_limits<int32_t>::min() && b == -1)){ return std::nullopt; } return a / b; } std::optional<int32_t> mod_checked(int32_t a, int32_t b){ if(b == 0 || (a == std::numeric_limits<int32_t>::min() && b == -1)){ return std::nullopt; } return a % b; } std::optional<int32_t> calculator(Operation op, int32_t x, int32_t y) { switch(op){ case Operation::Add:return add_checked(x, y); case Operation::Subtract: return sub_checked(x, y); case Operation::Multiply: return mul_checked(x, y); case Operation::Divide: return div_checked(x, y); case Operation::Modulo: return mod_checked(x, y); default: return std::nullopt; } }
mod preloaded;use preloaded::Operation;- #include <optional>
- #include <limits>
fn calculator(op: Operation, x: i32, y: i32) -> Option<i32> {match op {Operation::Add => x.checked_add(y),Operation::Subtract => x.checked_sub(y),Operation::Multiply => x.checked_mul(y),Operation::Divide => x.checked_div(y),Operation::Modulo => x.checked_rem(y)}- std::optional<int32_t> add_checked(int32_t a, int32_t b){
- int32_t r{};
- if(!__builtin_sadd_overflow(a, b, &r)){
- return r;
- }
- return std::nullopt;
- }
- std::optional<int32_t> sub_checked(int32_t a, int32_t b){
- int32_t r{};
- if(!__builtin_ssub_overflow(a, b, &r)){
- return r;
- }
- return std::nullopt;
- }
- std::optional<int32_t> mul_checked(int32_t a, int32_t b){
- int32_t r{};
- if(!__builtin_smul_overflow(a, b, &r)){
- return r;
- }
- return std::nullopt;
- }
- std::optional<int32_t> div_checked(int32_t a, int32_t b){
- if(b == 0 || (a == std::numeric_limits<int32_t>::min() && b == -1)){
- return std::nullopt;
- }
- return a / b;
- }
- std::optional<int32_t> mod_checked(int32_t a, int32_t b){
- if(b == 0 || (a == std::numeric_limits<int32_t>::min() && b == -1)){
- return std::nullopt;
- }
- return a % b;
- }
- std::optional<int32_t> calculator(Operation op, int32_t x, int32_t y) {
- switch(op){
- case Operation::Add:return add_checked(x, y);
- case Operation::Subtract: return sub_checked(x, y);
- case Operation::Multiply: return mul_checked(x, y);
- case Operation::Divide: return div_checked(x, y);
- case Operation::Modulo: return mod_checked(x, y);
- default:
- return std::nullopt;
- }
- }
Describe(Sample_Tests) { It(Valid_Input_Test) { Assert::That(calculator(Operation::Add, 1, 1), Equals(2)); Assert::That(calculator(Operation::Add, 16, 9), Equals(25)); Assert::That(calculator(Operation::Subtract, 1, 1), Equals(0)); Assert::That(calculator(Operation::Subtract, 57, 62), Equals(-5)); Assert::That(calculator(Operation::Multiply, -10, 10), Equals(-100)); Assert::That(calculator(Operation::Multiply, -12, -12), Equals(144)); Assert::That(calculator(Operation::Divide, 2, 4), Equals(0)); Assert::That(calculator(Operation::Divide, 4, 2), Equals(2)); Assert::That(calculator(Operation::Modulo, 3, 5), Equals(3)); Assert::That(calculator(Operation::Modulo, 5, 3), Equals(2)); } It(Invalid_Input_Test) { Assert::That(calculator(Operation::Add, std::numeric_limits<int32_t>::max(), 1), Equals(std::nullopt)); Assert::That(calculator(Operation::Subtract, std::numeric_limits<int32_t>::min(), 1), Equals(std::nullopt)); Assert::That(calculator(Operation::Multiply, std::numeric_limits<int32_t>::max(), 2), Equals(std::nullopt)); Assert::That(calculator(Operation::Divide, 1, 0), Equals(std::nullopt)); Assert::That(calculator(Operation::Modulo, 5, 0), Equals(std::nullopt)); } It(Boundary_Cases_Test) { Assert::That(calculator(Operation::Divide, std::numeric_limits<int32_t>::min(), -1), Equals(std::nullopt)); Assert::That(calculator(Operation::Modulo, std::numeric_limits<int32_t>::min(), -1), Equals(std::nullopt)); } };
#[test]fn test() {assert_eq!(calculator(Operation::Add, 1, 1), Some(2));assert_eq!(calculator(Operation::Add, 16, 9), Some(25));assert_eq!(calculator(Operation::Add, i32::MAX, 1), None);- Describe(Sample_Tests)
- {
- It(Valid_Input_Test)
- {
- Assert::That(calculator(Operation::Add, 1, 1), Equals(2));
- Assert::That(calculator(Operation::Add, 16, 9), Equals(25));
- Assert::That(calculator(Operation::Subtract, 1, 1), Equals(0));
- Assert::That(calculator(Operation::Subtract, 57, 62), Equals(-5));
- Assert::That(calculator(Operation::Multiply, -10, 10), Equals(-100));
- Assert::That(calculator(Operation::Multiply, -12, -12), Equals(144));
- Assert::That(calculator(Operation::Divide, 2, 4), Equals(0));
- Assert::That(calculator(Operation::Divide, 4, 2), Equals(2));
- Assert::That(calculator(Operation::Modulo, 3, 5), Equals(3));
- Assert::That(calculator(Operation::Modulo, 5, 3), Equals(2));
- }
assert_eq!(calculator(Operation::Subtract, 1, 1), Some(0));assert_eq!(calculator(Operation::Subtract, 57, 62), Some(-5));assert_eq!(calculator(Operation::Subtract, i32::MIN, 1), None);- It(Invalid_Input_Test)
- {
- Assert::That(calculator(Operation::Add, std::numeric_limits<int32_t>::max(), 1), Equals(std::nullopt));
- Assert::That(calculator(Operation::Subtract, std::numeric_limits<int32_t>::min(), 1), Equals(std::nullopt));
- Assert::That(calculator(Operation::Multiply, std::numeric_limits<int32_t>::max(), 2), Equals(std::nullopt));
- Assert::That(calculator(Operation::Divide, 1, 0), Equals(std::nullopt));
- Assert::That(calculator(Operation::Modulo, 5, 0), Equals(std::nullopt));
- }
assert_eq!(calculator(Operation::Multiply, -10, 10), Some(-100));assert_eq!(calculator(Operation::Multiply, -12, -12), Some(144));assert_eq!(calculator(Operation::Multiply, i32::MAX, 2), None);assert_eq!(calculator(Operation::Divide, 2, 4), Some(0));assert_eq!(calculator(Operation::Divide, 4, 2), Some(2));assert_eq!(calculator(Operation::Divide, 1, 0), None);assert_eq!(calculator(Operation::Modulo, 3, 5), Some(3));assert_eq!(calculator(Operation::Modulo, 5, 3), Some(2));assert_eq!(calculator(Operation::Modulo, 5, 0), None);}- It(Boundary_Cases_Test)
- {
- Assert::That(calculator(Operation::Divide, std::numeric_limits<int32_t>::min(), -1), Equals(std::nullopt));
- Assert::That(calculator(Operation::Modulo, std::numeric_limits<int32_t>::min(), -1), Equals(std::nullopt));
- }
- };
#include <utility> template<typename T, typename U> constexpr auto multiply(T a, U b) -> decltype(std::declval<T>() * std::declval<U>()){ return a * b; }
#define multiply(a,b) a*b- #include <utility>
- template<typename T, typename U>
- constexpr auto multiply(T a, U b) -> decltype(std::declval<T>() * std::declval<U>()){
- return a * b;
- }
I know this doesn't work in the current c+ version. Needs c++20.
But with concepts, some of this can be simplified
Concept to check if T + T is valid.
Concept to check if U(T + T) + T is valid, and is U.
T + T could give a different type U, but T + U must be U again.
/* #include <concepts> #include <vector> #include <numeric> #include <type_traits> namespace{ // Concept to check if T + T yields a valid type template <typename T> concept SelfAddable = requires(T a) { { a + a }; // Ensure T + T is valid }; // Concept to check if U + T is valid and results in U template <typename T, typename U> concept CompatibleAddable = requires(U u, T t) { { u + t } -> std::same_as<U>; }; // Function template with inferred U template <SelfAddable T> requires CompatibleAddable<T, decltype(std::declval<T>() + std::declval<T>())> auto sum(const std::vector<T>& v) { using U = decltype(std::declval<T>() + std::declval<T>()); // Infer U return std::accumulate(v.cbegin(), v.cend(), U{}, [](U acc, const T& elem) { return acc + elem; }); } } */ //OLD #include <vector> #include <numeric> #include <type_traits> #include <utility> namespace { template<typename, typename, typename = void> struct has_plus : std::false_type {}; template<typename T1, typename T2> struct has_plus<T1, T2, std::void_t<decltype(std::declval<T1>() + std::declval<T2>())>> : std::true_type {}; template<typename T1, typename T2> inline constexpr bool has_plus_v = has_plus<T1, T2>::value; template<typename T1, typename T2, bool = has_plus_v<T1, T2>> struct plus_result { using type = decltype(std::declval<T1>() + std::declval<T2>()); }; template<typename T1, typename T2> struct plus_result<T1, T2, false> {}; template<typename T1, typename T2> using plus_result_t = typename plus_result<T1, T2>::type; template<typename T = double, typename = std::enable_if_t<has_plus_v<T, T>>> plus_result_t<T, T> sum(const std::vector<T>& v) { return std::accumulate(v.cbegin(), v.cend(), T{}); } }
- /*
- #include <concepts>
- #include <vector>
- #include <numeric>
- #include <type_traits>
- namespace{
- // Concept to check if T + T yields a valid type
- template <typename T>
- concept SelfAddable = requires(T a) {
- { a + a }; // Ensure T + T is valid
- };
- // Concept to check if U + T is valid and results in U
- template <typename T, typename U>
- concept CompatibleAddable = requires(U u, T t) {
- { u + t } -> std::same_as<U>;
- };
- // Function template with inferred U
- template <SelfAddable T>
- requires CompatibleAddable<T, decltype(std::declval<T>() + std::declval<T>())>
- auto sum(const std::vector<T>& v) {
- using U = decltype(std::declval<T>() + std::declval<T>()); // Infer U
- return std::accumulate(v.cbegin(), v.cend(), U{}, [](U acc, const T& elem) {
- return acc + elem;
- });
- }
- }
- */
- //OLD
- #include <vector>
- #include <numeric>
- #include <type_traits>
- #include <utility>
- namespace
- {
- template<typename, typename, typename = void>
- struct has_plus : std::false_type {};
- template<typename T1, typename T2>
- struct has_plus<T1, T2, std::void_t<decltype(std::declval<T1>() + std::declval<T2>())>> : std::true_type {};
- template<typename T1, typename T2>
- inline constexpr bool has_plus_v = has_plus<T1, T2>::value;
- template<typename T1, typename T2, bool = has_plus_v<T1, T2>>
- struct plus_result
- {
- using type = decltype(std::declval<T1>() + std::declval<T2>());
- };
- template<typename T1, typename T2>
- struct plus_result<T1, T2, false> {};
- template<typename T1, typename T2>
- using plus_result_t = typename plus_result<T1, T2>::type;
- template<typename T = double, typename = std::enable_if_t<has_plus_v<T, T>>>
- plus_result_t<T, T> sum(const std::vector<T>& v)
- {
- return std::accumulate(v.cbegin(), v.cend(), T{});
- }
- }