Створіть квадрат збільшуваного розміру шляхом реплікації початкового коду


45

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

Мені досить складно визначити це завдання дуже добре, тому я наведу вам приклад:

  • Скажімо, ваш початковий код був CODEі що він надрукував:

    0
    
  • Потім вставте CODEв середину: ваш код стає COCODEDEі він повинен надрукувати:

    00
    00
    
  • Повторно вставляйте CODEпосередині: ваш код стає COCOCODEDEDE та повинен друкувати:

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

Деякі правила:

  • Ви можете використовувати будь-який друкований ASCII (32-127) в якості символу для площі. Ваш вибір повинен бути постійним (для кожної ітерації слід використовувати один і той же символ).

  • Початковий квадрат виходу повинен мати довжину сторони 1 .

  • Квадрат ascii-art визначається як рядок з N рядками (розділеними N-1 рядками / новинками рядка), і з кожним рядком, що містить N копій обраного символу.

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

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

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

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

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


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

2
Ласкаво просимо до PPCG! Я пропоную використовувати пісочницю для своїх майбутніх проблем.
користувач202729

7
Ласкаво просимо на сайт! Відмінне використання чергового виклику для натхнення, не потрапляючи в пастку :)
Shaggy

Ваша помічна програма не працює для програм з декількома рядками. Як щодо цієї модифікованої версії з іншого питання?
Джо Кінг

1
@ user77954 Але мій код для епізодів коротший, ніж ваш python :( (хтось коли-небудь говорив про це раніше?)
Jo King

Відповіді:


41

Pyth , 2 байти


5

Спробуйте в Інтернеті! Також Спробуйте в два рази , в три рази !

Як це працює?

\nце команда, яка друкує свій аргумент із заднім рядком, одночасно повертаючи його . Отже, кожного разу, коли ви робите вставку, ви перетворюєте ціле число буквально 5 на число, що містить N копій з 5 з’єднаних, а провідні рядки в основному переконайтеся, що він надрукований відповідну кількість разів, таким чином зберігаючи його квадратним.


6
Святий викрут, який короткий ...
ETHproductions

Доказ оптимальності (: P): Оскільки кількість байтів має бути парним і не може бути негативним, мінімально можливе число байтів становить 0 байт. Існує рівно 1 програма з 0 байтів, яка не виконує завдання. Тому оптимально 2 байти.
Містер Xcoder

10
Усі (особливо виборці HNQ) також запросити інші відповіді та уникати ефекту FGITW.
користувач202729

25

JavaScript (ES6), 42 32 30 байт

s=[this.s]+0;  console.log(s);

Друга ітерація:

s=[this.s]+0;  s=[this.s]+0;  console.log(s);console.log(s);

Це працює, додаючи 0до sкожного разу запуск першої половини коду та друкуючи sсебе щоразу, коли виконується друга половина. Скористається чотирма диваками JavaScript:

  1. Поточне середовище можна посилатися на this. Це дозволяє нам робити this.sзамість s.
  2. Під час доступу до властивості, яка не була визначена на об'єкті, замість того, щоб видавати помилку, JavaScript повертається undefined.
  3. Масив плюс число повертає рядок. [1,2,3] + 4 === "1,2,34"
  4. При строфікації масиву undefinedперетворюється на порожній рядок, що означає, що [undefined] + 0 === "0".

У сукупності це означає, що ми можемо виразити першу половину (генеруючи рядок нулів) всього в 13 байтах. Якщо використання alertзамість console.logдозволеного, ми можемо зберегти ще 4 байти, скорочуючи другу половину.


Вітаю, здає тести, які я зробив!

1
... Геніальний! :)
Shaggy




9

C (gcc) , 170 168 96 80 72 70 байт

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

i;main(n){for(;i++<n;)printf
#if 0

#endif
(" %*c",n=__LINE__/4, 10);}

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

Стара версія 168 байт:

#ifndef A
#define A p(c){putchar(c);}j,n;main(i){for(
#else
#define A n++,
#endif
A



#ifndef B
#define B i=++n;i--;p(10))for(j=n;j--;)p(64);}
#else
#define B
#endif
B

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



@ user202729 ах, так. Думав, що я виправив помилку, але ввів помилку. Повернення.
гастропнер

8

Python 2 , 30 байт

False+=1      ;print'*'*False;

Спробуйте в Інтернеті! , 2- а та 3-я ітерації

Це використовує той факт, що bools в Python в основному є int та іменами, Falseі їх можна Trueбуло призначити в Python 2.

Пітон 1 , 32 байти

exit=exit+'*'  ;print exit[30:];

Спробуйте в Інтернеті! , 2- а та 3-я ітерації

У Python 1 вбудовані рядки exitта quitіснували, щоб повідомити користувачеві інтерактивну оболонку про вихід із неї. Значенням за замовчуванням є "Use Ctrl-D (i.e. EOF) to exit.".


1
Я збирався запропонувати n=False+=1;print'*'*n;, але я постійно забуваю, що це не особливість Python ...
ETHproductions





5

Мозок-Флак , 74 байти

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

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

Спробуйте це вдвічі і втричі .

Пояснення

(((((()()()){}){}){}){}) # push 48 ("0") onto first stack
((()()()()()<>){})       # push 10 (\n) onto second stack
<>([]){({}[()]<          # a number of times equal to the height of the first stack:
  (({})<>)<>             #   copy the top of the first stack to the second stack
>)}{}<>                  # cleanup and return to second stack

Точка розриву знаходиться посередині <>в розділі "push 10". Розбивши це, ми залишимо 5 на третій стек, поки ми не досягнемо відповідної другої половини, і тоді, натиснувши 10, відновиться прямо там, де він зупинився.

Хоча можна висунути значення друку (пробіл) для друку в 22 байтах, це зробить центральне <>виконання після натискання 5. Додавши ще два байти, я зміг перемістити <>так, щоб увесь прогрес до натискання 10був на третьому стеку. Як бонус, це також зробило отриманий квадрат більш естетично.



4

тинілісп , 112 байт

(load library) (d N((q((x)(i x(inc x)1)))(v(h(t(t(h(t(q())))))))))(join(repeat-val(string(repeat-val 42 N))N)nl)

Спробуйте в Інтернеті! Також вдвічі і в п’ять разів .

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

Коли вводиться друга копія коду, вона розміщується всередині (q()), що додає її до списку. Потім (h(t(t(h(t(...))))))перегляньте цей список до частини після (d N. (v(...))оцінює його; потім ми передаємо його до безіменної функції (q((x)(i x(inc x)1))), яка збільшує отримане значення, якщо це число, і повертає 1, якщо це порожній список. Кінцевий результат присвоюється найбільш віддаленій гніздовій версії коду N. По суті, ми створили дивний тип рекурсії, який підраховує кількість рівнів вкладення.

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


3

R , 44 байти

F=F+1;T=TRUE*TRUE+12;
write(strrep(1,F),"");

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

Друкується із заднім рядком. Це T=TRUE*TRUE+12просто набивати довжину.

Спробуйте вдвічі і спробуйте втричі .


Ви можете усунути 2 байти, видаливши крапки з комою. Я припускаю, що в кінці першого рядка є пробіл, який ви можете замінити на #: F=F+1;T=TRUE*TRUE+12#<newline>write(strrep(1,F),"")
Андрей Костирка

@ AndreïKostyrka, це було б 43 байти, що навіть не, на жаль.
Джузеппе


3

SNOBOL4 (CSNOBOL4) , 130 68 байт

Тепер без коментарів! Подивіться історію редагування для пояснення старого алгоритму.

	X =X + 1
	A =ARRAY(X,DUPL(1,X));
I	I =I + 1
	OUTPUT =A<I>	:S(I)
END

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

Спробуйте це вдвічі і втричі

Пояснення:

	X =X + 1		;* increment X
	A =ARRAY(X,DUPL(1,X));	;* create an x-length array with 1 repeated x times for each element
I	I =I + 1		;* for i < x
	OUTPUT =A<I>	:S(I)	;* output a[i]
END

Оскільки ENDмітка потрібна і все після першого ENDмітки ігнорується, ми отримуємо дві переваги для цього виклику:

  • Операції в першій половині програми повторюються Xдля Xповторень
  • існуватиме (для перекладача) лише один примірник другої половини, включаючи етикетки .

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

Перша половина - це

	X =X + 1
	A =ARRAY(X,DUPL(1,X));

який при повторенні збільшує Xвідповідну кількість разів і створює ARRAY Aіндекси від 1до Xі де кожен елемент A- це рядок, 1повторений Xраз.

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

I	I =I + 1
	OUTPUT =A<I>	:S(I)
END

яка є типовою програмою SNOBOL, яка друкує елементи по Aодному, поки індекс не виходить за межі, а потім припиняє програму.

;- необов'язковий термінатор рядка, як правило, зарезервований для однорядного EVALчи CODEвисловлювань, який досить акуратно приводить кількість байтів до 68 і позначає півдороги, що дозволяє додавати туди код.


3

shortC , 56 44 байт

-12 байт: зачекайте, я використовую shortC, чому б не використовувати деякі скорочені речі C

s[];A
strcat(s,"@");//
Js);/*filling space*/

Я б використав стандартний C, але для цього потрібен }кінець, який псується з реплікацією. shortC вставляє його в EOF неявно.



1

Zsh , 10 байт

s+=0
<<<$s

Спробуйте повний тестовий набір онлайн!

... так, це трохи краще. Додайте до рядка N разів, а потім надрукуйте N разів. Виявляється, <<<foo<<<fooпрацює просто чудово.


Zsh , 64 байт

Використовуваний символ: (пробіл).

f(){printf '%*s\n' $1}
:<<'E'

E
repeat $[i=LINENO/3];f $i
exit

Спробуйте повний тестовий набір онлайн!

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


lol @ "незначне" поліпшення. може також висловити це якs+=0;<<<$s
roblogic
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.