Автор Тема: Выход из цикла или смерть Кощея  (Прочитано 94945 раз)

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: Выход из цикла или смерть Кощея
« Ответ #75 : Январь 15, 2013, 02:09:17 pm »
Еще одно подтверждение тезиса про легион.
Вы поймите, что все разработчики языков шизанулись на выходе из цикла.
В таких конструкциях получается, что для продолжения цикла нужна истина в в заголовке цикла и ложь в условия выхода (exit when). Вот это несовпадение логических знаков и портит всю малину.
Но только тем, у кого есть что портить.
Остальным - пох...
Именно это я и хотел показать этим примером :-)

Я прекрасно понимаю почему то что в Аде не является тем, что было там. Впрочем, до конца осознать ценность ИПока я тоже пока не могу. Но различие вижу.
Y = λf.(λx.f (x x)) (λx.f (x x))

Peter Almazov

  • Sr. Member
  • ****
  • Сообщений: 482
    • Просмотр профиля
Re: Выход из цикла или смерть Кощея
« Ответ #76 : Январь 15, 2013, 02:10:11 pm »
Ниче не понял... наоборот  в условии выхода (exit when заяц=null) должна быть истина.. разве нет?
Самого Exit не должно быть. Должно быть ключевое слово продолжения цикла.

DddIzer

  • Гость
Re: Выход из цикла или смерть Кощея
« Ответ #77 : Январь 15, 2013, 02:15:28 pm »
Ниче не понял... наоборот  в условии выхода (exit when заяц=null) должна быть истина.. разве нет?
Самого Exit не должно быть. Должно быть ключевое слово продолжения цикла.
вы считаете что "continue when заяц<>null" более правильно?

Peter Almazov

  • Sr. Member
  • ****
  • Сообщений: 482
    • Просмотр профиля
Re: Выход из цикла или смерть Кощея
« Ответ #78 : Январь 15, 2013, 02:52:48 pm »
Да. Но выглядит безобразно. Мой вариант - andwhile.

DddIzer

  • Гость
Re: Выход из цикла или смерть Кощея
« Ответ #79 : Январь 15, 2013, 03:01:32 pm »
Легион на эту хрень не заставишь даже смотреть...

А есть тупицы, которых не заставишь смотреть ни на что, что не блестит с первого взгляда.
Я предпочитаю искать там, где не ищут другие, потому что "не блестит".
боюсь что дерьмо есть универсальная отправная точка для ваших изысков ибо оно "не блестит" стопудово... как не крути... а насчет "запаха" у вас случайно  предпочтений нет?

DddIzer

  • Гость
Re: Выход из цикла или смерть Кощея
« Ответ #80 : Январь 15, 2013, 03:08:44 pm »
Да. Но выглядит безобразно. Мой вариант - andwhile.
надо подумать.. с одной стороны.. программа всего лишь  отображение на ЯП некоторого алгоритма... с другой стороны.. плодить вариации управляющих инструкций ЯП (для повышении "естественности" такого отображения).. слишком накладно.  кстати.. а что вам не нравится в линейном решении Albobin a?

Valery

  • Full Member
  • ***
  • Сообщений: 101
    • Просмотр профиля
Re: Выход из цикла или смерть Кощея
« Ответ #81 : Январь 15, 2013, 04:47:22 pm »

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

Товарищ забыл тело цикла, i=i+1.
О чем еще тут можно говорить?

А ведь Илья далеко не самый глупый в этом легионе.
Не согласен про бред.
Хорошая схема.
Если бы она еще формально была получена, то товарищ бы в принципе не смог забыть про i := i +1.
А то, что забыл - это в пост "Мои типичные ошибки". 

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: Выход из цикла или смерть Кощея
« Ответ #82 : Январь 15, 2013, 04:59:37 pm »
Чет я пропустил, что нужен еще вариант поиска комплекта без иглы.
-- ищем первый комплект без иглы
i = 0
box_count = #box_array
max_level = #func_array
j = max_level
while i < box_count and j == max_level do
    i = i + 1
    j = 0
    last = box_array[i]
    repeat
        j = j + 1
        current_func = func_array[j]
        last = current_func(last)
        result_array[j] = last
    until j == max_level or not last
end

if j < max_level then
    print(i)
    print(box_array[i], unpack(result_array))
end

ps http://repl.it/HAD

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: Выход из цикла или смерть Кощея
« Ответ #83 : Январь 15, 2013, 05:19:16 pm »
i := 0;

WHILE
  (i < LEN(сундуки)) &
  (
    ~ЗАЯЦ(сундуки[i], заяц) OR
    ~УТКА(заяц, утка)       OR
    ~ЯЙЦО(утка, яйцо)
  )
DO
  INC(i);
END;
+1
Имхо самый ходовой вариант. Я бы делал именно так (и обычно делаю так).
И похожая тема уже была кстати на оберкоре:
http://forum.oberoncore.ru/viewtopic.php?f=27&t=3175

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: Выход из цикла или смерть Кощея
« Ответ #84 : Январь 15, 2013, 05:49:44 pm »
ps http://repl.it/HAD
Если в браузере русские символы кракозябрами, то нужно принудительно выставить кодировку страницы UTF-8

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: Выход из цикла или смерть Кощея
« Ответ #85 : Январь 15, 2013, 05:59:20 pm »
И похожая тема уже была кстати на оберкоре:
http://forum.oberoncore.ru/viewtopic.php?f=27&t=3175
Да-да. И даже был мой пост в моем блоге: http://valexey.blogspot.ru/2011/01/and-then-in-c.html
Y = λf.(λx.f (x x)) (λx.f (x x))

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: Выход из цикла или смерть Кощея
« Ответ #86 : Январь 15, 2013, 06:04:21 pm »
...
Если бы она еще формально была получена, то товарищ бы в принципе не смог забыть про i := i +1.
А то, что забыл - это в пост "Мои типичные ошибки".
Не нужно для подобных задач просто while использовать. См. адский пример. То есть везде где это возможно следует использовать спец. формы циклов вроде foreach. Узкая специализация позволяет избавиться от многих ошибок.
Y = λf.(λx.f (x x)) (λx.f (x x))

DddIzer

  • Гость
Re: Выход из цикла или смерть Кощея
« Ответ #87 : Январь 15, 2013, 06:04:35 pm »
i := 0;

WHILE
  (i < LEN(сундуки)) &
  (
    ~ЗАЯЦ(сундуки[i], заяц) OR
    ~УТКА(заяц, утка)       OR
    ~ЯЙЦО(утка, яйцо)
  )
DO
  INC(i);
END;
+1
Имхо самый ходовой вариант. Я бы делал именно так (и обычно делаю так).
И похожая тема уже была кстати на оберкоре:
http://forum.oberoncore.ru/viewtopic.php?f=27&t=3175
да не пойдет же это , причем по ЧЕТКО сформулированному ИСХОДНОМУ условию... зайцевость, уткость. нужно сохранять... а не просто удостоверять на отсутствие...

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: Выход из цикла или смерть Кощея
« Ответ #88 : Январь 15, 2013, 06:06:58 pm »
Тык сохраняется же  ???

Тут:
ЗАЯЦ(сундуки, заяц)
заяц - OUT параметр...

ddn

  • Jr. Member
  • **
  • Сообщений: 59
    • Просмотр профиля
Re: Выход из цикла или смерть Кощея
« Ответ #89 : Январь 15, 2013, 06:07:37 pm »
Использование функций без побочных эффектов для извлечения различных элементов (сундуков, зайцев, уток, яиц, игл, смертей Кощея) друг из друга невозможно, так как структурные значения не могут быть результатами функций. Если выводить ссылку на значение, то это уже изменяет значение динамической переменной (побочный эффект).
Как например здесь:
i := 0;
WHILE (i < LEN(сундуки)) & ((ЗАЯЦ(сундуки[i]) = NIL) OR (УТКА(ЗАЯЦ(сундуки[i])) = NIL) OR (ЯЙЦО(УТКА(ЗАЯЦ(сундуки[i]))) = NIL)) DO INC(i) END
....
(* приск первого сундука с иглой *)
  WHILE list.HasMoreElements() AND смерть = NIL DO
    сундук := list.GetNext();
    IF  сундук.UnpackTo( заяц ) AND
        заяц  .UnpackTo( утка ) AND
        утка  .UnpackTo( яйцо ) AND
        яйцо  .UnpackTo( игла ) AND
        игла  .UnpackTo( смерть ) THEN
      Log.String("капец Кащею");
    END;
  END;
PROCEDURE Store (obj: ANYPTR; VAR ptr: ANYPTR): BOOLEAN;
BEGIN
ptr := obj;
RETURN obj # NIL
END Store;

i := 0;
WHILE (i < сундуки.length) &
~( Store(ЗАЯЦ(сундуки[i]), заяц)) & Store(УТКА(заяц(Заяц)), утка)) &
Store(ЯЙЦО(утка(Утка)), яйцо)) & Store(ИГЛА(яйцо(Яйцо)), игла)) )
DO
INC(i)
END
Впрочем само условие задачи (автор) требует, чтобы сохранялись промежуточные значения элементов. Так что без побочных эффектов не обойтись, если пользоваться одним выражением проверки.

Если представлять значения элементов самими указателями (как у меня), то их разыменованные значения (хранящие структуру вложенности элементов) станут изменяемыми во внешних модулях, то есть интерфейс модуля "сундуков Кощея" будет недостаточно изолирован. К тому же ссылочные структуры засоряют память.

Использование собственно процедур для извлечения различных элементов друг из друга, не позволит выполнять проверку в одном выражении. Придеться использовать вложенные операторы или же последовательные операторы с лишними проверками: (это собственно к вопросу о циклах)
existSearchDeath := FALSE; (* смерть Кощея пока не найдена *)
WHILE
  (i < ds.n) (* проверка, что непросмотренные сундуки еще остались *)
& ~existSearchDeath (* проверка, что смерть Кощея еще не найдена *)
DO
ds.сhests^[i].Hare(hare); (* извлечение зайца из сундука *)
IF hare # nullHare THEN (* проверка, что в сундуке есть заяц *)
hare.Duck(duck); (* извлечение утки из зайца *)
IF duck # nullDuck THEN (* проверка, что в зайце есть утка *)
duck.Egg(egg); (* извлечение яйца из утки *)
IF egg # nullEgg THEN (* проверка, что в утке есть яйцо *)
egg.Needle(needle); (* извлечение иглы из яйца *)
IF needle # nullNeedle THEN (* проверка, что в яйце есть игла *)
needle.Death(death); (* извлечение смерти Кощея из иглы *)
existSearchDeath := death # nullDeath; (* смерть Кощея найдена, если игла не пустая *)
END
END
END
END;
INC(i) (* переход к следующему (еще непросмотренному) сундуку, если такой есть *)
END
или
existSearchDeath := FALSE; (* смерть Кощея пока не найдена *)
WHILE
  (i < ds.n) (* проверка, что непросмотренные сундуки еще остались *)
& ~existSearchDeath (* проверка, что смерть Кощея еще не найдена *)
DO
ds.сhests^[i].Hare(hare); (* извлечение зайца из сундука *)
b := hare # nullHare; (* заяц найден, если сундук не пустой *)
IF b THEN (* проверка, что в сундуке есть заяц *)
hare.Duck(duck); (* извлечение утки из зайца *)
b := duck # nullDuck; (* утка найдена, если зайц не пустой *)
END;
IF b THEN (* проверка, что в зайце есть утка *)
duck.Egg(egg); (* извлечение яйца из утки *)
b := egg # nullEgg; (* яйцо найдено, если утка не пустая *)
END;
IF b THEN (* проверка, что в утке есть яйцо *)
egg.Needle(needle); (* извлечение иглы из яйца *)
b := needle # nullNeedle; (* игла найдена, если яйцо не пустое *)
END;
IF b THEN (* проверка, что в яйце есть игла *)
needle.Death(death); (* извлечение смерти Кощея из иглы *)
existSearchDeath := death # nullDeath; (* смерть Кощея найдена, если игла не пустая *)
END;
INC(i) (* переход к следующему (еще непросмотренному) сундуку, если такой есть *)
END