Utwórz kwadrat o rosnącym rozmiarze, replikując kod początkowy


45

Twoim zadaniem jest napisanie programu o równej długości , który drukuje kwadrat ASCII-art (opisany poniżej), który zwiększa jego długość boku o 1 jednostkę za każdym razem, gdy oryginalny kod źródłowy jest wklejany w środku bieżącego kodu.

Bardzo trudno jest mi bardzo dobrze zdefiniować to zadanie, dlatego dam wam przykład:

  • Powiedzmy, że twój początkowy kod był CODEi że został wydrukowany:

    0
    
  • Następnie wstaw CODEw środku: kod staje się COCODEDEi powinien zostać wydrukowany:

    00
    00
    
  • Ponownie wstaw CODEw środku: kod staje się COCOCODEDEDE i powinien zostać wydrukowany:

    000
    000
    000
    
  • I tak dalej. Twoja odpowiedź powinna teoretycznie zadziałać po dowolnej liczbie iteracji, ale rozumiem, czy z powodu ograniczeń wydajności językowej nie można rozsądnie przekroczyć określonego progu.

Niektóre zasady:

  • Możesz użyć dowolnego drukowalnego ASCII (32-127) jako znaku używanego dla twojego kwadratu. Twój wybór musi być stały (powinieneś używać tego samego znaku dla każdej iteracji).

  • Początkowy kwadrat wyjściowy musi mieć długość boku 1 .

  • Kwadrat ascii-art jest zdefiniowany jako ciąg z N liniami (oddzielonymi liniami N-1 linii / znaków nowej linii), a każda linia zawiera N kopii wybranego znaku.

  • Twoje dane wyjściowe nie mogą zawierać żadnych obcych znaków innych niż końcowy znak nowej linii.

  • Możesz użyć wartości domyślnych dla wejścia i wyjścia (programy lub funkcje są dozwolone, ale fragmenty nie są).

  • Środkowy o kodzie jest zdefiniowany jako punkt, gdzie kod źródłowy może być podzielona na dwie części tak, że dwie są równe.

  • Twoje odpowiedzi zostaną ocenione według długości oryginalnego programu , w bajtach. Wygrywa najniższa liczba bajtów. W przypadku remisu odpowiedź przesłana wcześniej wygrywa.

  • Możesz użyć tego programu do zastosowania wstawek bez konieczności robienia tego ręcznie.


1
Muszę przyznać, że zainspirowało mnie to postawione wcześniej pytanie . Jeśli ludzie uważają, że jest zbyt blisko, chętnie to usunę. Przepraszam również, jeśli popełniłem jakieś błędy, nadal nie mam zbyt dużego doświadczenia z zasadami tutaj. :)

2
Witamy w PPCG! Sugeruję korzystanie z piaskownicy do przyszłych wyzwań.
user202729

7
Witamy na stronie! Doskonałe wykorzystanie innego wyzwania dla inspiracji bez wpadania w pułapkę dupe :)
Shaggy

Twój program pomocniczy nie działa dla programów z wieloma liniami. Co powiesz na tę zmodyfikowaną wersję z drugiego pytania?
Jo King

1
@ user77954 Ale mój pieprzony mózg jest krótszy niż twój python :( (czy ktoś to kiedyś powiedział?)
Jo King

Odpowiedzi:


41

Pyth , 2 bajty


5

Wypróbuj online! Spróbuj także dwukrotnie , trzykrotnie !

Jak to działa?

\nto polecenie, które wypisuje swój argument na końcu nowej linii, jednocześnie zwracając go . Tak więc, za każdym razem, gdy wstawiasz, zamieniasz literał całkowitą 5 na liczbę zawierającą N kopii 5 połączonych, a wiodące znaki nowej linii w zasadzie upewniają się, że drukowana jest odpowiednia liczba razy, dzięki czemu jest kwadratowa.


6
Cholera, to krótko ...
ETHprodukcje

Dowód optymalności (: P): Ponieważ liczba bajtów musi być parzysta i nie może być ujemna, minimalna możliwa liczba bajtów wynosi 0 bajtów. Jest dokładnie 1 program z 0 bajtami, który nie spełnia zadania. Dlatego 2 bajty są optymalne.
Pan Xcoder,

10
Wszyscy (zwłaszcza wyborcy HNQ), głosujcie też na inne odpowiedzi i unikajcie efektu FGITW.
user202729

25

JavaScript (ES6), 42 32 30 bajtów

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

Druga iteracja:

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

Działa to poprzez dołączanie a 0do skażdorazowego uruchomienia pierwszej połowy kodu i drukowanie ssię za każdym razem, gdy uruchamiana jest druga połowa. Wykorzystuje cztery dziwactwa JavaScript:

  1. Do bieżącego środowiska można się odwołać za pomocą this. To pozwala nam zrobić this.szamiast s.
  2. Podczas uzyskiwania dostępu do właściwości, która nie została zdefiniowana w obiekcie, zamiast zgłaszania błędu, JavaScript zwraca undefined.
  3. Tablica plus liczba zwraca ciąg znaków. [1,2,3] + 4 === "1,2,34"
  4. Podczas tworzenia łańcucha tablica undefinedjest konwertowana na pusty ciąg znaków, co oznacza, że [undefined] + 0 === "0".

Podsumowując, oznacza to, że możemy wyrazić pierwszą połowę (generowanie ciągu zer) w zaledwie 13 bajtach. Jeśli użycie alertzamiast console.logjest dozwolone, możemy zaoszczędzić 4 bajty, skracając drugą połowę.


Gratulacje, zaliczam testy, które wykonałem!

1
... Pomysłowy! :)
Kudłaty



13

Python 2 , 22 bajty

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

Wypróbuj online!

Podwojony:

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

Zauważ, że druga połowa zaczyna się od znaku nowej linii.


9

C (gcc) , 170 168 96 80 72 70 bajtów

Znacznie krótsza wersja. Nadal chciałbym znaleźć rozwiązanie bez preprocesora.

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

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

Wypróbuj online!

Stara 168 bajtowa wersja:

#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

Wypróbuj online!



@ user202729 ah, tak. Myślałem, że poprawiłem literówkę, ale wprowadziłem błąd. Cofanie
gastropner

8

Python 2 , 30 bajtów

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

Wypróbuj online! , 2. i 3. iteracja

To sprawia, że korzystać z faktu, że bools w Pythonie są zasadniczo ints i nazwiska Falsei Truebyły ponownie przypisać w Pythonie 2.

Python 1 , 32 bajty

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

Wypróbuj online! , 2. i 3. iteracja

W Pythonie 1 struny wbudowanych exiti quitistniał do informowania użytkownika o interaktywnej powłoki jak to wyjść. Wartość domyślna to "Use Ctrl-D (i.e. EOF) to exit.".


1
Chciałem zasugerować n=False+=1;print'*'*n;, ale ciągle zapominam, że to nie jest funkcja Pythona ...
ETHproductions

6

Węgiel , 6 bajtów

⊞υωLυ⸿

Wypróbuj online! Wyjaśnienie:

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

υ kończy się na długości liczby powtórzeń.

    υ   List
   L    Length
        Implicitly print as a row of `-`s
     ⸿  Move to start of next line

6

Haskell , 68 bajtów

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

Wypróbuj online raz , dwa lub trzy razy .

Ze względu na lenistwo Haskella wyrażenie takie jak powyższe liczy się jako funkcja, która nie przyjmuje żadnych argumentów, jak na to pytanie Meta .




5

Brain-Flak , 74 bajty

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

Wypróbuj online!

Spróbuj podwoić i potroić .

Wyjaśnienie

(((((()()()){}){}){}){}) # 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

Punkt przerwania znajduje się pośrodku <>sekcji „push 10”. Zerwanie tego spowoduje pozostawienie 5 na trzecim stosie, aż dojdziemy do odpowiedniej drugiej połowy, w którym to momencie pchanie 10 wznawia się tam, gdzie zostało przerwane.

Chociaż możliwe jest wypchnięcie drukowanej wartości ASCII (spacji) do 22 bajtów, spowodowałoby to, że centrala <>byłaby wykonywana po wypchnięciu 5. Dodając jeszcze dwa bajty, byłem w stanie przenieść <>tak, że cały postęp w kierunku pchania 10był na trzecim stosie. Jako bonus, to również sprawiło, że powstały kwadrat był bardziej estetyczny.



4

tinylisp , 112 bajtów

(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)

Wypróbuj online! Również dwukrotnie i pięciokrotnie .

Podejście „buduj łańcuch w pierwszej połowie, drukuj w drugiej połowie”, że wiele języków używa, nie będzie działać w tinylisp, ponieważ nie ma zmiennych zmiennych. Zamiast tego wykonujemy poważne zagnieżdżanie kodu.

Po wstawieniu drugiej kopii kodu jest on umieszczany wewnątrz (q()), który zawija go na liście. Następnie (h(t(t(h(t(...))))))przechodzi do tej listy do następnej części (d N. (v(...))ocenia to; następnie przekazujemy ją do funkcji bez nazwy (q((x)(i x(inc x)1))), która zwiększa wynikową wartość, jeśli jest liczbą, i zwraca 1, jeśli jest to pusta lista. Ostateczny wynik w najbardziej zagnieżdżonej wersji kodu jest przypisany do N. Zasadniczo stworzyliśmy dziwny rodzaj rekurencji, który liczy liczbę poziomów zagnieżdżenia.

Druga połowa kodu tworzy następnie ciąg Ngwiazdek, następnie listę Ntakich ciągów, a następnie dołącza się do listy w nowej linii. Wynik jest wyświetlany z końcowym znakiem nowej linii.


3

R , 44 bajty

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

Wypróbuj online!

Drukuje z końcowym znakiem nowej linii. To T=TRUE*TRUE+12po prostu podbić długość.

Spróbuj podwoić i spróbuj potroić .


Możesz wyeliminować 2 bajty, usuwając średniki. Podejrzewam, że na końcu pierwszego wiersza jest spacja, którą możesz zastąpić znakiem #: F=F+1;T=TRUE*TRUE+12#<newline>write(strrep(1,F),"")
Andreï Kostyrka

@ AndreïKostyrka byłoby to 43 bajty, co nie jest nawet niestety.
Giuseppe,

3

Julia 0.6 , 29 bajtów

Wszystkie moje pomysły były dłuższe niż dostosowanie sprytnego rozwiązania pythonowego xnor.

i=0;i+=1;    i
println("0"^i)

Staje się

i=0;i+=1;    ii=0;i+=1;    i
println("0"^i)
println("0"^i)

Wypróbuj online!


3

SNOBOL4 (CSNOBOL4) , 130 68 bajtów

Teraz bez komentarzy! Zobacz historię edycji, aby uzyskać wyjaśnienie starego algorytmu.

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

Wypróbuj online!

Spróbuj podwoić i potroić

Wyjaśnienie:

	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

Ponieważ ENDetykieta jest wymagana i wszystko po pierwszej ENDetykiecie jest ignorowane, otrzymujemy dwie zalety tego wyzwania:

  • operacje w pierwszej połowie programu są powtarzane Xrazy dla Xpowtórzeń
  • (dla tłumacza) będzie istniała tylko jedna kopia drugiej połowy, w tym etykiety .

Sugeruje to, że używamy powtórzeń w pierwszej połowie, a następnie możemy zastosować bardziej „konwencjonalne” podejście do etykietowania, aby powtórzyć Xczasy wyjściowe .

Pierwsza połowa to

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

który, po powtórzeniu, zwiększa Xodpowiednią liczbę razy i tworzy ARRAY Aindeksy od 1do Xi gdzie każdy element Aciągu jest 1powtarzany Xrazy.

Następnie, bez względu na to, ile razy program się powtarza, interpreter widzi tylko:

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

który jest typowym programem SNOBOL, który drukuje elementy Apojedynczo, aż indeks przekroczy limit, a następnie kończy działanie programu.

;jest opcjonalnym zakończeniem linii zwykle zarezerwowanym dla jednowierszowych EVALlub CODEinstrukcji, które dość starannie zwiększają liczbę bajtów do 68 i oznaczają punkt w połowie, pozwalając na dołączenie tam kodu.




1

Zsh , 10 bajtów

s+=0
<<<$s

Wypróbuj pełny pakiet testowy online!

... tak, to jest trochę lepsze. Dołącz do ciągu N razy, a następnie wydrukuj N razy. Okazuje się, że <<<foo<<<foodziała dobrze.


Zsh , 64 bajty

Zastosowana postać: (spacja).

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

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

Wypróbuj pełny pakiet testowy online!

Punkt środkowy znajduje się między drugą Ea następującą po nim nową linią. Heredoc zakończy się, gdy pojawi się Esam wiersz, co dzieje się w samym środku kodu.


lol @ „nieznaczna” poprawa. może również wyrazić to jakos+=0;<<<$s
roblogic
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.