W przypadku tego wyzwania kołdra artystyczna ASCII będzie blokiem tekstu o szerokości 24 znaków i wysokości 18 linii, zawierającym znaki =-<>/\
w podobny do kołdry wzór, który jest symetryczny poziomo i pionowo.
Przykładowa kołdra:
========================
------------------------
//\\//\\\//\/\\///\\//\\
<<><<>>>>><<>><<<<<>><>>
/\\/\\\\/\/\/\/\////\//\
------------------------
/\/////\\///\\\//\\\\\/\
\///\/\/\\\\////\/\/\\\/
\///\/\/\\\\////\/\/\\\/
/\\\/\/\////\\\\/\/\///\
/\\\/\/\////\\\\/\/\///\
\/\\\\\//\\\///\\/////\/
------------------------
\//\////\/\/\/\/\\\\/\\/
<<><<>>>>><<>><<<<<>><>>
\\//\\///\\/\//\\\//\\//
------------------------
========================
Wszystkie kołdry mają tę samą formę:
- Są zawsze 24 na 18.
- Górna linia (linia 1) i dolna linia (linia 18) są
=
na całej długości . - Linie 2, 6, 13 i 17 są
-
na całej długości. - Linie 4 i 15 są tym samym losowym symetrycznym wzorem poziomym
<
i>
. - Wszystkie inne linie (3, 5, 7, 8, 9, 10, 11, 12, 14, 16) są wypełnione
/
i\
w całkowicie losowy sposób, że cała kołdra pozostaje poziomo i pionowo symetryczny .
Zauważ, że przy składaniu kołdry dokładnie na pół, pionowo lub poziomo, kształty postaci dokładnie do siebie pasują. Nie myl tego z dopasowanymi postaciami. np. linia 3 i linia 16 nie są identyczne, są to lustrzane odbicie w pionie.
Wyzwanie
Napisz program lub funkcję, która wydrukuje lub zwróci losową kołdrę artystyczną ASCII.
Ze względu na wiele zakodowanych linii i symetrię, jedyna prawdziwa losowość pochodzi od pierwszych 12 znaków w wierszach 3, 4, 5, 7, 8, 9:
- Pierwsze 12 znaków w linii 4 powinno mieć dowolny ciąg 12 znaków
<
i>
. - Pierwsze 12 znaków w wierszach 3, 5, 7, 8, 9 powinno mieć dowolny ciąg 12 znaków
/
i\
(niezależnie od siebie). - Te losowe sznurki są następnie odpowiednio dublowane, tworząc całą kołdrę.
Najkrótsza odpowiedź w bajtach wygrywa. Tiebreaker jest wcześniejszym postem.
Możesz użyć generatorów liczb pseudolosowych. (Nie, nie musisz udowadniać, że wszystkie 12 ciągów znaków <>
lub /\
PRNG twojego języka może zostać wygenerowany.)
Wynik może opcjonalnie zawierać końcowy znak nowej linii, ale nie może zawierać spacji końcowych ani innych znaków poza tym, co jest konieczne do pikowania.
Odpowiedzi:
CJam,
61605855545251 bajtówTrochę skrócono z pomocą Sp3000 i Optimizera.
Sprawdź to tutaj.
Wyjaśnienie
Jak zwykle w przypadku tych symetrycznych wyzwań artystycznych ASCII, generuję jeden kwadrant, a następnie rozszerzam go do pełnego zakresu za pomocą dwóch odpowiednich operacji dublowania.
Dla tego wyjaśnienia powinienem zacząć od funkcji
F
, którą gdzieś definiuję, ponieważ jest używana w trzech miejscach dla trzech różnych rzeczy:Oczekuje liczby całkowitej na górze stosu, a pod nią łańcucha. Jego celem jest odwrócenie łańcucha, a także zamiana niektórych znaków, aby uzyskać prawidłowe odbicie lustrzane. Liczba całkowita jest albo
1
czy3
i wskazuje, czy (1
) obydwa wsporniki i tnie powinny być wymieniane lub (3
) tylko uchwyty powinny być zamienione. Oto jak to działa:Teraz reszta kodu:
Dwie połówki i ta jedna nowa linia są następnie automatycznie drukowane na końcu programu.
źródło
Python 3,
257229192185176149143 bajtówZ pomocą @xnor w końcu dogoniliśmy JS!
Przykładowe dane wyjściowe:
Wyjaśnienie
(Nieco przestarzałe, zaktualizuje później)
"444046402"
koduje wiersze, a każda cyfra odnosi się do indeksu początkowego odpowiedniego 2-znakowego podłańcucha z'--==\/<>'
. Każdy pojedynczy rząd jest budowany na lewą stronę przez wielokrotne tasowanie dwóch znaków (używającsample(...,2)
, ponieważrandom.shuffle
niestety jest na miejscu) i łączenie łańcuchów.Uproszczonym przykładem tego, jak mogłoby wyglądać rozszerzenie dla czwartego rzędu, jest:
co dałoby
><>><><<><
:Ogólna kołdra jest również budowana na lewą stronę, ponieważ konstrukcja zaczyna się od rzędów 9/10, na zewnątrz. Aby to zrobić, zaczynamy od pustej listy
L
, do której dodajemy wiersze na początku i na końcun<"5"
Warunkiem jest, aby sprawdzić, czy mamy wiersz składają się><
, w tym przypadku dodajemy identyczną wiersz do tyłu, w przeciwnym razie jego odwrót.Wreszcie,
*_,=
jest wymuszenie ocenymap
tak, aby drukowanie miało miejsce, i jest to tylko krótszy sposóbprint("\n".join(L))
.Przez długi czas miałem tę funkcję
która pobiera ciąg i konwertuje
/\><
do\/<>
odpowiednio, ale wreszcie udało mi się go pozbyć :)źródło
Python 2, 300 bajtów
Ten program używa
join, lambda, replace, sample, import
i innych pełnych funkcji, więc nie zdobędzie żadnych nagród golfowych.Kod zanim auto-golfista go zdobył:
Przykładowy wynik:
źródło
APL (
5358)To nie do końcaNiestety tak symetryczny, jak myślałem. Poprawka kosztowała mnie 5 znaków, a teraz nie mam szans.
Wyjaśnienie:
L←+,3-⌽
: L jest funkcją, która zwraca argument, po którym następuje 3 - odwrotność argumentuL{L?12⍴2}¨⍳9
: generate 9 lines of 12 random values from [1,2] plus their reverse, then the reverse of those 9 lines732451451260688⊤⍨18/8
: generate the list0 2 4 6 4 2 4 4 4 4 4 4 2 4 _7_ 4 2 0
(that's where the damn asymmetricality is)+
: for each line, add the corresponding number to each value↑
: format as matrix'==--/\<><'[
...]
: for each of the numbers in the matrix, select the character from the string at that positionOutput:
źródło
<>
lines are not vertically symmetrical as you use your swap table when making the vertical mirror as well. (Thanks for posting the output btw, makes figuring out if APL works much easier ;p )<
to the end of the string, and incrementing the second line once more, thereby swapping it twice). Didn't even have to scrap the whole thing, though it won't win anymore now. (Perhaps next time I should't post the output :P)PHP,
408,407,402,387, 379 bytesI am not a good golfer, but this problem sounded fun so I gave it a try.
Ungolfed code
The ungolfed version has a little bonus: You can pass it an integer to seed
rand()
and get the same quilt each time for a seed:This results, for example, in this beautiful, hand woven quilt:
Edit: Turns out my first version did not return a correct quilt. So I fixed it. Funny enough, the fix is even shorter.
źródło
['/','<','\\','>','a','b']
can be replaced with['/','<','\\','>',a,b]
(notice the missing quotes arounda
andb
),@$s
can be replaced with$s
, you can storestr_repeat('-',12)
andstr_repeat('=',12)
in global variables/constants,for($b=8;$b>=0;$b--)
can be replaced withfor($b=9;$b--;)
,str_repeat
and repeated functions can be shortened by giving their name to a global variable (e.g.:global$R,$V;$R=str_repeat;$V=strrev;$V($R('=',12))
) and newlines (\n
) may be replaced by a multi-line string.strrev
unchanged, removed 1 space and a few small changes.<>><><
lines) to be the same.JavaScript (ES6) 169
195 201Edit 6 bytes saved thx @nderscore. Beware, the newline inside backquotes is significant and counted.
Edit2 simplified row building, no need of
reverse
andconcat
Run snippet to test (in Firefox)
źródło
z
. Move definition ofQ
inside of theMath.random
call. Replace'\n'
with template string of newline.|0
integer casting is not needed, as the values will be xor-ed later on.for(_ of-z+z)
mean?z
is not numeric so -z is NaN (not a number) NaN converted to string is "NaN" and 3 chars + 9 chars are 12.Ruby,
162155I like this one because it made me learn to abuse backslashes in both string literals and
String#tr
. The code isn't terribly clever otherwise, just compact.źródło
/
ina
andb
. The firsttr
can probably also do without parentheses. Single-character strings like'='
can be written?=
. And.join
can be replaced by*
.join
synonym save me 6 bytes. I can't remove the parentheses inx+x.reverse.tr(a,b)
because+
takes precedence over,
though. I'm also not actually escaping the slashes in my strings - I'm failing to escape one backslash in each. A second\
is necessary inb
because of the waytr
works, though I now realize the first\
ina
is superfluous, so there's another byte.Pyth, 57
59 61Thanks a lot to @Jakube for coming up with these 57 byte versions.
Algorithm very similar to Martin's. (Revised) Explanation to come.
Try it online
Explanation:
źródło
"<>"
with-GK
J"\<>/"K"\/"L+b_mXdK_Kbjbym+d_XdJ_JmsmOk12[\=\-K-JKK\-KKK
or reduceJ"\<>/"K"\/"jbu++HGXHK_Km+d_XdJ_JmsmOk12[KKK\-K-JKK\-\=)Y
J,
5654 bytesUsage:
1 byte thanks to @FUZxxl.
Explanation coming soon.
Try it online here.
źródło
5 1 3 1 5 1 1 1
with(3(2})8$5,3#1)
.Python
295287227 bytesNot that great but I'll post it anyway:
If you want an explanation just ask me.
źródło
=
and-
ind
.Javascript (ES7 Draft)
174168146Some inspiration taken from @edc65
Edit: Thanks to edc65 for some ideas to optimize building of rows.
Demonstration: (Firefox only)
Commented:
źródło
Pharo 4, 236
or formatted normally:
Explanation:
The string
s:='====----/\/\/<><<>'
together with the blockf:=[:c|s at:(s indexOf:c)+i]
are here both for tossing the characters and for reversing the patterns...For i=1, it performs horizontal reversion (
/
<->\
,<
<->>
).For i=3, it performs vertical reversion (
/
<->\
)For i=1 or 2 atRandom, it toss among
/
or\
,<
or>
'=-/</-///'
encodes the character typec
that will feed the blockf
for the 9 first lines.#() , '=-/</-///'
is a concatenation trick for transforming the String into an Array and thus collecting into an Array.The rest is simple concatenation after applying the horizontal/vertical symetry.
źródło
Squeak 4.X, 247
Or formatted:
Explanations:
s:='==--/\<>'.
obviously encodes the four posible pairs.r:=(1<<108)atRandom.
toss 108 bits (in a LargeInteger) for 9 rows*12 columns (we toss the == and -- unecessarily but performance is not our problem).h:=''
is the string where we will concatenate (Schlemiel painter because a Stream would be too costly in characters).(16to:0by:-2),(0to:16by:2)do:[:i|
is iterating on the rows (*2)(11to:0by:-1),(0to:11) do:[:j|
is iterating on the columns28266
is a magic number encoding the pair to be used on first 9 lines.It is the bit pattern
00 01 10 11 10 01 10 10 10
, where 00 encodes '==', 01 '--', 10 '/\' and 11 '<>'.101
is a magic number encoding the horizontal and vertical reversion.It is the bit pattern
0000 0000 0110 1010
, encoding when to reverse (1) or not (0) the first (0) or second (1) character of each pair '==' '--' '/\' and '<>', for the vertical symetry and horizontal symetry.n:=3 bitAnd: 28266>>i
gives the encoding of character pair for row i/2 (0 for '==', 1 for '--', 2 for '/\' and 3 for '<>').(r-1 bitAt: 6*i+j+1)
pick the random bit for row i/2 column j (1 is the rank of lowest bit thus we have a +1, k atRandom toss in interval [1,k] thus we have a -1).(101 bitAt: 3-n*4+m+p)
pick the reversal bit: (3-n)*4 is the offset for the group of 4 bits corresponding to the pair code n, m is the vertical reversion offset (0 for first 9, 2 for last 9 rows), p is the horizontal reversion offset (0 for first 12, 1 for last 12 columns)+1 because low bit rank is 1.bitXor:
performs the reversion (it answer an offset 0 or 1), ands at:2*n+1+bitXor_offset
pick the right character in s.But
(A>>a)+(B>>b) bitAnd: 1
costs less bytes than(A bitAt:a+1)bitXor:(B bitAt:b+1)
thus the bitXor was rewritten and offset +1 on p is gone...h,#[13]
is an ugly squeakism, we can concatenate a String with a ByteArray (containing code for carriage return).źródło