Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Задача на сложный цикл 
:(
    Опции темы
Zann
Дата 6.12.2009, 16:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 4.12.2009

Репутация: нет
Всего: нет



Привет.
В продолжении изучения Ruby столкнулся с задачей у Криса Пайна:
Цитата

Високосные годы. Напишите программу, которая будет спрашивать начальный год и
конечный год, а затем выдавать с помощью puts все високосные годы между ними (и
включая их, если они также високосные). Високосные годы — это годы, нацело
делящиеся на 4 (как 1984 и 2004). Однако, годы, нацело делящиеся на 100, — не
високосные (как 1800 и 1900) если только они не делятся нацело на 400 (как 1600 и
2000, которые действительно были високосными). 

Даже не могу представить как это сделать. Либо это сложная задача, либо методов не хватает, но думаю, что рано он такую задачу дал.
Приблизительно то, что думаю я:
Код

puts "Enter the begin year"
by = gets.chomp
puts "Enter the final year"
fy = gets.chomp
fy1 = fy + 1
# ny = метод постоянно уменьшающий fy1 на 1
while ny != (by- 1)
# уменьшать fy
  if #если делится
  else # если не делится
  end
# выводить
end

Если кто-то видел книгу Пайна, может еще что-то посоветуете? Или начинать программировать с руби сложно? Или продолжить дальше читать или про алгоритмы что-то посмотреть? Подскажите.
PM   Вверх
source777
Дата 6.12.2009, 17:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1878
Регистрация: 12.3.2007

Репутация: 6
Всего: 56



Цитата(Zann @  6.12.2009,  16:00 Найти цитируемый пост)
Либо это сложная задача, либо методов не хватает, но думаю, что рано он такую задачу дал.

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

Zann, судя по всему ты только начинаешь учиться программировать в принципе, поэтому первое что тебе надо осознать, что язык программирования - это лишь средство выражения алгоритмических мыслей.
Для записи алгоритмов есть и более простые средства, чем языки программирования, например, псевдокод и блок-схемы.
Хорошо заметно, что ты пропустил освоение этих выразительных средств в процессе своего обучения, в результате чего ты не осознаёшь пути выполнения написанного тобой кода. А это фактически ставит крест на твоих скриптах, пока ты не будешь понимать логику их работы, они не будут работать так как надо.
Поэтому тебе нужно на первых порах научиться писать программы на русском языке(псевдокод), позже (когда он с уровня алгоритма перейдёт на уровень архитектуры) псевдокод может мутировать в комментарии к коду.
Классический пример задачи для выявления уровня развития алгоритмического мышления на начальном этапе - это написать алгоритм похода в булочную за хлебом. Попробуй, это весело...

P.S. Решение для задачи про високосные года ниже по тексту, но не подсматривай, пока сам не додумаешься до правильного алгоритма.




Код

    y1 = gets.chomp.to_i
    y1 = (y1%4 == 0) ? y1 : (y1/4+1)*4
    y2 = gets.chomp.to_i
    y2 = (y2%4 == 0) ? y2 : y2/4*4
    y1.step(y2, 4) { |y| puts y if (y%100!=0 || y%400==0) }



Это сообщение отредактировал(а) source777 - 6.12.2009, 17:03


--------------------
Если бы программистам платили за то, чтобы убирать код из программы вместо того, чтобы добавлять его, программы были бы намного лучше © Николас Негропонте
PM MAIL   Вверх
Zann
Дата 6.12.2009, 17:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 4.12.2009

Репутация: нет
Всего: нет



source777,  огромное спасибо.
Да, это мой первый язык программирования впринципе. Не считая конечно HTML, но это и не язык программирования конечно.
Есть какое-нибудь хорошее руководство по псевдокоду или книга? 
зы Гугл наверняка поможет, но лучше услышать совет реальных специалистов.

Не удержался и подсмотрел...
y1 = (y1%4 == 0) ? y1 : (y1/4+1)*4
y2 = (y2%4 == 0) ? y2 : y2/4*4
y1.step(y2, 4) { |y| puts y if (y%100!=0 || y%400==0) }
Методы в этих строках не были рассмотрены в книге (%, :, ||, ?, step).
Все-таки, может этот пример был рановат smile

Это сообщение отредактировал(а) Zann - 6.12.2009, 18:40
PM   Вверх
source777
Дата 6.12.2009, 21:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1878
Регистрация: 12.3.2007

Репутация: 6
Всего: 56



Цитата(Zann @  6.12.2009,  17:29 Найти цитируемый пост)
Методы в этих строках не были рассмотрены в книге (%, :, ||, ?, step).

А может их вообще в этой книге не будет рассмотрено? Книга то для новичков, поэтому оттуда много убрано того, что обычно присутствует в более сложных книгах, таких как "The Ruby Way" Фултона.
В любом случае это не столь важно, тот же алгоритм можно записать десятками других способов. 
Тернарный условный оператор(условие ? если_истина : если_ложь) можно заменить на обычный (if(условие) если_истина else если_ложь end), это правда уже 5 строк вместо одной. Цикл step можно заменить на цикл while.
|| - сокращённое логическое "или"
a%b - взятие остатка от деление a на b


Цитата(Zann @  6.12.2009,  17:29 Найти цитируемый пост)
Есть какое-нибудь хорошее руководство по псевдокоду или книга? 

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

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


--------------------
Если бы программистам платили за то, чтобы убирать код из программы вместо того, чтобы добавлять его, программы были бы намного лучше © Николас Негропонте
PM MAIL   Вверх
Zann
Дата 6.12.2009, 23:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 4.12.2009

Репутация: нет
Всего: нет



Начало
1) Одеться
2) Взять деньги
3) Выйти из квартиры
4) Выйти из подъезда
5) Дойти до магазина
6) Войти в магазин
7) Дойти до хлебной полки
8) Взять хлеб
9) Дойти до кассы
10) Оплатить хлеб
11) Выйти из магазина
12) Дойти до дома
13) Войти в подъезд
14) Войти в квартиру
15) Положить хлеб на кухне
16) Раздеться
Конец алгоритма smile

Конечно еще можно было ответвления сделать. Например, посмотреть на градусник. Если больше 0 - одеть то, если меньше - одеть то. Также можно было подробнее расписать: одел левый носок, потом правый smile
PM   Вверх
source777
Дата 6.12.2009, 23:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1878
Регистрация: 12.3.2007

Репутация: 6
Всего: 56



Неплохо, один вопрос только, у тебя всегда дверь в квартиру открытой остаётся?

Следующее задание: нарисовать блок-схему для решения задачи о високосных годах.


--------------------
Если бы программистам платили за то, чтобы убирать код из программы вместо того, чтобы добавлять его, программы были бы намного лучше © Николас Негропонте
PM MAIL   Вверх
Zann
Дата 7.12.2009, 13:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 4.12.2009

Репутация: нет
Всего: нет



Получилось примерно следующее:

user posted image
PM   Вверх
source777
Дата 7.12.2009, 14:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1878
Регистрация: 12.3.2007

Репутация: 6
Всего: 56



1) Что за A3, A4? 
2) Пройди по блок-схеме с данными A1 = 1894, A2 = 1912. Что у тебя получится на выводе? Лично я чётко вижу бесконечный цикл в твоей блок-схеме.
3) Ты понял алгоритм, который подсмотрел в моём коде?
4) Не надо никаких "как-то", "что-то", алгоритмика такого не терпит. если надо вывести значение конкретной переменной, то так и надо написать. Запомнить значение можно только через присваивание, а не через "как-то".

Это сообщение отредактировал(а) source777 - 7.12.2009, 14:45


--------------------
Если бы программистам платили за то, чтобы убирать код из программы вместо того, чтобы добавлять его, программы были бы намного лучше © Николас Негропонте
PM MAIL   Вверх
Zann
Дата 8.12.2009, 22:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 4.12.2009

Репутация: нет
Всего: нет



Код

y1 = gets.chomp.to_i
y1 = (y1%4 == 0) ? y1 : (y1/4+1)*4
y2 = gets.chomp.to_i
y2 = (y2%4 == 0) ? y2 : y2/4*4
y1.step(y2, 4) { |y| puts y if (y%100!=0 || y%400==0) }

Если честно, то почти весь алгоритм не понят,  тк не знаю этих методов и как их использовать.

y1 = gets.chomp.to_i   # тут все понятно
y1 = (y1%4 == 0) ? y1 : (y1/4+1)*4   # если y1%4 == 0, то присваиваем y1, если нет, то (y1/4+1)*4 (не понял зачем (y1/4+1)*4  )
y2 = gets.chomp.to_i
y2 = (y2%4 == 0) ? y2 : y2/4*4   # также не понял зачем y2/4*4
y1.step(y2, 4) { |y| puts y if (y%100!=0 || y%400==0) }   # понял только, что мы выводим все переменныу y если y%100!=0 или y%400==0

PM   Вверх
source777
Дата 9.12.2009, 13:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1878
Регистрация: 12.3.2007

Репутация: 6
Всего: 56



Цитата(Zann @  8.12.2009,  22:01 Найти цитируемый пост)
не понял зачем (y1/4+1)*4

Год больший чем y1 и делящийся нацело на 4. Именно он является первым кандидатом в високосные, если y1 не делится нацело на 4.
Т.е. данная строчка округляет до 4 значение y1 в большую сторону.

Цитата(Zann @  8.12.2009,  22:01 Найти цитируемый пост)
также не понял зачем y2/4*4

Год меньший чем y2 и делящийся нацело на 4. Именно он является последним кандидатом в високосные, если y2 не делится нацело на 4.
Т.е. данная строчка округляет до 4 значение y2 в меньшую сторону.

Цитата(Zann @  8.12.2009,  22:01 Найти цитируемый пост)
понял только, что мы выводим все переменныу y если y%100!=0 или y%400==0

Ну собственно так и есть, осталось только добавить, что y принимает значения от y1 до y2 с шагом 4.


Это сообщение отредактировал(а) source777 - 9.12.2009, 14:00


--------------------
Если бы программистам платили за то, чтобы убирать код из программы вместо того, чтобы добавлять его, программы были бы намного лучше © Николас Негропонте
PM MAIL   Вверх
KiRiller2
Дата 11.6.2010, 10:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 22.1.2010

Репутация: нет
Всего: нет



тоже застрял на этой задачке, только мне показалось проще применить произвольный массив. Правда что дальше делать с массивом не знаю, свойства есть но не срабатывает.
 У меня это выглядит так:


puts 'input begin' # вводим начальный год
first = gets.chomp

puts 'input end'  #вводим конечный год
last = gets.chomp

years = Array(first .. last)  # задаем массив из введенных выше годов

years.each {|x|  x/4 } # каждый произвольный элемент массива делим на 4

*** не работает, дальше не могу сделать ветвление ***

puts ' -calculating- '  # просто строка для красивости внешнего вида

puts years # выводит високосные годы
PM MAIL   Вверх
KiRiller2
Дата 11.6.2010, 11:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 22.1.2010

Репутация: нет
Всего: нет



помозговал, вот еще вариант

puts 'input begin' # вводим начальный год
first = gets.chomp

puts 'input end'  #вводим конечный год
last = gets.chomp


years = Array(first .. last)  

puts ' -calculating- ' 
 
if years.each {|x| x%4 ==0 and  x%400 != 0}
 puts years

 else 
  puts '--'

end
PM MAIL   Вверх
source777
Дата 11.6.2010, 23:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1878
Регистрация: 12.3.2007

Репутация: 6
Всего: 56



Цитата(KiRiller2 @  11.6.2010,  10:25 Найти цитируемый пост)
только мне показалось проще применить произвольный массив.

Когда кажется, креститься надо...
Создавать массив, чтобы просто перебрать в цикле числовой диапазон, - это ни в какие ворота не лезет. 
А создавать массив, который заведомо как минимум на 75% состоит из совершенно ненужных значений, - это вообще полный аут.

P.S. Задачи даются для развития алгоритмического мышления, а не для того чтобы решать их первым попавшимся способом.
Решение должно быть в первую очередь красивым, тогда оно будет и простым и эффективным одновременно. 
Представь, что ты решаешь эту задачу вручную, тогда твой алгоритм будет выглядеть так: нарезать кучу бумажек, на каждой написать год, а потом перебирать все эти бумажки по одной. Однако более правильным будет экономить бумагу (оперативную память) и перебирать числа соответствующие годам(в компьютере это эквивалентно изменению значения регистра процессора), а не реальные объекты (типа Fixnum), на которых эти числа написаны.


--------------------
Если бы программистам платили за то, чтобы убирать код из программы вместо того, чтобы добавлять его, программы были бы намного лучше © Николас Негропонте
PM MAIL   Вверх
bilbobagginz
Дата 12.6.2010, 08:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Naughtius Maximus
****


Профиль
Группа: Экс. модератор
Сообщений: 8813
Регистрация: 2.3.2004
Где: Israel

Репутация: нет
Всего: 317



Цитата(source777 @  11.6.2010,  22:53 Найти цитируемый пост)
Решение должно быть в первую очередь красивым, тогда оно будет и простым и эффективным одновременно. 

khm... наверное, в первую очередь оно должно быть правильным ;-]



--------------------
Я ещё не демон. Я только учусь.
PM WWW   Вверх
source777
Дата 12.6.2010, 21:05 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1878
Регистрация: 12.3.2007

Репутация: 6
Всего: 56



Цитата(bilbobagginz @  12.6.2010,  08:54 Найти цитируемый пост)
khm... наверное, в первую очередь оно должно быть правильным ;-]

Правильные решения существуют только для примитивных задач, подобных рассматриваемой в данном топике. Причём даже для таких примитивных случаев критерии правильности довольно размыты, т.к. сама постановка задачи, как правило, содержит ошибки (к примеру в условии рассматриваемой задачи не сказано явно, что указанный алгоритм расчета високосности действует с 1582 года и может измениться в будущем, т.е. любое решение данной задачи, которое реализует описанный критерий и позволяет при этом вводить года менее 1582 и более 2010 является формально неправильным).
Что уж говорить о не учебных задачах, для которых правильное решение - это недостижимая абстракция, если бы было возможно иначе, то багов в программах вообще не было, а профессии "тестировщик" и "QA-инженер" отсутствовали бы за ненадобностью, однако суровая реальность такова, что правильное решение недостижимо за конечный интервал времени для 99.99% практических задач.
Так что на практике решение может удовлетворять только критерию корректности (согласованность программных элементов с заданной спецификацией), т.е. проходить формальное тестирование. Некорректное решение, строго говоря, не является законченным решением.


--------------------
Если бы программистам платили за то, чтобы убирать код из программы вместо того, чтобы добавлять его, программы были бы намного лучше © Николас Негропонте
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Ruby: Общие вопросы"
source777
  • С чего начать? начинаем
  • Ссылки на полезные ресурсы смотрим тут
  • Обязательно следуйте правилам Vingrad.
  • Пожалуйста, прочитайте рекомендации по работе в форуме и навигации по Vingrad.
  • Для вставки кодов Ruby используйте тег: [code=ruby]код[/code]. Когда в будущем подсветка синтаксиса для Ruby будет реализована, весь исходных код преобразится.
  • Используйтe чекбокс "Транслит" (возле кнопок кодов), если у Вас нет русских шрифтов.
  • Помните, для каждого вопроса должна быть своя тема.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, source777.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Ruby: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1642 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.