Задача про семью и лодку

Dmelinevskyi

Новичок
Всем доброго времени суток. Я в php новичок. У меня есть вот такая задача:
Наодномберегурекисемья - отец, мать, сынидочь. Семья хочет добраться до другого берега реки. Они нашли рыбака с лодкой, который согласился одолжить им лодку. Семья должна переправиться к другому берегу реки и вернуть лодку назад рыбаку. В лодку могут поместиться один взрослый человек или двое детей.

Решите эту задачу с помощью php5, использовать ООП, каждый объект должен быть экземпляром класса. Программа должна прочитать конфигурацию из ini файла. В нём возможно изменить число взрослых и / или детей на любое другое. Программа должна записать файл журнала с результатами своей работы, где каждый может проверить, как люди пересекли реку и сколько итераций прошло.
Вот её решение:
Первыми переправляются дети.
Сын возвращается к маме-папе.
Папа едет на берег к дочери, потом дочь едет за братом и возвращается с ним к папе.
Сын едет к маме, отдает ей лодку, чтобы она переплыла к папе и дочери.
После того, как мама переправилась, дочь садится в лодку и едет к брату, подбирает его, и вместе они едут к родителям.
Дочь остается с родителями, а сын едет к рыбаку, отдает ему лодку.
Рыбак едет к родителям и высаживается.
Дочь садится и едет за братом, привозит его с собой обратно (наконец-то вся семья снова вместе), они отдают лодку рыбаку.
Лодка пересекла реку 13 раз.
Вот алгоритм:
1) Нужно создать два класса, 1 для взрослых, другой для детей, читаем из файла сколько взрослых, даем им объект первого класса, читаем сколько детей, им объект второго класса.

2)Объявляем флаги, где пишем где находится каждый из них, а потом создать функцию, ей передаем массив тех, кого перемещаем и сторону, куда перемещаем (допустим 0 - это изначальная сторона, а 1 - нужна сторона реки)

3)Далее в функции проходимся циклом и меняем флаги перемещенных на номер стороны реки и логируем это все дело в файл, меняя флаги на 1, например (когда все люди будут иметь флаг 1, то задача решена)

Сделал только первый пункт:
PHP:
class GrownUp{
        public $numOfGrownUp;
        public function __construct($nogu) {
            $this->numOfGrownUp = $nogu; 
        }
        public function view() {
            echo "<p>Количество взрослых: ".$this->numOfGrownUp."<br>";
        }
    }
PHP:
class Children{
        public $numOfChildren;
        public function __construct($noc) {
            $this->numOfChildren = $noc; 
        }
        public function view() {
            echo "<p>Количество детей: ".$this->numOfChildren."<br>";
        }
    }
PHP:
$journal = fopen('journal.txt', 'w');
    $journal = fopen('journal.txt', 'a');
    $parse = parse_ini_file("php.ini");
    $Children = $parse['Children'];
    $GrownUp = $parse['GrownUp'];
    function __autoload($name){
        include "$name.class.php";
    }
    $c = new Children($Children);
    $c->view();
    $g = new GrownUp($GrownUp);
    $g->view();
    if($c<1){
        echo "Недостаточно людей для выполнения алгоритма";
    }else{
       
    }
Подскажите пожалуйста, как делать дальшье. Не могу разобраться из-за нехватки опыта.
 

AnrDaemon

Продвинутый новичок
Неверно. С самого начала. Вернитесь к чтению книжки про ООП, наследование и инкапсуляцию.
 

Вурдалак

Продвинутый новичок
Мне кажется или в задаче упущено условие типа «нельзя оставлять рыбака и дочь наедине»? Иначе смысл какой смысл мотаться обратно? :D
 

Вурдалак

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

Dmelinevskyi

Новичок
Это принципиально для программирования. Если нет понимания требований, то код не пишут. Должны быть четкие условия, которые можно перевести на язык программирования. Т.е. почему сын во втором пункте отправился обратно? В одной лодке с рыбаком? Получается, что требуется свойство, обозначающее пол: оставлять наедине с рыбаком нельзя ни дочь, ни жену? Но сына можно? Тебе не кажется, что не ответив на эти вопросы, программу составить попросту невозможно?
Ответы на все вопросы эти есть, я же в первом посте написал решение задачи. Понимание у меня тоже есть, но мне не хватает опыта, что бы это реализовать, поэтому я зашел на форум и спросил, надеясь на то, что мне кто-то подскажет.
 

Фанат

oncle terrible
Команда форума
Вурдалак, не тупи, это другая задача. Во втором пункте нет рыбака.
Здесь мотаются потому, что ребенок обеспечивает оборачиваемость лодки.
 
Последнее редактирование:

Фанат

oncle terrible
Команда форума
А по задаче - мне она активно не нравится.
ООП здесь притянуто за уши.
Нафига делать класс с единственным свойством?
Почему классов два, а не три - рыбак не человек что ли?
Почему в класс взрослый передается число? Что это за взрослый такой? Он что - шизофреник?
 

AnrDaemon

Продвинутый новичок
А по задаче - мне она активно не нравится.
ООП здесь притянуто за уши.
Нафига делать класс с единственным свойством?
Почему классов два, а не три - рыбак не человек что ли?
Почему в класс взрослый передается число? Что это за взрослый такой? Он что - шизофреник?
Почему три а не пять? Река, берег, лодка, человек, ребёнок, взрослый, член семьи, рыбак.
В общем, если стоит условие решить задачу с применением объектов, то решать надо с начала, а не с конца. А сначала надо выучить ООП, чего автор не сделал. И хочет, чтобы мы за него лабораторки писали.
 

Фанат

oncle terrible
Команда форума
Почему три а не пять? Река, берег, лодка, человек, ребёнок, взрослый, член семьи, рыбак.
В общем, если стоит условие решить задачу с применением объектов, то решать надо с начала, а не с конца. А сначала надо выучить ООП, чего автор не сделал. И хочет, чтобы мы за него лабораторки писали.
Автор следует указаниям методички. В которой про лодку ничего не сказано.
То, что автор не выучил ООП - проблема, но не только его. ПХП - отвратительный язык для изучения ООП, плюс уродская задача, плюс наверняка такое же преподавание.
Кстати, как следствие, и решение от него требуется не ООП-бейсед, а следующее говнометодичке.
 

ksnk

прохожий
imho, если решать задачи "на php", то их нужно решать тупо простым перебором. С отсечениями циклических и тупиковых веточек, для скорости и заради експириенса.
Один класс - "берег" в 2-х экземплярах, "правый" и "левый". С правого ссылка на левый и наоборот. Каждый со свойствами "количество взрослых, количество детей, лодка на этом берегу." Это если классы уж обязательно нужно прикрутить хоть куда-нибудь... Там хоть можно метод определить - "отправить", "проверить" и т.д.
В каждом шаге моделирования есть 5 вариантов действий - понять, что на нужном берегу остался один взрослый с лодкой (финиш), увидеть, что ситуация уже повторялась (3-х значнное число лодка-дети-взрослые и будет сигнатурой )- возврат назад,переправить взрослого на другой берег, переправить 2-х детей, переправить 1 ребенка.
Может получится забавно, если нужно поизучать перебор в теории игр... Для изучения ООП, конечно, не годится....
 

флоппик

promotor fidei
Команда форума
Партнер клуба
Потому что сначала надо предметную область определить, чтоб хоть какое-то ООП построить.
 

Вурдалак

Продвинутый новичок
Я считаю, вы не правы по поводу задачи. Напротив, это бы показало как вы умеете моделировать. Такого скилла очень не хватает среди разработчиков, порой уделяется слишком много внимания инфраструктуре (=== инструментам), не утруждая себя такими вещами, как выделение «чистой» модели, без всякого инфраструктурного говна. Нейминг, выделение наиболее подходящих понятий из предметной области — это очень важные скиллы, если человек обладает таковыми, то с ним приятнее работать. Проще находить проблемы/противоречия в бизнес-логике, проще понимать эти бизнес-требования, модифицировать их и т.д.

В этой лабе прежде всего стоит еще раз вернуться к самой задаче: обобщить её решение вплоть до создания блок-схемы на уровне N детей и M взрослых (по-моему, рыбак в данной задаче ничем от других взрослых не отличается), найти ограничения (например, минимум нужно 2 ребенка, если я правильно понял), а потом уже заняться моделированием.

Мне вспомнилась задача с одного из CTF, где нужно было что-то похожее (по части получения списка действий): имея несколько кувшинов разных объемов, получить определенное количество галлонов воды, чтобы открылась дверь, используя фиксированный набор команд а-ля «взять кувшин», «наполнить», «перелить» и т.д. Если не принимать во внимание, что это был CTF, то на ООП такое решение на порядок доступнее и гибче. Никаких переборов, нужен был алгоритм со минимальным количеством шагов. Если такое сделать в виде лабы, то, мне кажется, в этом что-то есть.
 

Dmelinevskyi

Новичок
Я считаю, вы не правы по поводу задачи. Напротив, это бы показало как вы умеете моделировать. Такого скилла очень не хватает среди разработчиков, порой уделяется слишком много внимания инфраструктуре (=== инструментам), не утруждая себя такими вещами, как выделение «чистой» модели, без всякого инфраструктурного говна. Нейминг, выделение наиболее подходящих понятий из предметной области — это очень важные скиллы, если человек обладает таковыми, то с ним приятнее работать. Проще находить проблемы/противоречия в бизнес-логике, проще понимать эти бизнес-требования, модифицировать их и т.д.

В этой лабе прежде всего стоит еще раз вернуться к самой задаче: обобщить её решение вплоть до создания блок-схемы на уровне N детей и M взрослых (по-моему, рыбак в данной задаче ничем от других взрослых не отличается), найти ограничения (например, минимум нужно 2 ребенка, если я правильно понял), а потом уже заняться моделированием.

Мне вспомнилась задача с одного из CTF, где нужно было что-то похожее (по части получения списка действий): имея несколько кувшинов разных объемов, получить определенное количество галлонов воды, чтобы открылась дверь, используя фиксированный набор команд а-ля «взять кувшин», «наполнить», «перелить» и т.д. Если не принимать во внимание, что это был CTF, то на ООП такое решение на порядок доступнее и гибче. Никаких переборов, нужен был алгоритм со минимальным количеством шагов. Если такое сделать в виде лабы, то, мне кажется, в этом что-то есть.
Данную задачу дали мне как тестовое задания, выполнив которое, меня могли бы взять на работу.
Алгоритм задачи у меня есть, решение я тоже смоделировал, но как его реализовать я не разобрался. Решение и моделирование я еще в первом посте написал.
Да, рыбак - это и есть взрослый, по крайней мере я тоже так думаю, единственное отличие, после того как все переправятся на второй берег, он должен переправится обратно. Условие я тоже поставил, о том, что если детей меньше двух, то не будет работать код (опять же таки я это в первом посте писал).
Вся проблема у меня возникла тогда, когда я попробывал сделать массив из детей (Детей двое, а они буду ведь еще и поодиночке плавать), пробовал вот так:
PHP:
public function converse(){
            for($i=$this->numOfChildren; $i>0; $i--){
                $arr[$i] = $i;
                $arr_rev = array_reverse($arr);
                echo "<pre>";
                print_r ($arr_rev);
                echo "</pre>";
            };
        }
Оно выдавало два массива вместо одного.
Если бы я этот пункт правильно реализовал, то мне бы оставалось создать функцию, в которой через цикл прогнать переменные(элементы массива) с одного берега на другой, меняя им флаг, если бы у всех флаг стал 1, то задача была решена.
Именно про то, как это реализовать я спрашивал.
Спасибо за то, что вы мне посоветовали дальше изучать ооп, я этим и займусь. Как говорится поспешишь - людей насмешишь, поэтому отправил работодателю письмо с тем, что у меня имелось и со словами "спасибо за предложенную работу, я буду учиться, а после уже буду пробывать устраиваться еще раз".
 

AnrDaemon

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

WMix

герр M:)ller
Партнер клуба
PHP:
interface Passenger{
   public function move( $side );
   public function isChild( );
}
class Boad{
   //...
   public function validate(){
     $passengers = count($this->passengers);
     if($passengers <= $this->config['max_parents'] || ($passengers <=$this->config['max_children'] && $this->passengersAreChildren() ) ){
       return true;
     }
     return false;
   }
   //...
}
 
Последнее редактирование:

ksnk

прохожий
WMix, Еcли цель решения задачи - устройство на работу, то такое перенасыщение сущьностями может сыграть и отрицательную роль :) Хотя для учебной задачи может и не вредно...
Условие в validate будет довольно криво смотреться, если вместимость лодки станет 2 взрослых или 4 ребенка, для случая - 1 взрослый и пара детей...
Вурдалак, Есть какие то идеи по поводу раскладки объектов? Для толковой учебной задачки потребуется не менее пары разных взаимодействующих классов с не особенно тупыми методами.
 

WMix

герр M:)ller
Партнер клуба
ksnk, буквально написал то что требуется в задаче, отбросив фантазию
В лодку могут поместиться один взрослый человек или двое детей.
В нём возможно изменить число взрослых и / или детей на любое другое.
где ты увидел что требуется
1 взрослый и пара детей...
WMix, overengineering at its best.
где овер?
 
Сверху