Мое циклическое решение - чит для этой головоломки? - PullRequest
1 голос
/ 10 марта 2010

Эта проблема программирования # 85 из страницы вопросов интервью Microsoft . Полное описание проблемы и мое решение опубликованы ниже, но я сначала хотел задать свой вопрос.

Правила гласят, что вы можете выполнять циклы фиксированное количество раз. То есть, если «x» является переменной, вы можете циклически проходить по блоку кода, основываясь на значении «x» во время входа в цикл. Если «x» изменится во время цикла, это не изменит количество циклов. Кроме того, это единственный способ зацикливаться. Например, вы не можете выполнить цикл, пока не будет выполнено какое-либо условие.

В моем решении проблемы у меня есть цикл, который будет установлен для выполнения ноль или более раз. Проблема в том, что в действительности он выполняется только 0 раз или 1 раз, потому что единственным оператором в моем цикле является оператор return. Так что, если мы войдем в цикл, у него будет шанс запустить только один раз. Я использую эту тактику вместо использования блока if-else, потому что логические сравнения и операторы if недопустимы. В правилах прямо не говорится, что вы не можете этого сделать, но мне интересно, считаете ли вы мое решение недействительным. Я не мог придумать другой способ сделать это.

Итак, вот мои вопросы:

  • Как вы думаете, мое решение недействительно?
  • Если это так, вы думаете о другом способе решения проблемы?

Описание проблемы:

85) У вас есть абстрактный компьютер, так что просто забудьте все, что вы знаете о компьютерах, этот делает только то, что я собираюсь вам сказать делает. Вы можете использовать столько переменных, сколько вам нужно, нет отрицательных числа, все числа целые. Вы не знаете размер целые числа, они могут быть бесконечно большими, поэтому вы не можете рассчитывать на усечение в любой точке. Не допускается сравнение, если нет заявления или что-то подобное. Есть только четыре операции, которые вы можно сделать по переменной.

  1. Вы можете установить переменную на 0.
  2. Вы можете установить переменную = другую переменную.
  3. Вы можете увеличивать переменную (только на 1), и это постинкремент.
  4. Вы можете зациклить. Итак, если вы скажете loop (v1) и v1 = 10, ваш цикл будет выполнен 10 раз, но значение в v1 не изменится, поэтому первая строка в цикле может изменить значение v1 без изменения сколько раз вы зациклились

Вам нужно сделать 3 вещи.

  1. Напишите функцию, которая уменьшается на 1.
  2. Напишите функцию, которая вычитает одну переменную из другой.
  3. Напишите функцию, которая делит одну переменную на другую.
  4. Посмотрите, сможете ли вы реализовать все 3, используя не более 4 переменных. Это значит, что вы не делаете вызовы функций сейчас, вы делаете макросы. И в большинство вы можете иметь 4 переменные. Ограничение действительно относится только к делить, другие 2 легко сделать с 4 переменными или меньше. Отдел по другая рука зависит от двух других функций, поэтому, если вычесть требуется 3 переменные, тогда деление имеет только 1 переменную, оставленную без изменений после звонка вычесть. В основном, просто сделайте ваши вызовы функций уменьшать и вычитать, чтобы вы передали свои переменные по ссылке, и вы не может объявить какие-либо новые переменные в функции, все, что вы передаете это получает.

Мое решение psuedocode (loop (x) означает цикл по этому блоку кода x раз):

    // returns number - 1
    int decrement(int number)
    {
        int previous = 0;
        int i = 0;

        loop(number)
        {
            previous = i;
            i++;
        }

        return previous;
    }

    // returns number1 - number2
    int subtract(int number1, int number2)
    {
        loop(number2)
        {
            number1= decrement(number1);
        }

        return number1;
    }


    //returns numerator/denominator
    divide(int numerator, int denominator)
    {
        loop(subtract(numerator+1, denominator))
        {
            return (1 + divide(subtract(numerator, denominator), denominator));
        }

        return 0;
    }

Вот методы C #, которые вы можете создавать и запускать. Я должен был сделать искусственный путь для меня удовлетворить правила зацикливания.

public int decrement(int num)
{
    int previous = 0;
    int LOOP = 0;

    while (LOOP < num)
    {
        previous = LOOP;
        LOOP++;
    }

    return previous;
}

public int subtract(int number1, int number2)
{
    int LOOP = 0;

    while (LOOP < number2)
    {
        number1 = decrement(number1);
        LOOP++;
    }   

    return number1;
}

public int divide(int numerator, int denominator)
{
    int LOOP = 0;

    while (LOOP < subtract(numerator+1, denominator))
    {
        return (1 + divide(subtract(numerator, denominator), denominator));
    }

    return 0;
}

1 Ответ

0 голосов
/ 14 июля 2010

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

 
int x, y, v, z;

//This function leaves x decremented by one and v equal to x
def decrement(x,v):
    v=0;
    loop(x):
        x=v;
        v++;

//this function leaves x decremented by y (x-y) and v equal to x
def subtract(x,y,v):
    loop(y):
        decrement(x,v);

//this function leaves x and z as the result of x divided by y, leaves y as is, and v as 0
//input of v and z dont matter, x should be greater than or equal to y or be 0, y should be greater than 0.
def divide(x,y,v,z):
    z=0;
    loop(x):
        //these loops give us z+1 if x is >0 or leave z alone otherwise
        loop(x):
            z++;
        decrement(x,v);
        loop(x):
            decrement(z,v)
        //restore x
        x++;
        //reduce x by y until, when x is zero z will no longer increment
        subtract(x,y,v);
    //leave x as z so x is the result
    x=z;



...