Зробіть свою мову * переважно * непридатною! (Нитка копів)


61

Натхненний цим коментарем ...

Дякую користувачам Step Step Hen , Wheat-Wizard та Dennis за те, що вони допомогли мені затвердити специфікацію цього завдання перед тим, як опублікувати його!

Це нитка копів. Для нитки розбійників перейдіть сюди


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

  • Візьміть числовий вхід і вихід

  • Додайте два числа разом

  • Перевірте, чи певне число є простим чи ні.

Це виклик для , де є два різні завдання з двома різними цілями: поліцейські намагатимуться написати якийсь код, який робить мову переважно непридатною, а грабіжники намагатимуться знайти прихований спосіб вирішення, який дозволяє поліцейським відновити свою мову.

Як поліцейський, ви повинні написати два фрагменти коду:

  1. Такий, який робить вашу мову в основному непридатним, наприклад, видаляючи вбудовані функції для введення / виводу та чисельних операцій. Чим більше функцій ви видалите, тим краще. Цей код НЕ дозволив врізатися або вийти. Потрібно додати код до кінця цього фрагмента, і цей код буде оцінено . І ...

  2. ... фрагмент коду, який приймає в якості двох невід’ємних цілих чисел, додає їх разом і виводить їх суму. Цей фрагмент повинен правильно функціонувати навіть після запуску першого фрагмента. Коли два фрагменти об'єднані разом, вони повинні сформувати повну програму, яка додає два числа, або визначити функцію, яка додає два числа. В ідеалі цей фрагмент повинен покладатися на дуже незрозумілу поведінку, щоб його було складніше знайти.

Ви можете обрати будь-який стандартний метод введення та виводу . Однак ви повинні точно розкрити, який формат (вхід і вихід) ви використовуєте. Грабіжник не може зламати вашу відповідь, якщо вони не використовують той самий формат, що і ви.

Написавши обидва ці фрагменти, ви повинні опублікувати перший як відповідь, не розкриваючи другий. Ваша відповідь повинна містити всю наступну інформацію:

  • Перший фрагмент (явно не другий).

  • Мова (включаючи незначну версію, оскільки більшість публікацій, ймовірно, покладаються на чужі кращі регістри)

  • Формат IO, включаючи, чи це функція, або повна програма. Грабіжники повинні використовувати той самий формат, щоб їх тріщина була дійсною.

  • Будь-які дивні випадкові випадки, необхідні для вашої відповіді. Наприклад, працює лише під Linux або вимагає підключення до Інтернету . Очевидно, це трохи суб'єктивно, але якщо у поліцейського є якийсь крайній край, який запобігає його розлому, а потім виявляє це лише після безпечності, я вважаю це поганим спортивним майстерністю. Потенційний грабіжник повинен мати всю інформацію, необхідну для того, щоб зламати вашу відповідь, перш ніж її зламати .

Вам не потрібно розкривати кількість байтів, поки відповідь не буде надійною.

Ось приклад. Для першого фрагменту ви можете надіслати наступну програму Python 3:

Пітон 3

print=None

Приймає вхід з STDIN і виводить на STDOUT

І тоді, як ваш другий фрагмент, ви можете написати:

import sys
a,b=int(input()),int(input())
sys.stdout.write(a+b)

Це дійсно, тому що він буде приймати два числа як вхідні дані та виводити їх суму, навіть якщо ви об'єднаєте два фрагменти разом, наприклад

print=None
import sys
a,b=int(input()),int(input())
sys.stdout.write(a+b)

Однак розбійникові буде знайти надзвичайно легко знайти рішення. Оскільки це було б дуже легко зламати, ви можете спробувати зафіксувати такий конкретний підхід таким чином:

import sys
sys.stdout=None
print=None

Однак навіть це дуже легке вирішення:

del print
a,b=int(input()),int(input())
print(a+b)

Як поліцейський, ваша мета - зробити прихований шлях максимально незрозумілим, щоб запобігти розбійникам його знайти.

У розбійників будуть дивитися на один з ваших відповідей, і спробувати зламати його. Вони можуть зламати його, написавши будь-який дійсний фрагмент, який міг би працювати як фрагмент 2 (додавання двох чисел разом після того, як мова стає в основному непридатною). Це не повинен бути таким самим фрагментом, як ви спочатку задумали. Якщо грабіжник зламає вашу відповідь, він залишить коментар до вашої відповіді, а потім вам слід відредагувати її, щоб вказати, що вона зламана. Якщо ваша публікація зламана, слід відредагувати свою відповідь, щоб показати рішення (фрагмент 2), яке ви спочатку планували. Це не правило як правило , а доброзичлива пропозиція зберегти гру веселою. Ви не повинні.

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

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

Веселіться!

Роз'яснення правил

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

  • Другий фрагмент повинен бути фактично виконаний, щоб відповідь була дійсною. Це означає, як відповідь

    import sys
    sys.exit()
    

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

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

  • Це повернеться до Будь ласка, розкрийте будь-які дивні випадкові випадки, необхідні для вашої відповіді на роботу ... Ваші подання повинні містити достатню кількість інформації, перш ніж виявити, щоб можна було відтворити після розкриття. Це означає, що якщо ваша відповідь стає безпечною, а потім ви редагуєте: Ось моя відповідь. О так, BTW, це працює лише в тому випадку, якщо ви запускаєте його на Solaris, жарт на вас! Ваша відповідь недійсна і буде видалена і не вважатиметься придатною для виграшу.

  • Другий фрагмент дозволений до збоїв після виведення суми - доки результат все ще правильний (наприклад, якщо ви вирішите вивести на STDERR, а потім отримаєте купу інформації про збій, це недійсно).

  • Ви не можете редагувати свій код після надсилання відповіді.

  • Ви не можете покладатися на криптографічні функції, такі як шифрування, хеш-функції, CSPRNG тощо.

Фрагмент, щоб знайти незавершені матеріали:


3
Що слід зробити для таких мов, як C? З'єднання дозволяє лише один "основний фрагмент", і будь-яка логіка повинна буде туди йти. Наприклад, якщо я маю, int main(){ do_evil_stuff(); }куди повинен піти код користувачів? У функції? Після всіх тверджень в main?
Conor O'Brien

1
Чи можна розмістити другий фрагмент де-небудь у першому фрагменті?
LegionMammal978

1
Я нічого не знаю про кодування, але це завдання виглядає дивовижно,
Прітт Балагопаль,

2
Я відредагував дивовижний фрагмент jimmy23013 . Не соромтеся повернутись, але я все одно використовував це для пошуку поданих матеріалів і вважав, що це може допомогти іншим.
Дом Гастінгс

2
@DomHastings Це надзвичайно корисно! Дуже дякую :)
DJMcMayhem

Відповіді:


2

Gforth 0.7.3 (TIO) , 231 байт [SAFE]

Цей код переосмислює як непотрібні деякі необхідні методи виведення, а також додавання та щось вирішальне для оголошення функцій. Удачі!

: . ;
: dec. ;
: u. ;
: .r ;
: u.r ;
: d. ;
: ud. ;
: d.r ;
: ud.r ;
: emit ;
: type ;
: + postpone 2drop ;
: ; + + + postpone exit reveal postpone [ ;

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

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

Ось шаблон , якщо ваша цільова функція названа f.

Рішення:

79 байт

Я фактично видалив immediateключове слово з кінця переосмислення ;, тому відповідь потрібно було включити на початку. Функція, яку я визначив, здебільшого еквівалентна внутрішньому визначенню ., але вона не друкує пробіл в кінці, а додавання виконується спочатку, переміщуючи числа до стека з плаваючою комою та назад.

immediate : f s>f s>f f+ f>d swap over dabs <<# #s rot sign #> (type) #>> 0 0 ;

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


1
Це дуже приємна відповідь. З такою швидкістю, схоже, це може бути єдиною нерозкритою відповіддю!
DJMcMayhem

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

21

Хаскелл, розбитий Крістіаном Сіверсом

import Prelude(getLine,print)
a=a

Повна програма, зчитування двох цілих чисел (включаючи негативні) від stdin та запис у stdout.

Я щойно відключив прелюдію, тому майже нічого не стосується сфери, а потім додав визначення; подальший імпорт синтаксично недійсний. Я тобі getLineі дав print.


Відредаговано, щоб додати своє оригінальне рішення. Крістіан Крікс був іншим, але він використовує ті самі основні функції (ви можете отримати дивовижну кількість обчислень, здійснюючи доступ до функцій, які мають синтаксичний цукор, навіть коли ви не можете зателефонувати до нічого, що вбудовано, або навіть назвати задіяні типи).

import Prelude(getLine,print)
a=a
(x:l)!0=x
(x:l)!n=l!d[0..n]
d[x,y]=x
d(x:l)=d l
x^y=[x..]!y
x+y=f[0..y](x^y)(-((-x)^(-y)))
f[]x y=y
f _ x y=x
f.g= \x->f(g x)
f&0= \x->x
f&n=f.(f&d[0..n])
x*y=((+x)&y)0
x%[]=x
x%('-':s)= -(x%s)
x%(c:s)=x*10+i c%s
i c=l['1'..c]
l[]=0
l(x:s)=1+l s
main=do
 x<-getLine
 y<-getLine
 print((0%x)+(0%y))

Що, мабуть, не є супер-гольфом у будь-якому випадку, але тут воно є легше:

import Prelude(getLine,print)
a=a

-- List indexing
(x : _) !! 0 = x
(_ : xs) !! n = xs !! (sndLast [0..n])

-- sndLast [0..n] lets us decrement a positive integer
sndLast [x, _] = x
sndLast (_ : xs) = sndLast xs

-- Pseudo-addition: right-operator must be non-negative
x +~ y = [x..] !! y

-- Generalised addition by sign-flipping if y is negative
x + y = switch [0..y] (x +~ y) (-((-x) +~ (-y)))
  where switch [] _ empty = empty   -- [0..y] is null if y is negative
        switch _ nonempty _ = nonempty

f . g = \x -> f (g x)

-- compose a function with itself N times
composeN f 0 = \x -> x
composeN f n = f . (composeN f (sndLast [0..n]))

-- multiplication is chained addition
x * y = composeN (+x) y 0

strToNat acc [] = acc
strToNat acc ('-' : cs) = -(strToNat acc cs)
strToNat acc (c : cs) = strToNat (acc * 10 + charToDigit c) cs

charToDigit c = length ['1'..c]

length [] = 0
length (_ : xs) = 1 + length xs

main = do
  x <- getLine
  y <- getLine
  print (strToNat 0 x + strToNat 0 y)


17

Пітон 2 , тріщинами

Реалізує додавання як названу функцію

import sys
c="".join(open(__file__).read().split('\n')[4:])
if set(c)-set(' &)(,.:[]a`cdfijmonrt~')or"import"in c:sys.setrecursionlimit(1)
f=lambda\

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

Що це робить?

Для того, щоб трохи допомогти вам, я поясню, що це робить. Цей код відкриває вихідний файл і перевіряє, чи відповідає решта коду наступним критеріям:

  • Не містить рядок import
  • Складається виключно з персонажів &)(,.:[]a`cdfijmonrt~

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

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

Щоб заощадити трохи часу, ось короткий список корисних речей, які ви не можете зробити з цим обмеженням

  • + ну так,

  • eval/ execНе збирався дозволити вам піти з цим

  • Числа, вони можуть бути кориснішими, ніж ви думаєте

  • Строкові літерали

  • len

  • =, Не присвоєння змінних

  • >, <, ==. . . Я не залишив вас ніяких порівнянь

  • *, -, /, %, ^, |, >>, << Єдині оператори Доступні ~і&

  • __foo__, Жоден із цих фантазійних методів подвійного підкреслення не дозволений.


1
Ух, це зовсім зло. Приємно!
HyperNeutrino

Фантастична відповідь, щоб
розігнати

Хе-хе, це, можливо, було натхнене тим тупим викликом короля-гірки, про який я намагався розібратися в чаті
Стефан

4
Я думаю, що це дійсна тріщина: codegolf.stackexchange.com/a/133209/68942
HyperNeutrino

ЗНАЙТИ перший фрагмент: This code is not allowed to crash or exit.(див. Чат для обговорення на ньому)
Стівен

12

Пітон 2 , тріщинами

Це четверта ітерація цієї відповіді. Кожен з останніх відповідей був розбитий шляхом скидання глибини рекурсії.

Реалізує додавання як названу функцію

import sys
if set("".join(open(__file__).read().split('\n')[4:]))-set(' &)(,.:[]a`cdfijmonrt~'):sys.setrecursionlimit(1)
for m in sys.modules:sys.modules[m]=None
del sys;f=lambda\

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

Що це робить?

Для того, щоб трохи допомогти вам, я поясню, що це робить. Цей код відкриває вихідний файл і перевіряє, чи решта коду зроблена виключно з символів &)(,.:[]a`cdfijmonrt~

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

Я також відключив усі модулі, тому ви нічого не можете імпортувати.

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

Щоб заощадити трохи часу, ось короткий список корисних речей, які ви не можете зробити з цим обмеженням

  • + ну так,

  • eval/ execНе збирався дозволити вам піти з цим

  • Числа, вони можуть бути кориснішими, ніж ви думаєте

  • Строкові літерали

  • len

  • =, Не присвоєння змінних

  • >, <, ==. . . Я не залишив вас ніяких порівнянь

  • *, -, /, %, ^, |, >>, << Єдині оператори Доступні ~і&

  • __foo__, Жоден із цих фантазійних методів подвійного підкреслення не дозволений.

Моє рішення

Тож тепер, коли xnor зламав це так, що я достатньо задоволений, я збираюся розкрити своє рішення

r,o:(o and f(~(~r&~o)&~(r&o),int(`r`[:r&~r].join([`dict()`[r&~r],`r&~r`,`dict([(r&~r,r&~r)])`[int(`~([]in[[]])`[[]in[[]]:])],`min`[[]in[[]]],`dict()`[~(r&~r)],`r&~r`]).format(r&o),int(`~([]in[[]])`[[]in[[]]:]))))or r

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

Я почав із досить стандартного алгоритму додавання

r,o:(o and f(r^o,r&o<<1))or r

Тоді я використовував побітовий трюк для подання ^з |, &, ~.

r,o:(o and f((r|o)&~(r&o),r&o<<1))or r

Я використовував інший побітний трюк, щоб позбутися цього |

r,o:(o and f(~(~r&~o)&~(r&o),r&o<<1))or r

Тепер все, що залишилося, це <<не повинно бути занадто важко, правда? Добре готуйтеся до вибагливої ​​їзди. Для заміни бітшиффа я використав рядки, щоб додати нуль до кінця його бінарного подання

r,o:(o and f(~(~r&~o)&~(r&o),int(bin(r&o)[2:]+"0",2)))or r

У цього є кілька проблем, але основним є використання доповнення , тому я працював над цим, використовуючи замість цього формат

r,o:(o and f(~(~r&~o)&~(r&o),int("{}0".format(bin(r&o)[2:]),2)))or r

Нам заборонено використовувати bin, тому я використовував форматування рядків для перетворення у бінарний файл.

r,o:(o and f(~(~r&~o)&~(r&o),int("{0:b}0".format(r&o),2)))or r

Оскільки рядкові літерали заборонені, я повинен будувати рядок {0:b}0із деталей, зроблених за допомогою зворотних кліщів, та joinїх разом.

r,o:(o and f(~(~r&~o)&~(r&o),int("".join(["{","0",":","b","}","0"]).format(r&o),2)))or r

Порожня рядок досить проста, можна просто зробити

`r`[:0]

Нулі були

`0`

і {:}всі були схоплені зі словників.

r,o:(o and f(~(~r&~o)&~(r&o),int("".join([`dict()`[0],`0`,`dict([(0,0)])`[2],"b",`dict()`[-1],`0`]).format(r&o),2)))or r

bздається, досить важко дістати, його немає в нашому наборі персонажів, тож як ми повинні отримати об'єкт, який має bсвоє repr? Ну ось як: При використанні reprвбудованої функції ви отримуєте щось подібне

<built-in function name>

І ось звідки ми дістанемо своє b.

r,o:(o and f(~(~r&~o)&~(r&o),int("".join([`dict()`[0],`0`,`dict([(0,0)])`[2],`min`[1],`dict()`[-1],`0`]).format(r&o),2)))or r

Тепер все, що залишилося, - це цифри, мені потрібні лише -1, 0, 1 і 2, ось ось, як я їх представляв:

-1 = ~(r&~r)
 0 = r&~r
 1 = []in[[]]
 2 = `~([]in[[]])`[[]in[[]]:]

2 насправді може бути байт коротше

```r&~r```.find(`r&~r`)

ґрунтуючись на пропозиціях @ Blender в коментарях, але я не думав про це лише після факту.

Тому ми замінюємо ці числа в

r,o:(o and f(~(~r&~o)&~(r&o),int(`r`[:r&~r].join([`dict()`[r&~r],`r&~r`,`dict([(r&~r,r&~r)])`[int(`~([]in[[]])`[[]in[[]]:])],`min`[[]in[[]]],`dict()`[~(r&~r)],`r&~r`]).format(r&o),int(`~([]in[[]])`[[]in[[]]:]))))or r

І ось тріщина.


Здається, цей фрагмент самостійно помилився.
Атако

@ATaco Я вважаю, що це обговорювалося в чаті, і було вирішено, що це нормально.
Пшеничний майстер

У правилах прямо вказано інше. "Цей код заборонено збиватися або виходити."
Атако

@ATaco Ось повідомлення, яке він сказав, що оновить його, коли отримає можливість.
Пшеничний майстер


10

C (gcc) Тріснув!

#define D(f)void f(void);
D(printf)D(fprintf)D(putc)D(puts)D(getchar)D(putc)D(fputc)D(ferror)D(feof)D(read)D(fclose)D(fread)D(wr1te)D(fgets)D(fgetc)D(popem)D(gets)D(read)D(scanf)D(setbuf)D(execl)D(execlp)D(putchar)D(execle)D(execv)D(malloc)D(execvp)D(execvpe)D(exec)D(system)D(close)D(fwrite)D(open)D(free)
int stdin;
int main(){
//your code goes here...hehe
}

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

Вхід з STDIN і вихід на STDOUT.

Це працює без помилок. Ха-ха, це зовсім зло. Я тестував його лише на gcc TIO. Як правило, ви повинні додати свій код після цього фрагмента, щоб він працював :) Коментар є середнім, не слухайте його.

Випробуваний на gcc (GCC) 6.3.1 20161221 (Red Hat 6.3.1-1). Має працювати в будь-якій системі Linux.

Оригінальне рішення

#define D(f)void f(void);
D(printf)D(fprintf)D(putc)D(puts)D(getchar)D(putc)D(fputc)D(ferror)D(feof)D(read)D(fclose)D(fread)D(wr1te)D(fgets)D(fgetc)D(popem)D(gets)D(read)D(scanf)D(setbuf)D(execl)D(execlp)D(putchar)D(execle)D(execv)D(malloc)D(execvp)D(execvpe)D(exec)D(system)D(close)D(fwrite)D(open)D(free)
int stdin;
int main(){
//your code goes here...hehe
}
void __attribute__ ((destructor)) dtor() {
    int a,b,c,d;a=b=c=0;
    struct FILE* z = popen("cat", "r");
#define q(x)for(;(c=getc(z))^32&&c^-1;)x=10*x+c-48;
q(a);q(b);
    char*y=calloc(c=a+b,1);
    for(a=0;c;){y[a++]=(48+(c%10));c=c/10;}
    for(b=0;b<a/2;b++){d=y[b];y[b]=y[a-b-1];y[a-b-1]=d;}
    write(1,y,a);
}

@ LegionMammal978 Ага так
Conor O'Brien

2
Вкажіть свою платформу!
Джошуа

@Joshua Я додав деяку інформацію
Conor O'Brien


Ну, __asm__і у вас є безліч функцій на вибір :) не думайте, що C і C ++ тут ​​хороші вороги.
edmz

9

Хаскелл , розтрісканий Бен

main=main--

Спробуйте в Інтернеті! Це має бути повною програмою, що читає два числа зі stdin та виводить суму в stdout.

Кожна повна програма починається із запуску mainфункції, але тут mainвикликає себе і викликає нескінченний цикл. Що ще гірше, запускається коментар до рядка --безпосередньо за рекурсивним викликом, щоб запобігти його зміні, наприклад, main2а потім визначити це для підведення підсумків.


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

main=main--$()
_ --$ _ = do
     x <- readLn
     y <- readLn
     print $ x+y

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

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



5
ви можете просто додати "де main = ..."
michi7x7

+1 для рішення Haskell, яке працює лише через ледачу оцінку Haskell.
Jules

9

C (GCC в Linux) (зломлений)

Замість використання дурних методів пісочниці для читання файлів, ми робимо це належним чином - із списками SECCOMP!

Ваше завдання: здійснити додавання з введенням із STDIN та виведенням у STDOUT.

#include <stdlib.h>
#include <unistd.h>
#include <sys/prctl.h>
#include <linux/seccomp.h>
#include <syscall.h>
#include <stdio.h>
void sandbox();
__attribute__ ((constructor(0))) int s() {
    close(0);
    close(1);
    close(2);
    prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT);
}
int main() {
    sandbox();
    syscall(SYS_exit, EXIT_SUCCESS);
}
void sandbox() {
    // Your code here!
}

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

WTF це!

Щоб допомогти вам у вашому непереборному завданні, я поясню, що робить цей код.

__attribute__ ((constructor(0)))гарантує, що sфункція виконується першою. Функція закриває всі дескриптори відкритого файлу для STDIN, STDOUT та STDERR. Тоді програма обмежує себе суворим списком SECCOMP, який обмежує ваші системні виклики наступним чином:

read(2)
write(2)
_exit(2)
sigreturn(2)

Тому ви не можете відкрити будь-які нові файли (або взагалі робити що-небудь). Потім ми переходимо до основної та називаємо ваш код, добре заплетений у sandboxфункцію.

syscall(SYS_exit, EXIT_SUCCESS);Зрештою , це просто , щоб забезпечити програму виходить чисто - за замовчуванням GCC буде завершуватися з exit_group(2)якої не дозволено Seccomp білий список. Ця функція виходу викликається після запуску вашого коду.

Отже, у вас немає дескрипторів відкритого файлу, і ви не можете відкрити нічого нового. Неможливо, правда? ;)



8

x86 16-бітний реальний режим складання ( тріщини )

_main:
    call l
    cli
    hlt
l:  pop si
    xor ax, ax
    mov bp, cs
    mov es, ax
    mov di, 12
    mov [di], si
    mov [di + 2], bp
    pushf
    mov bp, sp
    or word [bp], 256
    popf

Легко, якщо ви знаєте хитрість.


1
Як ви приймаєте вклад? На стеку, чи в регістри? (Крім того, схоже, що це повинна бути 16-розрядна збірка, але якщо так, or [bp], 256недійсна. Це має бути or WORD PTR [bp], 256?)
Коді Грей,

1
Також слід вказати, який процесор ви використовуєте; там багато версій і клонів x86, і багато невизначених інструкцій. Якби я написав код для "незрозумілого клона 80186", так просто трапилася невизначена інструкція, яка взяла б кілька аргументів і бла-бла-бла ... Нам також може знадобитися оточення. 16-бітова Windows дала гарантію SS == DS, що, наприклад, інші системи можуть не робити.
Оріон

1
Вам потрібно лише вказати , який процесор , якщо ви на самому справі є використовувати деякий трюк , який працює тільки на одній конкретній моделі (або одного конкретного покоління). Цей код не такий, тому я думаю, що "x86-16" є достатнім. На мою думку, чим загальніше, тим краще. Погодились, що реальний або захищений режим повинен бути вказаний, хоча наявність hltінструкції (дзвінок 0) рівно означає, що це не захищений режим.
Коді Грей

3
@Joshua, якщо вона не працює на кожній платформі, ви, принаймні, мусите вказати платформу, на якій вона буде працювати. Your submission must contain enough information before being revealed to be reproducible after being revealed
Стівен

1
@StepHen: Рішення для скасування мови - це платформа агностик одного разу в реальному режимі x86-16, але введення / виведення не є платформою агностиком. Хто його вирве, може вказати ОС, для якої він вибухнув. Я додав позначку _main пізно, щоб хтось теоретично міг зробити майже агностичний розрив, зв’язавшись з libc.
Джошуа

4

Javascript, тріщинами

Цей виклик є наслідком гранта Девіса , але він фіксує рішення, яке він мав на увазі (що створює iframe та використовує iframe window). Рішення працює в консолі javascript на chrome's about:blank pageі займає два input()s, додає їх разом і console.logs результат. Поставте свій код після:

d=prompt=console=document;new MutationObserver(s=>s.forEach(e=>{t=e.target;t.parentNode.removeChild(t)})).observe(d,{"childList":d, "subtree":d})

По- перше, ми затирати promptі consoleі встановити ярлик d. Потім ми створюємо спостерігач за мутацією із зворотним дзвінком, який видаляє кожну місію, яку вимкнено. Ми встановлюємо цього спостерігача за мутацією спостерігати за документом, повідомляти про childListта subtreeзміни. Замість буквального true, ми використовуємо наш ярлик до значення truthy document( специфікація цього не дозволяє, але хром робить).

Опублікувавши це, я зрозумів набагато більш елегантний клобер. Моє призначене рішення як і раніше працює, але розміщена тріщина не:

 h=document.querySelector("html");h.parentNode.removeChild(h);

Ласкаво просимо на сайт! Мені цікаво подивитися, яке рішення буде :)
DJMcMayhem


4

Perl 5, розтрісканий Ільмарі Каронен

$_=<DATA>;
s/[+'{dPz|K.UD!_ iJ;o}e6tjWb7253k@%&Iq4l0AN:?\$8B`Yywn9^pfmZQTF"M#-]//g;
eval;
print@_,$!,pop,shift,<>,eval"@>",$\,@ARGV,eval"@$",$@,eval"@@",$,,eval"@,",$/
__DATA__

Вхід надходить окремими рядками STDINта виводиться на друк STDOUT.

Весь код йде за __DATA__маркером. Для цього використовується метод, подібний до рішення @ WheatWizard, в тому, що код аналізується, а непридатні символи видаляються.

Це було протестовано на версіях 5.8, 5.10 та 5.16, і не вимагає прапорів командного рядка.

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


2
Не могли б Ви вказати спосіб та формат введення / виводу?
Ільмарі Каронен

Вибачення @IlmariKaronen, це STDINсимволи на окремих рядках та STDOUT. Я додам це до основного корпусу.
Дом Гастінгс


4

Python 3, потрісканий zbw

import sys
for mod in sys.modules.values():mod.__dict__.clear()
1+1

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


Мені дуже цікаво побачити фрагмент, який працює після цього
NickA

Ну, вам доведеться чекати сім днів або на нетривіальну тріщину, що станеться першою ...
pppery


Ну що ж, подібні виклики дуже складно зробити добре
pppery

4

APL (ngn-apl) , розтрісканий ngn

Зроблено у співпраці з моїм колегою Маршаллом .

Введіть аргументи зліва і справа на +. Тобто ваша мета - вставити код після наступного, щоб ваш останній рядок читав ⎕←3+2і виводив 5на STDOUT.

+←-←−←⍴←≢←≡←⊥←⊤←⍟←○←⍳←⌹←~←∈←∊←⍷←<←≤←=←≥←>←≠←,←⍪←⌷←⌽←⍉←⊖←{}⋄⍣←∘

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

Працює, встановивши всі корисні функції, до {}яких береться один або два аргументи та повертає порожній числовий список. Також встановлює просто складати функції.


Тріщина

+←{⌈/⍋⍺⍵1/0}

⍺⍵1/0 повторити 0 лівим аргументом та правим аргументом та 1

 отримати індекси, які б це сортували (оскільки всі елементи дорівнюють нулю, це дає 0 1 2… (a + b)

⌈/ максимальне значення (a + b)


ngn / apl включає можливість виконання довільного JavaScript. Я не вважаю таке рішення дійсним, оскільки тоді мова піде про відключення JavaScript, а не APL. Дійсно є дійсний (хоч і незрозумілий) спосіб скидання, +використовуючи лише чисті APL та без брудних хитрощів.
Адам

3

Пітон 2 , тріщинами

Це друга ітерація відповіді, яку колись зламав @HyperNuetrino методом, якого я не очікував. Зараз я її зафіксував, тому сподіваюся, що єдине рішення, що залишилося, доведеться дотримуватися намічених обмежень.

Реалізує додавання як названу функцію

import sys
c="".join(open(__file__).read().split('\n')[4:])
if set(c)-set(' &)(,.:[]a`cdfijmonrt~')or"import"in c:sys.setrecursionlimit(1)
sys.modules['sys'],sys.modules['os']=None,None;del sys;f=lambda\

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


Я думаю, я міг би це зробити, якби мав u, але я без цього застряг.
isaacg

@isaacg Просто з цікавості, що б ти робив u?
Пшеничний майстер

.count. Я можу отримати рядок доки бажаний вихід, але я не можу прийняти його довжину.
isaacg

__import__('sys').setrecursionlimit(100)... і нічого насправді не зафіксували. Мені не дуже хочеться розміщувати його в розбійницькій нитці, хоча відчуваєш, як обман. Спробуйте в Інтернеті
Value Ink


3

Java 8, потрісканий @ OlivierGrégoire

Ось моя спроба. Насправді, ідея полягає в тому, щоб просто перевантажити всі простори імен, які ви можете використовувати для виведення (і, сподіваюсь, відображаю). Вихід призначений для вивільнення (System.out).

class java {
    public static void main(String[]s){
       //there is no executable code in snippet one.
       //your code here.
    }
    class Class{}
    class Method{}
    class System{}
    class FileDescriptor{}
    class Logger{}
    class Runtime{}
    class Scanner{}
}

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


1
Це не виконуваний клас ...
Олів'є Грегоар

1
@ OlivierGrégoire Вибачте за це, я додав class String{}після тестування, не розуміючи, що це буде вибивати main(String[] ...). Це має працювати зараз
лорд Фаркваад

1
Так, це зроблять, дякую! :) Це не змінить тріщини, яку я збираюся зробити: о
Олів'є Грегоар

1
Тріснув! Мені це дуже сподобалось :)
Олів'є Грегоар

1
Я дивився на щось подібне (вибачте, що важко відформатувати код у коментарях), але я думаю, що ваше рішення набагато int sum = 0; new Exception("" + sum) { public void printStackTrace() { ClassLoader cl = ClassLoader.getSystemClassLoader(); try { printStackTrace(new PrintStream((PrintStream)cl.loadClass("java.lang.System").getDeclaredField("out").get(null))); } catch (Exception e){} } }.printStackTrace();
чіткіше

3

cQuents, потрісканий Mayube

#|1,1:A

Це має бути досить легко, але ви ніколи не знаєте.

"Проблема" полягала в тому, що без Cвашого коду ви отримали помилку.

Рішення Майбе:

#|1,1:A+BC

Кожен елемент у послідовності є першим входом плюс другим разом третім (aka 1)

Мої рішення:

#1,1:A+B,C

Послідовність циклів між першим входом плюс другим входом і третім входом (1). Перший пункт у другому - це A+B.

#1,1:A+B+C-C

Подібно до рішення Майбе - замість того, щоб множити B*C, просто додає Cта віднімає його.

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

Пояснення

#|1,1      Append 1 and 1 to the end of the user's input
     :     Set mode to : (sequence 1: if given n, output nth term in sequence; if given no n, output whole sequence)
      A    Each item in the sequence equals the first input

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


Документи здаються справді незграбними, я не можу за все життя зрозуміти, що це означає, коли він говоритьDefault input is combined with user input to form the total input, which must align with the expected input (which is based on the highest input requested by the Sequence Definition)
Skidsdev

@Майбе, це дивно, мені потрібно знайти спосіб сказати це правильно. В основному, ваш вхід до програми може бути рівним найбільшому входу, запитуваному змінними A,B,C,D,Eв коді. Наприклад, якщо в будь-якій точці у вас є змінна Dу вашій програмі, аналізатор розраховує, що там буде 4 входи, але якщо є також E, аналізатор розраховує, що там буде 5 входів. Не може бути менше очікуваної суми. Однак завжди є необов'язковий останній вхід n, який використовується різними способами в різних режимах.
Стівен

@Mayube фрагмент, який я опублікував вище, містить A, тому він шукає один вхід. Оскільки є два, обидва з #яких вказують вхід за замовчуванням, він використовує перше як Aзначення ', а друге як n.
Стівен

Отже, якби я дав 2 входи, а додав BCби, A - перший вхід, B - другий, C - 1, а n - другий 1?
Skidsdev

@Mayube точно, вибачте за мої шалені документи. TMI: якби початок виглядав #1,1(немає смужки), це було б: A як перший 1, B як другий 1, C як перший вхід, і n як другий вхід. Ви також можете зробити #1|1, де A - перший 1, B - перший ввід, C - другий вхід, а n - другий 1.
Stephen

3

Версія Node.JS 7.3.0 (розтріскана Домом Гастінгсом)

var p=process,f;(_=>{var w=p.stdout.write,n='f'+(Math.random()*1e7|0),l=1
f=p.stdout.write=a=>eval(`(function ${n}(a){while(l&&((typeof a)[0]!='s'||'f'+a!=n));a=l?l="":a;w.apply(p.stdout,arguments);})`)(a)})();

Помістіть другий блок коду після першого.

Відмова від відповідальності: другий блок коду не буде функціонувати самостійно (без розміщення після першого). Якщо це заборонено, проте я можу змінити другий фрагмент.

Це повна програма. Вихід є process.stdout(STDOUT), введення - process.argv(аргументи командного рядка)

Це мої перші копи та грабіжники, сподіваюся, це хороший виклик :)

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


Виклик пояснено

Створює випадкову змінну nвід 0 до 1e7. Якщо ви зателефонували на запис із правильним записом n, він не надрукує нічого, але встановить l0, що "розблокує" функцію запису, що дозволяє надрукувати що-небудь. Якщо ви спробуєте зателефонувати до запису за допомогою рядка, він надсилає вас у нескінченний цикл. Якщо ви намагаєтеся зателефонувати на запис із будь-яким іншим, ніж правильним, nпоки запис "заблокований", він надсилає вас у нескінченний цикл, щоб запобігти здогадуванню.

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

Пробирається повз typeof, який, здавалося б, перевіряє рядки лише за допомогою Symbol, який також починається з s. Це призводить до помилки у функції, що є результатом виклику eval, оскільки ви не можете додати рядок "f" до символу. Ми вловлюємо помилку і використовуємо регулярний вираз для відновлення nзі сліду стека, де він знаходиться в імені функції. Потім ми намагаємося записати, nщо нічого не друкує, але встановлює змінну "lock" lна 0, щоб "розблокувати" функцію запису. Тепер, коли функція запису розблокована, ми просто надрукуємо суму.

try{f(Symbol())}catch(e){f(e.stack.match(/f(\d+)/)[1])
f(+p.argv[2]+ +p.argv[3]+"")}


Це геній ... Спочатку я був на правильному шляху! Дякую за тренування мозку!
Дом Гастінгс

3

RProgN2 , Тріщини на Арнольд Палмер

"+-/*÷^"{²[[\=};

Пише над усіма математичними операторами, не маючи можливості відновити їх. Зокрема, він замінює їх функцією, яка видаляє два верхні пункти у стеку.

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

Оригінальне рішення

{S]‘[L}`d={0RL}`i=«x=y=x{xd`x=yi`y=x}:y»`+=

{S]‘[L}`d={0RL}`i=«x=y=x{xd`x=yi`y=x}:y»`+=
{     }`d=                                  #Define a function, "d", which returns n-1
 S                                          #Convert the input to a stack, which, as a number, makes a stack of 1 - n.
  ]‘                                        #Duplicate the stack, and pop the top value off it.
    [                                       #Discard the popped'd value.
     L                                      #Get the length of the stack, which now is n-1.
          {   }`i=                          #Define a function, "i", which returns n+1
           0R                               #Get the range of numbers between 0 and n.
             L                              #Get the length of that stack, which is n+1
                  «                    »`+= #Define a function, "+", which takes two numbers, and outputs their sum. We use «» here, because it localises references, instead of globalising them.
                   x=                       #Set the first input to the value of "x", which by default, is x.
                     y=                     #Ditto for y.
                       x{          x}:      #While x is truthy, which in this case, is non-zero.
                         xd                 #Get x - 1
                           `x=              #Set x to it.
                              yi`y=         #And set y to y + 1
                                      y     #Push y to the output. And we're done.

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


Я переглядаю вашу документацію і, здається, не можу знайти те, що ²робить символ. Хочете просвітити мене?
Арнольд Палмер

Ця документація не є надзвичайно актуальною для RProgN2, і цей символ приймає наступні два поняття [[в цьому випадку і вкладає їх у функцію @ArnoldPalmer
ATaco


Данг, це набагато краще. Я не знав про операторів стеків, що точно було б корисно. Крім того, знання про «»створення локальних змінних на відміну від псування глобальних було б дуже корисним.
Арнольд Палмер

3

Haskell, 161 144 байт, Тріщини на славка

{-#OPTIONS_GHC -fth -w#-}
module M where

Вхід до STDIN, вихід до STDERR. Додайте до кінця програми.

Редагувати: призначений для компіляції без зайвих аргументів GHC, а лише звичайних ghc --make prog.hs.

Знову відредаговано, щоб зменшити кількість байтів.

Веселіться!


Тож я не можу цього зробити, бо основна функція не буде викликана? main = do x <- readLn :: IO Integer; y <- readLn; print $ x + y
BlackCap

@BlackCap Ні, оскільки GHC очікує, що mainфункція буде в модулі, Mainколи не -main-isвказаний прапор.
zbw

Це не працює, але я хочу все-таки поділитися ідеєю
BlackCap

Я буду називати це тріщинами. Ось моє задумане рішення, гольф вниз. Він не працює в TIO, оскільки обгортка не надсилає введення компілятору.
zbw

Якщо ви опублікуєте своє рішення, я відзначу його тріщинами.
zbw

3

Маскарпоне , поламаний Ільмарі Каронен

[ Make 'i' and 'z' print 'q' ]$
v ['q.]v* 'i<^
v ['q.]v* 'z<^

[ Disable some standard commands ]$
v[]v*   '1<^
v[]v*   '$<^
v[]v*   '@<^
v[]v*   '{<^
v[]v*   '}<^
v[<:]v* '<<^
v[]v*   'v<^$

Введення - церковні цифри на stdio, використовуючи iдля збільшення та zнуля. Наприклад, 2 + 3 буде:

iiziiiz

З

останнім рядком у вихідному рядку повинно бути число на stdout, у тому ж форматі, що і на stdio. Наприклад, якщо відповідь п’ять, слід вивести:

iiiiiz

(у маскарпоне немає поняття числа)


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

: '[/''/'i/'./' /':/',/'>/'!/']/* 'i<^
: '[/':/',/'>/'!/']/* 'z<^
: ,>!
'z.

Це не видно з документації, але, як заявив @IlmariKaronen у своєму тріщині, рядкові літерали в Маскарпоне насправді є синтаксичним цукром для просування послідовності символів.

Я навмисно писав коментарі, [this]$щоб зробити так, щоб я виглядав так, ніби я натискаю на рядок і одразу після цього вискакую. Наївний зломщик, можливо, спробував щось на кшталт [:,>!]/*насунути струну, поміняти її інтерпретатором і інтерпретувати.

Я також претендую на те, що я перекладаю перекладача, якого я залишив у групі $, але $його вже переглянули на НОП. Ви залишаєте цього перекладача на стеку, і вам доведеться носити його з собою через всю програму; через кожен символ кожного рядка.


Тріснув. І ні, я ніколи не чув про Маскарпоне перед цим викликом.
Ільмарі Каронен

@IlmariKaronen Нова улюблена мова? Хороша робота!
BlackCap

2

C # (.NET Ядро) Тріщини від Ілмарі Karonen

Також тріщини на Навина .

namespace System
{
    class Console
    {
        static void Main()
        {
            //Your code goes here
        }
    }
}

Читає два значення зі stdin і записує результат у stdout. Тестується на Windows з Framework версією 3, 4.6 та TIO .

Ось повна програма, яку я задумав.

namespace System
{
    class Console
    {
        static void Main()
        {
            var t = Reflection.Assembly.Load("mscorlib").GetType("System.Console");
            var r = t.GetMethod("ReadLine");
            int a = int.Parse((string)r.Invoke(null, null));
            int b = int.Parse((string)r.Invoke(null, null));
            var w = t.GetMethod("WriteLine", new[] { typeof(int) });
            w.Invoke(null, new object[] { a + b });
        }
    }
}

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



codegolf.stackexchange.com/a/133412/14306 Я припускаю, що це не було наміченим рішенням.
Джошуа

@IlmariKaronen: +1. Це було намічене рішення.
raznagul

@Joshua: +1 для пошуку іншого рішення, ніж я задумав.
raznagul

2

GolfScript , зламаний Деннісом

{}' !$%&()*+,-./<=>?@[\]^`|~'':'*~;

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

Це є виклик, в кінці кінців, так чому б не спробувати GolfScript?

Дійсним рішенням повинен бути фрагмент, який зчитує два цілих числа зі стека, додає їх разом і повертає результат у стеку. Проблема полягає в тому, що вона повинна працювати навіть після того, як наведений вище код переосмислив майже всі вбудовані оператори GolfScript, щоб робити абсолютно нічого. Принаймні, я залишився ;недоторканим, тож ви все ще можете виводити значення зі стека. ;-) Ваш код повинен працювати на стандартному інтерпретаторі GolfScript, як це реалізовано, наприклад, на TIO (див. Посилання вище).


Рішення Денніса , як і моє власне , спирається на рідко використовувану функцію GolfScript, яка дозволяє інтерполювати код Ruby у рядках з подвійним цитуванням. Ми використовуємо цю функцію для визначення нового оператора додавання, який працює точно так само, як і вбудований +оператор, а потім викликаємо його.

(Однією з причин, чому так рідко використовується функція інтерполяції Ruby в GolfScript, є те, що незручно інтерпольований код Ruby виконується під час розбору , а його вихід кешується інтерпретатором GolfScript. Таким чином, якщо у вас є, наприклад, рядок з інтерпольованим кодом Ruby у циклі код запускається лише один раз до запуску фактичної програми, після чого завжди повертає однакове значення для кожної ітерації циклу. Ви можете обійти це, використовуючи рядок eval, щоб відкласти розбір, але це робить уже незручний синтаксис ще більше некрасиво і багатослівно, і в будь-якому випадку для цього виклику я також відключив оператора eval ~, однак виявляється, що визначаючи нові вбудовані оператори GolfScript одна річ, ця функція насправді робить дуже красиво і чисто.)



Тріснув. Нарешті з’ясував, що я роблю не так.
Денніс

@Dennis: Так, цього разу ти це прибив. FWIW, моє передбачуване рішення було "#{var'_','gpush a+b'.cc2}";_, яке працює точно так само, як і ваше, за винятком того, що воно на кілька байт коротше.
Ільмарі Каронен

2

Node.js v8.2.0, розірваний Домом Гастінгсом

let mess = ctx => f => new Proxy (f, {
  has: (t, p) => p in t || p in ctx
, get: (t, p) => {
    let k = p in t? t[p]: ctx[p];

    if (k instanceof Function) return (
      function fetch (_k) {
        return mess (ctx) ( x => ( q => q instanceof Function
                                      ? fetch (q)
                                      : t (q)
                                  ) ( _k(x) )
                          )
      })(k);

    return k;
  }
});

with (mess (global) (x => x)) {
  dot   = f => a => b => f(a(b))
  ap    = f => g => x => f (x) (g (x))
  flip  = f => x => y => f (y) (x)
  Const = a => b => a
  id    = x => x
  num   = n => n (x => x + 1) (0)
  log   = console.log

  let x = flip (Const . id . id)
    , y = flip (Const . id . id . id)
  for (let i = 0; i < process.argv[2]; i++) x = ap (dot) (x)
  for (let i = 0; i < process.argv[3]; i++) y = ap (dot) (y)
  process.argv = [];

  logic = x => y => /* Your code here */;

  log . id . num ( logic (ap (dot) (x))
                         (f => z => (( y(flip (id) . id . flip (dot (id)) (f)) ) (Const (z))) (id) )
                 );
}

Ви повинні реалізувати logicфункцію. Вхід - це аргументи, надані (від stdin), вихід - це те, що повертається вашою функцією (друкується до stdout).


Моя церква коду кодує числа з вхідних даних. Решта коду якраз там, щоб залякати вас.
Функція безлад робить певну хитрість для впровадження точкової нотації ( a . b == dot (a) (b)), яку я в першу чергу використовую для додавання . id .до випадкових місць, яка нічого не робить, але заплутує когось незнайомого з функціональним програмуванням.
Перетворення, застосоване до чисел до того, як я передам їх у logicфункцію, є x+1і y-1, що додає до 0, тож це ще один НОП, який слід додати до незрозумілості.

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

logic = x => y => f => z => x (f) (y (f) (z))


@DomHastings Це не призначене рішення, але я скажу, що ви можете, доки програма припиняється без винятку, і не друкує додаткові символи до виводу
BlackCap

Я щойно опублікував альтернативу! (Ви можете бачити моє попереднє рішення в історії цієї відповіді!)
Дом Гастінгс

О, уау, я був у дорозі ... Все-таки це краще, ніж моя перша дуже хитра спроба! Дякую за головоломку!
Дом Гастінгс

2

Інформуйте 7 , потрісканий мідь

For reading a command: rule fails.

[Your code here.]

Гравець повинен вводити вхід як інтерактивну команду, наприклад, add 17 to 25або sum 17 25. Ви можете вибрати точну форму команди, яку слід ввести, якщо вона містить два числа. Суму чисел (наприклад 42) слід надрукувати у відповідь на команду.

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

Я протестував своє рішення в GNOME Inform 7 IDE, версія 6L38 , на Ubuntu Linux. Задумане рішення працює як на задній частині Glulx, так і на Z-машині, а також має працювати і на інших останніх версіях Inform 7. Зауважте, що (без відповідного обходу) наведений вище код призведе до того, що інтерпретатор замикається в циклі, коли він намагається прочитати команду; Здається, інтерпретатор Z-машини стає абсолютно невідповідним, коли це відбувається, і його не можна зупинити зсередини IDE, тому я рекомендую використовувати Glulx для тестування.


тріснув , і якщо вам було цікаво, я ніколи не чув про це до цього виклику
pppery

2

CPython 3 (знову), потрісканий Сізіфом

import sys,os,functools
def p(f,e,a,_=os._exit):
 if e == "c_call":_(1)
sys.setprofile(p)

Ви можете робити все, що завгодно - доки це не буде реалізовано в C. Це означає, що ні print, ні input- всі вони потраплять у _(1)лінію та закінчуються. Вхід з STDIN з числами на двох окремих лініях, вихід на STDOUT. Цікаво, як довго це триватиме ... Займав мене досить довго, щоб знайти другий робочий фрагмент після того, як придумав цей відключний трюк. Явно вказуючи Cpython, щоб уникнути розлому на основі не якоїсь альтернативної реалізації sys.setprofile.


Тріснув. Я дуже мало розумію, чому це працює.
Сизіф

Я думаю, я можу зараз запитати: чому functools?
Денніс

@Dennis Оскільки сиспіф виявив лазівку, а не намічене рішення
pppery

@Sisyphus Ваша тріщина була зареєстрована як помилка в python
pppery

2

Java 8 ( тріщини )

Друга спроба. Цього разу я вклав дві хвилини тестування.

static {

    try {

        System.setIn(null);
        System.setOut(null);
        System.setErr(null);

        for (Method m : System.class.getMethods()) {

            m.setAccessible(false);

        }

        System.class.getMethod("getSecurityManager", new Class[0]).setAccessible(false);

        for (Method m : Class.class.getMethods()) {

            m.setAccessible(false);

        }

        SecurityManager mngr = new SecurityManager() {

            @Override
            public void checkPermission(Permission p) {

                if (p.getName().equals("createSecurityManager")) throw new SecurityException();
                if (p.getActions().startsWith("read")) throw new SecurityException();

            }

        };

        System.setSecurityManager(mngr);

        // Your code goes here.

    } catch (Throwable t) {

    }

}

Більшість речей повинні бути висвітлені.


1
Будь ласка, додайте це до класу з відповідним імпортом? Це виклик, коли ці невеликі зміни можуть внести або порушити запис. Я отримав кілька рішень для цього, як є, але це різко скорочується, якщо ви просто вкладете це в клас / інтерфейс. Також формат для видалення всіх цих рядків був би дуже приємним для нас, читачів.
Олів'є Грегоар

Там зламана відповідь, використовуючи саме ваш код. І +1, бо, здається, я його забув. Вибачте.
Олів'є Грегоар

#SetAccessible (помилкові) дзвінки нічого не роблять.
Невай

1

Пітон 2 тріснув

import sys,hashlib
c=open(__file__).read().split()[-1]
if c!='#'and hashlib.sha256(c).hexdigest()!='e6400dd63733d10ec042e3c28033cfa85e1d25fbef80020810c354d7c942e843':sys.exit() #

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

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


Натхненний відповідями Пшеничного майстра та HyperNeutrino .

Фрагмент зчитує вихідний файл і відмовляється продовжувати, якщо останній фрагмент коду, відокремлений пробілом, не переходить у e6400dd63733d10ec042e3c28033cfa85e1d25fbef80020810c354d7c942e843.

EDIT : Відредаговано трохи у відповідь на цей коментар . Основна проблема не змінюється, будь-яка спроба тріщини не визнається недійсною.


1
ЗНАЙТИ перший фрагмент:This code is not allowed to crash or exit.
Стівен

Це недійсне значення, оскільки воно закривається, що не дозволено для першого фрагмента.
DJMcMayhem


1

Java 8 Тріщини на @ OlivierGrégoire

Я намагався зробити це якомога важче! :) І, на відміну від інших відповідей Java на даний момент, вам доведеться дотримуватися точних правил завдання, розміщуючи його після цього всього фрагмента (так ні, ви не вводите свій код у public static void main(String[] args)метод, ви ставите його після всього класу. :) Удачі!

Я додав коментарі, щоб показати, що обмежено.
( Натхненний цією публікацією, яка менш обмежує і приваблива тим самим підходом, який я міг би використовувати для своєї відповіді. )

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileDescriptor;
import java.io.FilePermission;
import java.io.PrintStream;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class Main {

  // Put everything in a static block so it is run before the static main method 
  // and any trailing (static) initializer-blocks:
  static {
    try {
      initializing();
    } catch (final Exception e) {
    }
  }

  static void initializing() throws Exception {
    // Overwrite System.out, System.err and System.in:
    System.setOut(new PrintStream(new ByteArrayOutputStream()));
    System.setErr(new PrintStream(new ByteArrayOutputStream()));
    System.setIn(new ByteArrayInputStream(new byte[0]));

    // Enable reflection for System.out, System.err and System.in:
    final Field modifiersField = Field.class.getDeclaredField("modifiers");
    modifiersField.setAccessible(true);
    final Class<?> fdClass = java.io.FileDescriptor.class;
    final Field outField = fdClass.getDeclaredField("out");
    outField.setAccessible(true);
    modifiersField.setInt(outField, outField.getModifiers() & ~Modifier.FINAL);
    final Field errField = fdClass.getDeclaredField("err");
    errField.setAccessible(true);
    modifiersField.setInt(errField, errField.getModifiers() & ~Modifier.FINAL);
    final Field inField = fdClass.getDeclaredField("in");
    inField.setAccessible(true);
    modifiersField.setInt(inField, inField.getModifiers() & ~Modifier.FINAL);

    // Replace existing System.out FileDescriptor with a new (useless) one:
    outField.set(null, new FileDescriptor());
    // Replace existing System.err FileDescriptor with a new (useless) one:
    errField.set(null, new FileDescriptor());
    // Replace existing System.in FileDescriptor with a new (useless) one:
    inField.set(null, new FileDescriptor());

    // Disable reflection for System.out, System.err, System.in again:
    modifiersField.setInt(outField, outField.getModifiers() & ~Modifier.FINAL);
    modifiersField.setInt(errField, errField.getModifiers() & ~Modifier.FINAL);
    modifiersField.setInt(inField, inField.getModifiers() & ~Modifier.FINAL);
    inField.setAccessible(false);
    errField.setAccessible(false);
    outField.setAccessible(false);
    modifiersField.setAccessible(false);

    // Overwrite the SecurityManager:
    System.setSecurityManager(new SecurityManager() {

      private boolean exitAllowed = false;

      @Override
      public void checkExec(final String cmd) {
        throw new SecurityException();
      }

      @Override
      public void checkPermission(final java.security.Permission perm) {
        final String name = perm.getName();
        // You're not allowed to read/write files:
        if (name.equals("setIO") || name.equals("writeFileDescriptor")
            || name.equals("readFileDescriptor")
            || ((perm instanceof FilePermission) && name.startsWith("/proc/self/fd/"))) {
          throw new SecurityException();
        }
        // You're not allowed to overwrite the Security settings:
        if (name.equals("setSecurityManager") || name.equals("suppressAccessChecks")) {
          throw new SecurityException();
        }
        // You're not allowed to use reflection anymore:
        if (name.equals("getModifiers") || name.equals("get") || name.equals("set")
            || name.equals("setBoolean") || name.equals("setByte")
            || name.equals("setChar") || name.equals("setShort") || name.equals("setInt")
            || name.equals("setLong") || name.equals("setFloat") || name.equals("setDouble")
            || name.equals("setFieldAccessor") || name.equals("setFieldAccessor")) {
          throw new SecurityException();
        }
        // When you try to leave the current VM it will stop the program:
        if (name.startsWith("exitVM") && !this.exitAllowed) {
          this.exitAllowed = true;
          System.exit(0);
        }

        // You know what, nothing is allowed!
        throw new SecurityException("Mhuahahahaha!");
      }
    });
  }

  public static void main(String[] args) {
    // Overwritting all given arguments:
    args = new String[0];

    // Exit the program before you can do anything!
    System.exit(0);
  }
}

// Your code goes below:

Спробуйте тут. (ideone.com замість TIO, оскільки він, здається, не працює там. Тестування проводилося в IDE Eclipse, але моє призначене рішення працює, якщо ви використовуєте ideone.com)



1

Желе: ЗАКРАНІ

Це буде шалено просто порівняно з дивовижною відповіддю Python Wizard Python, але ось ми підемо: P

“for c in code_page:
 if c in atoms:atoms[c].call=None”ŒVø<insert code snippet here>

Шестнадцятковий моєму вирішенні sha256, включаючи перший фрагмент, є cfeb1e193ad77f66f039c0d6a792a3e4c311490f6412698e019ca1fae10c0e0a.

Примітка

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

Зламаний DJMcMayhem

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

Також рішення Джонатана Аллана

У цьому рядку не використовується новий рядок, тому він зламався. : P

Моє рішення таке:

“for c in code_page:
 if c in atoms:atoms[c].call=None”ŒVø“print(int(input())+int(input()))”ŒV

Перший фрагмент видаляє лише окремі атоми символів, це означає, що Python eval все ще працює :)))


Другий фрагмент завжди додається до кінця першого фрагмента.
Стівен

@StepHen Просто уточнюючи: P Але я забув додати ноту; це дійсно важливо.
HyperNeutrino

3
Я не думаю, що ти можеш так обмежити розбійників. Якщо ви можете зламати його за допомогою Newlines, це дійсна тріщина. Чи є в будь-якому випадку запобігання доданню Newlines або примушування до виконання першого рядка?
DJMcMayhem


1
Мені подобається твій призначений тріск. Дуже підлий.
Денніс

1

JavaScript, тріщинами

Вхід: prompt()двічі

Вихід: console.log()

Моє рішення не працює в jsfiddle. Працює про about: пусту сторінку з JS-консоллю Google chrome.

prompt=console=0

Моє рішення:

x=document.createElement("iframe")
x.src="data:text/html,<script>console.log(prompt()-0+(prompt()-0))</script>"
document.body.appendChild(x)

Пояснення:

Я видалив підказку та консоль, встановивши їх рівним 0.

У своєму рішенні я створюю iframe, який створює пісочницю, і новий екземпляр вікна, де підказки та консолі працюють належним чином.



@CRDrost Я не вірю, що в специфікації є тестування на первинність, і ви не показуєте обидва фрагменти.
Стівен

Вибачте, ви праві, я неправильно прочитав.
CR Drost

1

Ява, тріщинами

import java.lang.reflect.*;
public class Main{
  public static void main(String... args){
    System.setOut(null);
    System.setErr(null);
    /*Your code here*/
  }
}

Це повинно бути дуже легко зламати.

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

import java.lang.reflect.*;
public class Main{
public static void main(String... args){
  System.setOut(null);
  System.setErr(null);
  try{
    Class<?> cistream = Class.forName("java.io.InputStream");
    Class<?> cfostream = Class.forName("java.io.FileOutputStream");
    Class<?> costream = Class.forName("java.io.OutputStream");
    Class<?> cfdescriptor = Class.forName("java.io.FileDescriptor");
    Object sout = cfostream.getConstructor(cfdescriptor).newInstance(cfdescriptor.getField("out").get(null));
    Class<?> csys = Class.forName("java.lang.System");
    Field mod = Field.class.getDeclaredField("modifiers");
    mod.setAccessible(true);
    Field stdout = csys.getField("out");
    mod.set(stdout,Integer.class.cast(mod.get(stdout) )&~ Modifier.FINAL);
    stdout.set(null,Class.forName("java.io.PrintStream").getConstructor(costream).newInstance(sout));
    Class<?> cscanner = Class.forName("java.util.Scanner");
    Object scanner = cscanner.getConstructor(cistream).newInstance(System.in);
    Method nextInt = cscanner.getMethod("nextInt");
    int f = Integer.class.cast(nextInt.invoke(scanner));
    int s = Integer.class.cast(nextInt.invoke(scanner));
    int sum = s + f;
    System.out.println(sum);
  }catch(Throwable t){t.printStackTrace();}
  }
}

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



Я повністю забув про java.io.. Але ви все одно отримали намічене рішення ..
Роман Греф

Я не бачу тут жодної проблеми. Я фактично написав другий фрагмент, просто забув його відредагувати. Згідно з TIO, перший фрагмент складається без попередження.
Роман Ґраф

@ OlivierGrégoire Готово. Я думаю, що будь-який ІДЕ буде кричати на мене за це, але я, принаймні, компілятор приймає це ...
Роман Гряф
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.