Нуль довільно великої комірки в Brainf ***


28

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

Ви можете припустити, що l ліві клітини зліва та r клітини праворуч від поточної комірки, які спочатку дорівнюють нулю. Програма може мати доступ лише до цих клітинок l + r +1. Після того, як ваш код закінчиться, він повинен залишити додаткові комірки l + r нульовими та покажчиком на поточну комірку у вихідному положенні.

Ви не можете використовувати будь-який вхід / вихід.

Виграє код з найменшим l + r . Якщо є нічия, виграє найкоротший код. Рекомендується також вказати часову складність вашої програми для довідки, де n - абсолютне значення вихідного цілого числа в поточній комірці.

Корисні інструменти

Ви можете протестувати програму Brainfuck в цьому варіанті, використовуючи цей інтерпретатор на TIO від mbomb007 .

Ви також можете використовувати інтерпретатора у цій відповіді бутбі (інші відповіді Python, ймовірно, також працюють, але я не перевіряв).


Я позначив це кодом-гольф, тому що думаю, що ми швидко досягнемо оптимальної l + r.
jimmy23013

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

4
@ jimmy23013 Чи є у вас перекладач BF з підписаними клітинками, які ми можемо використовувати для цього?
mbomb007

@ mbomb007 codegolf.stackexchange.com/a/3085/25180, але, мабуть, занадто гофрований ...
jimmy23013

1
@Mego Чому? У "справжньому" виклику ви також повинні отримати оптимальний l + r, що, ймовірно, ускладнить зменшення розміру коду.
jimmy23013

Відповіді:


17

l + r = 0 + 2 = 2, 55 53 51 байт

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

l + r = 1 + 2 = 3, 46 44 байти

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

Мій власний алгоритм. Вказівник повинен починатися з числа, яке має бути нульовим. Часова складність становить O (n ^ 2).

Як це працює:

  • Починаємо з числа n.
  • Ми збільшуємо одиницю, тому число стає n+1.
  • Ми декрементуємо два, тому число стає n+1-2 = n-1
  • Ми збільшуємо три, тому число стає n-1+3 = n+2.
  • У нас декремент чотири, тому число стає n+2-4 = n-2.

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


2
Саме алгоритм, про який я придумав,
переживши

9

l + r = 0 + 2 = 2; 58 байт

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

Складність становить O (n ^ 2).

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

p='''
>+<
[
>
[<->>+<-]
>+<
<[>]>
[<<+>+>-]
<
[->+<]
>[<]>
+ [-<+>]
<<
]
> [-] <
'''

p = ''.join(p.split())

cpp = '''
#include <bits/stdc++.h>
using namespace std;
void test(int q) {
long long t[3] = {q, 0, 0};
int i = 0;
ZZZ
printf("q=%d %lld %lld %lld\\n", q, t[0], t[1], t[2]);
}
int main() {
while(true) {
    int q; cin >> q; test(q);
}
}
'''

d = {
'>': '++i; assert(i<3);',
'<': '--i; assert(i>=0);',
'+': '++t[i];',
'-': '--t[i];',
'[': 'while(t[i]){',
']': '}',
}

print cpp.replace('ZZZ', ''.join(d[c] for c in p))

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

Схоже, це працює на мене.
mbomb007

2
Це повинно бути оптимальним l + r. Швидкий доказ того, що 1 неможливо: у кожній точці, в якій запасна комірка потрапляє до нуля, ви можете зберігати лише обмежений обсяг даних на додаток до значення вихідної комірки (у положенні головки стрічки та вказівнику інструкції), що означає, що Ви обмежені тим, наскільки далеко ви можете налаштувати головну комірку з цієї точки хоча б в одному напрямку.

@ ais523 Можуть бути й інші еквівалентні. Було б цікаво, якби хтось створив l + r = 1 + 1.
mbomb007
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.