Pascal - „správná čísla“

Datum vydání: 2012-11-01 00:00:00; aktualizováno: 2012-11-02 19:48:05

Zadání příkladu

Program vyzve uživatele k zadání celého čísla. Úkolem programu je zjistit, zda dané číslo je dělitelné jednotlivými ciframi (číslicemi) daného čísla. Např. když uživatel zadá „672“ program vypíše, že jde o „správné číslo“, protože 672 : 6 = 112; 672 : 7 = 96; 672 : 2 = 336. Naopak číslo 726 „není správné číslo“, protože 726 : 7 = 103,7143.

Dále program vyzve uživatele, aby zadal interval od A do B a v rámci tohoto intervalu program vypíše veškerá „správná čísla“.

Řešení ve Free Pascalu

Cyklus repeat until

program SpravnaCisla;
uses crt;
var n, a, b, i: integer;

function spravneCislo(cislo: integer): boolean;
var cifra, torzo: integer;
begin
    spravneCislo := true;
    torzo := cislo;
    repeat
        cifra := torzo mod 10; // dostanu posledni cifru cisla
        if (cifra = 0) or ((cislo mod cifra) <> 0) then // cislo neni delitelne cifrou
        begin
            spravneCislo := false;
            break;
        end;
        torzo := torzo div 10; // uriznu posledni cifru cisla
    until torzo = 0;
end;

begin
    clrScr;

    write('Zadejte cislo: ');
    read(n);
    if spravneCislo(n) then
        writeln('Cislo je "spravne".')
    else
        writeln('Cislo ', n, ' "neni spravne".');
    writeln;

    write('Zadejte rozmeni od A do B (cisla oddelte mezerami, A < B): ');
    read(a, b);
    write('"Spravna" cisla v rozmezi od ', a, ' do ', b, ' jsou: ');
    for i := a to b do
    begin
        if spravneCislo(i) then
            write(i:7);
    end;

    repeat
    until keyPressed;
end.

Spuštění programu

Zadejte cislo: 672
Cislo je "spravne".

Zadejte rozmeni od A do B (cisla oddelte mezerami, A < B): 7 50
"Spravna" cisla v rozmezi od 7 do 50 jsou:       7      8      9     11     12
   15     22     24     33     36     44     48

Poznámky

Pro zpracování je použita funkce. Pro separaci čísel na jednotlivé cifry se využívá operátoru div a mod. Použila jsem cyklus repeat until. Většinou však je výhodnější a přehlednější cyklus while. Zde máte upravený program, který využívá cyklus while a místo ukončení cyklu pomocí break a testuje správnost čísla už na začátku cyklu. U while cyklu musíme přidat podmínku na počáteční test čísla vůči nule.

Cyklus while

program SpravnaCisla;
uses crt;
var n, a, b, i: integer;

function spravneCislo(cislo: integer): boolean;
var cifra, torzo: integer;
begin
    spravneCislo := true;
    torzo := cislo;

    if torzo = 0 then
        spravneCislo := false;
    while (torzo <> 0) and spravneCislo do
    begin
        cifra := torzo mod 10; // dostanu posledni cifru cisla

        // nulou nelze delit; vyuzivam zde zkraceneho vyhodnocovani podminek
        if (cifra = 0) or ((cislo mod cifra) <> 0) then // cislo neni delitelne cifrou
            spravneCislo := false;
        torzo := torzo div 10; // uriznu posledni cifru cisla
    end;
end;

begin
    clrScr;

    write('Zadejte cislo: ');
    read(n);
    if spravneCislo(n) then
        writeln('Cislo je "spravne".')
    else
        writeln('Cislo ', n, ' "neni spravne".');
    writeln;

    write('Zadejte rozmeni od A do B (cisla oddelte mezerami, A < B): ');
    read(a, b);
    write('"Spravna" cisla v rozmezi od ', a, ' do ', b, ' jsou: ');
    for i := a to b do
    begin
        if spravneCislo(i) then
            write(i:7);
    end;

    repeat
    until keyPressed;
end.

Prográmek si musí dát pozor na dělení nulou. Mezi číslicemi se totiž může vyskytovat i nula a pak nelze použít operátor div ani mod. Abych nemusela dělat jeden if navíc, tak jsem využila tzv. zkráceného vyhodnocení podmínek, kdy v podmínce se nejprve otestuje číslo na 0 a teprve pak se vyhodnotí zbytek po dělení. Pokud první část podmínky bude pravdivá (tj. cifra bude rovna nule), tak se podmínka dále již nevyhodnocuje, protože pro logický operátor or stačí, aby jedna část byla pravdivá, a je již celý výraz pravdivý. Proto již nedojde k provedení testu na zbytek dělení a nulou se v podmínce dělit nebude. Záleží však na nastavení překladače, zda je zkrácené vyhodnocování podmínek povoleno!

Pokud byste si nebyli jisti a zkrácené vyhodnocení podmínek používat nechtěli, tak níže je varianta bez zkráceného vyhodnocení podmínek.

Cyklus while bez zkráceného vyhodnocování podmínek if

program SpravnaCisla;
uses crt;
var n, a, b, i: integer;

function spravneCislo(cislo: integer): boolean;
var cifra, torzo: integer;
begin
    spravneCislo := true;
    torzo := cislo;

    if torzo = 0 then
        spravneCislo := false;
    while (torzo <> 0) and spravneCislo do
    begin
        cifra := torzo mod 10; // dostanu posledni cifru cisla

        if (cifra = 0) then // nulou nelze delit;
            spravneCislo := false;
        else if (cislo mod cifra) <> 0 then // cislo neni delitelne cifrou
            spravneCislo := false;
        torzo := torzo div 10; // uriznu posledni cifru cisla
    end;
end;

begin
    clrScr;

    write('Zadejte cislo: ');
    read(n);
    if spravneCislo(n) then
        writeln('Cislo je "spravne".')
    else
        writeln('Cislo ', n, ' "neni spravne".');
    writeln;

    write('Zadejte rozmeni od A do B (cisla oddelte mezerami, A < B): ');
    read(a, b);
    write('"Spravna" cisla v rozmezi od ', a, ' do ', b, ' jsou: ');
    for i := a to b do
    begin
        if spravneCislo(i) then
            write(i:7);
    end;

    repeat
    until keyPressed;
end.

Program se tváří optimisticky, tj. nastavuje proměnnou spravneCislo na true. Stačí však jedna cifra, kterou nelze dělit a pokazí se celé číslo. Takže jakmile narazíme na první cifru, kterou by nešlo dělit, můžeme skončit a vrátit celkově false. Obsah proměnné spravneCislo (jmenuje se shodně jako funkce) je pak návratovou proměnnou funkce.