Narysuj losową kołdrę artystyczną ASCII


31

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 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.


czy możemy przyjmować dane wejściowe jako losowe ziarno?
Destructible Lemon

Odpowiedzi:


15

CJam, 61 60 58 55 54 52 51 bajtów

Trochę skrócono z pomocą Sp3000 i Optimizera.

"=-/</-///"{C*1{"<\/>"%1$W%\_W%er}:F~+mrC<1FN}%s3F(

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:

{"<\/>"%1$W%\_W%er}:F

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 1czy 3i wskazuje, czy ( 1) obydwa wsporniki i tnie powinny być wymieniane lub ( 3) tylko uchwyty powinny być zamienione. Oto jak to działa:

"<\/>"            "Push a string with all four relevant characters.";
      %           "% applied to a string and an integer N (in any order) selects every
                   Nth character, starting from the first. So with N = 1 this just
                   leaves the string unchanged, but with N = 3 it returns a string
                   containing only < and >.";
       1$         "Copy the string we want to mirror.";
         W%       "% also takes negative arguments. Giving it -1 reverses the string.";
           \_     "Swap the two strings and duplicate the <\/> or <> string.";
             W%   "Reverse that one. Due to the symmetry of this string, we'll now
                   have the characters to be swapped at corresponding indices.";
               er "Perform element-wise transliteration on the reversed input string
                   to complete the mirroring operation.";

Teraz reszta kodu:

"=-/</-///"                            "This string encodes the 9 different line types.
                                        Note that for the /\ and <> lines we only use
                                        one of the characters. This idea is due to
                                        Sp3000. Thanks! :)";
           {                   }%      "Map this block onto the characters.";
            C*                         "Repeat the character 12 times, turning it into
                                        a string.";
              1{...}:F~                "Define and call F on the resulting string. The
                                        reversal doesn't do anything, but the character
                                        swapping creates strings containing both \/ and
                                        <>.";
                       +mr             "Add the two halves together and shuffle them.";
                          C<           "Truncate to 12 characters. We've now got our
                                        random half-lines.";
                            1F         "Call F again to mirror the half-line.";
                              N        "Push a newline.";
                                 s     "Join all those separate strings together by
                                        converting the array to a string.";
                                  3F   "Perform one more mirroring operation on the
                                        half-quilt, but this time only swap < and >.
                                        This yields the correct full quilt, except
                                        there are two newlines in the centre.";
                                    (  "This slices the leading newline off the second
                                        half and pushes it onto the stack.";

Dwie połówki i ta jedna nowa linia są następnie automatycznie drukowane na końcu programu.


12

Python 3, 257 229 192 185 176 149 143 bajtów

from random import*
k,*L=80703,
while k:s=eval("''"+".join(sample('--==<>\/'[k%4*2:][:2],2))"*12);L=[s]+L+[s[::(-1)**k]];k//=4
*_,=map(print,L)

Z 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ąc sample(...,2), ponieważ random.shuffleniestety jest na miejscu) i łączenie łańcuchów.

Uproszczonym przykładem tego, jak mogłoby wyglądać rozszerzenie dla czwartego rzędu, jest:

''.join(['<','>']).join(['>','<']).join(['>','<']).join(['<','>']).join(['>','<'])

co dałoby ><>><><<><:

               ''
    <>         .join(['<','>'])
   >  <        .join(['>','<'])
  >    <       .join(['>','<'])
 <      >      .join(['<','>'])
>        <     .join(['>','<'])

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ńcu

L=[s]+L+[[s,s[::-1]][n<"5"]]

n<"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 oceny maptak, aby drukowanie miało miejsce, i jest to tylko krótszy sposób print("\n".join(L)).

Przez długi czas miałem tę funkcję

g=lambda s:s.translate({60:62,62:60,92:47,47:92})

która pobiera ciąg i konwertuje /\><do \/<>odpowiednio, ale wreszcie udało mi się go pozbyć :)


Specyfikacja mówi, że dopóki może wygenerować wszystkie możliwe dywany, jest w porządku.

6

Python 2, 300 bajtów

Ten program używa join, lambda, replace, sample, importi innych pełnych funkcji, więc nie zdobędzie żadnych nagród golfowych.

from random import*
f=lambda a,b,t:t.replace(a,'*').replace(b,a).replace('*',b)
k=lambda a:''.join(sample(a*12,12))
c='-'*24
e=k('<>')
h=e+f('<','>',e[::-1])
j=[d+f('/','\\',d[::-1])for d in[k('\\/')for i in'quilt']]
g=['='*24,c,j[0],h,j[1],c]+j[2:]
print'\n'.join(g+[f('/','\\',d)for d in g[::-1]])

Kod zanim auto-golfista go zdobył:

from random import *

change = lambda a,b,t: t.replace(a,'*').replace(b,a).replace('*',b)
pick = lambda a: ''.join(sample(a*12, 12))

innerline = '-' * 24
line4h = pick('<>')
line4 = line4h + change('<', '>', line4h[::-1])
diag = [d + change('/', '\\', d[::-1]) for d in [pick('\\/') for i in 'quilt']]

quilt = ['='*24, innerline, diag[0], line4, diag[1], innerline] + diag[2:]
print '\n'.join(quilt + [change('/', '\\', d) for d in quilt[::-1]])

Przykładowy wynik:

========================
------------------------
\\\\/\////\\//\\\\/\////
<><<>>>><><><><><<<<>><>
/\\\\////\\\///\\\\////\
------------------------
\\\\//\///\\//\\\/\\////
//\//\\\\/\/\/\////\\/\\
\/\\\\/\//\/\/\\/\////\/
/\////\/\\/\/\//\/\\\\/\
\\/\\////\/\/\/\\\\//\//
////\\/\\\//\\///\//\\\\
------------------------
\////\\\\///\\\////\\\\/
<><<>>>><><><><><<<<>><>
////\/\\\\//\\////\/\\\\
------------------------
========================

9
Nie najkrótszy, ale hej, z 7 dodatkowymi bajtami masz program godny twojego imienia : D
Calvin's Hobbies

Widzę, co tu zrobiłeś.
Logic Knight

2
Auto-golfista? Czy nikt nie ma czasu na ręczne granie w golfa?
Lars Ebert

5
Znasz nas hakerów. Jeśli muszę wykonać 3-minutowe zadanie więcej niż raz, spędzę 10 godzin na pisaniu programu, który go zautomatyzuje. Chodzi mi o wydajność ;-)
Logic Knight

6

APL ( 53 58)

To nie do końcaNiestety tak symetryczny, jak myślałem. Poprawka kosztowała mnie 5 znaków, a teraz nie mam szans.

L←+,3-⌽⋄'==--/\<><'[↑(732451451260688⊤⍨18/8)+L{L?12⍴2}¨⍳9]

Wyjaśnienie:

  • L←+,3-⌽: L jest funkcją, która zwraca argument, po którym następuje 3 - odwrotność argumentu
  • L{L?12⍴2}¨⍳9: generate 9 lines of 12 random values from [1,2] plus their reverse, then the reverse of those 9 lines
  • 732451451260688⊤⍨18/8: generate the list 0 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 position

Output:

========================
------------------------
///////\\///\\\//\\\\\\\
<<><<><><<<<>>>><><>><>>
\\\\\//\/\\\///\/\\/////
------------------------
/\///\\/\/\/\/\/\//\\\/\
\////////\//\\/\\\\\\\\/
\\/\\\//\///\\\/\\///\//
//\///\\/\\\///\//\\\/\\
/\\\\\\\\/\\//\////////\
\/\\\//\/\/\/\/\/\\///\/
------------------------
/////\\/\///\\\/\//\\\\\
<<><<><><<<<>>>><><>><>>
\\\\\\\//\\\///\\///////
------------------------
========================

1
I had +1ed because the algorithm you posted was interesting and original, but I've just noticed that your <> 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 )
FryAmTheEggman

@FryAmTheEggman: shit, didn't notice that. I'll probably have to scrap the whole algorithm now, since there's one line that's not like the others. Well, thanks for telling me rather than just downvoting.
marinus

@FryAmTheEggman: well, it's fixed (by adding another < 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)
marinus

2
That solution is quite clever, you can keep the +1 :)
FryAmTheEggman

@Calvin'sHobbies: fix one thing, break another. Now it's really fixed.
marinus

6

PHP, 408, 407, 402, 387, 379 bytes

I am not a good golfer, but this problem sounded fun so I gave it a try.

<?$a=str_replace;$b=str_repeat;function a($l,$a,$b){while(strlen($s)<$l){$s.=rand(0,1)?$a:$b;}return$s;}$c=[$b('=',12),$b('-',12),a(12,'/','\\'),a(12,'<','>'),a(12,'/','\\'),$b('-',12)];while(count($c)<9){$c[]=a(12,'/','\\');}for($d=9;$d--;){$c[$d].=strrev($a(['/','<','\\','>',1,2],[1,2,'/','<','\\','>'],$c[$d]));$c[]=$a(['/','\\',1],[1,'/','\\'],$c[$d]);}echo implode("
",$c);

Ungolfed code

<?php

    function randomString($length, $a, $b) {
        $string = '';
        while(strlen($string) < $length) {
            $string .= rand(0, 1) ? $a : $b;
        }
        return $string;
    }

    if(isset($argv[1])) {
        srand(intval($argv[1]));
    }

    $lines = [
        str_repeat('=', 12),
        str_repeat('-', 12),
        randomString(12, '/', '\\'),
        randomString(12, '<', '>'),
        randomString(12, '/', '\\'),
        str_repeat('-', 12)
    ];
    while(count($lines) < 9) {
        $lines[] = randomString(12, '/', '\\');
    }

    for($index = count($lines); $index--;) {
        $lines[$index] .= strrev(str_replace(['/', '<', '\\', '>', 1, 2], [1, 2, '/', '<', '\\', '>'], $lines[$index]));
        $lines[] = str_replace(['/', '\\', 1], [1, '/', '\\'], $lines[$index]);
    }

    echo implode("\n", $lines) . "\n";

?>

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:

php quilt.php 48937

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.


1
You can do many things to golf this: ['/','<','\\','>','a','b'] can be replaced with ['/','<','\\','>',a,b] (notice the missing quotes around a and b), @$s can be replaced with $s, you can store str_repeat('-',12) and str_repeat('=',12) in global variables/constants, for($b=8;$b>=0;$b--) can be replaced with for($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.
Ismael Miguel

Here is a shorter version: pastebin.com/2TabUqbA (373 bytes). I've changed a few tips: removed the global variables, lets strrev unchanged, removed 1 space and a few small changes.
Ismael Miguel

4
I think you need line 4 and line 15 (the <>><>< lines) to be the same.
Logic Knight

1
Sorry, here's a 357-bytes long solution: pastebin.com/TugNDjjL I forgot to reduce some things.
Ismael Miguel

@IsmaelMiguel Thanks for your help. I took some of your advice, but some of it results in a notice getting thrown.
Lars Ebert

4

JavaScript (ES6) 169 195 201

Edit 6 bytes saved thx @nderscore. Beware, the newline inside backquotes is significant and counted.

Edit2 simplified row building, no need of reverse and concat

F=(o='')=>[...z='/\\/-/<\\-='].map((c,i,_,y=[z,'\\/\\-\\>/-='],q=[for(_ of-z+z)Math.random(Q=k=>q.map(v=>r=y[v^!k][i]+r+y[v^k][i],r='')&&r+`
`)*2])=>o=Q()+o+Q(i!=5))&&o

Run snippet to test (in Firefox)

F=(o='')=>[...z='/\\/-/<\\-='].map((c,i,_,y=[z,'\\/\\-\\>/-='],q=[for(_ of-z+z)Math.random(Q=k=>q.map(v=>r=y[v^!k][i]+r+y[v^k][i],r='')&&r+`
`)*2])=>o=Q()+o+Q(i!=5))&&o

Q.innerHTML=F()
<pre id=Q style='font-size:9px;line-height:9px'>


1
-6 bytes: Remove parenthesis around definition of z. Move definition of Q inside of the Math.random call. Replace '\n' with template string of newline. |0 integer casting is not needed, as the values will be xor-ed later on.
nderscore

What does this for(_ of-z+z) mean?
Derek 朕會功夫

@Derek I need to iterate 12 times and the best I have is a 9 char string. z is not numeric so -z is NaN (not a number) NaN converted to string is "NaN" and 3 chars + 9 chars are 12.
edc65

4

Ruby, 162 155

I 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.

a='/\\'
b='\\\/'
t=Array.new(9){x=''
12.times{x+=a[rand(2)]}
x+x.reverse.tr(a,b)}
t[0]=?=*24
t[1]=t[5]=?-*24
t[3].tr!a,'<>'
puts t,((t.reverse*'
').tr a,b)

2
Welcome to Programming Puzzles & Code Golf Stack Exchange! Here are a couple of Ruby-specific tips: I don't think you need to escape the / in a and b. The first tr can probably also do without parentheses. Single-character strings like '=' can be written ?=. And .join can be replaced by *.
Martin Ender

@MartinBüttner Thanks for the welcome and the tips! The character literals and join synonym save me 6 bytes. I can't remove the parentheses in x+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 in b because of the way tr works, though I now realize the first \ in a is superfluous, so there's another byte.
ezrast

3

Pyth, 57 59 61

J"\<>/"K"\/"L+b_mXdK_Kbjbym+d_XdJ_JmsmOk12[\=\-K-JKK\-KKK

J"\<>/"K"\/"jbu++HGXHK_Km+d_XdJ_JmsmOk12[KKK\-K-JKK\-\=)Y

Thanks 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:

=G"\<>/"                            : Set G to be the string "\<>/"
K"\/"                               : Set K to be the string "\/"
Jm+d_XdG_GmsmOk12[\=\-K"<>"K\-KKK;  : Set J to be the top half of the carpet
                 [\=\-K"<>"K\-KKK;  : Make a list of possible chars for each row
          msmOk12                   : for each element of that list,
                                    : make a list of 12 randomly chosen characters
                                    : from it, then join them
Jm+d_XdG_G                          : for each element of that list,
                                    : make a new list with the old element,
                                    : and its horizontal reflection
jb+J_mXdK_KJ                        : Print the whole carpet
     mXdK_KJ                        : For each element of J make its vertical reflection

Very nice. Shouldn't have thrown in the towel. 1 char save by replacing "<>" with -GK
Jakube

And another one by either using lambda J"\<>/"K"\/"L+b_mXdK_Kbjbym+d_XdJ_JmsmOk12[\=\-K-JKK\-KKK or reduce J"\<>/"K"\/"jbu++HGXHK_Km+d_XdJ_JmsmOk12[KKK\-K-JKK\-\=)Y
Jakube

@Jakube Thanks! Both of those are quite clever optimizations. I really like how the lambda lets you put the list at the end.
FryAmTheEggman

2

J, 56 54 bytes

'=/\<>--></\'{~(-,|.)0,(3(2})8$5,3#1)+(,1-|.)"1?8 12$2

Usage:

   '=/\<>--></\'{~(-,|.)0,(3(2})8$5,3#1)+(,1-|.)"1?8 12$2
========================
------------------------
///\\\\/\///\\\/\////\\\
><<><><>><>><<><<><><>><
\\/\//\\/\//\\/\//\\/\//
------------------------
\/\/\//////\/\\\\\\/\/\/
/\/\\//\//\\//\\/\\//\/\
//\\\\/////\/\\\\\////\\
\\////\\\\\/\/////\\\\//
\/\//\\/\\//\\//\//\\/\/
/\/\/\\\\\\/\//////\/\/\
------------------------
//\/\\//\/\\//\/\\//\/\\
><<><><>><>><<><<><><>><
\\\////\/\\\///\/\\\\///
------------------------
========================

1 byte thanks to @FUZxxl.

Explanation coming soon.

Try it online here.


Save one character: Replace 5 1 3 1 5 1 1 1 with (3(2})8$5,3#1).
FUZxxl

@FUZxxl Great! I tried a ton of alternatives but haven't found this. (CJam got away in score overnight so J will not reach them. :P)
randomra

1

Python 295 287 227 bytes

Not that great but I'll post it anyway:

from random import*
m,d=[],dict(zip("\/<>=-","/\><=-"))
v=lambda w:[d[x]for x in w]
for e in '=-/>/-///':f=[choice([e,d[e]])for x in[0]*12];t=''.join(f+v(f[::-1]));print t;m+=''.join(e=='/'and v(t)or t),
print'\n'.join(m[::-1])

If you want an explanation just ask me.


@Sp3000 Thanks for pointing it out, I fixed it. A shame it came if even longer though...
Def

Here's a bunch of golfs which are too long to fit in a comment. You might be able to get it down even more if you put = and - in d.
Sp3000

@Sp3000 Thanks a lot for all the advice. A lot of it was pretty obvious (spaces, removing reversed) as I'm not the greatest golfer (both code and irl), but I learned some new python too (so again thanks). Removing the if statement by including = and - in the dict turned out to be a very good idea. P.S. would you mind explaining how a recursive quilt is made in so few code (decrypting translate sucks)
Def

1

Javascript (ES7 Draft) 174 168 146

Some inspiration taken from @edc65

Edit: Thanks to edc65 for some ideas to optimize building of rows.

F=(o='')=>[for(i of'555357531')(z=[for(_ of c='==--/\\<>golf')Math.random(r=x=>z.reduce((s,y)=>c[w=i^y^x]+s+c[w^1],'')+`
`)*2],o=r()+o+r(i<7))]&&o

Demonstration: (Firefox only)

F=(o='')=>[for(i of'555357531')(z=[for(_ of c='==--/\\<>golf')Math.random(r=x=>z.reduce((s,y)=>c[w=i^y^x]+s+c[w^1],'')+`
`)*2],o=r()+o+r(i<7))]&&o

document.write('<pre>' + F() + '</pre>');


Commented:

// define function, initialize output to ''
F = (o = '') =>
    // loop through character indexes of first 9 lines
    [
        for (i of '555357531')(
            // build array of 12 random 0/1's, initialize character list
            z = [
                for (_ of c = '==--/\\<>golf')
                    Math.random(
                        // define function for generating lines
                        // if x is true, opposite line is generated
                        r = x =>
                            z.reduce(
                                (s, y) => 
                                    c[w = i ^ y ^ x] + s + c[w ^ 1],
                                ''
                            ) + `\n`
                    ) * 2
            ],
            // build new lines and wrap output in them
            // x true in the second line for indexes < 7 (not character '>')
            o = r() + o + r(i < 7)
        )
    ]
    // return output
    && o

1
See my edit, it's good for your solution too
edc65

@edc65 nice idea! I've implemented something similar now.
nderscore

0

Pharo 4, 236

|s i f v h|s:='====----/\/\/<><<>'.f:=[:c|s at:(s indexOf:c)+i].v:=#(),'=-/</-///'collect:[:c|h:=(String new:12)collect:[:x|i:=2atRandom.f value:c].i:=1.h,(h reverse collect:f)].i:=3.String cr join:v,(v reverse collect:[:k|k collect:f])

or formatted normally:

|s i f v h|
s:='====----/\/\/<><<>'.
f:=[:c|s at:(s indexOf:c)+i].
v:=#() , '=-/</-///'
  collect:[:c|
    h:=(String new:12)collect:[:x|i:=2atRandom.f value:c].
    i:=1.
    h,(h reverse collect:f)].
i:=3.
String cr join:v,(v reverse collect:[:k|k collect:f])

Explanation:

The string s:='====----/\/\/<><<>' together with the block f:=[: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 type c that will feed the block f 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.

========================
------------------------
\\/\/\\\\/\/\/\////\/\//
>>>><><><>><><<><><><<<<
\/\/\//\///\/\\\/\\/\/\/
------------------------
/\//\/\/////\\\\\/\/\\/\
\\//\//\\\/\/\///\\/\\//
////\\/\/\//\\/\/\//\\\\
\\\\//\/\/\\//\/\/\\////
//\\/\\///\/\/\\\//\//\\
\/\\/\/\\\\\/////\/\//\/
------------------------
/\/\/\\/\\\/\///\//\/\/\
>>>><><><>><><<><><><<<<
//\/\////\/\/\/\\\\/\/\\
------------------------
========================

0

Squeak 4.X, 247

|r s h m n p|s:='==--/\<>'.r:=(1<<108)atRandom.h:=''.m:=0.(16to:0by:-2),(0to:16by:2)do:[:i|n:=3bitAnd:28266>>i.p:=0.(11to:0by:-1),(0to:11)do:[:j|h:=h,(s at:n*2+1+(r-1>>(6*i+j)+(101>>(3-n*4+m+p))bitAnd:1)).j=0and:[p:=1]].i=0and:[m:=2].h:=h,#[13]].h

Or formatted:

|r s h m n p|
s:='==--/\<>'.
r:=(1<<108)atRandom.
h:=''.
m:=0.
(16to:0by:-2),(0to:16by:2) do:[:i|
  n:=3 bitAnd: 28266>>i.
  p:=0.
  (11to:0 by:-1),(0to:11) do:[:j|
    "h:=h,(s at:n*2+1+((r-1bitAt:6*i+j+1)bitXor:(101bitAt:3-n*4+m+p))). <- originally"
    h:=h,(s at:n*2+1+(r-1>>(6*i+j)+(101>>(3-n*4+m+p))bitAnd:1)).
    j=0and:[p:=1]].
  i=0and:[m:=2].
  h:=h,#[13]].
h

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 columns

28266 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), and s 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).

========================
------------------------
/\/\\\/\//\/\/\\/\///\/\
><>><<>>>><<>><<<<>><<><
////\\////\\//\\\\//\\\\
------------------------
/\\\/\\/\\//\\//\//\///\
\/\\/\//////\\\\\\/\//\/
\\\//\\\////\\\\///\\///
///\\///\\\\////\\\//\\\
/\//\/\\\\\\//////\/\\/\
\///\//\//\\//\\/\\/\\\/
------------------------
\\\\//\\\\//\\////\\////
><>><<>>>><<>><<<<>><<><
\/\///\/\\/\/\//\/\\\/\/
------------------------
========================
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.