Создайте квадрат увеличивающегося размера путем репликации исходного кода


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! Я предлагаю использовать Песочницу для ваших будущих задач.
user202729

7
Добро пожаловать на сайт! Превосходное использование другой задачи для вдохновения, не попадая в ловушку для дураков :)
Shaggy

Ваша вспомогательная программа не работает для программ с несколькими строками. Как насчет этой модифицированной версии из другого вопроса?
Джо Кинг

1
@ user77954 Но мой мозговой код короче, чем твой питон :( (кто-нибудь когда-нибудь говорил это раньше?)
Джо Кинг,

Ответы:


41

Pyth , 2 байта


5

Попробуйте онлайн! Также попробуйте это в два раза , в три раза !

Как это работает?

\nэто команда, которая печатает свой аргумент с завершающей строкой, возвращая его одновременно. Таким образом, каждый раз, когда вы делаете вставку, вы превращаете целочисленный литерал 5 в число, содержащее N копий из 5 сцепленных строк, и ведущие символы новой строки в основном удостоверяются, что он печатается соответствующее количество раз, сохраняя его квадратным.


6
Черт возьми, это коротко ...
ETHproductions

Доказательство оптимальности (: P): Поскольку число байтов должно быть четным и не может быть отрицательным, минимально возможное число байтов равно 0 байтов. Существует ровно 1 программа из 0 байтов, которая не выполняет задачу. Поэтому 2 байта является оптимальным.
г-н Xcoder

10
Все (особенно избиратели HNQ), также проголосуйте за другие ответы и избегайте эффекта FGITW.
user202729

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
... Гениально! :)
Лохматый




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;

Попробуйте онлайн! , Вторая и третья итерация

Это использует тот факт, что bools в Python в основном являются целочисленными значениями и именами Falseи Trueбыли переназначены в Python 2.

Python 1 , 32 байта

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

Попробуйте онлайн! , Вторая и третья итерация

В Python 1 строки встроенных exitи quitсуществует , чтобы информировать пользователя о интерактивной оболочки , как выйти из нее. Значением по умолчанию является "Use Ctrl-D (i.e. EOF) to exit.".


1
Я собирался предложить n=False+=1;print'*'*n;, но я продолжаю забывать, что это не особенность Python ...
ETHproductions





5

Brain-Flak , 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 возобновится прямо с того места, где оно остановилось.

Несмотря на то, что можно выдвинуть печатное значение ASCII (пробел) в 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)

Попробуйте онлайн! Также вдвое и в пять раз .

Подход «построить строку в первой половине, напечатать ее во второй половине», который используется многими языками, не будет работать в tinylisp, поскольку нет изменяемых переменных. Вместо этого мы делаем серьезное вложение кода.

Когда вторая копия кода вставлена, она помещается внутрь (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

@ AndreïKostyrka это будет 43 байта, что, к сожалению, даже не так.
Джузеппе


3

СНОБОЛ4 (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 неявно.


2

Perl 5 , 25 байт

24-байтовый код + 1 для -p.

Примите во внимание, что вы, возможно, не хотите разрешать флаги командной строки, пожалуйста, дайте мне знать, если это не правильно.

$@=0 x++$n;;$_="$@
"x$n;

Попробуйте онлайн!



1

Зш , 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и новой строкой, следующей за ней. Heredoc прекратит работу, когда Eсама строка будет включена, что происходит прямо в середине кода.


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