Pseudo-fraktal persegi panjang

13

Tujuan

Tujuan program ini adalah menggambar persegi panjang seni ASCII berulang kali dua kali lipat, bergantian secara horizontal dan vertikal. Setiap kali persegi panjangnya berlipat ganda, area tambahan diwakili oleh karakter yang berbeda dan area sebelumnya tetap tidak berubah. Dua bagian terkecil masing-masing berisi satu karakter dan mungkin ada di sudut mana pun.

Program menerima bilangan bulat tunggal sebagai input, mendefinisikan jumlah bagian yang berisi persegi panjang penuh.

Tidak ada sumber daya eksternal atau input yang diizinkan.

Input dan output sampel

10

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

Kriteria pemilihan

Kode terpendek dalam seminggu memenangkan poin.

Makanan Tangan
sumber
Apa yang seharusnya menjadi output untuk non-kekuatan 4?
marinus
Apakah output harus dari urutan A, B, C, dll?
Kendall Frey
2
@marinus Apa yang spesial dari kekuatan 4? Mungkin Anda salah paham contohnya?
Kendall Frey
@ KendallFrey, tidak, hanya perlu ada n karakter unik yang dapat dicetak.
Hand-E-Food
Apakah itu harus berulang tepat di sudut kiri atas
mniip

Jawaban:

10

APL, 25 karakter / byte *

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

Tampilan meledak

{                   ⍵↑⎕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

Contohnya

      {⍉⍣⍵⊃{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 dapat ditulis dalam charset byte tunggal miliknya (legacy) yang memetakan simbol APL ke nilai 128 byte atas. Oleh karena itu, untuk tujuan penilaian, program karakter N yang hanya menggunakan karakter ASCII dan simbol APL dapat dianggap sebagai panjang N byte.

Tobia
sumber
9

GolfScript, 30 karakter

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

Contoh (jalankan online ):

> 7
01335555
22335555
44445555
44445555
66666666
66666666
66666666
66666666
Howard
sumber
Ini menghasilkan output yang salah untuk bilangan genap, seperti yang ada di pertanyaan ...
Timwi
@Timwi Saya baru saja mengujinya dan berfungsi untuk saya. Keluaran ditransposisikan tetapi orientasi tidak ditentukan dalam pertanyaan.
Howard
Baiklah, saya kira saya terlalu ketat :)
Timwi
@Howard Hm, begitulah cara saya memahami "dan area sebelumnya tetap tidak berubah". Dia mengatakan dua karakter pertama mungkin ada di sudut mana pun, tetapi dia tidak mengatakan orientasi mungkin berubah.
Martin Ender
7

Python 2.7 - 85 103

Ini menggunakan zip(*s)sintaks untuk terus mengubah urutan daftar. Terima kasih banyak untuk Daniel atas tipnya yang mencukur 12 karakter! Kemudian mencukur beberapa lagi dengan menggunakan angka, bukan huruf.

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)

Juga, ini menggunakan 1<<xdaripada 2**xbit shift memiliki prioritas lebih rendah (?). Mengamati:

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

Dan beberapa output:

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

sumber
1
Bagus. Anda dapat mempersingkat sedikit dengan for i in s:print''.join(i).
Daniel Lubarov
5

Ruby, 88

Membaca N dari input standar.

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

Contoh Penggunaan untuk N = 8:

echo 8 | rectangular-pseudo-fractal.rb

Keluaran:

ABDDFFFFHHHHHHHH
CCDDFFFFHHHHHHHH
EEEEFFFFHHHHHHHH
EEEEFFFFHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH

N = 10

echo 10 | rectangular-pseudo-fractal.rb

Keluaran:

ABDDFFFFHHHHHHHHJJJJJJJJJJJJJJJJ
CCDDFFFFHHHHHHHHJJJJJJJJJJJJJJJJ
EEEEFFFFHHHHHHHHJJJJJJJJJJJJJJJJ
EEEEFFFFHHHHHHHHJJJJJJJJJJJJJJJJ
GGGGGGGGHHHHHHHHJJJJJJJJJJJJJJJJ
GGGGGGGGHHHHHHHHJJJJJJJJJJJJJJJJ
GGGGGGGGHHHHHHHHJJJJJJJJJJJJJJJJ
GGGGGGGGHHHHHHHHJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
Paul Prestidge
sumber
Seperti apa output dari ini?
@LegoStormtroopr menambahkan beberapa contoh, formatnya sama persis dengan pertanyaannya.
Paul Prestidge
4

J, 57 43

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

Contoh:

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

7 (,`,.@.(=/@$@[)$${&a.@(66+2&^.@#@,)^:)1$'A'
ABDDFFFFHHHHHHHH
CCDDFFFFHHHHHHHH
EEEEFFFFHHHHHHHH
EEEEFFFFHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH
tukang cukur
sumber
C dan D keduanya memanjang secara horizontal. Mereka harus bergantian secara horizontal dan vertikal.
Hand-E-Food
@ Hand-E-Food Anda benar. Terima kasih telah menunjukkannya. Saya sudah memperbaiki kode (dan memposting).
barbermot
4

MATLAB, 86 Karakter

Percobaan terpendek saya di MATLAB, pimped oleh @ flawr (dua kali!):

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

Contoh output:

>> disp(f(7))
ACEEGGGG
BCEEGGGG
DDEEGGGG
DDEEGGGG
FFFFGGGG
FFFFGGGG
FFFFGGGG
FFFFGGGG
knedlsepp
sumber
Ini akan menghemat beberapa 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! Jelas!
knedlsepp
Simpan byte lain dengan mengganti argumen fixdengan fix(n/2-[.5,1])PS: Solusi yang benar-benar bagus cat, tidak tahu tentang penggunaan ini di mana Anda dapat memilih dimensi =)
flawr
@ flawr: Menurut saya, saya cukup boros. ;-)
knedlsepp
Saya baru saja memperhatikan Anda baru di sini, jadi selamat datang di codegolf.SE, senang memiliki.) Beberapa pecandu matlab, b.) Penutur bahasa Jerman di sini (saya berasumsi)!
flawr
3

q [73 karakter]

{"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}

contoh

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"
nyi
sumber
3

Sclipting , 59 karakter

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

(Program ini bisa menjadi sedikit lebih pendek jika saya memiliki instruksi untuk basis-2 logaritma, tetapi saya tidak melakukannya, jadi saya melakukannya secara manual dengan sebuah loop.)

Kode beranotasi

n adalah 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]
終

Keluaran

Untuk n= 6:

ABDDFFFF
CCDDFFFF
EEEEFFFF
EEEEFFFF

Tentu saja Anda dapat mengubah 뀀( @) ke karakter dasar lainnya, misalnya dengan (spasi) dan n= 7:

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

Angka tertinggi yang tidak membuat program lebih lama adalah (= 255), yang memberi kami ( n= 8 kali ini):

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

Jika kita membuat karakter program 1 lebih panjang, mis. Gunakan 냟및(= \u4DFF) dan n= 9, kita mendapatkan:

一丁七七丅丅丅丅万万万万万万万万
丂丂七七丅丅丅丅万万万万万万万万
丄丄丄丄丅丅丅丅万万万万万万万万
丄丄丄丄丅丅丅丅万万万万万万万万
丆丆丆丆丆丆丆丆万万万万万万万万
丆丆丆丆丆丆丆丆万万万万万万万万
丆丆丆丆丆丆丆丆万万万万万万万万
丆丆丆丆丆丆丆丆万万万万万万万万
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
Timwi
sumber
3

C #, 239 185 182 180 byte

C # tidak memiliki apa pun dalam bahasa yang kurang bertele-tele.

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, karakter yang dipilih untuk kecantikan:

!"$$&&&&((((((((****************
##$$&&&&((((((((****************
%%%%&&&&((((((((****************
%%%%&&&&((((((((****************
''''''''((((((((****************
''''''''((((((((****************
''''''''((((((((****************
''''''''((((((((****************
))))))))))))))))****************
))))))))))))))))****************
))))))))))))))))****************
))))))))))))))))****************
))))))))))))))))****************
))))))))))))))))****************
))))))))))))))))****************
))))))))))))))))****************
Makanan Tangan
sumber
1
Tidak yakin bagaimana Anda menghitung, tapi saya menghitung 184. Anda dapat menyimpan dua karakter dengan membuang kawat gigi dari forlingkaran luar , menghasilkan 182.
Bob
Terima kasih @ Bob! Saya pasti salah hitung saat mengoptimalkan mikro.
Hand-E-Food
2

PERL, 122 karakter

$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

dengan spasi tambahan:

$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

Keluaran:

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

PERL,  94   81 karakter

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

Itu membangun fraktal iteratif huruf per huruf, menambahkan baris dan kolom baru dan baris dan kolom ... Menggunakan operasi string sederhana untuk melakukan itu. Perhatikan bahwa saya menyalahgunakan variabel standar, bukan huruf satu untuk memungkinkan sintaksis gula (seperti menghilangkan spasi -$:x2 dll.)

Dengan spasi dan komentar tambahan:

$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

Beberapa output:

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

Sclipting , 45 karakter

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

Solusi ini bekerja sangat berbeda dari solusi Sclipting lainnya. Ini jauh lebih membosankan, tetapi lebih pendek ...

Beranotasi

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
⓶丟各겠終
Timwi
sumber
1

Delphi 348 || 449 dengan indentasi

Tanpa indentasi

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.

Dengan indentasi

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.
Teun Pronk
sumber
1

CJam, 30 (23) byte

CJam beberapa bulan lebih muda dari tantangan ini sehingga tidak memenuhi syarat untuk tanda centang hijau.

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

Uji di sini.

OP mengklarifikasi dalam komentar bahwa setiap set karakter unik yang dapat dicetak diperbolehkan, jadi saya hanya mengambil karakter ASCII yang dapat dicetak dari awal (dengan spasi di sudut, ! berikutnya dan seterusnya).

Jika orientasi dapat berubah antara input genap dan ganjil (yang menurut saya tidak, tapi itulah yang dilakukan oleh GolfScript), saya dapat melakukannya dalam 25 byte:

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

Idenya sangat sederhana: mulai dengan kisi yang berisi spasi, lalu N-1 kali transpos dan gandakan semua garis dengan karakter berikutnya.

Untuk versi panjang, pada akhirnya saya juga memindahkan lagi N-1 kali untuk menjamin orientasi yang konsisten.

Martin Ender
sumber