Pseudo-frattale rettangolare


13

Obbiettivo

L'obiettivo del programma è quello di disegnare un rettangolo artistico ASCII più volte raddoppiato per dimensioni, alternandosi in orizzontale e in verticale. Ogni volta che il rettangolo raddoppia in dimensioni, l'area extra viene rappresentata da un carattere diverso e le aree precedenti rimangono invariate. Le due sezioni più piccole contengono un carattere ciascuna e possono trovarsi in qualsiasi angolo.

Il programma accetta come input un singolo intero, definendo il numero di sezioni contenute nel rettangolo completo.

Non sono consentite altre risorse o input esterni.

Input e output di esempio

10

ABDDFFFFHHHHHHHHJJJJJJJJJJJJJJJJ
CCDDFFFFHHHHHHHHJJJJJJJJJJJJJJJJ
EEEEFFFFHHHHHHHHJJJJJJJJJJJJJJJJ
EEEEFFFFHHHHHHHHJJJJJJJJJJJJJJJJ
GGGGGGGGHHHHHHHHJJJJJJJJJJJJJJJJ
GGGGGGGGHHHHHHHHJJJJJJJJJJJJJJJJ
GGGGGGGGHHHHHHHHJJJJJJJJJJJJJJJJ
GGGGGGGGHHHHHHHHJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ

Criteri di selezione

Il codice più corto in una settimana vince i punti.


Quale dovrebbe essere l'output per i non-power di 4?
Marin

L'uscita deve essere della sequenza A, B, C, ecc.?
Kendall Frey,

2
@marinus Qual è la particolarità dei poteri di 4? Forse hai frainteso l'esempio?
Kendall Frey,

@KendallFrey, no, ci devono essere solo n caratteri stampabili unici.
Hand-E-Food

Deve

Risposte:


10

APL, 25 caratteri / byte *

{⍉⍣⍵⊃{a,⍺⍴⍨⍴a←⍉⍪⍵}/⌽⍵↑⎕A}

Vista esplosa

{                   ⍵↑⎕A}   ⍝ take the first ⍵ letters
    ⊃{           }/⌽        ⍝ fold over them, using the first one as initial accum. value
            a←⍉⍪⍵           ⍝    ensure the accum. is a table, transpose it and call it 'a'
        ⍺⍴⍨⍴                ⍝    make a table as large as 'a' filled with the next letter
      a,                    ⍝    append it to the right of 'a' and loop as new accumulator
 ⍉⍣⍵                        ⍝ transpose the result as many times as the original ⍵ number

Esempi

      {⍉⍣⍵⊃{a,⍺⍴⍨⍴a←⍉⍪⍵}/⌽⍵↑⎕A}¨⍳8
A AB  AB  ABDD  ABDD  ABDDFFFF  ABDDFFFF  ABDDFFFFHHHHHHHH
      CC  CCDD  CCDD  CCDDFFFF  CCDDFFFF  CCDDFFFFHHHHHHHH
                EEEE  EEEEFFFF  EEEEFFFF  EEEEFFFFHHHHHHHH
                EEEE  EEEEFFFF  EEEEFFFF  EEEEFFFFHHHHHHHH
                                GGGGGGGG  GGGGGGGGHHHHHHHH
                                GGGGGGGG  GGGGGGGGHHHHHHHH
                                GGGGGGGG  GGGGGGGGHHHHHHHH
                                GGGGGGGG  GGGGGGGGHHHHHHHH

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
*: APL può essere scritto nel proprio set di caratteri a byte singolo (legacy) che associa i simboli APL ai valori superiori di 128 byte. Pertanto, ai fini del calcolo del punteggio, un programma di N caratteri che utilizza solo caratteri ASCII e simboli APL può essere considerato lungo N byte.


9

GolfScript, 30 caratteri

~(,[0`]{{[49+]1$,*+}+%zip}@/n*

Esempio (eseguito online ):

> 7
01335555
22335555
44445555
44445555
66666666
66666666
66666666
66666666

Questo produce un output errato per i numeri pari, come quello nella domanda ...
Timwi,

@Timwi L'ho appena provato e funziona per me. L'output viene trasposto ma l'orientamento non è stato specificato nella domanda.
Howard,

Bene, immagino di essere stato troppo severo allora :)
Timwi

@Howard Hm, è così che ho capito "e le aree precedenti rimangono invariate". Dice che i primi due personaggi possono trovarsi in qualsiasi angolo, ma non dice che l'orientamento potrebbe cambiare.
Martin Ender,

7

Python 2.7 - 85 103

Questo utilizza la zip(*s)sintassi per trasporre continuamente l'elenco. Grazie mille a Daniel per il suo consiglio che ha rasato 12 personaggi! Quindi rasati qualche altro utilizzando i numeri anziché le lettere.

s=[]
for i in range(input()):x=1<<i/2;s=zip(*s+[chr(65+i)*x]*x)
for i in s:print''.join(i)

Inoltre, questo utilizza 1<<xpiuttosto che 2**xil bit shift ha una precedenza (?) Più bassa. Osservare:

>>> 1<<(2*3)
64
>>> 1<<2*3
64
>>> 2**2*3
12
>>> 2**(2*3)
64

E alcuni output:

10
01335555777777779999999999999999
22335555777777779999999999999999
44445555777777779999999999999999
44445555777777779999999999999999
66666666777777779999999999999999
66666666777777779999999999999999
66666666777777779999999999999999
66666666777777779999999999999999
88888888888888889999999999999999
88888888888888889999999999999999
88888888888888889999999999999999
88888888888888889999999999999999
88888888888888889999999999999999
88888888888888889999999999999999
88888888888888889999999999999999
88888888888888889999999999999999

1
Bello. Puoi accorciarlo un po 'con for i in s:print''.join(i).
Daniel Lubarov,

5

Ruby, 88

Legge N dall'input standard.

s=[?A]
66.upto(64+gets.to_i){|i|x=i.chr*y=s.size;i%2<1?s.map!{|r|r+x}:s+=[x*2]*y}
puts s

Esempio di utilizzo per N = 8:

echo 8 | rectangular-pseudo-fractal.rb

Produzione:

ABDDFFFFHHHHHHHH
CCDDFFFFHHHHHHHH
EEEEFFFFHHHHHHHH
EEEEFFFFHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH

N = 10

echo 10 | rectangular-pseudo-fractal.rb

Produzione:

ABDDFFFFHHHHHHHHJJJJJJJJJJJJJJJJ
CCDDFFFFHHHHHHHHJJJJJJJJJJJJJJJJ
EEEEFFFFHHHHHHHHJJJJJJJJJJJJJJJJ
EEEEFFFFHHHHHHHHJJJJJJJJJJJJJJJJ
GGGGGGGGHHHHHHHHJJJJJJJJJJJJJJJJ
GGGGGGGGHHHHHHHHJJJJJJJJJJJJJJJJ
GGGGGGGGHHHHHHHHJJJJJJJJJJJJJJJJ
GGGGGGGGHHHHHHHHJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ

Come appare l'output di questo?

@LegoStormtroopr ha aggiunto alcuni esempi, è lo stesso identico formato della domanda.
Paul Prestidge,

4

J, 57 43

(,`,.@.(=/@$@[)$${&a.@(66+2&^.@#@,)^:)1$'A'

Esempi:

5 (,`,.@.(=/@$@[)$${&a.@(66+2&^.@#@,)^:)1$'A'
ABDDFFFF
CCDDFFFF
EEEEFFFF
EEEEFFFF

7 (,`,.@.(=/@$@[)$${&a.@(66+2&^.@#@,)^:)1$'A'
ABDDFFFFHHHHHHHH
CCDDFFFFHHHHHHHH
EEEEFFFFHHHHHHHH
EEEEFFFFHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH

C e D si estendono entrambi orizzontalmente. Dovrebbero alternarsi in orizzontale e in verticale.
Hand-E-Food

@ Hand-E-Food hai ragione. Grazie per la segnalazione. Ho riparato il codice (e posta).
barbermot,

4

MATLAB, 86 personaggi

Il mio tentativo più breve in MATLAB, stimolato da @flawr (due volte!):

function M=f(n)
M='';
if n
M=cat(mod(n,2)+1,f(n-1),64+n*ones(2.^fix(n/2-[.5,1])));
end

Esempio di output:

>> disp(f(7))
ACEEGGGG
BCEEGGGG
DDEEGGGG
DDEEGGGG
FFFFGGGG
FFFFGGGG
FFFFGGGG
FFFFGGGG

Questo ti farà risparmiare alcuni byte:function M=f(n) M=''; if n M=cat(mod(n,2)+1,f(n-1),64+n*ones(2.^fix([n-1,n-2]/2))); end
flawr

@flawr: Oh! Ovviamente!
Knedlsepp,

Salva un altro byte sostituendo l'argomento fixcon fix(n/2-[.5,1])PS: soluzione davvero piacevole con cat, non sapevo di questo uso dove puoi scegliere la dimensione =)
flawr

@flawr: Mi sembra abbastanza dispendioso. ;-)
knedlsepp il

Ho appena notato che sei nuovo qui, quindi benvenuto su codegolf.SE, è bello avere un.) Altri drogati di matlab, b.) Di madrelingua tedesca qui (presumo)!
flawr

3

q [73 caratteri]

{"c"$64+{n:x 0;m:x 1;if[2>n;m:(),m];(o;$[n-2*n div 2;,';,][m;(#m;#m 0)#o:n+1])}/[x-1;(1;1)]1}

esempio

10
"ABDDFFFFHHHHHHHHJJJJJJJJJJJJJJJJ"
"CCDDFFFFHHHHHHHHJJJJJJJJJJJJJJJJ"
"EEEEFFFFHHHHHHHHJJJJJJJJJJJJJJJJ"
"EEEEFFFFHHHHHHHHJJJJJJJJJJJJJJJJ"
"GGGGGGGGHHHHHHHHJJJJJJJJJJJJJJJJ"
"GGGGGGGGHHHHHHHHJJJJJJJJJJJJJJJJ"
"GGGGGGGGHHHHHHHHJJJJJJJJJJJJJJJJ"
"GGGGGGGGHHHHHHHHJJJJJJJJJJJJJJJJ"
"IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ"
"IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ"
"IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ"
"IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ"
"IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ"
"IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ"
"IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ"
"IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ"

3
"AB"
"CC"

6
"ABDDFFFF"
"CCDDFFFF"
"EEEEFFFF"
"EEEEFFFF"

3

Sclipting , 59 caratteri

❶塊갠分감⓶左貶終辦감標가⓺貶⓹開上❶❶貶雙是不⒉갠乘⒉終가①上뀀❷②갠分小是增終❸⓷另要감右⓶갠加⓶終丟字⓶終丟겠終

(Questo programma potrebbe essere un po 'più breve se avessi le istruzioni per il logaritmo di base 2, ma non lo faccio, quindi lo faccio manualmente con un ciclo.)

Codice annotato

n è l'input.

❶ | n n

f = i => (1 << (i/2)) - 1;
塊갠分감⓶左貶終 | n n f

w = f(n);
辦 | n w f

d = 1;
감 | n w f d

s = "";
標 | n w f d M [s]

for (y in [0..f(n-1)])
가⓺貶⓹開上 | w d M [s] y

    if ((y & (y-1)) == 0) d *= 2;
    ❶❶貶雙是不⒉갠乘⒉終 | w d M [s] y

    for (x in [0..w])
    가①上 | w d M [s] y x

        c = 64; // '@'
        뀀 | w d M [s] y x c

        if (x < d/2) c++;
        ❷②갠分小是增終 | w d M [s] y x c

        a = x | y;
        ❸⓷另 | w d M [s] y c a

        while (a > 0) { a >>= 1; c += 2; }
        要감右⓶갠加⓶終丟 | w d M [s] y c

        s += (char) c;
        字⓶ | w d M [s] y
    終丟 | w d M [s]

    s += "\n"
    겠 | w d M [s]
終

Produzione

Per n= 6:

ABDDFFFF
CCDDFFFF
EEEEFFFF
EEEEFFFF

Ovviamente puoi cambiare 뀀( @) con qualsiasi altro carattere base, ad es. Con (spazio) e n= 7:

!"$$&&&&
##$$&&&&
%%%%&&&&
%%%%&&&&
''''''''
''''''''
''''''''
''''''''

Il numero più alto che non allunga il programma è (= 255), che ci dà ( n= 8 questa volta):

Āāăăąąąąćććććććć
ĂĂăăąąąąćććććććć
ĄĄĄĄąąąąćććććććć
ĄĄĄĄąąąąćććććććć
ĆĆĆĆĆĆĆĆćććććććć
ĆĆĆĆĆĆĆĆćććććććć
ĆĆĆĆĆĆĆĆćććććććć
ĆĆĆĆĆĆĆĆćććććććć

Se allunghiamo il carattere del programma 1, ad esempio usa 냟및(= \u4DFF) e n= 9, otteniamo:

一丁七七丅丅丅丅万万万万万万万万
丂丂七七丅丅丅丅万万万万万万万万
丄丄丄丄丅丅丅丅万万万万万万万万
丄丄丄丄丅丅丅丅万万万万万万万万
丆丆丆丆丆丆丆丆万万万万万万万万
丆丆丆丆丆丆丆丆万万万万万万万万
丆丆丆丆丆丆丆丆万万万万万万万万
丆丆丆丆丆丆丆丆万万万万万万万万
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈

3

C #, 239 185 182 180 byte

C # non ha nulla sui linguaggi meno prolissi.

using C=System.Console;
class P{
    static void Main(string[]a){
        for(int x,i,n=int.Parse(a[0]);n-->0;C.CursorTop=0)
            for(i=1<<n,x=1<<n/2+n%2;i-->0;)
                C.Write((char)(n+33)+(i%x<1?"\n":""));
    }
}

Output, personaggi scelti per la bellezza:

!"$$&&&&((((((((****************
##$$&&&&((((((((****************
%%%%&&&&((((((((****************
%%%%&&&&((((((((****************
''''''''((((((((****************
''''''''((((((((****************
''''''''((((((((****************
''''''''((((((((****************
))))))))))))))))****************
))))))))))))))))****************
))))))))))))))))****************
))))))))))))))))****************
))))))))))))))))****************
))))))))))))))))****************
))))))))))))))))****************
))))))))))))))))****************

1
Non sono sicuro di come hai contato, ma ho contato 184. Puoi salvare due personaggi abbandonando le parentesi graffe dal forloop esterno , facendo 182.
Bob

Grazie @Bob! Devo aver contato male durante la microottimizzazione.
Hand-E-Food

2

PERL, 122 caratteri

$N=<>;$x=$r=1;do{$_=chr$a+++65;$s=$x;$o=$_ x$s;$o.=$_++x$s,$s*=2while$N+65>ord++$_;print"$o\n"x$r;$r=$x;$x*=2}while++$a<$N

con spazi bianchi aggiunti:

$N=<>;
$x=$r=1;
do{
    $_=chr$a+++65;
    $s=$x;
    $o=$_ x$s;
    $o.=$_++x$s,$s*=2 
        while $N+65>ord++$_;
    print "$o\n"x$r;
    $r=$x;
    $x*=2
} while++$a<$N

Produzione:

$ echo 8 | perl pseudo-fractal.pl
ABDDFFFFHHHHHHHH
CCDDFFFFHHHHHHHH
EEEEFFFFHHHHHHHH
EEEEFFFFHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH

1

PERL,  94   81 caratteri

$N=$_;$_=$:=A;$h=1;++$i%2?s/$/$:x$h/gem:($_.=($/.$:x2x$h)x$h,$h*=2)while++$:,--$N

Costruisce il frattale iterativamente lettera per lettera, aggiungendo nuove righe e colonne e righe e colonne ... Utilizza semplici operazioni di stringa per farlo. Nota che sto abusando della variabile standard anziché della lettera uno per consentire lo zucchero di sintassi (come omettere gli spazi - $:x2ecc.)

Con spazi bianchi e commenti aggiunti:

$N=$_;
$_=$:=A;                    # $: is current letter
$h=1;

++$i%2? 
s/$/$:x$h/gem:              # every odd run - add "columns"
($_.=($/.$:x2x$h)x$h,$h*=2) # every even run - add "rows"
while++$:,--$N              # iterate over letters

Alcuni output:

$ echo 8 | perl -p pseudo-fractal.fill.pl.5a5
ABDDFFFFHHHHHHHH
CCDDFFFFHHHHHHHH
EEEEFFFFHHHHHHHH
EEEEFFFFHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH

1

Sclipting , 45 caratteri

가⓶貶上倘감雙⓶壹長⓸講增字⓶復⓷是標⓷各①合終并不⓶梴❸⓶疊合終不뀐標뀐并終終⓶丟各겠終

Questa soluzione funziona in modo completamente diverso dall'altra soluzione Sclipting. È molto più noioso, ma è più corto ...

commentata

for i in [0..n-1]
가⓶貶上
    if (i != 0)
    倘
        i &= 1
        감雙
        e = list[0].Length
        ⓶壹長
        c = ((char) (c[0] + 1)).Repeat(e)
        ⓸講增字⓶復
        if (i)
        ⓷是
            concatenate c onto every element of list
            標⓷各①合終并
        else
        不
            concatenate c.Repeat(list.Length) onto list
            ⓶梴❸⓶疊合
        終
    else (i.e., i == 0)
    不
        c = "A"
        뀐
        list = ["A"]
        標뀐并
    終
終
concatenate "\n" to every element in list
⓶丟各겠終

1

Delfi 348 || 449 con trattino

Senza rientro

var inp,j,i,x: integer;s:string;L:TStringlist;begin L:=TStringList.Create;readln(s);inp:=StrToIntDef(s,4);if inp<4then inp:=4;s:='';l.Add('AB');for I:=2to inp-1do begin j:=Length(L[0]);if i mod 2=0then for x:=0to L.Count-1do L.Add(s.PadLeft(j,Chr(65+i)))else for x:=0to L.Count-1do L[x]:=L[x]+s.PadLeft(j,Chr(65+i));end;Write(L.GetText);readln;end.

Con trattino

var
  inp,j,i,x: integer;
  s:string;
  L:TStringlist;
begin
  L:=TStringList.Create;
  readln(s);
  inp:=StrToIntDef(s,4);
  if inp<4then inp:=4;
  s:='';
  l.Add('AB');

  for I:=2to inp-1do
  begin
    j:=Length(L[0]);
    if i mod 2=0then
      for x:=0to L.Count-1do L.Add(s.PadLeft(j,Chr(65+i)))
    else
      for x:=0to L.Count-1do
        L[x]:=L[x]+s.PadLeft(j,Chr(65+i));
  end;
  Write(L.GetText);
  readln;
end.

1

CJam, 30 (23) byte

CJam ha qualche mese in meno di questa sfida, quindi non è idoneo per il segno di spunta verde.

l~(Sa1${{_,I'!+*+}%z}fI\{z}*N*

Provalo qui.

L'OP ha chiarito in un commento che è consentito qualsiasi set di caratteri stampabili unici, quindi sto prendendo i caratteri ASCII stampabili dall'inizio (con uno spazio nell'angolo, !successivo e così via).

Se l'orientamento può variare tra input pari e dispari (cosa che non penso, ma è quello che fa l'invio GolfScript), posso farlo in 25 byte:

S]l~({{_,I'!+*+}%z}fIN*

L'idea è davvero semplice: inizia con una griglia contenente uno spazio, quindi N-1 volte lo traspone e raddoppia tutte le linee con il carattere successivo.

Per la versione lunga, alla fine traspongo anche N-1 volte per garantire un orientamento coerente.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.