Повторно используйте ваш код!


23

В этой задаче мы пытаемся решить две важные проблемы одновременно. Они есть:

  1. Учитывая целые числа a и b , скажите, является ли a b -1 простым числом.
  2. Даны целые числа a и b , вернуть nCr (a, b).

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

счет

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

правила

  1. Вы должны написать две программы на одном языке, которые решают задачи, описанные выше. Вы можете использовать любые методы ввода / вывода, которые вы хотите. Для задачи 1 вы можете вернуть истинное / ложное значение или выбрать два значения, которые означают true и false, и вернуть их соответственно. Например. Вы можете выбрать, что "prime"означает истину, а "not prime"значит ложь.
  2. Используемые вами алгоритмы должны работать для всех возможных входов, но это нормально, если код не подходит для больших чисел из-за ограничений используемого типа чисел. Вы можете предположить, что ввод действителен.
  3. Никакое подмножество программы не должно решить проблему, т.е. код не должен работать, если какие-либо символы удалены. Например, следующий код недействителен, поскольку можно удалить неиспользуемый блок else, не нарушая программу:

    if (1) { /* change to 0 to get the second program*/
        ...
    } else {
        ...
    }
    
  4. Стандартные лазейки не допускаются.

Контрольные примеры

а б -1 простое число?

a b
1 1 false
2 3 true
5 2 false
2 5 true
4 3 false
2 7 true

Ncr

a b nCr(a,b)
1 1 1
5 2 10
4 3 4
10 7 120
12 5 792

1
Это может быть удобно для вычисления расстояния Левенштейна
Луис Мендо

3
Идея хорошая, но я думаю, что вы все равно получите решения с расстоянием Левенштейна 1, которые смогут так или иначе предотвратить модификации неиспользуемых деталей, а затем эффективно привести к структуре, которую вы хотите запретить.
Мартин Эндер,

6
@ LuisMendo Проблема в том, что многие из этих решений действительно медленные. Вы можете использовать этот скрипт Mathics вместо этого.
Мартин Эндер,

3
Я думаю, что лучшей метрикой было бы расстояние Левенштейна, деленное на общую длину двух программ.
Грег Мартин

1
@GregMartin Не приведет ли это к боулингу кода? Можно искусственно увеличить программы и при этом утверждать, что в них нет ненужного кода.
fergusq

Ответы:


7

MATLAB, расстояние 10

простоты:

function x=f(a,b);x=isprime(a^b-1);

Ncr:

function x=f(a,b);x=nchoosek(a,b);

4
Это то, что я искал!
Kritixi Lithos

7

PHP, расстояние 29

a^b-1 выводит 0 для истины и любое целочисленное значение> 0 для ложных

[,$a,$b]=$argv;for($c=-$i=1;$i<=$d=$a**$b-1;$d%++$i?:$c++);echo$c;

nCr(a,b)

[,$a,$b]=$argv;for($c=$i=1;$i<=$a;$c*=$i**(1-($i<=$a-$b)-($i<=$b)),$i++);echo$c;

PHP, расстояние 36

a^b-1 печатает 1 для истинного ничего для ложного

[,$a,$b]=$argv;for($c=-1,$i=1;$i<=$d=-1+$a**$b;)$d%++$i?:$c++;echo$c<1;

nCr(a,b)

[,$a,$b]=$argv;for($c=$d=$i=1;$i<=$a;$c*=$i++)$d*=$i**(($i<=$a-$b)+($i<=$b));echo$c/$d;

7

Рубин, расстояние 1, комбинированная длина 194

Первичная проверка:

->a,b{s='[(a**b-1).prime?,(1..b).inject(1){|m,i|(a+1-i)/i*m}][0]';require'math'<<s.size*2;eval s}

Попробуйте онлайн!

Ncr:

->a,b{s='[(a**b-1).prime?,(1..b).inject(1){|m,i|(a+1-i)/i*m}][1]';require'math'<<s.size*2;eval s}

Попробуйте онлайн!

Как и предсказывалось в комментариях, некоторые рывки всегда должны идти вразрез с духом проблемы. Хотя было весело найти способ обойти это! Вот как это работает: у нас есть два отдельных решения проблем. Мы запускаем оба, помещаем их в массив, а затем либо выбираем 0-й элемент или 1-й для расстояния редактирования 1. Обычно это будет недопустимым, поскольку вы можете просто удалить все, кроме требуемого вычисления, и оно все равно будет работать , Однако каждый фрагмент кода написан так, чтобы полагаться на загрузку одной и той же стандартной библиотеки 'mathn':

  • Первый использует свой встроенный prime?
  • Второе полагается на mathnизменение того, как работает деление - перед загрузкой оно 3/4оценивается 0, а затем оно вычисляется до дроби (3/4). Поскольку промежуточный результат (a+1-i)/iне всегда является целым числом, общий результат неверен без библиотеки.

Теперь нам нужно сделать так, чтобы загрузка библиотеки зависела от остальной части кода, которая не была изменена. Мы делаем это, генерируя имя mathn, используя длину символа остальной части основного кода: объединенное вычисление имеет длину 55, которая удвоена до 110 - это значение ASCII для n. Таким образом, объединение этого в строку «математика» дает желаемую библиотеку.

В качестве бонуса, введение библиотечных зависимостей также заставляет код выполняться в разумные сроки. В частности, наивный подход к nCr не даст частичных промежуточных результатов.



4

С накоплением , расстояние 13

[([@.!]$/{%y!x y-!*})fork!]
[^#-:([]1/$%{!n 1-!})fork!=]

Попробуйте онлайн! Первое вычисляет nCr, второе простое значение, используя теорему Вильсона.

(f g h) fork!извлекает Nаргументы из стека (вызывает их a0 ... aN) и применяет a0 ... aN f a0 ... aN h g.

Для первой программы:

[([@.!]$/{%y!x y-!*})fork!]
[(                  )fork!]  apply the fork of:
  [@.!]                      equiv. { x y : x ! } => `x!`
       $/                    divided by
         {%        }         two-arg function
           y!                y!
             x y-                 (x - y)!
                 *              *

И для второго:

[^#-:([]1/$%{!n 1-!})fork!=]  
[^                         ]  exponentiate  (a^b)
  #-                          decrement     (a^b-1)
    :                         duplicate     (a^b-1 a^b-1)
     (              )fork!    apply the fork to:
      []1/                    1-arg identity function
          $%                  modulus by
            {!     }          1-arg with `n`:
              n 1-             (n-1)
                  !                 !
                          =   check for equality


3

Mathematica, расстояние 10

Задание 1: PrimeQ[#2^#-1]&

Задача 2: Binomial[#2,#]&

Обе функции принимают входные данные в порядке b,a.


3

Javascript ES7, расстояние 14

Спасибо @Conor O'Brien за сокращение расстояния на 7

простоты:

f=x=>y=>{t=x**y-1;s=1;for(i=2;i<t;i++){if(!t%i)s=i-i}return s}

Возвращает 1, если простое число возвращает 0, если не простое число.

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

Ncr:

f=x=>y=>{t=x+1;s=1;for(i=1;i<t;i++){if(y<i)s*=i/(i-y)}return s}

Умножает 1 на каждое число от y + 1 до x и делит на каждое число от 1 до xy (x! / Y!) / (Xy)!


Изменение второй программы f=x=>y=>{t=x+1;s=1;for(i=1;i<t;i++){if(y<i)s*=i/(i-y)}return s}дает расстояние редактирования 14. Попробуйте онлайн!
Конор О'Брайен




1

PHP, расстояние 14

Написание программы с двумя функциями и вызов только одной из них приведет к расстоянию 1, но это будет слишком неубедительно.

Prime Test, 100 байт:

[,$a,$b]=$argv;function f($n){for($i=$n;--$i>0&&$n%$i;);return$i==1;}echo f($a**$b*-1)*(1|f($a-$b));

nCr, 98 байт:

[,$a,$b]=$argv;function f($n){for($i=$n;--$i>0&&$n*=$i;);return$n*=1;}echo f($a)/(f($b)*f($a-$b));


0

JavaScript, оценка: 1, длина: 144 142 126 117

function(a,b){s="a=Math.pow(a,b)-t;for(b=2;a%b++;);b>a1for(;b;)t=t*a--/b--";t=s.length-56;return eval(s.split(1)[0])}

функция (а, б) {s = "а = Math.pow (а, б) -s.length + 79; для (Ь = 2, A% B ++;); б> a1for (т = s.length-79 ; b;) t = t * a - / b - "; return eval (s.split (1) [1])}

function A(a,b){a=Math.pow(a,b)-(B+0).length+63;for(b=2;a%b++;);return b>a;}
function B(a,b){for(t=(A+0).length-76;b;)t=t*a--/b--;return t;}
F=A

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.