• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Szczęśliwa 11

VPS Starter Arubacloud
0 głosów
1,129 wizyt
pytanie zadane 22 grudnia 2019 w C i C++ przez Hubertius Bywalec (2,970 p.)

Cześć, napotkałem na takie zadanie:

Liczba jest podzielna przez 11, jeżeli wartość bezwzględna z różnicy sumy jej cyfr stojących na miejscach parzystych i sumy jej cyfr stojących na miejscach nieparzystych dzieli się przez 11. Wykorzystując podaną własność napisz rekurencyjną funkcję sprawdzającą, czy dana liczba większa od 0 jest podzielna przez 11 wobec faktu, że jedyną liczbą jednocyfrową podzielną przez 11 jest zero. Funkcja ma zwrócić 1, jeżeli liczba jest podzielna przez 11, 0 w przeciwnym przypadku. Prototyp funkcji powinien wyglądać następująco:

int is_divisible_by_11(int number);

Napisz program, który pobierze od użytkownika liczbę i sprawdzi, wykorzystując przygotowaną wcześniej funkcję, czy jest ona podzielna przez 11 czy nie. Program ma wypisać komunikat "YES" lub "NO". W przypadku wprowadzenia błędnych danych program powinien wyświetlić komunikat Incorrect input i niezwłocznie zakończyć działanie z kodem błędu 1.

Uwaga W programie nie wolno używać zmiennych globalnych.

Uwaga W programie nie wolno używać słowa kluczowego static.

Uwaga W programie nie wolno używać pętli.

Uwaga W programie nie wolno korzystać z biblioteki math.

Uwaga W programie nie wolno korzystać z operatora modulo oraz dzielenia, za wyjątkiem dzielenia przez 10.

Przykładowe wejście:

Podaj liczbę: 121

Przykładowe wyjście:

YES

Dwa zapytania mam co do tego zadania:

-jak mogę zastąpić operację modulo?

- jak mogę przechować  z każdą kolejną rekurencją pod postacią is_divisible_by_11(number/10) informację o danej liczbie i o jej indeksie? Niestety nie mogę przekazać do każdego wywoływania rekurencyjnego tablicy ani jakiejkolwiek informacji o "size".

2 odpowiedzi

0 głosów
odpowiedź 25 grudnia 2019 przez profesorek96 Szeryf (91,420 p.)

Zazwyczaj nie robię za nikogo zadań, jednak ten problem mnie niezwykle zaciekawił. Jeśli miałbyś jakieś pytania to zapraszam, tylko w wątku by zostało to dla potomnych :)

Proszę bardzo:

#include <iostream>
using namespace std;
int parzyste(int n,int k)
{
	if(n<=0)
	{
		return 0;
	}
	else
	{
		int d=n/10;
		int ost=n-(d*10);
		if(k%2==0)return ost+parzyste(n/10,++k);
		return 0+parzyste(n/10,++k);
		
	}
}
int nie_parzyste(int n,int k)
{
	if(n<=0)
	{
		return 0;
	}
	else
	{
		int d=n/10;
		int ost=n-(d*10);
		if(k%2!=0)return ost+nie_parzyste(n/10,++k);
		return 0+nie_parzyste(n/10,++k);
		
	}
}
int przez_11(int n)
{
	if(n<=0)return 0;
	else return 1+przez_11(n/10);
}
int is_divisible_by_11(int number)
{
	int roznica=nie_parzyste(number,0)-parzyste(number,0);
	if(roznica<0)roznica*=(-1);
	if(roznica==0)return 1;
	else return 0;
	return is_divisible_by_11(roznica);
}
int main() {
	int n;
	cin>>n;
	if(is_divisible_by_11(n)==1)cout<<"YES";
	else cout<<"NO";
	return 0;
}

 

komentarz 25 grudnia 2019 przez mokrowski Mędrzec (155,460 p.)

1. Funkcje parzyste(...) i nie_parzyste(...), różnią się 1 linijką (13 i 28). Chodzi o:

if(k%2!=0)
// i 
if(k%2==0)

Łamiesz regułę DRY.

2. Wykonujesz 2 x tę samą pracę "przejścia po reprezentacji dziesiętnej". To jest nieefektywne.

3. "Engliszo-Poliszo" kod. Ja bym języków nie mieszał tym bardziej że sygnatura funkcji sugeruje użycie jednego z nich.

4. Nie do końca rozumiem co chcesz wyrazić przez to:

0+parzyste(n/10,++k)

5. Nierówności "ostre" w większości platform działają szybciej niż "nie-ostre".

6.

Uwaga W programie nie wolno korzystać z operatora modulo oraz dzielenia, za wyjątkiem dzielenia przez 10.

 

komentarz 25 grudnia 2019 przez profesorek96 Szeryf (91,420 p.)
Co do 1 tak łamię, zgadza się. Jeśli chodzi o 2 to nie wiem jak można by to było zrobić w jednym.

Nie potrzebnie mieszałem polski z angielskim.

W 4 chciałem by było sumowanie.

Jeśli chodzi o punkt 6 to mój program nie wykonuje w żadnym z linii dzielenia innego niż przez 10 jak i nie korzysta z operacji modulo. Co czyni mój program absolutnie zgodny z warunkami zadania. Nie chcę nic mówić ale raczej to zadanie nie jest na czystość kodu lecz na wyćwiczenie rekurencji. Jak wiadomo rekurencja to nie najlepszy sposób na rozwiązywanie problemów i powinna być zastępowana jeśli tylko się da iteracją.
komentarz 25 grudnia 2019 przez mokrowski Mędrzec (155,460 p.)

k%2

...nie korzysta z operacji modulo.

To jednak modulo. Wystarczy zastąpić to:

(k & 0x01)

A co do DRY, wystarczy przy rekurencji zbierać informację z 2 sum. Dla parzystych i nieparzystych. Czyli np. z taką sygnaturą:

void od_even_sum(int value, int& odd_sum, int& even_sum, bool flag);

za każdym razem w rekurencji uaktualniająć wartość bieżącej sumy dla odd i even a flag oznaczyć czy chodzi o odd czy even (to oczywiście szkolne rozwiązanie).

A jeśli ma być "czysto funkcyjnie bez efektu ubocznego", to niestety z funkcji trzeba zwrócić parę wartości dla odd i even i w argumentach przesłać kopie.

Nie chcę nic mówić ale raczej to zadanie nie jest na czystość kodu lecz na wyćwiczenie rekurencji.

Każde zadanie jest na wyćwiczenie czystości kodu :) Czysty kod to taki który pokazuje że komuś zależy by był czysty,

0 głosów
odpowiedź 25 grudnia 2019 przez mokrowski Mędrzec (155,460 p.)

-jak mogę zastąpić operację modulo?

Np. wynikiem modulo 10 dla liczb dodatnich będzie:

value - ((value / 10) * 10);

jak mogę przechować  z każdą kolejną rekurencją pod postacią is_divisible_by_11(number/10) informację o danej liczbie i o jej indeksie

Możesz bawić się we flagi jak napisałem (w szkolnej wersji poniżej), lub zauważyć że dla liczby jednocyfrowej, wartość będzie zawsze nieparzysta a dla wielocyfrowej, nastąpi przestawienie.

Żeby od razu nie zdradzać rozwiązania:

void sum_odd_even(int value, int& odd_sum, int& even_sum) {
    // ...
    // jeśli wartość jest "więcej-cyfrowa"
    sum_odd_even(value, even_sum, odd_sum);
    // zauważ powyżej przestawienie even_sum i odd_sum.
}

int is_divisible_by_11(int value) {
    // ...
    sum_odd_even(value, odd_sum, even_sum);
    // ...
}

 

komentarz 26 grudnia 2019 przez mokrowski Mędrzec (155,460 p.)

Jeśli już wykonasz własną pracę, możesz zerknąć tutaj:

#include <iostream>

void sum_odd_even(int value, int& odd_sum, int& even_sum)
{
    odd_sum += value - ((value / 10) * 10);
    value /= 10;
    if(value) {
        sum_odd_even(value, even_sum, odd_sum);
    }
}

int is_divisible_by_11(int value)
{
    int odd_sum = 0;
    int even_sum = 0;
    sum_odd_even(value, odd_sum, even_sum);
    int diff = odd_sum - even_sum;
    diff = (diff < 0 ? -diff: diff);
    return (diff > 10 ? is_divisible_by_11(diff): !diff);
}

int main()
{
    int n;
    std::cin >> n;
    std::cout << (std::cin ? (is_divisible_by_11(n) ? "YES": "NO") : "Incorrect input") << '\n';
}

 

komentarz 26 grudnia 2019 przez Hubertius Bywalec (2,970 p.)
W ostatnim czasie trochę ślęczałem nad zadaniami z sortowania. Jeszcze dzisiaj postaram się usiąść z powrotem nad tym zadaniem ze szczęśliwą 11 i dam znać, jeżeli będę miał z nim jakieś kłopoty.

Podobne pytania

–1 głos
2 odpowiedzi 1,822 wizyt
pytanie zadane 2 stycznia 2017 w C i C++ przez Arkadiusz Sieczak Początkujący (400 p.)
0 głosów
4 odpowiedzi 346 wizyt
pytanie zadane 30 listopada 2015 w C i C++ przez Kaydan Początkujący (260 p.)
0 głosów
1 odpowiedź 394 wizyt
pytanie zadane 1 czerwca 2015 w C i C++ przez gabon95 Nowicjusz (160 p.)

92,451 zapytań

141,261 odpowiedzi

319,073 komentarzy

61,853 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...