Зробіть свою мову * в основному * непридатною для використання (нитка розбійника)


31

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

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

Це нитка Розбійника! Щодо теми копів, перейдіть сюди


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

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

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

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

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

Копи напишуть два фрагменти коду:

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

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

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

Відповідь поліцейських завжди виявиться

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

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

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

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

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

Ось приклад. На перший фрагмент ви можете побачити наступну програму 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)

Це дійсна тріщина їх відповіді.

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

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

Веселіться!

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

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

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

    import sys
    sys.exit()
    

    недійсний, оскільки він не порушує мову. Він просто відходить.

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

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

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

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

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

#User                       #Score
Ilmari Karonen              8

Dennis                      5

Olivier Grégoire            4

Sisyphus                    3
Veedrac                     3

Arnold Palmer               2
Bruce Forte                 2
DJMcMayhem                  2
Dom Hastings                2
ppperry                     2

1bluston                    1
2012rcampion                1
Ben                         1
BlackCap                    1
Christian Sievers           1
Cody Gray                   1
HyperNeutrino               1
Joshua                      1
Kaz                         1
Mark                        1
Mayube                      1
Xnor                        1
zbw                         1

Відповіді:


3

Java 8 Олів'є Грегоара

class A {
  public A() {
    String[] args = System.lineSeparator().split(",");
    System.out.print(Integer.parseInt(args[0]) + Integer.parseInt(args[1]));
  }
}

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

Оскільки Олів'є явно дозволив передавати вхід через властивості, встановлені за допомогою аргументів VM, я вкажу, що вхід повинен бути вказаний в аргументі VM -Dline.separator=X,Y, де Xі Yякі цифри потрібно додати. Тобто, наприклад, щоб додати числа 17 і 25, програму слід викликати як:

java -Dline.separator=17,25 Main

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


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

class SecurityManager extends sun.awt.AWTSecurityManager {
  static {
    String[] args = System.getProperty("sun.java.command").split(" ");
    int a = Integer.parseInt(args[args.length-2]);
    int b = Integer.parseInt(args[args.length-1]);
    System.out.println(a+b);
  }
}

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

Це вийшло набагато менш багатослівним, ніж попереднє . Важкою частиною було пошук підкласу, SecurityManagerякий не жив у просторі імен, починаючи з " java.". Я підозрюю, що це все ще не призначене рішення, але воно працює. *

*) Щонайменше, на TIO; sun.awt.AWTSecurityManagerклас і sun.java.commandвластивість , здається, не бути офіційно зареєстровані, і не можуть бути доступні на всіх віртуальних машинах.


Хороша робота! Я спробував це, але не зміг знайти SecurityManagerте, що було в обсязі ... Ти також можеш читати з System.inцього моменту, хоча це ще не закрито.
zbw

На жаль, це відповідь, що залежить від платформи, з двох питань: і те, sun.awt.SecurityManagerі "sun.awt.command"залежать від платформи, і не є частиною Java .
Олів'є Грегоар

Так, тріщини! :) Задумане рішення було пройти через System.getProperties().get("blah")(оскільки я лише заблокував доступ , але System.getPropertyне System.getProperties), але це досить добре! Молодці!
Олів'є Грегоар

22

C (GCC / Linux) від Сизіфа

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

}
int close(int x) {
  int a, b;
  scanf("%d %d", &a, &b);
  printf("%d\n", a + b);

  exit(0);

20

Пітон, рішення пшеничного майстра тут

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\
:[]                                                      # my code starts here
sys.setrecursionlimit(1000)
print(int(input())+int(input()))

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

Працює над TIO

Примітка

Це моє перше в історії подання CnR, тому якщо це порушує будь-які правила, будь ласка, скажіть мені, і я видалю це.


4
Я тупа за те, що пропустила це
Пшеничний майстер

@WheatWizard :)
HyperNeutrino

@wheatwizard Ще не розкривайте намічене рішення. Я б looove бачити кращий поліцейський з оригінальним рішенням , яке виправляє цю проблему.
DJMcMayhem

@Djmcmayhem Я, мабуть, збираюся репостувати з del sys.
Пшеничний майстер

@WheatWizard Пам'ятайте os.sys, якщо це має значення: P
HyperNeutrino

15

Haskell від Ben

import Prelude(getLine,print)
a=a
[]++s=s
(a:as)++s=a:(as++s)
r""=""
r(c:s)=(r s)++[c]
t(_:r)=r
ts l=l:ts(t l)
x[_](v:_)=v
x(_:r)(_:s)=x r s
d(a:_:_:_:_:_:_:_:_:_:r)=a:d r
(a:_)!!""=a
l!!(n:m)=d(x['0'..n](ts l))!!m
a+b=[[0..]!!a..]!!b
a-b=let n=[0..]!!a;m=[0..]!!b in
    case [n..m] of
      [] ->   x[m..n][0..]
      l  -> -(x l    [0..])
add('-':x)('-':y)= -(r x+r y)
add('-':x)y=r y-r x
add x('-':y)=r x-r y
add x y=x+y
main=do a<-getLine;b<-getLine;print(add a b)

Я до сих пір є буквальні цифри і букви (я використовую 0, '0'і '-'), а також [a..]і [a..b]які дуже корисні. У мене є одинак -, але я міг би обійтися і без.

Я заново ++реалізувати r( reverse) і визначити tі tsякі є tailі tails. x a bповертає nth елемент b, де nдовжина aмінус один. xзазвичай можна визначити як snd.last.zip. Функція dбере список і повертає список з елементами з тих позицій, кратних десяти. l!!sповертає nth елемент l, де sє зворотне подання рядка n. +повертає як ціле число суму двох натуральних чисел, поданих у вигляді зворотних рядків, також -для різниці. addповертає як ціле число суму двох, можливо, негативних цілих чисел, заданих у вигляді рядків.

Цікаво, чи це дещо схоже на те, що мав на увазі Бен.


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


7

Python 2 від Wheat Wizard (четверта ітерація)

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\
c,d:(`int([]in[])`[:[]in[]]).join([((c)and`dict([((int([]in[])),(int([]in[])))])`[(int([]in[[]])):][(int([]in[[]]))].join([`dict([((int([]in[])),(int([]in[])))])`[(int([]in[]))],`dict([((int([]in[])),c)])`[(int([]in[[]])):][(int([]in[[]])):][(int([]in[[]])):][(int([]in[[]])):]])or`int([]in[])`[:[]in[]]).format((int([]in[]))),((d)and`dict([((int([]in[])),(int([]in[])))])`[(int([]in[[]])):][(int([]in[[]]))].join([`dict([((int([]in[])),(int([]in[])))])`[(int([]in[]))],`dict([((int([]in[])),d)])`[(int([]in[[]])):][(int([]in[[]])):][(int([]in[[]])):][(int([]in[[]])):]])or`int([]in[])`[:[]in[]]).format((int([]in[]))),`(int([]in[]))`]).rfind(`(int([]in[]))`)

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

Ніяких подвигів, лише функція додавання, використовуючи лише символи ' &)(,.:[]a`cdfijmonrt~', як задумано (фактично лише '(),.:[]`acdfijmnort').

Я не робив спроб зробити це коротким; Я щойно написав піддепресії для проміжних значень, таких як 0, та порожнього рядка та рядків, замінених рядками.

def f(c,d):
	FALSE = []in[]
	TRUE = []in[[]]
	ZERO = int([]in[])
	ONE = int(TRUE)
	EMPTY = `int([]in[])`[:[]in[]]
	ZERO_STR = `ZERO`
	ONE_STR = `ONE`

	ZERO_DICT = dict([(ZERO,ZERO)])
	ZERO_DICT_STR = `ZERO_DICT`

	OPEN_BRACE = ZERO_DICT_STR[ZERO]
	COLON = ZERO_DICT_STR[ONE:][ONE]
	CLOSE_BRACE = ZERO_DICT_STR[ONE:][ONE:][ONE:][ONE:][ONE]

	C_STR = `c`
	D_STR = `d`

	FORMAT_STR_C = ''.join([OPEN_BRACE, ZERO_STR, COLON, C_STR, CLOSE_BRACE])
	FORMAT_STR_D = ''.join([OPEN_BRACE, ZERO_STR, COLON, D_STR, CLOSE_BRACE])

	LENGTH_C_STR = c and FORMAT_STR_C.format(ONE_STR) or EMPTY
	LENGTH_D_STR = d and FORMAT_STR_D.format(ONE_STR) or EMPTY

	TOTAL_STR = EMPTY.join([LENGTH_C_STR, LENGTH_D_STR, ZERO_STR])
	RESULT = TOTAL_STR.find(ZERO_STR)

	return RESULT

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

Основна ідея полягає в тому, щоб формат рядка '{0:5}'.format('1')проклав число нуль до довжини 5подібної '1 '. Шляхом об'єднання двох таких рядків ''.join, сума їх довжини є сумою вхідних чисел. Потім ми дотягуємося 0до кінця і називаємо .find()остаточну позицію, яка є сумою.

Рядок '{0:5}'для форматування створюється шляхом вилучення {:}символів із рядкових репперів словників, створених за допомогою dict. Рядковий репр кожного наступного зведення розміщується там, де було б 5. Я хотів використати диктант, як {0:5}сам, але його репр містить пробіл, який переплутав його.

Введення даних на 0 заплутало процес, тому що підряд має мінімальну довжину 1. У нас є ті, у кого введено and/orпорожній рядок.


1
Це зовсім інше, ніж те, що я задумав, я хотів би побачити пояснення.
Пшеничний майстер

Ви можете int([]in[])грати int()в гольф просто так, як обидва вийдуть 0.
Чорнило вартості


5

16-бітна збірка в реальному режимі x86 Джошуа

    int  0x3                  ; <---  this is the "robber" portion

    ; -- begin code to print numbers in real-mode asm using ROM BIOS video interrupts --
    add  dx, cx               ; add input values together
    mov  ax, dx               ; move result into AX
    push WORD 0xB800
    pop  ds                   ; DS == starting address of text-mode video buffer
    xor  cx, cx               ; digit counter
    xor  di, di               ; position counter
    mov  bx, 0xA              ; divisor

    test ax, ax               ; is number negative?
    jns  .GetDigits
    neg  ax                   ; convert negative number to positive
    mov  WORD ds:[di], 0x4F2D ; output leading negative sign, in white-on-red
    add  di, 2                ; increment position counter

.GetDigits:
    xor  dx, dx
    div  bx                   ; divide DX:AX by 10 (AX == quotient, DX == remainder)
    push dx                   ; push digit onto stack
    inc  cx                   ; increment digit counter
    test ax, ax
    jnz  .GetDigits           ; keep looping until we've got 'em all

.PrintDigits:
    pop  dx                   ; get digit off of stack
    dec  cx                   ; decrement digit counter
    mov  dh, 0x4F             ; high byte: color attribute (white-on-red)
    add  dl, 0x30             ; low  byte: convert to ASCII
    mov  WORD ds:[di], dx     ; output digit
    add  di, 2                ; increment position counter
    test cx, cx
    jnz  .PrintDigits         ; keep looping until we've printed 'em all

    cli
    hlt

скріншот дамп-коду налагодження разом із висновком у верхньому лівому куті

Пояснення:

"Поломка", запроваджена кодом Джошуа, - це встановлення прапора пастки (TF), який переводить ЦП в одномоментний режим. Це означає, що одночасно буде виконуватися лише одна інструкція, перш ніж ЦП зупиняється (пастки) з перериванням типу-1. Це те, що дозволяє налагоджувачам реалізувати однокроковий код - це дуже зручно, але справжній PITA, якщо ви хочете запустити код поза контекстом налагоджувача!

Це наступний розділ коду, який вмикає прапор пастки:

pushf               ; push the FLAGS register onto the top of the stack
mov bp, sp          ; load the pointer to the top of the stack into BP
or word [bp], 256   ; bitwise-OR the WORD at the top of the stack (the copy of FLAGS)
                    ;  with 0x100, which turns on bit 8 (TF)
popf                ; pop the modified flags back off the stack into FLAGS

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

Хитрість полягає в INT 3інструкції, яка викликає переривання № 3. Існує дві причини, чому це працює, щоб "скасувати" код:

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

  2. Спосіб переривання роботи по суті такий же, як і далеко CALL. Вони викликають обробник переривання, адреса якого зберігається у відповідному положенні в глобальній таблиці векторів переривання. Оскільки ця таблиця починається з адреси 0x0000:0000та зберігається у 4-байтовому segment:offsetформаті, обчислення адреси так само просто, як і множення 4 на вектор / число переривання. У цьому випадку ми викликаємо переривання 3, так що це було б 4 × 3 = 12.

    … І ви помітите, що Джошуа задумливо налаштував це для нас. Перед включенням прапора пастки він має такий код:

    mov  di, 12
    mov  [di], si
    mov  [di + 2], bp
    

    який встановлює 0x0000:000C(обробник переривання для INT 3) BP:SI. Це означає, що кожного разу, коли INT 3він викликається, він виштовхує реєстр FLAGS на стек, після чого повертається адреса, а потім гілки на BP:SI, що дозволяє нам знову починати виконання коду в контексті, коли прапор пастки вимкнено.

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

Джошуа дозволяє грабіжнику вказати будь-який механізм вводу / виводу, який він хоче , тому я використовую спрощений підхід припускати, що значення передаються в DXі CXрегістри. Це розумно, оскільки вони ніде не закріплені його кодом "пролог".

Вихід тоді виконується шляхом зберігання байтів ASCII безпосередньо у відеопам'яті. Буфер відеозапускається у 0xB800:0000текстовому режимі CGA, EGA та / або VGA, тому ми починаємо друкувати там. Формат: символ у низькому байті та атрибут кольору у високому байті. Це означає, що кожен символ знаходиться на 2-байтному зміщенні. Ми просто повторюємо кожну з цифр числа (база-10), перетворюючи їх у ASCII і друкуючи їх по черзі на екран. Так, це багато коду. Немає функцій бібліотеки, які б допомогли нам у мові складання. Це майже точно можна оптимізувати далі, але я втомився працювати над цим ...

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


Я спантеличений; Я не можу зрозуміти, як це минає інструкцію hlt в BP: SP + 1.
Джошуа

@ Джошуа Хм, це хороший момент. Я навіть про це не думав. Перебираючи код у налагодженні, я виконую INT 3і негайно повертаюся до інструкції, що слідує за ним, тому я просто пішов з ним. Можливо, щось стосується мого тестувального середовища? CLIвимкне лише апаратні переривання, але навіть якби він пройшов повз HLT, ви подумаєте, що він провалиться та виконає код lнегайно після цього.
Коді Грей

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

Я також тестувався без одноразового кроку. Без різниці. Це на FreeDOS останній у VM Virtualbox. У мене є справжнє обладнання, але не відчуваю, як його включити. @Joshua
Коді Грей

Ну, ви явно це зламали тоді. Можливо, ви знайшли спосіб підняти цю НМІ.
Джошуа


4

Python 3 , ppperry «S 2 - й виклик

Ого, це було весело! Мені подобалося вирішувати це.

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

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

# My code begins here
str = "Hello!".__class__
int = (37).__class__
object = str.__base__

def find_subclass(superclass, name):
	for cls in superclass.__subclasses__():
		if cls.__name__ == name:
			return cls

_io_IOBase      = find_subclass(object, '_IOBase')        # <class '_io._IOBase'>
_io_RawIOBase   = find_subclass(_io_IOBase, '_RawIOBase') # <class '_io._RawIOBase'>
_ioFileIO       = find_subclass(_io_RawIOBase, 'FileIO')  # <class '_io.FileIO'>
stdout = _ioFileIO('stdout', mode='w', opener=lambda name,flags: 1) # FD for stdout is 1
stdin  = _ioFileIO('stdin',  mode='r', opener=lambda name,flags: 0) # FD for stdin is 0
nums = str(stdin.read(), encoding='utf-8').split()
stdout.write(str(int(nums[0]) + int(nums[1])).encode('utf-8') + b'\n')
stdout.flush()

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


Я отримую помилку. sys.excepthook is missing?
Rɪᴋᴇʀ

Хм ... працює на мене. Яка справжня помилка ви отримуєте? (Це відбувається тому, що код ppperry знищив майже все, в тому числі, знаючи, як показувати винятки, тому це sys.excepthook, але там буде справжня причина, перерахована десь там.)
zbw

Не зважаючи, справжня помилка IndexError('list index out of range',). Це на одному рівні з визначенням _io_RawIOBase.
Rɪᴋᴇʀ

Проблема полягає в тому, що порядок підкласів не встановлений. _io_IOBase = [cls for cls in object.__subclasses__() if cls.__name__ == '_IOBase'][0]повинні працювати всюди.
Денніс

@Dennis Yep, я зрозумів це і просто виправив це. Він працює на TIO зараз!
zbw

4

Haskell від zbw

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

import Language.Haskell.TH.Syntax
import System.IO.Unsafe

a = $( runIO $ TupE[] <$
              do x <- readLn :: IO Integer
                 y <- readLn
                 print $ x + y )

Не вдається запустити код під час виконання? Запустити його в час компіляції!

Це було дуже весело, я не знав шаблону haskell перед цим викликом.



3

Python 2 від Wheat Wizard

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\
a,b:a+b
__import__('sysconfig').__dict__['os'].__dict__['sys'].setrecursionlimit(1000)
print(f(1,2))

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


Це виявляється складніше, ніж я думав.
Пшеничний майстер

3

Java від LordFarquaad

Блокування доступу до об'єктів на рівні джерела було справді розумним (і дратує при тестуванні), молодець!

public class java {
  public static void main(String[] s) {
    //there is no executable code in snippet one.
    //your code here.
    try {
      ClassLoader cl = ClassLoader.getSystemClassLoader();
      Object in = cl.loadClass("java.lang.System").getDeclaredField("in").get(null);
      Object out = cl.loadClass("java.lang.System").getDeclaredField("out").get(null);
      Object scanner = cl.loadClass("java.util.Scanner").getConstructor(cl.loadClass("java.io.InputStream")).newInstance(in);
      int i = (Integer)cl.loadClass("java.util.Scanner").getMethod("nextInt").invoke(scanner);
      int j = (Integer)cl.loadClass("java.util.Scanner").getMethod("nextInt").invoke(scanner);
      cl.loadClass("java.io.PrintStream").getMethod("println", Object.class).invoke(out, i+j);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  class Class {}
  class Method {}
  class System {}
  class FileDescriptor {}
  class Logger {}
  class Runtime {}
  class Scanner {}
}

Приємно! Що робити, якщо ClassLoaderвін був затіненим?
Якоб

1
@JakobCornell "".getClass().getClassLoader(). Затінення тіней - це лише проблема, про яку ти повинен подумати один раз, і тоді це нормально. Можна навіть затінити Object, я все-таки зможу це вирішити. Гаразд, ви можете змусити мене прийняти рішення на 1 кб, але це можливо.
Олів'є Грегоар


3

Інформ 7, Ільмарі Каронен

Повна зловживання неоднозначними іменниками ... Мій код починається з factory is a room. Попередній рядок - код поліцейського. add 1 and 1Наприклад, введіть, щоб отримати 2.

For reading a command: Rule fails

factory is a room.
The adder one is a thing. The adder two is a thing. The adder one is in factory. The adder two is in factory.
Before reading a command: change the text of the player's command to "examine adder"

For printing a parser error: 
    if the player's command includes "add [number] ":
        let N be the number understood;
        if the player's command includes "and [number]":
            say the number understood plus N;

2

Ява, Роман Граф

public class Main {
    public static void main(String... args){
        System.setOut(null);
        System.setErr(null);

        System.setOut(new java.io.PrintStream(new java.io.FileOutputStream(java.io.FileDescriptor.out)));
        System.setErr(new java.io.PrintStream(new java.io.FileOutputStream(java.io.FileDescriptor.err)));
        System.out.println("This");
        System.err.println("works");
    }
}

Встановлює stdoutі stderrповертається до початкових значень.

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

Редагувати: ось рефлексивне рішення, використовуючи лише java.lang.reflect.*:

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class Test {
    public static void main(String... args) {
        System.setOut(null);
        System.setErr(null);

        try {
            Class<?> psClass = Class.forName("java.io.PrintStream");
            Class<?> fsClass = Class.forName("java.io.FileOutputStream");
            Class<?> osClass = Class.forName("java.io.OutputStream");
            Class<?> fdClass = Class.forName("java.io.FileDescriptor");
            Class<System> sClass = System.class;
            Constructor psCtor = psClass.getConstructor(osClass);
            Constructor fsCtor = fsClass.getConstructor(fdClass);

            Field modifiersField = Field.class.getDeclaredField("modifiers");
            modifiersField.setAccessible(true);

            Object sout = psCtor.newInstance(fsCtor.newInstance(fdClass.getDeclaredField("out").get(null)));
            Field outField = sClass.getDeclaredField("out");
            modifiersField.setInt(outField, outField.getModifiers() & ~Modifier.FINAL);
            outField.set(null, sout);

            Object serr = psCtor.newInstance(fsCtor.newInstance(fdClass.getDeclaredField("err").get(null)));
            Field errField = sClass.getDeclaredField("err");
            modifiersField.setInt(errField, outField.getModifiers() & ~Modifier.FINAL);
            errField.set(null, serr);

            System.out.println("This");
            System.err.println("works");
        } catch (Exception ignore) {
        }
    }
}

Так, stdin, stdoutі stderrзберігаються в іншому місці! Вам навіть не потрібно використовувати setOutі setErrяк ви можете просто використовувати PrintStreamбезпосередньо.
Олів'є Грегоар

Додано рефлексивне рішення, а також я відчуваю, що цього спочатку очікували
Майра

2

JavaScript Даніель Франклін

location="data:text/html;base64,PHNjcmlwdD5jb25zb2xlLmxvZygxKnByb21wdCgpKzEqcHJvbXB0KCkpPC9zY3JpcHQ+"

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

Майбутні версії блокують ініційовані вмістом верхні кадри до даних: URL-адреси. Для отримання додаткової інформації див. Https://goo.gl/BaZAea .

Пс. Ось ще одна тріщина, цього разу без попереджень:

Node.prototype.removeChild=function(){}
document.body.innerHTML='<iframe src="data:text/html;base64,PHNjcmlwdD5jb25zb2xlLmxvZygxKnByb21wdCgpKzEqcHJvbXB0KCkpPC9zY3JpcHQ+"/>'

Я думаю, що prompt()- -prompt()економить два байти
Марі

2

Java 8 Олів'є Грегоара

Дуже багатослівна тріщина для дуже багатослівного завдання. :) Біль від опосередкованої роботи з класами, які ви не можете назвати, відчутна.

    try {
      Class loader = Class.class.getMethod("getClassLoader").getReturnType();
      Object sysLoader = loader.getMethod("getSystemClassLoader").invoke(null);
      Class integer = (Class) loader.getMethod("loadClass", String.class).invoke(sysLoader, "java.lang.Integer");
      Class system  = (Class) loader.getMethod("loadClass", String.class).invoke(sysLoader, "java.lang.System");
      Class filein  = (Class) loader.getMethod("loadClass", String.class).invoke(sysLoader, "java.io.FileInputStream");

      InputStream cmd = (InputStream) filein.getConstructor(String.class).newInstance("/proc/self/cmdline");
      byte[] buf = new byte[65536];
      int len = cmd.read(buf);
      String[] args = new String(buf, 0, len).split("\0");
      
      int a = (int) integer.getMethod("parseInt", String.class).invoke(null, args[args.length-2]);
      int b = (int) integer.getMethod("parseInt", String.class).invoke(null, args[args.length-1]);

      Object out = system.getField("out").get(null);
      out.getClass().getMethod("println", String.class).invoke(out, ""+(a+b));
    } catch (Exception e) {
      throw new Error(e);
    }
  }
}
class ClassLoader {
  public static ClassLoader getSystemClassLoader() { return new ClassLoader(); }
  public ClassLoader loadClass(String s) { return this; }
  public ClassLoader getDeclaredField(String s) { return this; }
  public ClassLoader getMethod(String s) { return this; }
  public ClassLoader getMethod(String s, Class c) { return this; }
  public InputStream get (Object o) { return new FakeInputStream(); }
  public void invoke(Object o, SecurityManager sm) {}
}
class FakeInputStream extends InputStream {
  public int read() {
    return -1;

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

Пс. Ось моя попередня спроба, написана до того, як Олів'є уточнив, що введення має бути зроблене аргументами командного рядка. На відміну від тріщини вище, цей не є специфічним для Linux.

    try {
      Class loader = Class.class.getMethod("getClassLoader").getReturnType();
      Object sysLoader = loader.getMethod("getSystemClassLoader").invoke(null);
      Class integer = (Class) loader.getMethod("loadClass", String.class).invoke(sysLoader, "java.lang.Integer");
      Class system  = (Class) loader.getMethod("loadClass", String.class).invoke(sysLoader, "java.lang.System");
      Class scanner = (Class) loader.getMethod("loadClass", String.class).invoke(sysLoader, "java.util.Scanner");

      InputStream in = (InputStream) system.getField("in").get(null);
      Object scanIn = scanner.getConstructor(InputStream.class).newInstance(in);

      int a = (int) scanner.getMethod("nextInt").invoke(scanIn);
      int b = (int) scanner.getMethod("nextInt").invoke(scanIn);

      Object out = system.getField("out").get(null);
      out.getClass().getMethod("println", String.class).invoke(out, ""+(a+b));
    } catch (Exception e) {
      throw new Error(e);
    }
  }
}
class ClassLoader {
  public static ClassLoader getSystemClassLoader() { return new ClassLoader(); }
  public ClassLoader loadClass(String s) { return this; }
  public ClassLoader getDeclaredField(String s) { return this; }
  public ClassLoader getMethod(String s) { return this; }
  public ClassLoader getMethod(String s, Class c) { return this; }
  public InputStream get (Object o) { return new FakeInputStream(); }
  public void invoke(Object o, SecurityManager sm) {}
}
class FakeInputStream extends InputStream {
  public int read() {
    return -1;

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


Якщо ви готові до цього, ось мій новий виклик .
Олів'є Грегоар

Тільки заради того, щоб написати це тут: оскільки я не маю права сказати "Gotcha! Це працює лише в одній системі", ця відповідь не зовсім зламає проблему, оскільки вона працює лише в Linux.
Олів'є Грегоар

@ OlivierGrégoire: FWIW, я придумав альтернативне рішення, використовуючи String[] args = ((String) system.getMethod("getProperty", String.class).invoke(null, "sun.java.command")).split(" ");це не для Linux, але використовує те, що видається недокументованим властивістю, встановленою деякими JVM.
Ільмарі Каронен

Це все ще не портативно. Наприклад, він не працюватиме на Java Java. Однак приємна ідея! :)
Олів'є Грегоар

2

C # (.NET Core) by raznagul

Я припускаю, що це не було наміченим рішенням.

int a;
int b;

using (var f = new System.IO.FileStream("/dev/stdin", System.IO.FileMode.Open, System.IO.FileAccess.Read))
{
using (var fs = new System.IO.StreamReader(f))
{
a = int.Parse(fs.ReadLine());
b = int.Parse(fs.ReadLine());
}
}
using (var f = new System.IO.FileStream("/dev/stdout", System.IO.FileMode.Open, System.IO.FileAccess.Write))
{
using (var fs = new System.IO.StreamWriter(f))
{
fs.WriteLine((a + b).ToString());
}
}

Гарний трюк /dev/std*там. Спочатку я прагнув подібного підходу, але не зміг знайти жодного простого способу відкрити потоки для stdin / out без доступу до System.Console, тому замість цього я вибрав роздуми. Звичайно, ваше рішення, імовірно, працює лише в Linux та інших системах Unixish з відповідними /devзаписами, але рознагал не сказав прямо, що він повинен працювати в Windows. І це працює на TIO.
Ільмарі Каронен

@IlmariKaronen: Дійсно; і мій план, якби це Windows, не вийшов би з ладу TIO.
Джошуа

1

Java, від racer290

Це було скоріше базовим оглядом того static, що перед mainметодом викликаються ініціалізатори . Це була приємна спроба: спочатку я злякався throw new Error(), але в підсумку знайшов дорогу;)

public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException, NoSuchMethodException {

    try {

        System.class.getField("in").set(null, null);
        System.class.getField("out").set(null, null);
        System.class.getField("err").set(null, null);

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

        File.class.getField("fs").set(null, null);

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

            m.setAccessible(false);

        }

        SecurityManager mngr = new SecurityManager() {

            @Override
            public void checkPermission(Permission p) {

                throw new Error("Muahaha!");

            }

            @Override
            public void checkLink(String s) {

                throw new Error("Not this way, my friend!");

            }

        };

        System.setSecurityManager(mngr);

    } catch (Throwable t) {

    }
    // My code here, I guess...
} static {
  java.util.Scanner s = new java.util.Scanner(System.in);
  System.out.println(s.nextInt()+s.nextInt());

    // End of my code
}

System.out.println("Hello World!");Не додає двох цілих чисел? .. " 2. Фрагмент коду, який приймає два числа як вхідні дані, додає їх разом і виводить їх суму. Цей фрагмент повинен правильно функціонувати навіть після запуску першого фрагмента. Коли два фрагменти разом вони повинні сформувати повну програму, яка додає два числа, або визначити функцію, яка додає два числа. Цей фрагмент, ймовірно, буде покладатися на незрозумілу поведінку, і його буде важко знайти. "
Кевін Круїйсен

@KevinCruijssen Що я можу сказати? Якщо поліцейські не виконують свою роботу, то чому я повинен робити їх? : P
Олів’є Грегоар

1
@KevinCruijssen Там я поклав доповнення туди.
Олів'є Грегоар

@ OlivierGrégoire вся справа в тому, щоб не допустити додавання чисел, чи то шляхом видалення можливості вводити, додавати чи виводити.
Стівен

@StepHen Так, я зрозумів це трохи згодом. Перевірте ще 3 мої тріщини, щоб побачити, що я нарешті зрозумів це;)
Олів'є Грегоар

1

Ява Кевіна Круїссена

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

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);
  }
}

class System {
  static void exit(int n) {}
  static void setSecurityManager(SecurityManager sm) {
    java.util.Scanner scanner =new java.util.Scanner(java.lang.System.in);
    java.lang.System.out.println(scanner.nextInt() + scanner.nextInt());
  }
  static void setIn(Object o) {}
  static void setOut(Object o) {}
  static void setErr(Object o) {}
}

Спробуйте тут.


Це було швидко .. Це було дійсно моє точне намічене рішення! Молодці. :) РЕДАКТУВАННЯ: Ви можете сміливо додати посилання TIO, якщо ви не заперечуєте.
Kevin Cruijssen

Ну, я фактично працював над цією ідеєю з викликом гонщика 290, коли ви розміщували своє. І, ні, я не проти.
Олів'є Грегоар


1

cQuents , Step Hen , 3 байти

+BC

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

Взяв багато розмов із Степом Хеном, щоб зрозуміти, як на біса працює його дивна мова, але коротко:

Його код був #|1,1:A. #|1,1є вводом за замовчуванням, тобто будь-який вхід, що подається програмі, додається 2 1. (IE якщо ви передаєте 47 і 53, ваш вклад є [47, 53, 1, 1].

:просто встановлює режим, який виведе цей nелемент у послідовності, якщо nвін встановлений, і в іншому випадку виведе всю послідовність.

Нарешті Aотримує перший вхід.

Оскільки у нас є 4 входи [47, 53, 1, 1], додавання BCдо кінця також отримає 2-й та 3-й входи, і 4-й вхід неявно стає n.

Оскільки наша послідовність є ABC, вона алгебраїчно розбирається, тобто вона стає A*B*C. Ми цього не хочемо, але якщо ми вставимо +між A і B, це стане A+B*C, де Aі Bє нашими входами, і Cце 1.


how the hell his weird language worksможливо, як тільки я закінчу це, це може мати щось більше сенсу
Стівен

@StepHen не зрозумійте мене неправильно, це акуратна мова, але дивно, як у пеклі
Skidsdev

1

C # (.NET Core) by raznagul

var console = typeof(System.ConsoleCancelEventArgs).Assembly.GetType("System.Console");
var readLine = console.GetMethod("ReadLine");
var writeLine = console.GetMethod("WriteLine", new Type[] { typeof(int) });
int a = Int32.Parse((string) readLine.Invoke(null, null));
int b = Int32.Parse((string) readLine.Invoke(null, null));
writeLine.Invoke(null, new object[] {a+b});

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

Напевно, це зайняло б менше часу, якби я насправді знав будь-який C #. Однак, переглянувши документацію та трохи допомогли від Джона Скіта , мені вдалося обмотати щось, що працює.


1

Vim виклик від @DJMcMayhem

Минуло час, як я не зміг вийти з vim , ось моє рішення (зауважте, це набагато більше, ніж 23байти - тому, мабуть, це не призначене рішення):

i
echo "
12
39
"|awk '{s'$(python -c "print(''.join([chr(43),chr(61)]))")'$1} END {print s}'<Esc>vgg!bash

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

Ідея полягає в тому , щоб просто труби два цілих чисел з awkдопомогою bash, так =і +відключений мені довелося використовувати невеликі обхідним. awkЛінія розширюється:

"|awk '{s'+='} END {print s}

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

Ось запропоноване виправлення @DJMcMayhem: Спробуйте в Інтернеті!


Я думаю, не думаю, що ти можеш це робити [insert your number here]в режимі вставки. Натомість це просто вже в буфері. Але ви могли б це обійти Oecho "<esc>Go"|awk..., тому я думаю, що це має значення. Чудово зроблено! Це не тріщина, про яку я мав на увазі (я сподівався на чисту відповідь vim), тому я, ймовірно, опублікую нову відповідь, яка виправляє зовнішні команди та !.
DJMcMayhem

1
Ось приклад, який сприймає правильний спосіб: Спробуйте це в Інтернеті!
DJMcMayhem

Так, я не був впевнений у вкладі. Але вирішення дійсно було б легким. Я редагую офіційним способом.
ბიმო

До речі, тут мій виправлений підхід: codegolf.stackexchange.com/a/133441/31716
DJMcMayhem

1

Java 7 від Poke

  }
  public static void main(java.lang.String[]a) throws Exception {
    int x = Integer.parseInt(a[0]);
    int y = Integer.parseInt(a[1]);
    java.lang.System.out.println(x+y);
  }
}
class String {
}
class System {
  public static java.io.InputStream in = new java.io.ByteArrayInputStream(new byte[0]), out = in, err = in;
  public static void setProperties (Object o) {

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

Ніяких хитрощів для Linux не потрібно, просто просте маскування некваліфікованих Stringі Systemімен класів. Це, мабуть, не призначене рішення, але воно працює.



1

RProgN2 від @ATaco

"+-/*÷^"{²[[\=};
{"D"=11{‹1D&¬\D›]"D"=}:]1\2\Š1{[\D‹|"D"=};D¬{1"D"=1\2\Š1{[D‹"D"=};}{[}?D}"~"={"d"="g"=g~d&gd~&|}"±"={"H"="I"=11{‹H1&I1&±\H›"H"=I›"I"=H¬¬I¬¬|}:1\2\Š1{[H‹|"H"=};H}"×"={"J"="K"=1{JK&‹JK×"K"=]"J"=}:JK|}"+"=

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

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

У початковому дописі ATaco він фактично просто перерозподілив всі основні арифметичні оператори для знищення їх вхідних даних. Щоб виправити цю проблему, я переглянув, яке додавання було з точки зору його бінарних операцій, що було болем, оскільки RProgN2 не має оператора бінарного заперечення або xor.

Примітка. Якщо ви хочете перевірити введення, у формі повинні бути цифри, що містять більше однієї цифри "XX..." n для перетворення у фактичне число, оскільки RProgN2 приймає кожен символ таким, як це є, якщо це не поняття чи рядок. Редагувати: @ATaco зазначив, що додавання "$" перед багатозначним числом зробить те саме.

EDIT: Ось логіка мого рішення. Як бачите, напевно, не самий вдосконалений код, але він працює.

{"D"=11{‹1D&¬\D›]"D"=}:]1\2\Š1{[\D‹|"D"=};D¬{1"D"=1\2\Š1{[D‹"D"=};}{[}?D}"~"= # Defines the ~ operator which negates a number
{"D"=                                                                   }     # Remove the top of the stack and assign D with the popped value
     11                                                                       # Push 2 1's to the stack.  The first is used as a counter, the second if the initial truthy value for the loop
       {             }:                                                       # Start a while loop if the top of the stack (popped) is truthy (removes final falsey value)
        ‹                                                                     # Left shift the counter variable
         1D&¬                                                                 # Push negation of last bit of D
             \                                                                # Swap the counter (index 1) and the negated bit (index 0)
              D›]"D"=                                                         # Push D, right shift it, duplicate the value on the stack, then pop and assign the top to D
                       ]1\                                                    # Duplicate the counter, push 1, and swap the counter to the top of the stack
                          2\Š                                                 # Push 2, swap with the counter, then take the log (log_2(counter))
                             1{         };                                    # Run the for loop "for (i=1;i<=log_2(counter);i+=1)"
                               [\                                             # Pop off i, then swap the original counter with the next bit to append
                                 D‹|"D"=                                      # Left shift D, or it with the next bit, then assign D the new value
                                          D¬                                  # Need to check if D was 0 or not (in the case of 0b11...1~)
                                            {                     }{ }?       # Conditional on the truthiness of not D
                                             1"D"=                            # If D was 0, we assign it as 1, then start to bit shift it up
                                                  1\2\Š1{       };            # Same for loop as earlier since the original counter is still on the top of the stack
                                                         [D‹"D"=              # Pop off i, left shift D, then reassign it
                                                                    [         # Else D was non-zero, so just pop off the counter we've been carrying around
                                                                       D      # Push the final value to the top of the stack as a return
                                                                         "~"= # Assign the function between the {}'s to the character '~'

{"d"="g"=g~d&gd~&|}"±"=                                                       # Defines the ± operator which performs a single bit xor
{"d"="g"=         }                                                           # Assign d and g the first and second values on the stack respectively
         g~d&                                                                 # Push ~g&d to the top of the stack
             gd~&                                                             # Push g&~d to the top of the stack
                 |                                                            # Or the top 2 values giving us (~g&d)|(g&~d)
                   "±"=                                                       # Assign this function to the ± operator

{"H"="I"=11{‹H1&I1&±\H›"H"=I›"I"=H¬¬I¬¬|}:1\2\Š1{[H‹|"H"=};H}"×"=             # Defines the × operator which performs a full number xor
{"H"="I"=                                                   }                 # Store the top 2 stack values in H and I (in that order)
         11{                            }:                                    # Another while loop with the first one being a counter for later, and the second is our truthy value to start the loop
            ‹H1&I1&±                                                          # Left shift the counter, then push the bit xor of H's and I's lowest bit ((H&1)±(I&1) in infix notation)
                    \                                                         # Swap the calculated bit and the counter
                     H›"H"=I›"I"=                                             # Right shift both variables and store the values back in them
                                 H¬¬I¬¬|                                      # Effectively pushing the value (H!=0 | I != 0)
                                          1\2\Š1{        };                   # Same for loop as the ones above
                                                 [H‹|"H"=                     # Pop off the for loop counter, left shift H, or it with the next bit, and reassign
                                                           H                  # Push the final computed xor value to the top of the stack
                                                             "×"=             # Assign this whole function to the × operator

{"J"="K"=1{JK&‹JK×"K"=]"J"=}:JK|}"+"=                                         # Finally, a function redefining addition as the "+" operator
{"J"="K"=                       }                                             # Store the top 2 stack values in J and K respectively
         1{                }:                                                 # An initial truthy value to start the while loop and the loop itself
           JK&‹                                                               # Push (J&K)<<1 to the stack
               JK×                                                            # Compute the full xor of J and K (J^K in Python)
                  "K"=                                                        # Assign K the value of J xor K
                      ]"J"=                                                   # Duplicate (J&K)<<1 and assign 1 copy to J, leaving (J&K)<<1 as our while check (while ((J&K)<<1))
                             JK|                                              # Finally push the value J|K to the stack to get the addition
                                 "+"=                                         # Assign this function to the "+" operator, restoring it

Надання долара перед жаркою цифр також групує його як одне число, наприклад 56$46$12, підштовхне цифри 5, 6, 46 та 12. Я опублікую своє фактичне рішення та таке завтра
ATaco

Не знав цього. Я ніби просто переглянув ваші дзвінки, щоб зрозуміти, що це таке.
Арнольд Палмер

Я можу насправді написати певну документацію через цей виклик.
Атако

Це було б чудово. Мені вдалося знайти список команд для RProgN, але втратив його ... І це лише настільки допомогло, оскільки функції у всіх різні. Мені довелося засвоїти ваші функції через вашу стару сторінку підручника RProgN та ваші заняття по дзвінку. З цим було весело грати, навіть якщо не відразу було очевидно, як все працює.
Арнольд Палмер

1

JavaScript (Node.js) від jrich , 298 байт

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

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.stderr.write.call(process.stdout,''+((0|process.argv[2])+(0|process.argv[3])));

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


1
Не задумане рішення, але дуже розумне! Nice crack +1
jrich

@jrich Так, я подумав, не соромтеся виправити це, я обов'язково ще один піду задумане рішення!
Дом Гастінгс

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