Серпінскій кодекс


47

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

Наприклад, якщо ваш текстовий блок є

TXT
BLK

потім запустіть програму

TXTTXTTXT
BLKBLKBLK
TXT   TXT
BLK   BLK
TXTTXTTXT
BLKBLKBLK

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

Аналогічно працює

TXTTXTTXTTXTTXTTXTTXTTXTTXT
BLKBLKBLKBLKBLKBLKBLKBLKBLK
TXT   TXTTXT   TXTTXT   TXT
BLK   BLKBLK   BLKBLK   BLK
TXTTXTTXTTXTTXTTXTTXTTXTTXT
BLKBLKBLKBLKBLKBLKBLKBLKBLK
TXTTXTTXT         TXTTXTTXT
BLKBLKBLK         BLKBLKBLK
TXT   TXT         TXT   TXT
BLK   BLK         BLK   BLK
TXTTXTTXT         TXTTXTTXT
BLKBLKBLK         BLKBLKBLK
TXTTXTTXTTXTTXTTXTTXTTXTTXT
BLKBLKBLKBLKBLKBLKBLKBLKBLK
TXT   TXTTXT   TXTTXT   TXT
BLK   BLKBLK   BLKBLK   BLK
TXTTXTTXTTXTTXTTXTTXTTXTTXT
BLKBLKBLKBLKBLKBLKBLKBLKBLK

слід вивести 2, оскільки це форма другої ітерації килима Сьєрпінського.

Запуск текстового блоку як є

TXT
BLK

має вивести, 0тому що це можна вважати нульовою ітерацією.

Це повинно працювати для всіх подальших ітерацій. (Принаймні теоретично, якщо припустити, що комп'ютер має пам'ять і все.)

Деталі

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

Ви можете використовувати цей фрагмент стека для створення килима для заданого текстового блоку на будь-якій ітерації:

<style>#o,#i{font-family:monospace;}</style><script>function c(e){e=e.split("\n");for(var n=new Array(3*e.length),t=0;t<n.length;t++){var l=t%e.length;n[t]=e[l]+(t>=e.length&&t<2*e.length?e[l].replace(/./g," "):e[l])+e[l]}return n.join("\n")}function f(){for(i=document.getElementById("i").value,n=parseInt(document.getElementById("n").value);n>0;)i=c(i),n--;document.getElementById("o").value=i}</script><textarea id='i'placeholder='code block...'rows='8'cols='32'></textarea><br>Iterations <input id='n'type='text' value='1'><br><br><button type='button'onclick='f()'>Generate</button><br><br><textarea id='o'placeholder='output...'rows='8'cols='32'style='background-color:#eee'readonly></textarea>

Оцінка балів

Переможцем є подання, початковий текстовий блок якого найменший за площею (ширина разів висота). TXT\nBLKПриклад 3 на 2 на бал 6. ( в основному короткі виграші коди, тому кодове поле для тега.)

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

Відповіді:


23

CJam, 9 байт

Я думаю, що це можна вдосконалити, але поки що, попустимо з цим ...

];U):U8mL

Як це працює :

];             "Wrap everything on stack in an array and discard it";
               "Before this point, the only thing on array can be the log 8 result of";
               "last updated value of U, or nothing, if its the first code";
  U):U         "Increment by 1 and update the value of U (which is pre initialized to 0)";
      8mL      "Take log base 8 of U. This is the property of Sierpinski carpet that";
               "the occurrence of the code is 8 to the power iteration count, indexed 0";

Спробуйте його онлайн тут


35

пієт - 32 * 6 = 192

введіть тут опис зображення

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

Ось друга ітерація: введіть тут опис зображення

оригінал: 32 * 7

введіть тут опис зображення


19

> <> , 11 * 2 = 22

";n"00pbi1v
+$3*:@3-0.>

Тут ми застосовуємо інший підхід, використовуючи функцію стрибка / телепорту> <>.

Програма виконує лише блоки у верхньому ряду, виконуючи 1-й / 2-й блок, потім 3-й / 4-й блоки, 9-й / 10-й блоки, 27-й / 28-й блоки тощо (збільшившись з потужністю 3). Оскільки у верхньому рядку є 3^nблоки, nвиконуються лише блоки до того, як програма завернеться до початку, виводить верхню частину стека та зупиняється (завдяки nінструкції, розміщеній через p).

Програма використовує правило "Вводу немає", оскільки iкоманда натискає -1 на стек, якщо EOF виконано. Тому для перевірки цього вам потрібно буде ввести порожній файл.


Попереднє подання, 7 * 4 = 28

l"v"10p
v>:1=?v
3  ;n{<
<^}+1{,

Перший рядок постійно висуває довжину стека для кожного блоку і змінює першу "цитату на стрілку вниз vза допомогою команди pput. На момент закінчення першого рядка стек виглядає так

[0, 1, 2, .., 3^n]

(Зверніть увагу, що початковий lвикористовується два рази.)

Останні три рядки потім підраховують, скільки разів нам потрібно розділити на 3, перш ніж натиснути на 1 (оскільки у <<> немає функції журналу). Нижній нуль використовується для відстеження підрахунку.


13

Перл, 26

$_+=.91/++$n;
die int."\n";

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

Стара версія (34):

$n--or$n=3**$s++;
print$s-1if!$o++;

Це дуже акуратно!
писклива косточка

10

Perl, 30 (15 × 2)

Перш за все, я хочу стверджувати, що 10 ітерацій - це розумна межа, а не 2 32 . Після 10 ітерацій програма, що складається з N байтів, розшириться до ( N × 3 20 ) байт (плюс розриви рядків), що перевищує 3 гігабайти навіть для N = 1. 32-розрядна архітектура не змогла б обробити 11 ітерацій. (І очевидно, у Всесвіті недостатньо частинок для 2 32 ітерацій).

Тож ось моє рішення:

$n++; $_=log$n;
print int;exit;

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

Простий логарифм для основи e (2.718 ..) досить близький, щоб дати правильні результати для перших 10 ітерацій.


2
Згідно з ОП, вона теоретично повинна працювати для всіх ітерацій.
Натан Меррілл

2
@NathanMerrill Ну добре. Але для дотримання оригінальної специфікації також довелося б працювати в альтернативних всесвітах. Запитання було відредаговано відтоді.
писклива косточка

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

Більшість із цих матеріалів зберігають контроль лише у верхньому ряду плиток 3 ^ nx 1. Якщо ви просто генеруєте цей сегмент килима, ви можете масштабувати трохи далі. Майже напевно до того, де помилки округлення вас зламають.
captncraig

1
Як я вже згадував, в оригінальному запитанні було задано код, який міг би масштабуватись до "розумної" кількості ітерацій (до 2 ^ 32) . Якщо ви зробите математику, ви побачите, що навіть один байт розшириться до понад 10 ^ 4098440370 байт після багатьох ітерацій. Я запропонував відповідь , який я думав , було трохи більше розумним, але з тих пір слово «розумний» зник з питання: - /. Подивіться, я закінчив тут. Просто спростуйте цю відповідь, якщо вона вам не подобається.
писклива косточка

9

Гольфскрипт, 9 * 2 = 18

0+       
,3base,(}

(Зверніть увагу, що в першому рядку є пробіли, які роблять його прямокутним)

Я не міг знайти функцію журналу для Golfscript, тому baseдовелося це зробити.

Гольфскрипт починається з порожнього рядка, тому 0+просто збільшує довжину рядка на 1 (за примусом). До того моменту, коли перший рядок закінчиться, стек буде мати довжину рядка 3^n, яку ми беремо на базу журналу 3, перш ніж ми супер коментуємо. nпотім автоматично друкується.


Ви можете зберегти два знаки, використовуючи ціле число замість рядка і, отже, зберегти ,на другому рядку. Перший рядок 0or):; другий рядок 3base,(}. Інша очевидна мета - це (на другому рядку. Це складніше, але його також можна видалити, замінивши перший рядок 1+~abs(на прямокутник 7 * 2.
Пітер Тейлор

8

C, 12x8 = 96

Натхненний @ciamej, я скоротив її. Він використовує ділення на 3 трюки плюс усвідомлення того, що килим ефективно перетворює цикл if у певний час.

Код був протестований на gcc / Ubuntu на повторення до 3.

#ifndef A //
#define A //
x;main(a){//
a++;/*    */
if(a/=3)x++;
printf(   //
"%d",x);} //
#endif    //

Попереднє рішення: C, 11x12

Не переможець розміру, але ей, це C.

Він знаходить log2 блок-рахунку шляхом біт-зміщення, потім використовує деякі магічні числа та урізання int для оцінки log3. Математика повинна працювати до 26 ітерацій (42-бітове число).

#ifndef A//
#define A//
int n=0;//_
int main//_
(v,c){//___
n+=1;/*..*/
while(n//__
>>=1)v++;//
n=.3+.62*v;
printf(//__
"%d",n);}//
#endif//__

Привіт, я опублікував скорочену версію вашого рішення.
ciamej

Гарний трюк з цим, якщо! ;)
ciamej

6

CJam, 9 байт

Ідея використання ]- від Optimizer, але для підрахунку використовується дуже інший метод.

X~]:X,8mL

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

Як це працює:

X~          "push X and dump its contents.  On the zeroth iteration, X is a single number, but later is it an array.";
  ]         "wrap everything into an array.  The stack would contain the contents of X plus the result of the previous instance of the code";
   :X       "store this array back into X.  X is now 1 element longer";
     ,      "take the length of X";
      8mL   "do a base-8 logarithm of it";

Два інших 9-байтних рішень

]X+:X,8mL

],X+:X8mL

Це насправді пов’язує оптимізатор, навіть із краваткою. : P Tiebreakerbreaker: виграли раніше повідомлення.
Захоплення Кальвіна

Я думаю, що це гарне рішення незалежно. Мені не вдалося перемогти 9 символів.
PhiNotPi

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

4

Пітон 2, 15 * 3 = 45

m=n=0;E=exit  ;
m+=1;n+=m>3**n;
print n;E()   ;

Ще одна реалізація ідеї count-first-row-then-log-three-and-exit. Можливо, все одно можна пограти в гольф справедливо трохи більше.



2

Гольфскрипт, 7 * 2 = 14

1+~abs(
3base,}

Це надихає Sp3000 в відповідь , і , зокрема , прагненням оптимізувати довгу другу лінію. 3base,такий короткий, як логарифм базового 3 отримає в GS, і супер коментар }явно оптимальний.

Перший рядок необхідний - це зіставити порожній рядок ''від початкового stdin до 0, а потім зіставити кожне невід'ємне ціле число на його наступника. Таким чином ми закінчуємо перший рядок 3^n - 1на стеці, і 3base,він не вимагає ніяких декрементів.


2

С, 13х8

#ifndef A//__
#define A//__
x;a;main(){//
a++;;;;;;;;;;
while(a/=3)//
x++;printf(//
"%d",x);}//__
#endif//_____

1

Перл, 76

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

$_++;                                 
if(not$_&$_-1){print log()/log 8;$_--}

@ Алекс, здається, не працює навіть на 1-й ітерації.
PhiNotPi

Так, це працює так, як є. Ви перевірили свій метод?
PhiNotPi

Шахта працює на ideone: ideone.com/othumP .
PhiNotPi

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

1

> <> (Риба), 12 * 3 = 36

Більш просте> <> рішення:

'v'00p0l1+  
>  :2-?v$1+v
^$+1$,3< ;n<

Спочатку запускаємо верхній ряд верхніх блоків. 'v'00pставить vна першу позицію всієї програми, спрямовуючи вказівник програми вниз, коли вона повертається до початку після досягнення кінця рядка. Перед цим кожен блок натискає на нього 0, а довжина стека + 1. (стек буде 0 2 0 4 0 6 ...)

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

В кінці виводимо другий на верхній елемент стека.


1

Луа, 3 * 17 = 51

Така ж стратегія, як і більшість людей:

x=(x or 0)+1;    
y=math.log(x,3)  
print(y)os.exit()

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