2015-11-30 3 views
2

Я пишу процедуру для вычисления. Программа запрашивает у пользователя любое число от 1 до 9999, а затем вычисляет, является ли этот номер счастливым.Написание программы для расчета Счастливые номера в Паскаль. Застрял с бесконечным циклом

program EindEvaluatieProceduresFuncties2; 

    uses wincrt, math; 

    var lucky: boolean; 
    num: longint; 
    i, j: integer; 
    arr: array [1..4] of integer; 
    sum: integer; 


    procedure HappyNumber; 

    begin 
    repeat 
    begin 
     repeat 
     begin 
      i:=i+1; 
      //writeln('i = ',i); 
      arr[i]:=num mod 10; 
      //writeln('a[i] = ', arr[i]); 
      num:=num div 10; 
      //writeln ('n = ', num); 
     end; 
     until num=0; 
     //writeln('Digits are : '); 
     //for j:=i downto 1 do 
     //writeln('a[j] = ', arr[j],' ', j); 
     //writeln('Calculating Happy Number'); 
     for j := i downto 1 do 
     sum := sum + (Sqr(arr[j])); 
     for j := i downto 1 do 
     writeln('sum = ',sum); 
     num := sum; 

    end; 
    until sum < 10 ; 
    end; 

    begin 
    lucky := false; 
    writeln('Please give a positive number below 10000.'); 
    readln(num); 
    while (num < 1) or (num > 9999) do 
    begin 
     writeln('Number must be positive and less than 10000. Try again.'); 
     readln(num); 
    end; 
    HappyNumber; 
    if (lucky = True) then 
    begin 
     writeln(num, ' is a happy number.'); 
    end 
    else 
    begin 
     writeln(num, ' is not a happy number.'); 
    end; 
    writeln(''); 
    writeln('Press <ENTER> to end the program.'); 
    readln; 
    end.  

В рамках процедуры у меня есть команда i: = 0; как показано ниже:

procedure HappyNumber; 

     begin 
     repeat 
     begin 
      repeat 
      begin 
       i:=0; 
       i:=i+1; 

Здесь возникает проблема. Если я это сделаю, это станет бесконечным циклом, однако, если я положу команду за пределами цикла повтора, то я не сбрасываю в 0 в начале каждой итерации цикла, в котором я нуждаюсь.

Я должен указать, что большая часть кода есть на данный момент, просто чтобы я мог видеть, что происходит и не будет частью окончательного кода. Где бы я ни вставил «//» эти строки.

Я знаю, что, возможно, лучший способ я мог бы сделать всю эту программу. Если у кого-то есть предложения по тому, как я могу сделать это легче, я бы тоже это оценил.

спасибо.

+0

http://ericlippert.com/2014/03/05/how-to-debug-small-programs/ –

+0

Положите 'i: = 0;' над вторым 'повтором' и это будет инициализировать до 0 каждый внешний повтор (который вы хотите). B.T.W. ваша программа все равно будет зависать на несчастливых номерах (как определено «недовольным номером»), поэтому вам нужно создать какой-то механизм, чтобы обнаружить, что вы находитесь в цикле. (вы также можете удалить начало/конец в пределах повтора/до повтора/до тех пор, пока «действие» не будет выполнено как начало/конец блока) – Rik

+0

Дополнительное примечание: вы делаете 'до суммы <10;' как если бы числа ниже 10, а не 1 недовольны. Это не правда. Например, 7 счастлив. '7> 49> 97> 130> 10> 1'. Число 4 заканчивается в цикле: '4> 16> 37> 58> 89> 145> 42> 20> 4> 16> 37> 58> .....' и т. Д. Поэтому вам всегда нужно кэшировать числа, которые вы видели и если вы видите повтор, вы находитесь в петле (что несчастливо). См. Https://en.wikipedia.org/wiki/Happy_number. – Rik

ответ

1

Никогда не слышал о счастливых/несчастливых чисел и нашел, что это довольно интересно, чтобы решить эту задачу :-)

Существует еще много, чтобы оптимизировать, но я думаю, что вы можете использовать его для изучения.

program EindEvaluatieProceduresFuncties2; 

uses SysUtils, crt ; 

var input: string; 
    number: integer; 
    code: integer; 

function HapyNumber(num: integer):boolean; 
var 
    erg: integer; 
    digit: integer; 
begin 
    Result := true; 
    erg := 0; 
    if num = 4 then Result := false; 
    if num = 4 then exit; 
    if num = 1 then exit; 
    if num = 0 then exit; 

    // serialize the number into digits and calculate the next number 
    while num > 0 do begin 
    digit := num mod 10; 
    num := num div 10; 
    erg := erg + digit * digit; 
    write(IntToStr(digit) + ' '); 
    end; 

    write(IntToStr(num) + ' '); 
    writeln('=' + IntToStr(erg)); 
    Result := HapyNumber(erg); 
end; 

begin 

    repeat 
    writeln('Please give a positive number below 10000.' + sLineBreak + 'Number must be positive and less than 10000.' + sLineBreak + 'Type x for exit!'); 
    readln(input); 
    if lowerCase(input) = 'x' then exit; 
    val(input, number, code); 
    if code <> 0 then begin 
     ClrScr; 
     writeln('Invalid number "' + input + '" !'); 
    end 
     else if (number > 0) and (number <= 9999) then begin 
     ClrScr; 
     writeln('Cheking ' + IntToStr(number) + '..'); 
     if HapyNumber(number) then writeln(number, ' is a happy number.') 
      else writeln(number, ' is not a happy number.'); 
     writeln('Press enter to continue'); 
     readln; 
     ClrScr; 
     end; 

    until lowerCase(input) = 'x'; 
end. 

Важным codepart является

while num > 0 do begin 
    digit := num mod 10; 
    num := num div 10; 
    erg := erg + digit * digit; 
    write(IntToStr(digit) + ' '); // just output the tmp result 
    end; 

Это сериализации число в цифры (1973 будет 3 7 9 1)

Я использовал рекурсию просто для удовольствия, и это на самом деле не нужно :-)

+0

Omg большое вам спасибо за это, и я сожалею, что никогда не ответил раньше. Я был затоплен и позволил этому заданию сидеть на стороне в течение нескольких дней. Есть что-то, что я хотел бы задать. Переменная эрг. Что это такое, что означает имя? –

+0

Я использовал erg в качестве справочной переменной. Это значение всегда печатается один раз за вызов функции HapyNumber. Не стесняйтесь спрашивать, когда что-то неясно. Пожалуйста, проголосуйте за мой ответ, если он решает ваш вопрос. :-) –