program który po podaniu liczby obliczy jej sumę (doda wszystkie cyfry liczby) wyświetli wynik a następnie powtórzy ten sam proces dla obliczonej sumy. Proces powinien być zakończony gdy dana liczba będzie 1 cyfrowa
Jakie jest pytanie?
1.Traktuj liczbę jak string lub liczbę.
2. Jeśli string sprawdź długość czy większa jest od 1, a jak liczba, to czy większa od 9.
3. Jak string, to skonwertuj każdy znak na liczbę i dodaj / lub / dziel przez 10, aż nie pójdzie dzielić i dodaj wszystkie reszty.
4. powtórz etap 2 lub przejdź do 5.
5. Wypisz wynik.
Prosz
#include <iostream>
#include <algorithm>
#include <string>
#include <numeric>
template<typename T> struct is {
is(T const &data): data(data) {}
auto in_range(T const &min, T const &max) { return data >= min && data <= max; }
T const &data;
};
template<typename T> struct map {
map(T const &data): data(data) {}
template<typename F> auto operator()(F f) { return f(data); }
T const &data;
};
template<typename T> struct loop_transform {
loop_transform(T const &data): data(data) {}
template<typename Pred, typename F> auto operator()(Pred pred, F f) { while(!pred(data)) data = f(data); return data; }
T data;
};
template<typename T> auto get(std::istream &in) {
T data {};
in >> data;
return data;
}
int main() {
auto data = get<unsigned long long>(std::cin);
loop_transform {data} (
[](auto data) { return is {data}.in_range (1, 9); },
[](auto data) {
auto str = map {data} (static_cast<std::string(*)(decltype(data))>(std::to_string));
auto sum = std::accumulate(std::begin(str), std::end(str), -'0'*str.length());
std::cout << "data {" << data << "}.sum == " << sum << std::endl;
return sum;
}
);
return 0;
}
http://melpon.org/wandbox/permlink/J8ZSzN5eXXhzk2p9
Start
data {789789789789123}.sum == 102
data {102}.sum == 3
0
Finish
Wypadałoby napisac chociaż czy to ma być C czy C++. ( uhonorowałem post powyżej za trolling ).
Napisałem na odwal się ale chyba to jest to.
#include <stdio.h>
#include <string.h>
int main(void) {
char strnum[200];
int sum = 0;
scanf( "%s", strnum );
for(;;) {
sum = 0;
for(int i = 0; i < strlen(strnum); i++) sum += strnum[i] - '0';
if( sum < 10 ) break;
sprintf( strnum, "%i", sum );
}
printf("%i", sum );
return 0;
}
#include <stdio.h>
#include <stdbool.h>
long long sum_char(const char * str, long long partial_sum) {
unsigned value = *str;
return (!value ? partial_sum : sum_char(++str, partial_sum + value - '0'));
}
void process_number(long long value) {
char str[200];
snprintf(str, 199, "%lld", value);
printf("%s->sum->", str);
long long result = sum_char(str, 0);
printf("%lld\n", result);
(void)((result > 10) && (process_number(result), true));
}
int main() {
long long value;
printf("Podaj liczbę: ");
scanf("%199llu", &value);
process_number(value);
}
A kto powiedział, że liczba musi zmieścić się w long longu?? Albo mieć nie więcej niż 199 cyfr??
#include <boost/multiprecision/cpp_int.hpp>
#include <iostream>
#include <cstdlib>
int main()
{
boost::multiprecision::cpp_int i;
std::cin >> i;
if(!std::cin.good() || i < 0)
return EXIT_FAILURE;
while(i >= 10)
{
boost::multiprecision::cpp_int j;
while(i > 0)
{
j += (i % 10);
i /= 10;
}
i = j;
std::cout << i << '\n';
}
return EXIT_SUCCESS;
}
@Mokrowski: "Czas chyba zrobić to na szablonach liczone w trakcie kompilacji... o!"
template <size_t num>
size_t huh() {
return num < 10 ? num : (num % 10) + huh<num / 10>();
}
A właściwie to
template <size_t num>
constexpr size_t huh_impl() {
return num < 10 ? num : (num % 10) + huh_impl<num / 10>();
}
template <size_t num>
constexpr size_t huh() {
return num < 10 ? num : huh_impl<(num % 10) + huh_impl<num / 10>()>();
}
int main () {
const size_t num = 42;
std::cout << huh<num>();
}
Nie obeszło się bez pomocy p.t. Forumowiczów co prawda, ale jest:
#include <boost/multiprecision/cpp_int.hpp>
#include <iostream>
#include <ios>
#include <iomanip>
#include <cstdlib>
#include <string>
#include <sstream>
#include <thread>
#include <future>
#include <utility>
#include <stdexcept>
#include <exception>
void sum_of_digits(std::string::const_iterator it, std::string::const_iterator jt,
std::promise<boost::multiprecision::cpp_int> res)
{
try {
if(jt - it <= 0) {
throw std::invalid_argument("Zero or negative range");
}
else if(jt - it == 1) {
std::stringstream si{std::string{it, jt}}; si.exceptions(
std::ios_base::badbit | std::ios_base::failbit | std::ios_base::eofbit);
si.str(si.str()+"\n"); boost::multiprecision::cpp_int i; si >> i; if(i < 0 || i > 9)
throw std::logic_error("A digit is not a digit");
res.set_value_at_thread_exit(i);
}
else if(jt - it == 2) {
std::stringstream si{std::string{it, it+1}}; si.exceptions(
std::ios_base::badbit | std::ios_base::failbit | std::ios_base::eofbit);
si.str(si.str()+"\n"); boost::multiprecision::cpp_int i; si >> i; if(i < 0 || i > 9)
throw std::logic_error("A digit is not a digit");
std::stringstream sj{std::string{jt-1, jt}}; sj.exceptions(
std::ios_base::badbit | std::ios_base::failbit | std::ios_base::eofbit);
sj.str(sj.str()+"\n"); boost::multiprecision::cpp_int j; sj >> j; if(j < 0 || j > 9)
throw std::logic_error("A digit is not a digit");
res.set_value_at_thread_exit(i+j);
}
else if(jt - it > 2) {
std::promise<boost::multiprecision::cpp_int> leftmost_range;
std::promise<boost::multiprecision::cpp_int> rightmost_range;
auto lrf = leftmost_range.get_future(); auto rrf = rightmost_range.get_future();
std::thread lrt(sum_of_digits, it, it + (jt - it) / 2, std::move(leftmost_range));
std::thread rrt(sum_of_digits, it + (jt - it) / 2, jt, std::move(rightmost_range));
if(!lrf.valid()) throw std::future_error(std::future_errc::no_state); lrf.wait();
if(!rrf.valid()) throw std::future_error(std::future_errc::no_state); rrf.wait();
lrt.join(); rrt.join();
if(!lrf.valid() || !rrf.valid()) throw std::future_error(std::future_errc::no_state);
res.set_value_at_thread_exit(lrf.get() + rrf.get());
return;
}
else throw std::logic_error("Exclusive conditions not exclusive");
} catch(...) {
res.set_exception_at_thread_exit(std::current_exception());
}
}
int main()
{
std::ios_base::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cin.exceptions(
std::ios_base::badbit | std::ios_base::failbit | std::ios_base::eofbit);
std::cout.exceptions(
std::ios_base::badbit | std::ios_base::failbit | std::ios_base::eofbit);
boost::multiprecision::cpp_int i; std::cin >> i;
if (i < 0) std::cin.setstate(std::ios_base::failbit);
while(i >= 10) {
std::stringstream si; si.exceptions(
std::ios_base::badbit | std::ios_base::failbit | std::ios_base::eofbit);
si << std::noshowpos << std::noshowbase << std::dec << std::setw(0) << i;
auto str = si.str();
std::promise<boost::multiprecision::cpp_int> pr; auto fut = pr.get_future();
std::thread thr(sum_of_digits, str.begin(), str.end(), std::move(pr));
if(!fut.valid()) throw std::future_error(std::future_errc::no_state); fut.wait();
if(!fut.valid()) throw std::future_error(std::future_errc::no_state); auto ni = fut.get();
thr.join();
if(!(ni < i)) throw std::logic_error("Infinite loop");
i = ni;
std::cout << i << '\n';
}
return EXIT_SUCCESS;
}