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

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

Мистер Xcoder
источник
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 байта, сократив вторую половину.

ETHproductions
источник
Поздравляю, проходит испытания, которые я сделал!
1
... Гениально! :)
Лохматый
17

Python 2 , 42 38 28 байт

id='%s@'%id  ;print id[22:];

Попробуйте онлайн! , Вы также можете попробовать 2-ю и 3-ю итерации

прут
источник
Э-э ... символ, а не строка.
user202729
@ user202729 спасибо за исправление, исправлено =]
Род
13

Python 2 , 22 байта

i=0;i+=1; i
print'*'*i

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

Вдвое:

i=0;i+=1; ii=0;i+=1; i
print'*'*i
print'*'*i

Обратите внимание, что вторая половина начинается с символа новой строки.

XNOR
источник
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

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

gastropner
источник
@ 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
6

Древесный уголь , 6 байт

⊞υωLυ⸿

Попробуйте онлайн! Объяснение:

  ω     Predefined empty string (any variable would do here)
 υ      Predefined initially empty list
⊞       Push

υ заканчивается длиной количества повторений.

    υ   List
   L    Length
        Implicitly print as a row of `-`s
     ⸿  Move to start of next line
Нил
источник
6

Haskell , 68 байт

let s@(z:n)="0\n"in case lines<$>[]of(h:t):_->(h:h:t)>>(z:h++n);_->s

Попробуйте онлайн один , два или три раза .

Из-за лени Хаскелла выражение, подобное приведенному выше, считается функцией, которая не принимает аргументов, согласно этому мета-вопросу .

Laikoni
источник
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был на третьем стеке. В качестве бонуса это также сделало получившийся квадрат более эстетичным.

Nitrodon
источник
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таких строк, а затем присоединяется к списку в новых строках. Результат отображается с завершающей новой строкой.

DLosc
источник
3

R , 44 байта

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

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

Печать с завершающим переводом строки. Это T=TRUE*TRUE+12просто, чтобы дополнить длину.

Попробуй вдвое и Попробуй втрое .

Giuseppe
источник
Вы можете удалить 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 и отмечает половину точки, позволяя добавлять туда код.

Giuseppe
источник
3

shortC , 56 44 байта

-12 байт: подожди, я использую shortC, почему бы не использовать сокращенный материал C

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

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

MD XF
источник
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сама строка будет включена, что происходит прямо в середине кода.

GammaFunction
источник
LOL @ "небольшое" улучшение. может также выразить это какs+=0;<<<$s
roblogic