Мы отобрали для Вас несколько интересных вопросов и алгоритмических задач, задаваемых на собеседованиях в Luxoft.

КДПВ

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

Вопросы


  1. 3 Travellers crossing the river
    Three travellers need to cross a river. Each traveller has certain amount of gold coins kept in his bag.
    Traveller A has 1000 gold coins
    Traveller B has 700 gold coins
    Traveller C has 300 gold coins

    To cross the river there is a boat which can carry a maximum of two objects at a time that means either a maximum of two travellers can cross the river or a traveller with a bag can cross the river. The problem is that in this process of crossing the river if a traveller is left with an amount of coins more than his own then he will run away with that. The same rule applies for two travellers, if they are left with a total of more than their cumulative gold coins then they will run away with that money.
    What strategy will ensure that they all cross the river properly ?
    Перевод
    Трём путешественникам нужно пересечь реку. У каждого из них определенное количество золотых монет в рюкзаке.
    Путешественник А имеет 1000 монет
    Путешественник B имеет 700 монет
    Путешественник C имеет 300 монет

    Для пересечения реки есть лодка, которая может вместить максимум 2 объекта — двух путешественников или путешественника с рюкзаком. Проблема заключается в том, что если оставить любого путешественника с количеством золота, превышающим его собственное — он сбежит, прихватив все деньги. То же касается и двух путешественников, если они останутся с золотом, превышающим их суммарные запасы — они убегут с золотом.
    Какая стратегия позволит всем пересечь реку и остаться при деньгах?

  2. Heavy rock in the boat
    You are in a rowing boat on a lake. A large heavy rock is also in the boat. You heave the rock overboard. It sinks to the bottom of the lake. What happens to the water level in the lake? Does it rise, fall or stay the same?
    Перевод
    Вы находитесь в гребной лодке посреди озера. В лодке также лежит тяжёлый камень. Вы с усилием поднимаете камень и выбрасываете за борт, в результате чего, камень уходит на дно озера. Что произойдёт с уровнем воды в озере? Он поднимется, опустится или останется таким же?


Задачи


  1. Multiple of 3
    Write an efficient method to check if a number is multiple of 3.
    Перевод
    Напишите эффективную программу для проверки, является ли число произведением тройки.

  2. Write a quine
    A quine is a program which prints a copy of its own as the only output. A quine takes no input. You are not allowed to use, open and then print file of the program. Quines are named after the American mathematician and logician Willard Van Orman Quine (1908–2000).
    Перевод
    Напишите куайн — программу, которая печатает на вывод свой исходный код. Куайн не принимает никаких входных данных. Вам не разрешено использовать файл, а потом выводить его содержимое. Куйан назван в честь американского математика и логика Уилларда Ван Ормана Куайна (1908-2000).

  3. Min/Max without branching
    On some rare machines where branching is expensive, the below obvious approach to find minimum can be slow as it uses branching.

    /* The obvious approach to find minimum (involves branching) */
    int min(int x, int y)
    {
      return (x < y) ? x : y
    }
    

    Write a program to find the minimum of two integers without branching.
    Перевод
    На некоторых машинах, где ветвление является дорогим, следующий подход для нахождения минимума будет медленным:

    /* The obvious approach to find minimum (involves branching) */
    int min(int x, int y)
    {
      return (x < y) ? x : y
    }
    

    Напишите программу для нахождения минимума из двух чисел, не используя ветвление.

Ответы будут даны в течение следующей недели — успейте решить. Удачи!

Комментарии (40)


  1. Andy_U
    16.02.2018 21:21

    Вопрос N2:


    Ответ и решение

    Ответ: Уровень воды уменьшится.


    1) Как легко понять, неважно, где камень, в лодке на дне или привязан за веревку и находится полностью в воде. Ну, заменим камень песком или тяжелой жидкостью...


    2) Т.е. если утопить камень (или перерезать веревку) сумма объема воды в озере плюс объем камня не изменится.


    3) Но лодка всплывет.


    4) Значит уровень воды упадет.


    1. Segrio
      17.02.2018 08:13
      +1

      Я бы сказал ваше объяснение для меня не совсем ясное. Я понимаю это так:

      Ход мысли
      — воду вытесняемую человеком и лодкой не трогаем, т.к. эта составляющая неизменна;
      — камень в лодке на плаву, значит вытеснен объем воды по массе равный массе камня;
      — камень на дне, значит вытеснен объем самого камня.
      Из того, что плотность камня больше плотности воды (камень тонет), следует, что при одинаковой массе вода имеет больший объем чем камень.
      Те. V_озера+V_воды_массой_камня > V_озера+V_камня.


      1. Andy_U
        17.02.2018 13:34

        Ну, конечная формула, очевидно, та же самая, что у меня. Только я совсем без формул и упоминания закона Архимеда в объяснении обошелся.

        P.S. У меня может быть не совсем понятен только первый пункт. Ну, могу подробнее. Считаем лодку плоскодонкой. Далее давайте условно расплавим камень, потом, сделаем поверх новое дно лодки а низ отрежем — пусть тонет. Понятно, что мы имеем право считать дно лодки невесомым — неважно, где вес сосредоточен.


  1. yellow79
    16.02.2018 21:46

    Задача 1

    Путешественник А перевозит все деньги на другой берег. Далее перевозит путешественника Б, но на обратном пути забирает свою тысячу. Забирает путешественника C, оставив свою тысячу на изначальном берегу, после возвращается за ними.


    1. Andy_U
      16.02.2018 22:09

      Путешественник А перевозит все деньги на другой берег.

      И сбегает с ними…


      1. yellow79
        16.02.2018 22:11

        с какого перепуга? согласно условий он сбегает если сумма чужих денег выше чем у него, а в данном случае получится сумма равна


        1. Andy_U
          16.02.2018 22:13

          Все деньги, это 1000+700+300? Или таки только свои?


          1. yellow79
            16.02.2018 22:24

            да, все две тысячи постепенно перевезти на другую сторону, согласно условия задачи

            с количеством золота, превышающим его собственное

            он не сбежит, так как количество чужого золота не превышает его собственное


            1. Andy_U
              16.02.2018 22:35

              Про «постепенно»… Я спрашивал про первый ход.


            1. Dimenko
              17.02.2018 10:52

              согласно условиЮ


        1. Andy_U
          16.02.2018 22:28

          Нет. См. условие задачи. Он сбегает, как только он остается наедине с суммой, большей, чем у него было изначально:

          The problem is that in this process of crossing the river if a traveller is left with an amount of coins more than his own then he will run away with that.


  1. ITMatika
    16.02.2018 21:52

    Multiple of 3

    Не совсем понятно условие.
    Если число представлено в десятичной записи, то достаточно проверить сумму его цифр на делимость на 3.


    1. reci Автор
      16.02.2018 22:13

      Да, число вводится в десятичной записи.


      1. Andy_U
        16.02.2018 22:15

        Как строка?


        1. reci Автор
          16.02.2018 22:26

          Думаю, как int


          1. Andy_U
            16.02.2018 22:33

            Тогда оно окажется в системе счисления компьютера, и школьное правило окажется неэффективным, поскольку потребует предварительного перевода N-ричного числа в десятичную систему счисления.


        1. ITMatika
          17.02.2018 07:48

          да, как строка, и тогда можно работать с ооооооооооооооооооочень длинной арифметикой )


  1. Andy_U
    16.02.2018 22:07

    Задача N3:

    Если число десятичное, то школьное правило, если троичное, то ноль в конце, если шестнадцатеричное, то поскольку 16^N mod 3 == 1, то тоже самое школьное правило, для прочих систем счисления тоже можно найти подобные правила (типа как для двоичной — см. google):

    На самом деле последовательность вида M^k mod 3, k=1,2,3… где M — основание системы счисления бывает, вроде бы, всего лишь трех типов:

    0, 0, 0, 0,…
    1, 1, 1, 1…
    1, 2, 1, 2,… (или с двойки начинается).

    Если первый вариант, то систем «троичная» и надо, чтобы был ноль в конце. Если второй — то «школьное» правило, а вот если третий вариант, то тот же способ, что и для двоичной системы — надо, что бы сумма цифр, стоящих на четных местах, минус сумма, стоящих на нечетных, делилась на три.

    A вот если N число задано, например, последовательностью из N единиц, а потом нулем, и неизвестно, на какой системе счисления основан компьютер (или даже просто неизвестно про систему счисления — ну, типа в римских числах), то все становится интереснее.


  1. smer44
    16.02.2018 23:52

    первая задача:
    Обозначение: берег — {лодка} --> берег

    B,C, 1000 — {A,1000} --->> 0
    B,C, 1000 << — {A} — 1000
    A, 1000 — { B,C} --->> 1000
    A, 1000 << — {C, 300} — B, 700
    C, 300 — {A,1000} -->> B, 700
    C, 300 << — {B, 700} — A, 1000
    1000 — {B,C} --->> A, 1000
    1000 << — {A} — B,C, 1000
    0 — {A, 1000} -->> B,C, 1000

    Минимум без условий:
    min = (a + b – (a – b) & 0x7FFFFFFF) / 2

    Задача про деление на три: если разница между суммой четных и нечетных битов делится на три. Сумму считаем примерно как в классическом примере о подсчёте битов.
    Разница может быть только меньше 16 для x32 числа и меньше 32 для x64 числа, поэтому для неё можно сделать лукап- таблицу.
    попозже может мину исходники: дерево решений для первой и код для других задач.


    1. smer44
      17.02.2018 01:03

      #define yMIN(a,b) (b- ((a-b) & 0x7FFFFFFF) +a )>>1
      #define yMAX(a,b) (b+ ((a-b) & 0x7FFFFFFF) +a )>>1
      
      #define SWAP_NO_IF(a,b,type) { type t = (a^b) & -(a > b); a = a^t; b = b^t;}
      
      
      uint32_t lookupDiv3[] = {1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0};
      
      
      int div3(uint32_t x){
      
      	uint32_t evens = (x & 0xAAAAAAAA) >> 1;
      
      	evens = ((evens>>2) & 0x33333333) + (evens & 0x33333333);
      	evens = ((evens>>4)+evens) & 0x0F0F0F0F;
      	evens = ((evens>>8)+evens) & 0x00FF00FF;
      	evens = ((evens>>16)+evens) & 0xFF;
      
      	uint32_t odds = x & 0x55555555;
      	odds = ((odds>>2) & 0x33333333) + (odds & 0x33333333);
      	odds = ((odds>>4)+odds) & 0x0F0F0F0F;
      	odds = ((odds>>8)+odds) & 0x00FF00FF;
      	odds = ((odds>>16)+odds)& 0xFF;
      
      	SWAP_NO_IF(evens, odds, uint32_t);
      
      
      	return lookupDiv3[odds - evens]; //lookupDiv3[odds - evens];
      }


    1. vesper-bot
      17.02.2018 07:28

      В этом случае А едет с двумя мешками на первом или на последнем ходу. То есть в лодку не влезет.


  1. Rsa97
    17.02.2018 08:14

    Вопрос 1
    1. Туда: A + 1000, обратно: А
    2. Туда: B + C, обратно B + 700
    3. Туда: A + 1000, обратно C + 300
    4. Туда: B + C, обратно A
    5. Туда: A + 1000


    1. ITMatika
      17.02.2018 09:16

      Multiple of 3 решена неверно )


      1. Rsa97
        17.02.2018 11:55

        Да, пока модерация шла, я уже сам понял.

        Надо заменить return !sum; на
        if ($sum < 0) {
              $sum = -$sum;
          }
          return !$sum || ($sum > 2 && isMultiplyOf3($sum));

        }


        1. ITMatika
          17.02.2018 12:19

          Подумайте ещё )


        1. ITMatika
          17.02.2018 16:17

          Пардон, не разглядел приведение модуля, вот теперь похоже не правду )


  1. IIvana
    18.02.2018 00:55

    Задачка 3

    r = (a+b-abs(a-b))/2;
    надеюсь взятие модуля числа и деление на 2 сдвигом недороги на неуказанной абстрактной платформе, где будет исполняться кот


    1. smer44
      18.02.2018 05:35
      +1

      в предполагаемой платтформе, взятие модуля числа будет либо операцией с условием либо каким то числовым трюком как в моём ответе


      1. IIvana
        18.02.2018 05:43

        зависит от представления отрицательных чисел — в обратном, дополнительном до 1 или дополнительном до 2 коде. где-то достаточно просто занулить знаковый бит по И по маске, где-то просто прибавить максимальное число разрядной сетки умноженное на знаковый бит, сдвинутый вправо на ту же величину разрядной сетки — получается мы прибавляем макс_сигнед_инт умноженный на 1 если число отрицательное и на 0 если положительное — и получаем модуль числа.


        но это уже детали реализации. стравлю 200 денег, что составители задачи хотели увидеть именно такое решение, как написано выше


        1. 71rmn
          18.02.2018 16:55
          +1

          а как же через сигн и массив
          можно еще разложить входные данные в массив, потом взять sign от разницы чисел и использовать его для адресации по массиву.
          примерно так:
          int[3] a={y,y,x};
          int i=sign(x-y);
          return a[i+1];


          1. IIvana
            18.02.2018 17:24

            Отлично. Сигн по знаковому биту, выделенному маской и сдвинутому в 0 позицию даже проще чем модуль.


  1. IIvana
    18.02.2018 05:42

    del


  1. IIvana
    18.02.2018 06:09
    +2

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


    1. ViViVi
      18.02.2018 15:39

      Варианты когда плотность камня меньше плотности воды или воздуха рассматривать лень


      Камень плотность которого меньше воздуха — взлетит), камень плотность которого меньше воды — всплывет)). За условием задачи камень упал на дно — значит его плотность больше плотности воды.


      1. IIvana
        18.02.2018 17:22

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


        1. andyudol
          19.02.2018 08:13

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


  1. IIvana
    18.02.2018 06:11

    Квайн:
    1
    проверяется в любом РЕПЛе


    я не думаю, что составители задачи будут в восторге от такого ответа, но квайнопись сильно зависит от языка — а он не был озвучен. Или это интервью в ту компанию, где кроме С языков не знают? ))


    1. qw1
      18.02.2018 09:07

      Для интерпретируемых языков самый простой квайн — пустой файл.


  1. andyudol
    18.02.2018 14:53

    #! /bin/more
    Дальше что угодно.


  1. Nick_mentat
    19.02.2018 14:01
    +1

    переправа
    Назовём пустников 1,2,3, у 1 — 300 у 3 — 1000.
    -2 уезжает со своими 700 и оставляет там, возвращаясь
    -3 берёт 300 и отвозит на тот берег, возвращается (ведь у него и своих столько же)
    -отбывают 1 и 2, кто-то из них возвращается со своим, чтобы его место на том берегу занял 3 (со своим)
    -отбывает второй со своим, теперь оба переезжают без мешков, все три путника на другом берегу
    -3 плывёт назад за 700 и возвращается
    -1 плывёт назад за 300 и возвращается