Копи та грабіжники: перероблена первинність (нитка розбійників)


9

Це нитка розбійників. Поліцейські нитки тут .

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

Відповіді:


6

Brainfuck , Джо Кінг

>>>>>+>,[>++++++[-<-------->]<+>,]<[-[█<█<]++++++++++<]>[-]>>██[>█>>█>]+[<]<<[<]>█<<+>>[>]█>[>]█+[<]<<[<]>-█>]>>[->]<[-[[<]<]++++++++++<]>[-]>[<█]>]>[>]<[[█]<]<<<<<[<]<<██>>[>]<█[->+<]<█>>[>]<[-[[<]<]++++++++++<]>███>[<<]>[[[>]>████[<]<[-[[<]<]++++++++++<]>[-]>[█<]>]>[>]<[[-]>+[>]<-<[<]<]+<<<<<[<]>[[>]+[[>]>]>[>]>[-<+>]<[<]<[>+[<]>>-<<<<<[[<]<]>>███████>[[█]>]<]<[[<]<]<[█]>]>>>[[>]<->>]]>[[>]>]<<[[[█]<]<]<<<[█]<<█>>>[>]█[-[[<]<]++++++++++<]>>[[>]+[------->++<]>.+.+++++.[---->+<]>+++.>>]>[>]+[------->++<]>++.++.---------.++++.--------.
>>>>>+>,[>++++++[-<-------->]<+>,]<[-[[<]<]++++++++++<]>[-]>>[[[>]>>[>]+[<]<<[<]>[<<+>>[>]>>[>]<+[<]<<[<]>-]>]>>[->]<[-[[<]<]++++++++++<]>[-]>[<<]>]>[>]<[[-]<]<<<<<[<]<<[>>>[>]<[[->+<]<]>>[>]<[-[[<]<]++++++++++<]>[-]>[<<]>[[[>]>[>]+[<]<[-[[<]<]++++++++++<]>[-]>[<<]>]>[>]<[[-]>+[>]<-<[<]<]+<<<<<[<]>[[>]+[[>]>]>[>]>[-<+>]<[<]<[>+[<]>>-<<<<<[[<]<]>>[[-]+>]>[[>]>]<]<[[<]<]<[<]>]>>>[[>]<->>]]>[[>]>]<<[[[-]<]<]<<<[<]<<]>>>[>]<[-[[<]<]++++++++++<]>>[[>]+[------->++<]>.+.+++++.[---->+<]>+++.>>]>[>]+[------->++<]>++.++.---------.++++.--------.

Спробуйте в Інтернеті!

Це реалізує сито Ератостена.

Початкові >>>>>+>,[>++++++[-<-------->]<+>,]вводять кожну цифру як символьний код і віднімають 47, щоб поставити її в діапазон 1-10. Це дозволяє значенню клітинки 0 позначати проміжки між числами. +>Ближче до початку розділу сил число , щоб бути принаймні дві цифри, які будуть важливі в найближчим часом .

Далі, і одне з перших речей, які я з’ясував, - це розділ <[-[[<]<]++++++++++<]>[-]>. Це з'являється в коді кілька разів, кожен з різними шаблонами редагування, але не важко було здогадатися, що всі ці екземпляри були, мабуть, однаковими. Цей код вимагає трьох нулів зліва від десяткового числа на стрічці, і його дія полягає у зменшенні числа. Остання ітерація циклу поставить значення 10 двох осередків, що залишилися від числа, але [-]очищає його.

Якщо десяткове число було 0, стороннє 10 не створюється, а осередок, обведений нулем, [-]є найбільш значущою цифрою. Тоді головка стрічки знаходиться на другій за значимістю цифрі (саме тому потрібно принаймні дві цифри). Більшість екземплярів цього фрагмента одразу слідує за цим [<<]>, який розміщує голову на ненульовій комірці в нормальних умовах та нульовій комірці, якщо початкове десяткове число було нульовим. Здається, що в цій програмі десяткове представлення n-1використовується для позначення n, так що декрементація до 0ловиться замість декрементації до -1.

Наступна частина відкладає на стрічку числа від n-1 (n) до 0 (1):

>[                      until the number reaches zero:
  [                     for each digit:
    [>]>>[>]+[<]<<[<]>  create a placeholder for the next copy
    [                   while the original value of the digit is nonzero:
      <<+               add 1 to copy two cells left (to keep one copy)
      >>[>]>>[>]<+      go to new copy and increment that cell
      [<]<<[<]>-        go back to original digit and decrement
    ]                   (this is effectively the same as [<+>>+<-] but with the cells at variable locations)
  >]                    next digit
  >>[->]                cancel the placeholder 1s that were used for the new copy
  <[-[[<]<]++++++++++<]>[-]>[<<]> decrement
]
>[>]<[[-]<]      clean up the trash 10s on the tape while ending at a known location relative to the last number

Тепер ці цифри знаходяться на стрічці з двома нульовими осередками, що розділяють їх. <<<<<[<]<<ставить нас у кінцеву клітинку передостаннього числа на стрічці, саме там ми будемо знаходитись у кожній ітерації циклу. Цикл закінчується, коли обробляються всі числа, крім оригіналу.

На початку циклу переміщуємо поточне число (останнє все ще знаходиться на стрічці) одну клітинку праворуч, щоб мати місце для декременту, а потім продовжуємо та зменшуємо:

[>>>[>]<[[->+<]<]>>[>]<[-[[<]<]++++++++++<]>[-]>[<<]>

Якщо цей декремент не перейшов, ми переходимо до перетворення числа в одинарне:

[[[>]>[>]+[<]<[-[[<]<]++++++++++<]>[-]>[<<]>]

Зауважте, що цей фрагмент не закритий [. У результаті решта цього циклу пропускається, якщо число було 0 (що представляє 1). Після переходу в одинарний, ми очищаємо залишки 10, перетягуючи одинарне представлення з нами вліво:

>[>]<[[-]>+[>]<-<[<]<]+

Я не помічав, поки що це писав, але +кінець цього фрагмента відокремлений від одинарного подання одним 0. Він також є частиною унарного подання: послідовність 1011...11буде представляти 0 мод k. Наступне <<<<<[<]>ставить нас на початок числа k+1, починаючи новий цикл.

Внутрішня петля тут "позначає" кожне число на стрічці з 1 на комірці відразу праворуч і використовує одинарне подання як годинник, щоб визначити, які числа кратні k.

[
  [>]+             mark the current decimal number
  [[>]>]           move to end of decimal part of tape
  >[>]             move to 0 in middle of unary "clock"
  >[-<+>]          move the following 1 to the left if possible
  <[<]<            if a 1 was moved this will bring us back to a zero before the start of this "clock";
                   otherwise the looped move command doesn't move us at all and we are at the final 1
  [                if there was no gap (happens every kth iteration):
    >+[<]>>-       reset to original position
    <<<<<[[<]<]>>  go to number that was just marked
    [[-]+>]        replace digits with 0s (cell value 1)
    >[[>]>]<       go back to where we would be without this conditional
  ]
  <[[<]<]<[<]>     return to first unmarked number
]

У [[-]+>]цьому розділі була остання частина, яку я зрозумів. До цього я припускав, що програма просто проводить пробні підрозділи, але я не бачив, де використовується результат.

Ця петля закінчується двома клітинками, що залишилися від лівого далекого числа, і >>>[[>]<->>]]видаляє маркери, розміщені на стрічці, і повертає нас до кінця стрічки знову. Після цього >[[>]>]<<[[[-]<]<]видаляється або одинарний годинник, або, якщо весь цей сегмент був пропущений, залишилося 10 секунд. Петля встановлюється в початковий стан за допомогою <<<[<]<<].

Після цього просто читаємо, чи замінено вхідний номер на 1 в будь-якій точці:

>>>[>]<[-[[<]<]++++++++++<]>>                      do the check
[[>]+[------->++<]>.+.+++++.[---->+<]>+++.>>]      conditionally print "not "
>[>]+[------->++<]>++.++.---------.++++.--------.  unconditionally print "prime"

На щастя, фактичний результат взагалі не редагувався.


"Ніч довга, яка ніколи не знаходить дня". Це все-таки сьогодні вночі? : P
Стюі Гріффін

@StewieGriffin я не зміг це зробити тієї ночі, і тоді це просто прослизнуло мені в голові. Дякуємо за нагадування.
Нітродон

Я не думаю, що я міг би пояснити власний код так само, як ви тут. Дуже приємна робота.
Джо Кінг

5

Мова Вольфрама (Mathematica)

Тріскається ця відповідь .

f[x_]:=(p=ToString@Boole@PrimeQ@x;StringMatchQ[p&@@Infinity,RegularExpression@"(\
\n{}\b+, )?1"])

Спробуйте в Інтернеті!


Прокручування не потрібна для читання коду :)
user202729

Приємно! Сильно відрізняється від наміченого рішення, тому я поки не розкриватиму це.
Павло

@Pavel Що з цим ? Або все ще "принципово те саме"?
користувач202729

Ось підказка: це великий двійковий об'єкт не містить ні BooleНЕ PrimeQ.
Павло

5

Мозок-Флак, МегаТом

(({████){██[████)█>(({}))<>}<>{}███{}((██({}))█████{}]██)({}(<>))<>{(({})){({}[()])<>}{}}{}<>([{}()]{})██[██()██(()█[()]██{}██}{}<>{})
(({})<>){([[]]{})<>(({}))<>}<>{}{}{{}(([]({}))[({}[{}])])({}(<>))<>{(({})){({}[()])<>}{}}{}<>([{}()]{})}([][()])((){[()](<{}>)}{}<>{})

Спробуйте в Інтернеті!

Ця програма виконує пробні поділи з n-2 вниз до 1, потім виводить 1, якщо і лише тоді, коли це припинено фактором 1.


4

8086 DOS COM Джошуа

xxd представлення через кодування та нульові байти та інші страшні речі:

00000000: 31c0 b90a 0031 dbbe 8100 ac3c 0d74 3c3c  1....1.....<.t<<
00000010: 2075 f7ac 3c0d 7410 2c30 7c2f 3c09 7f2b   u..<.t.,0|/<..+
00000020: 93f7 e193 01c3 ebeb 83fb 027c 19c6 0653  ...........|...S
00000030: 0159 b902 0039 d974 1289 d831 d2f7 f109  .Y...9.t...1....
00000040: d274 0341 ebef c606 5301 4eb4 09ba 5301  .t.A....S.N...S.
00000050: cd21 c341 0d0a 24                        .!.A..$

Спочатку розбирали копа вручну, потім збирали за допомогою язму. Деякі байти були пошкоджені використовуваним конертером Джошуа, але я просто ставився до них, як до редактованих байтів. Я на 99,72% впевнений у їх фактичному вмісті. Однак це не повинно зайняти багато часу, якщо я помиляюся. Насолоджуйтесь:

; A COM file is just a 16-bit flat binary
; loaded at 0x100 in some segment by DOS

org 0x100
bits 16

; Unsurprisingly, we start by converting
; the commandline string to a number. During
; the conversion, SI is a pointer to the
; string, CX is the base, and BX holds the
; partial result
parse_input:
; We'll read the input character by character
; into AL, but we need the resulting digit as
; a 16-bit number. Therefore, initialise AX to
; zero.
    xor ax, ax
    mov cx, 10
    xor bx, bx
; When a DOS program is loaded, it's preceded
; in memory by the Program Segment Prefix,
; which holds the commandline arguments at
; offset 0x81, terminated by a carriage return
    mov si, 0x81

.skip_prog_name:
; Load a character and move the pointer
    lodsb
; If we find the terminator here, the program
; was not given any arguments.
    cmp al, 13
    je finish

    cmp al, ' '
    jne .skip_prog_name

.input_loop:
    lodsb
    cmp al, 13
    je got_input

; If the ASCII value of the character is less
; than the one of '0', error out. Adjust the
; value in AL so that it holds the digit
; itself. This exploits the fact that the
; comparison instruction is just a subtraction
; that throws away the actual result.
    sub al, '0'
    jl finish

; If we have a value larger than 9, this
; character wasn't a digit.
    cmp al, 9
    jg finish

; Multiply the intermediate result by 10 and
; add the new digit to it.

    xchg ax, bx
    mul cx
    xchg ax, bx
    add bx, ax
    jmp .input_loop

got_input:
; The loop below would go haywire when given a
; zero or a one, so make them a special case.
    cmp bx, 2
    jl composite

; Patch the output string to say that it's
; prime
    mov byte[outstr], 'Y'

; BX = number being checked
; CX = loop counter, potential divisor of BX
    mov cx, 2

.loop:
; If CX = BX, we looked everywhere and couldn't
; find a divisor, therefore the number is prime
    cmp cx, bx
    je finish

; DIV takes DX:AX as a 32-bit number for the
; dividend. We don't want nor need the extra
; precision, so we set DX to 0.
    mov ax, bx
    xor dx, dx
    div cx

; DX now contains the remainder. To check if
; it's 0, we perform some noop operation, that
; happens to set the flags appropriately. AND
; and OR are commonly used for this purpose.
; Because of what's presumably a bug in the
; encoder used by Joshua, I do not yet know
; which for certain. However, I can make an
; educated guess. All other instances of the
; bug happened with a codepoint below 32.
; Moreover, no other bytes from that range
; occur in the code. Because an AND would be
; encoded as an exclamation mark, while OR -
; - as a tab, I am highly confident that Joshua
; used an OR.
    or dx, dx
    jz composite

; Increment the counter and loop again!
    inc cx
    jmp .loop

composite:
    mov byte[outstr], 'N'

finish:
    mov ah, 9
    mov dx, outstr
    int 0x21
    ret

outstr:
    db 'A', 13, 10, '$'

Єдина відмінність між моїми полягала в тому, bx < 2щоб закінчити, а не складати. FYI-корупція була спричинена тим, що спочатку використовувала X як символ маски та не виправляла все належним чином при переході на █.
Джошуа

@Joshua Спочатку я теж використовував фінішну обробку, але потім я згадав, що потрібна обробка 1 правильно. Про корупцію - ось один із сценаріїв, які я уявляв
NieDzejkob

3

Желе

Тріскається ця відповідь.

25██26█966836897364918299█0█1█65849159233270█02█837903312854349029387313█ị██v
250126,9668368973649182994001,658491592332700020837903312854349029387313ṖịØJv

Спробуйте в Інтернеті!


Пояснення:

Дивлячись на, і vя думаю скласти список номерів, ввести його в якийсь список і оцінити його.

"Тривіальний" спосіб перевірки первинності в Jelly є ÆP, тому (якщо він може зламати подання):

  • Список, який слід індексувати, повинен містити Æта P.
  • Список індексів повинен бути порівняний з модулю 256з [14, 81].

Отже ... список на початку програми відповідає [14, 81, 49]моду 256 ( TIO ) і з'являється останній елемент.


3

sh + coreutils

Тріскається ця відповідь .

eecs c "██████WyAkKHNoIC1jICJg█WNobyBabUZqZEc5eWZIUnlJQ2█2SnlBblhHNG5m██JoYVd3Z0t6SjhkMk1nTFhjSyB8YmFzZTY0IC1kYCIpIC1lcSAxIF0K█b█se6███d`"
exec sh -c "`echo WyAkKHNoIC1jICJgZWNobyBabUZqZEc5eWZIUnlJQ2M2SnlBblhHNG5mSFJoYVd3Z0t6SjhkMk1nTFhjSyB8YmFzZTY0IC1kYCIpIC1lcSAxIF0K|base64 -d`"

Ні Спробуйте в Інтернеті! цього разу через деякі проблеми . Однак ви можете використовувати jdoodle .

Повертається за кодом виходу. 0(успіх) для простих, 1(помилка) для композитного.

Фактична виконана команда є

factor|tr ':' '\n'|tail +2|wc -w

Як тріснути

  1. Подивіться на код, розпізнайте Base64.
  2. Дізнайтеся, як використовувати base64команду.
  3. Знайте, що +це дійсний base64 символ.
  4. Спробуйте розшифрувати .
  5. Поставте обгортку sh -c "`echo ...|base64 -d`"назад до початкової програми .
  6. Створення вкладених base64 з команд .

Правильний метод. "Деякі проблеми", як виявляється, не всі машини знають tail +n. Коли я спробував твою тріщину на машині на роботі, вона скаржилася на це. Ви розкрили правильний код так ... :(
Джошуа

3

Октава , 86 байт, Стюі Гріффін .

@(x)eval([(str2num(cell2mat([cellstr(reshape('0█1███1█0█0█00',████))])')'█')','(x)'])
@(x)eval([(str2num(cell2mat([cellstr(reshape('04141113040800',2,[]))])')+'e')','(x)'])

Спробуйте в Інтернеті!

Це було весело! Я боровся з цим добру пару днів.

Перший ключ визнавав в eval([...,'(x)'])якості конструкції , що створює виклик до isprimeфункції, так як конкатенація intsі charбуде неявно перетворити масив char, так що ...потрібно бути isprimeабо масив , який мав значення ASCII з isprime, [105, 115, 112, 114, 105, 109, 101].

Інша частина - це лише розміщення документації, щоб визначити, що reshapeможе мати один невідомий вимір [], хоча, мабуть, я міг би зробити це reshape(...,2, 7)при тому ж байті.

Використання +'e'(101) замість +'d'(100) було приємним дотиком, який кинув на мене ще кілька хвилин, поки я не помітив, що останні цифри (без уваги) були, 00а не 01з цим було легко.


2

JavaScript

x=>{if(x<4)return(!0);for(y=x>>>Math.log10(p=████;--y-1;(p=x/y%1)████if(██&&(███))break████return(███)}
x=>{if(x<4)return(!0);for(y=x>>>Math.log10(p=2-1);--y-1;(p=x/y%1)){;;if(!p&&(1<2))break;;;}return(!!p)}

Спробуйте в Інтернеті!

Я якось сумніваюся, що це саме те, що ви мали на увазі, але це працює.


2

> <> , Езоляція плодів

:1@v>~~:?1n;█$-1<█?=2:}*{█@:$@:

до

:1@v>~~:?1n;
$-1</?=2:}*{%@:$@:

Спробуйте в Інтернеті!

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


Приємно. Будь-який з ^, v, /або \ для другої заготовки міг би працювати там. Я зараз хочу, щоб я накрив *замість цього /.
Esolanging Fruit

2

Java (OpenJDK 8) , Чарівна урна восьминога

class X{public static void main(String[]args){System.out.println(new String(████████[Integer.parseInt(args[0])]).matches("█████████████")?███);}}
class X{public static void main(String[]args){System.out.println(new String(new char[Integer.parseInt(args[0])]).matches(".?|(..+?)\\1+")?0:1);}}

Спробуйте в Інтернеті!

Код взято з RosettaCode і пояснено на SO .


Не мав уявлення, що це той популярний ха-ха! Давно це було в моїй кишені. Я чесно вкрав його з файлу утиліти, який я мав з того часу, як ... Jeez ... 2014?
Чарівний восьминіг Урна

2

Python 3 , 44 байти, osuka_

p=lambda x,i=2:i>=x or(x%i and p(x,i+1))or 0

Спробуйте в Інтернеті!

Не працює, коли х <2. or 0Може бути замінений >0{2 spaces}або навіть 4 пробілу

Що стосується проблеми x <2, оскільки її i>=xпотрібно поставити на передній частині (інакше буде нескінченна петля), і i>=xповернення відповідає дійсності відразу, коли x <2, тому я думаю, що це не виправити.


Отже, як виявляється, і мій код не працює з x <2. На жаль (Я, мабуть, просто перевірив його з діапазоном (2, ...), тому що я дурний)
osuka_

2

М, ділнан

ÆPø“;;“»VOḣ2S⁵++3Ọ;”Pv

Це, мабуть, не було наміченим рішенням.

Спробуйте в Інтернеті!

Як це працює

ÆP - це вбудований тест первинності.

øстворює новий, ніладієвий ланцюг. Оскільки попереднє повернене значення (результат ÆP) виходить за межі, воно друкує це неявно.

“;;“»оцінює список рядків ["< Aalst" ""]і Vнамагається їх зрівняти. sнамагається розділити свій аргумент на шматки довжиною 0 , що спричиняє збій інтерпретатора M, пригнічуючи подальший вихід.


Не задумане рішення, але приємне. Незабаром буде оновлено повідомлення про розтріскування. Якби я сказав слово "зоопарк", це призвело б до іншого можливого рішення?
dylnan

Гм, це звучить як складна нескінченність.
Денніс


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