Начала Паскаля: линейные программы, целые и вещественные типы

Здесь предлагаются условия и обсуждаются варианты решения простейших Паскаль-задач технического характера на ввод, линейные вычисления и вывод данных, с привлечением арифметики целочисленных и вещественных типов.

значит решение 8 задачи будет

значит решение 8 задачи будет таким же,только все нужно взять по модулю?

Чеснокова Мария

Пожалуйста, обращайся ко мне на "ты".

хорошо,извини,просто проявляю

хорошо,извини,просто проявляю уважение...так что по поводу 8 задачи?

На счёт решения задачи 8 я

На счёт решения задачи 8 я ещё не думал.

понятно...спасибо тебе

понятно...спасибо тебе большое,можно спросит?скольтко по времени ты паскаль изучаешь?

Я Паскаль почти не изучал.

Я Паскаль почти не изучал. Совсем немного в школе. Кстати, по поводу задачи: мне кажется, что trunc и round здесь использовать нельзя, потому что всё получается слишком просто.

да надо подумать над решением

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

Спасибо.

Спасибо.

а по-моему логическая цепочка

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

А по-моему решение задачи 8

А по-моему решение задачи 8 будет таким же. Из этого я и сделал вывод, что round и trunc нельзя использовать. Вероятно без их использования задачи 7 и 8 решались бы по разному. Только вот как?

Замечания по задачам от 10.10.10

Aлексей, Программа z6 - строки 8, 9 вызывают вопросы;
Дмитрий, Программа a7 - строки 7, 8 вызывают вопросы;
Задача 8 - решение пока не представлено.

writeln(abs(x mod y)*

writeln(abs(x mod y)* abs(x)/x:2:0);

x mod y - остаток целочисленного деления
abs(x mod y) - всегда положительный остаток целочисленного деления
abs(x)/x - единица со знаком данного числа.

Вариант, когда x=0 - не уместен. Ошибка детектед...
Хорошо, оптимизируем получение единицы со знаком abs(x+1)-abs(x)

Debug
x=7 => 8-7 = 1
x=-7 => 6-7 = -1
x=0 => 1-0 = 1
Всё верно

Final
8 writeln(abs(x mod y)*(abs(x+1)-abs(x)));
9 writeln(abs(x mod y)*(abs(y+1)-abs(y)));

Так подойдёт?

Закрыты задачи 2,3,6

Алексей Зубко: Задача 2 - закрыта.
Молчанов Дима: Задача 3 - закрыта. Хотя и остался без ответа мой вопрос о 6-й строчке.
Алексей Зубко: Задача 6 - закрыта. Правда, не понятно, зачем с самого начала в 6-8, 6-9 была применена вещественная операция "/" вместо естественной там "div". Но и найденные Алексеем решения типа abs(x+1)-abs(x) снимают вопрос.
Молчанов Дима: В решении задача 7 - ошибка, плюс оговорки о форматировании вывода (см.ниже).

Мои комменты:
1. Плохая идея - использовать арифметику плавающей точки при решении задач целочисленной арифметики;
2. Не следует использовать не рассмотренные на лекциях средства, такие как форматный вывод (типа Write(x:2:0) );
3. Тот же форматный вывод (типа Write(x:2:0) ) не создаёт целое, а в общем случае подавляет дробные цифры вещественного, создавая видимость целого - с логической точки зрения не безупречный приём.

Итог этой сессии: Алексей Зубко - 5 баллов, Дима Молчанов - 2 балла.

Попытка решения 8й задачи

  1. program task8;
  2. {$APPTYPE CONSOLE}
  3. uses
  4.   SysUtils;
  5. var
  6.   n: real;
  7. label error;
  8. begin
  9.  error: writeln ('Введите отрицательное вещественное число');
  10.  readln (n);
  11.   if n<0 then
  12.    begin
  13.     writeln ('Наибольшее целое, не превосходящее заданное значение = ', trunc(n-1));
  14.     writeln ('Результат округления заданного значения до ближайшего целого = ', round(n));
  15.     writeln ('Наименьшее целое, не меньшее, чем заданное значение = ', trunc(n));
  16.     {Функция int(x) при работе с отрицательными числами просто отбрасывает дробную часть.
  17.       Взято отсюда: http://tid.com.ua/tid1/addonres.php?id=10949}
  18.     writeln ('Результат «усечения» заданного значения = ', int(n):2:0)
  19.     {Поскольку результатом функции будет число в экспоненциальной форме - мы используем форматный вывод.
  20.       Делается это только для эстетически красивого отображения результата на экране}
  21.      end
  22.     else
  23.      begin
  24.       writeln ('Ввдённое Вами число противоречит условию задачи');
  25.       goto error
  26.      end;
  27.  readln;
  28. end.

Использование оператора безусловного перехода goto считается плохим стилем программирования, но данная задача не представляет собой особо сложную структуру. Поэтому данный оператор поможет нам не перезапускать программу в случае не корректного ввода начального значения.

Теперь проверим задачу. Например возьмём число -3.86 и запустим программу.

  1. -3.86<0 - истина;
  2. trunc(-3.86-1)=trunc(-4.86)=-4 смотрим рисунок;
  3. round(-3.86)=-4 - округление до ближайшего целого;
  4. trunc(-3.86)=-3 опять смотрим рисунок;
  5. int(-3.86)= -3 отбрасывание дробной части.

Ну вроде как-то так. Хотя наверняка не правильно.

Номер 3 под моим решением

  1. program z3;
  2. var chislo,desyatki,edinitsy,itog:integer;
  3. begin
  4.    readln(chislo);
  5.    edinitsy:=chislo mod 10;
  6.    desyatki:=(chislo div 10) mod 10;
  7.    itog:=((desyatki mod edinitsy)+9) div 10;
  8.    writeln(itog)
  9. end.

Решение 8ой задачи

  1. program zadacha8;
  2.    var a:real;
  3. begin
  4.    writeln('Vvedite otricatel`nuy veshestvennuy peremennuy');
  5.    readln(a);
  6.    if a<0 then
  7.      begin
  8.        writeln(trunc(a)-1);
  9.        writeln(round(a));
  10.        writeln(trunc(a));
  11.        writeln(trunc(a));
  12.      end
  13.    else writeln('Vi vveli nekkorektnuy peremennuy');
  14.    readln
  15. end.

думаю так...

Увы, ошибки!

Роман, не могу не отметить Ваше решение, как очень основательное. Но, к сожалению, оно не без ошибок.
Вы этим решением замечательно проиллюстрировали следующую технологическую аксиому:
Тестами невозможно доказать правильность программ, ими можо доказать только их неправильность.

Так же содержат ошибки: решения Александра и Валерия.
Будьте внимательней, коллеги!

Исправил

  1. program zadacha8;
  2.    var a:real; b,c,d,e:integer;
  3. begin
  4.    writeln('Vvedite otricatel`nuy veshestvennuy peremennuy');
  5.    readln(a);
  6.    if a<0 then
  7.      begin
  8.        b:=(trunc(a)-1);
  9.        c:=(round(a));
  10.        d:=(trunc(a));
  11.        e:=(trunc(a));
  12.        writeln(b);
  13.        writeln(c);
  14.        writeln(d);
  15.        writeln(e);
  16.      end
  17.    else writeln('Vi vveli nekkorektnuy peremennuy');
  18.    readln
  19. end.

Еще раз прочитав

Еще раз прочитав задание,особенно фразу "печатать целое значение",предполагаю что ошибка была в выводе вещественного значения вместо целого

Думаю, Валерий,

Думаю, Валерий, второе Ваше решение не отличается от первого ...

А по поводу goto, Роман, уж

А по поводу goto, Роман, уж если защищать от ошибок ввода, то правильней, например, так:

  1. ...
  2. repeat
  3.     writeln ('Введите отрицательное вещественное число');
  4.     readln (n);
  5.     if a<0 then break;
  6.     writeln ('Ввдённое Вами число противоречит условию задачи')
  7. until false;
  8. ...

Нашел ошибку в 8ой

Нашел ошибку в 8ой строке
исправил

  1. program zadacha8;
  2.    var a:real; b,c,d,e:integer;
  3. begin
  4.    writeln('Vvedite otricatel`nuy veshestvennuy peremennuy');
  5.    readln(a);
  6.    if a<0 then
  7.      begin
  8.        if a=trunc(a) then b:=trunc(a) else b:=trunc(a)-1;
  9.        c:=(round(a));
  10.        d:=(trunc(a));
  11.        e:=(trunc(a));
  12.        writeln(b);
  13.        writeln(c);
  14.        writeln(d);
  15.        writeln(e);
  16.      end
  17.    else writeln('Vi vveli nekkorektnuy peremennuy');
  18.    readln
  19. end.

Да, но ведь if запрещён!

Да, но ведь if запрещён!

безусловно

  1. program zadacha8;
  2.    var a:real; b,c,d,e:integer;
  3. begin
  4.    writeln('Vvedite otricatel`nuy veshestvennuy peremennuy');
  5.    readln(a);
  6.    b:=round(a-0.4);
  7.    c :=round(a);
  8.    d:=trunc(a);
  9.    e:=trunc(a);
  10.    writeln(b);
  11.    writeln(c);
  12.    writeln(d);
  13.    writeln(e);
  14.    readln
  15. end.

Можно пожалуйста спросить у

Можно пожалуйста спросить у Вас,Валерий,расскажите,что происходит на 6 строчке,решенной Вами задаче?что такое 0.4?

Ну для начала со мной можно

Ну для начала со мной можно на ты:)
А по поводу 6ой строчки:
нам надо найти целую часть заданного значения (наибольшее целое, не превосходящее заданное),например для числа -23.1 или -23.7 таким наибольшим целым не превосходящее заданное является число -24,но для числа -23 таким числом является само число -23,а значит,исходя из моего решения:(для наглядности взял несколько чисел)
1)Мы вводим нецелое число (-23.1,-23.5,-23.9)
2)От него отнимается 0.4 (-23.5,-23.9,-24.3)
3)Далее происходит округление получившегося числа (-24,-24,-24)
Действительно,получилось нужное нам число.

Тоже самое происходит с целым числом:
1)Мы вводим целое вещественное число (-23)
2)От него отнимается 0.4 (-23.4)
3)Округление получившегося числа (-23)
И снова получается нужное нам число.

В 2ух первых моих (неправильных) решениях эта строка была записана как trunc(a)-1,тогда решение выдавалось правильное только для нецелых чисел (например для -23.1,получалось -24,что нам и нужно),но если ввести целое число,то результат выдавался не правильным (например вводим -23,выдавалось -24,а это неправильное решение)

Спасибо)

Спасибо)

Всегда пожалуйста;) Но я

Всегда пожалуйста;)
Но я снова нашел у себя в решении ошибку,уже думаю как исправить....

О какой ошибке Вы говорите,

О какой ошибке Вы говорите, Валерий?

Ошибка

Ну допустим для чисел -23,-23.1,-23.9 программа правильная,но если например -20.01,то нет:(

Да, Валерий

Вы нашли-таки свою ошибку. Это тонкая ошибка и Вам за скурпулёзность - дополнительный плюс.
Но, если никто не "перехватит" окончательного решения (чего я искренне желал бы), давайте немного позже вместе посмотрим, можно ли здесь что-то поделать ...

Валерий,в таком случае число

Валерий,в таком случае число может быть любым,например -20.000000121212121231231231234 и как тогда быть?

А сейчас - РАЗБОР КОНРОЛЬНЫХ РАБОТ

А сейчас - РАЗБОР КОНРОЛЬНЫХ РАБОТ. Я их буду публиковать и разбирать позадачно, в произвольном порядке.
Приглашаю к уастию в разборе всех желающих. Как обычно, за активное участие и результативность начисляю бонусы.

Задача 2-1. Определить, представляют ли цифры заданного в десятичной записи 3-х значного натурального числа возрастающую последовательность. Вывести 1, если да и вывести 0, если нет. Например, на числах 527, 224, 543 программа ответит - 0, а на числе 478 - 1.
Предполагается линейное (т.е. не содержащее условных и циклических операторов) решение на Паскале.
Я немного подожду предложений.

Валерий

Валерий Шахамболетович,благодарю!
Мария,вот над этим я как раз таки и ломаю голову:)

Валерий Шахамболетович в числе

Валерий Шахамболетович в числе 478 он должен выводить 1 а не ноль, ну или на оборот в тех числах тогда 0, так как тут разници нет что правельно, что не правельно всё ровно 0

Да что ж такое

Уже 3 часа сижу никак не получаеться решить задачу контрольной работы :(
Вот некоторые догадки, но тут только половина програмы (ее недочеты описаны под програмой):

  1. Program x1;
  2. var a,b,c,x,y,n:Integer;
  3. begin
  4. a:=n div 100;
  5. b:=(n div 10) mod 10;
  6. c:=n mod 10;
  7. x:=(a+1) div (b+1);
  8. y:=(b+1) div (a+1);
  9. a:=x*y;
  10. x:=(b+1) div (c+1);
  11. y:=(c+1) div (b+1);
  12. b:=x*y;
  13. x:=(a+1) div (b+1);
  14. y:=(b+1) div (a+1);
  15. n:=x*y;
  16. write(n)
  17. end.

Тут будет выводиться 0 если 2 цифры в числе одинаковые т.е. 155 или 776, но 1 будет выводиться как в случае возврастающей последовательности цифр, так и в остальных, например при 341 тоже будет выводиться 1.
У кого нибудь есть идеи как это исправить?

Предложений нет

Предложений нет. Тогда подсказка. Что если:
1. Цифры числа записать в порядке следования в переменные a1,a2.a3.
2. Cocтавить произведение b=(a3 div a2)*(a2 div a1) и на него посмотреть ...
Проблема того, что некоторые цифры могут быть нули уже на этом форуме решена ...

Вижу, Евгений

Вижу, Евгений пошёл именно этим путём ...

... но с одним принципиальным

... но с одним принципиальным отличием от моего ...
Думаю, теперь тупик будет преодолён.

Валерий Шахамболетович

Я что то не пойму смысл b=(a1 div a2)*(a2 div a3), для чего оно нужно нам?

Там была неточность,

Там была неточность, исправил.

А ты возьми несколько

А ты возьми несколько последовательнойстей и подставь в b,думаю поймешь..
Я встал в тупик в ситуации если есть одинаковые числа в последовательности...

Кажеться понял, проверьте:

  1. Program x1;
  2. var a,b,c,x,y,n:Integer;
  3. begin
  4. a:=n div 100;
  5. b:=(n div 10) mod 10;
  6. c:=n mod 10;
  7. n:=((c+1) div (b+1))*((b+1) div (a+1))
  8. x:=(a+1) div (b+1);
  9. y:=(b+1) div (a+1);
  10. a:=x*y;
  11. x:=(b+1) div (c+1);
  12. y:=(c+1) div (b+1);
  13. b:=x*y;
  14. x:=(a+1) div (b+1);
  15. y:=(b+1) div (a+1);
  16. n:=n*x*y;
  17. write(n)
  18. end.

1 ошибку я у тебя вижу,ведь

1 ошибку я у тебя вижу,ведь последовательность состоит из натуральных чисел,поэтому тип переменных word

Я понял что там что-то не то

Я понял что там что-то не то, и решил проверить в обратном порядке: что будет при b:=(a3 div a2)*(a2 div a1) а потом из полученного результата сделал вывод и совместил с моим решением, сделал несколько проверок в паскале, вроде выводил правильные. Но если бы вы не написали подсказку никогда б не догадался!

Тип переменных

Ну насколько я знаю нужно написать программу, которая будет выполнять поставленную задачу! Если цепляться к таким вещам как тип, то тут нужно еще учитывать, что надо написать write('введите трехзначное число')

Ну возможно это не ошибка,но

Ну возможно это не ошибка,но все же,и помоему эта программа должна начинаться с readln(a)..
А на счет подсказки ты прав

Точно! забыл read

  1. Program x1;
  2. var a,b,c,x,y,n:Word;
  3. begin
  4. read(n);
  5. a:=n div 100;
  6. b:=(n div 10) mod 10;
  7. c:=n mod 10;
  8. n:=((c+1) div (b+1))*((b+1) div (a+1));
  9. x:=(a+1) div (b+1);
  10. y:=(b+1) div (a+1);
  11. a:=x*y;
  12. x:=(b+1) div (c+1);
  13. y:=(c+1) div (b+1);
  14. b:=x*y;
  15. x:=(a+1) div (b+1);
  16. y:=(b+1) div (a+1);
  17. n:=n*x*y;
  18. write(n)
  19. end.

Помоему программа верная,но 1

Помоему программа верная,но 1 факт:
если ввести 3 одинаковых числа,она выводит 1,а это,если я не ошибаюсь,не верно....

Не надо обижаться, Евгений.

Не надо обижаться, Евгений. Понятно, что Ваше внимание сконцентрировано на существе решаемой задачи, но и Валерий, в принципе прав. Правильней его поблагодарить за замеченные недочёты.

А оценку правильности решения я бы предоставил остальным (в частности, Вам, Валерий)