Статьи

Мужчина, Женщина, Собака: задание из прошлого

Вступление

Эта статья — личное отражение больше, чем какой-то учебник или статья с практическими рекомендациями — которую я в основном написал в прошлом. В нем описаны решения для упражнения, которое было дано студентам экономического факультета, которые посетили факультет информатики. Задача относительно проста, но в то время мы не могли справиться с ней.

мотивация

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

Упражнение

Более десяти лет назад, когда я изучал информатику, мой друг изучал экономику в Германии. Ему было поручено написать простую программу для простой задачи, характерной для уроков физики, где мужчина и женщина находятся далеко друг от друга и движутся друг к другу, а их собака движется к ним и от них. Основная задача состояла в том, чтобы подсчитать, сколько раз собака двигалась к мужчине и женщине, прежде чем они встретились. Программа должна была быть написана на C, который мы не знали хорошо и который был одной из причин неудачи.

программирование

Прошлое

Незнание синтаксиса программирования было основной причиной проблемы, но решение на абстрактном уровне могло быть сделано без него. Для расчетов соотношения скорости, времени и расстояния требовалась физическая формула. Я только догадывался, что это можно сделать, зная время встречи между мужчиной и женщиной как глобальный случай и время встречи между собакой и мужчиной и собакой и женщиной как вторичный случай. Это был первый прогноз проблемы, который использовался в то время. Но, не зная синтаксиса, задача не может быть выполнена, и никакие дальнейшие ответы или детали решения не могут быть решены. Это было действительно неприятно.

Решение

Решения для этой проблемы были сделаны в несколько шагов и были реализованы на Java:

  • Реализация формулы физики
  • Добавление трех разных скоростей
  • Основной процесс — итерация во времени

    • за каждую секунду
    • по расчету времени встречи

Итерация по времени для каждой секунды

package name.stojanok.dzone.manwomandog;

public class ManWomanDog1 {
   public static void main(String[] args) {
      long startTime = System.currentTimeMillis();

      int initDistance = 1000;

      int manVelocity = 15;
      int womanVelocity = 10;
      int dogVelocity = 30;

      int time = 0;
      int dogTime = 0;
      int dogDistance = initDistance;

      boolean directionToMan = true;

      while (true) {
         double dW = calculateDistance(womanVelocity, time);
         double dM = calculateDistance(manVelocity, time);
         if (dW + dM >= initDistance) {
           System.out.println("man and woman met!");
           break;
         }

          double dD = calculateDistance(dogVelocity, dogTime);
          double dWd = calculateDistance(womanVelocity, dogTime);
          double dMd = calculateDistance(manVelocity, dogTime);

          if (directionToMan && dMd + dD >= dogDistance || !directionToMan
&& dWd + dD >= dogDistance) {
            if (directionToMan && dMd + dD >= dogDistance) {
               System.out.println("met man! woof!");
            } else if (!directionToMan && dWd + dD >= dogDistance) {
               System.out.println("met woman! woof!");
            }
            directionToMan = !directionToMan;
            System.out.println(dD + "m");
            System.out.println(dogTime + "s");
            dogDistance = (int) Math.abs(initDistance - dW - dM);
            dogTime = 0;
         }

         dogTime++;
         time++;
      }
      System.out.println(System.currentTimeMillis() - startTime + "ms");
   }

   private static double calculateDistance(double velocity, double time) {
      return velocity * time;
   }
}

Итерация по времени путем расчета времени встречи

package name.stojanok.dzone.manwomandog;

public class ManWomanDog2 {
   public static void main(String[] args) {
      long startTime = System.currentTimeMillis();

      int initDistance = 1000;

      int manVelocity = 15;
      int womanVelocity = 10;
      int dogVelocity = 30;

      int totalTime = 0;

      boolean directionToMan = true;

      double meetingDtime = 0;

      double innerDistance = initDistance;

      double meetingTtime = calculateTime(initDistance, manVelocity
+ womanVelocity, false);
      while (true) {
         double dogV = dogVelocity;
         if (directionToMan) {
             dogV += manVelocity;
             meetingDtime = calculateTime(innerDistance, dogV, true);
             innerDistance = calculateDistance(dogVelocity, meetingDtime)
- calculateDistance(womanVelocity, meetingDtime);
         } else {
             dogV += womanVelocity;
             meetingDtime = calculateTime(innerDistance, dogV, true);
             innerDistance = calculateDistance(dogVelocity, meetingDtime)
- calculateDistance(manVelocity, meetingDtime);
         }
         totalTime += meetingDtime;
         if (totalTime >= meetingTtime) {
             System.out.println("man and woman met!");
             break;
         } else {
            if (directionToMan) {
               System.out.println("met man! woof!");
            } else {
               System.out.println("met woman! woof!");
            } 
            double dD = calculateDistance(dogVelocity, meetingDtime);
            System.out.println(dD + "mm");
        }
        System.out.println(meetingDtime + "s");
        directionToMan = !directionToMan;
     }
     System.out.println(System.currentTimeMillis() - startTime + "ms");
   }

   private static double calculateDistance(double velocity, double time) {
      return velocity * time;
   }

private static double lostTime = 0;

private static int calculateTime(double distance, double velocity,
boolean useOptimization) {
   double rawResult = distance / velocity;
   if (useOptimization && lostTime != 0) {
      rawResult -= lostTime;
   }
   int returnValue = (int) Math.ceil(rawResult);
   lostTime = useOptimization ? returnValue - rawResult : 0;
   return returnValue;
   }
}

Проблемы

Поскольку я хотел, чтобы выходные данные отладки были такими же, как возможно, необходимо, чтобы вторая программа (путем расчета метода времени встречи) использовала дополнительный параметр разницы во времени в качестве обходного пути для расчета времени. Это общая проблема, если вы хотите создать больше решений (методов расчета) для той же проблемы, когда другое измерение вычисления используется в качестве эталона, или точность каждого результата должна быть очень подробной.

Анализ

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

вдохновение

Еще одним источником вдохновения для меня при написании этой статьи стала песня из новейшего альбома Daft Punk «Random Access Memories», третьего, где итальянский музыкальный продюсер Джованни Джорджио Мородер рассказывает о своих первых днях написания музыки. Слова там звучали довольно ностальгически, что вдохновило меня задуматься и о своем прошлом.

Резюме

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