Відновлення мутованого вихідного коду


27

У дуже незвичайній аварії, що стосується невеликого зразка радію, китового кита та трьох жувальних ведмедів, частина вихідного коду The Management ™ була вимкнена. Мало що знає бос Управління ™, насправді відповідали поліцейські ©, намагаючись зірвати "злі" плани Управління ™. Тож Robbers® найняли спробу витягнути оригінальний код, бо кому не подобається бути злим часом?

Примітка. Цей виклик був сильно натхненний розшифруванням вихідного коду .

Опис

Це виклик .

  • У поліцейських буде написати програму (мутантний код) , який виконує завдання # 1 (а також написати програму , яка виконує завдання # 2, але тримається в секреті).
  • У розбійників будуть намагатися переламати «мутацію» і змінити вихідний код в код , який виконує завдання # 2.

У цьому виклику завдання №1 полягатиме в тому, щоб вивести nперше просте число , а завдання №2 - вивести nчисло число Фібоначчі (що так чи інакше лихо, на думку Cops © у будь-якому випадку). Послідовність Фібоначчі визначається як ( n=11; n=21; n=32; ... ...), а прості числа визначаються як ( n=12; n=23; n=3→ → 5; ... ...).

Мета поліцейських - мінімізувати різницю між програмами, які виконують завдання №1 та завдання №2, водночас не дозволяючи грабіжникам відтворити код, який виконує завдання №2.

Правила копа

Копи напишуть дві програми (одну, яка виконує завдання №1, та одну, яка виконує завдання №2), та оприлюднить таку інформацію:

  • Перша програма (який виводить nе просте число)
  • Редагувати відстань Левенштейна між першою програмою і другий програми
  • Мова програмування, на якій написані обидві програми (повинна бути однаковою для обох програм)

Наступні обмеження стосуються обох програм:

  • Вони повинні бути довжиною 128 символів або менше.
  • Вони повинні використовувати тільки ASCII для друку (плюс нові рядки, які також дозволені).
  • Їм потрібно зайняти менше 10 секунд для запуску n=45, і від них не потрібно виробляти правильний вихід для жодного n>45.
  • Вони не повинні використовувати будь-які хеширующие чи криптографічні функції.

Правила грабіжника

Грабіжник спробує змінити програму поліцейського (яка виконує завдання №1) на програму, яка виконує завдання №2 (не обов'язково оригінальну програму, написану поліцейським) на відстань редагування, вказану поліцейським.

Пошкоджене подання вже не може бути зламане (лише перший грабіжник, який зламає подання, отримує кредит).

Після злому подання виконайте такі дії:

  • Опублікуйте відповідь на супровідне запитання (посилання) на це завдання , вказавши мову, ваше рішення та посилання на оригінальну відповідь.
  • Залиште коментар з текстом "Зламаний", який посилається на вашу опубліковану відповідь.
  • Відредагуйте відповідь поліцейського, якщо у вас є права редагування (якщо ви цього не зробите, або зачекайте, поки хтось із необхідними привілеями зробить це за вас, або запропонуйте редагувати).

Оцінка балів

Якщо програма поліцейського залишається нерозробленою протягом 1 тижня, поліцейський може розмістити оригінальний код, який виконує завдання №2 (на вказаному відстані редагування), і подання з цього моменту вважається "безпечним". Безпечне подання, що має найменшу відстань редагування, виграє. У разі вирівнювання виграє найкоротша програма (оригінал, що виконує завдання №1). Якщо два подання ще не зв'язані, виграє те, що було розміщено раніше.

Якщо грабіжник успішно зламає подання поліцейського, оцінка грабіжника збільшується на відстань редагування цього повідомлення. Наприклад, грабіжник, який розбиває подання з відстанью редагування 3 і один з відстані 5, заробляє 8 балів. Перемагає грабіжник з найвищим балом. У разі нічиїх перших перемагає грабіжник, який заробив рахунок.

Таблиця лідерів

  1. Рубі, 6 (гістократ)

Невеликий інструмент для обчислення відстані Левенштейна


1
Що таке 1-е число Фібоначчі? 0 або 1? Або це не має значення
kukac67

@ kukac67 Це 1; Я відредагував публікацію.
Дверна ручка

Яким повинен бути вихід програм, у разі переповнення?
es1024

Повинно це бути повноцінною програмою чи це може бути функцією? Що з анонімною функцією?
Тиїло

2
Що вважається "хеширующей або криптографічною функцією"? Чи можу я перетворити базу? Чи можу я взяти великі експоненціалі по модулю великих праймес?
Мартін Ендер

Відповіді:


6

Python 2, відстань = 8 [ тріщини ]

from fractions import*
n=input()
k,=P=[2]
while n>len(P):k+=1;z=reduce(lambda x,y:x*y,P,1);P+=[k]*(gcd(z,k)<2)
print P[-1]

Нарешті потрапив цей під обмеження. Не повинно бути занадто важким, але я думав, що ідея цікава.


Задумане рішення:

from fractions import* n=input() k,=P=[1] while n>len(P):k+=1;z=reduce(lambda x,y:x+y,P[:-1],1);P+=[z]*(gcd(z,k)<2) print P[-1]

Ідея полягала в тому F(n+2) = 1 + (sum over F(k) from k = 1 to n), щоб скористатися цим і тим, що послідовні числа Фібоначчі є першочерговими. 1В аргументі скорочення повинен був забезпечити +1.

Схоже, feersum знайшов іншу лінію атаки!




4

Ruby, відстань 6 [безпечно]

require'prime';p Prime.take(n=gets.to_i)[-1]
#p (((807462154311276410)**n/(5**0.5)).round)

Створення пар формул з короткими відстанями редагування - це цікаво, але, здається, такий підхід може бути більш ефективним / дратівливим. Ви можете точно зрозуміти, що я зробив, але це не означає, що ви можете його змінити.

Рішення:

require'prime';p=Prime.take(n=gets.to_i)[-1] p (((0742154311276/4e10)**n/(5**0.5)).round)

Пояснення:

Код формує Золоте співвідношення до 11 знаків після коми і використовує його для прямого обчислення послідовності Фіббоначі. Це достатньо точності, щоб правильно підібрати необхідну кількість термінів. Ця частина взагалі не була затуманена, якщо ви випадково знаєте формулу. Для того, щоб важче перевернути мої мутації і відновити константу, я застосував восьмеричні позначення (провідні 0) та наукові позначення (4e10). Поділ на 4e10, а не на 1e11, виглядає більш схожим на те, що я ділиться чимось, .0щоб змусити поділ поплавця, коли насправді що-небудь у науковій нотації чомусь завжди є "Поплавком у Рубі", навіть коли Bignum, здається, має більше сенсу. Я думав, що я розумний до цього p=матеріалу, але так, як я його написав, ви можете просто видалити його p. Я міг би'p=рішення, використовуючи p&&замість #другого рядка, але я не думав про це.


Не думав намагатися вставити eтуди, коли робиш грубу силу. Дійсно підлий рішення. :)
Векторизований

3

Python 2 - LD = 13 тріщин

n=1;j=input();
while j>0:
    n+=1;j-=1;
    while~-all(n%i for i in range(2,n)):n+=1;
print n

Гарний, простий (сподіваємось, не надто легкий), щоб почати справи :)

Схоже, це було занадто просто;) Я відчуваю себе досить нерозумно, що забув, що ви можете використовувати коментарі: /



3

Хаскелл, відстань = 13

import Data.List
x=id=<<snd(mapAccumL(\m n->(,)=<<(++m)$[n|and[n`mod`m1/=0|m1<-m]])[1+1][3..])
main=print.(!!)(0:2:x)=<<readLn

Це може бути читабельніше, але importз'їли занадто багато байтів, тому мені довелося трохи пограти в нього.


2

Ruby, відстань 14 ( тріщинами )

p [x=2,y=1,*(1..200).map{|i|y==(y*x**(i-1)+x%2).divmod(i)[x-1]?i:1}].-([x-1])[gets.to_i-1]


Гм, ваша послідовність Fibbonaci починається з 0, де правила кажуть починати з 1. В іншому випадку перевіряйте (хоча сильно відрізняється від мого призначеного рішення).
гістократ

Добре, виправлено. Гарне використання btw Fermat's.
Векторизований


2

J, відстань = 4 [безпечно]

f =: 3 :  '{. (p:) (+) / 0 , y - 1x'

Рішення:

f =: 3: '{. 2 (x :) (+%) / 0, y $ 1x '

Спосіб:

Знаменник {. 2(x:)тривалої дроби (+%)1 + 1 / (... (1 + 1 / (1 + 1 / (1 + 1 / (1))))).


1

Python 3, відстань = 14 [ тріщини ]

n = int(input())
P = [2]
k = 2
while n > len(P):
 k += 1
 for x in P:
  if k%x == 0: break
 else: P += [k]
print(k)

У мене було кілька запасних символів, тому я поставив пробіл для ясності :)




1

TI-BASIC , відстань 38

Input N:{2>L1:For(A,3,E99:If min(1=gcd(A,seq(A,A,2,$(A:A>L1(1+dim(L1:End:L1(N

>являє собою STO→ключ і $являє символ квадратного кореня.


4
Деякі з цих символів не здаються для друку ASCII.
feersum

@feersum Спасибі, виправлено. Відстань все ще 38.
Timtech

1

Python 2 - відстань = 12 [ тріщинами ]

Я якось задоволений тим, як це вийшло.

f=lambda p,i:p if p[45:]else f(p+[i]if all(i%q for q in p[1:])else p,-~i)
print f([1,2,3],2)[input()]

Подивимося, скільки часу пройде ... Я припускаю, що все одно буде зламано.

Редагувати: скорочений код невеликий шматочок, не впливає на роботу / відстань.

Задумане рішення

Я намагався не звертатись на коментарі чи зміни в новому рядку.

f=lambda p,i:p if p[45:]else f(p+[p[i]+p[-2]]if all(i|q for q in p[1:])else p,-~i) print f([1,1,1],2)[input()]



Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.