Прямоугольный псевдофрактал

13

Цель

Цель программы - нарисовать художественный прямоугольник ASCII, многократно удвоенный по размеру, чередуясь по горизонтали и вертикали. Каждый раз, когда размер прямоугольника удваивается, дополнительная область представляется другим символом, а предыдущие области остаются неизменными. Два самых маленьких раздела содержат по одному символу каждый и могут находиться в любом углу.

Программа принимает одно целое число в качестве входных данных, определяя количество разделов, которые содержит полный прямоугольник.

Другие внешние ресурсы или входы не допускаются.

Пример ввода и вывода

10

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

Критерий отбора

Самый короткий код за неделю выигрывает очки.

Hand-E-Food
источник
Каким должен быть выход для не-степеней 4?
Маринус
Требуется ли выходной сигнал последовательности A, B, C и т. Д.?
Кендалл Фрей
2
@marinus Что особенного в силах 4? Может быть, вы неправильно поняли пример?
Кендалл Фрей
@KendallFrey, нет, просто должно быть n уникальных печатных символов.
Hand-E-Food
Должен

Ответы:

10

APL, 25 символов / байт *

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

В разобранном виде

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

Примеры

      {⍉⍣⍵⊃{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 может быть записан в своей собственной (устаревшей) однобайтовой кодировке, которая отображает символы APL в верхние 128-байтовые значения. Следовательно, для целей оценки программа из N символов, в которой используются только символы ASCII и символы APL, может рассматриваться как длина N байтов.

Тобия
источник
9

GolfScript, 30 символов

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

Пример (запустить онлайн ):

> 7
01335555
22335555
44445555
44445555
66666666
66666666
66666666
66666666
Говард
источник
Это приводит к неправильному выводу четных чисел, например, в вопросе ...
Тимви
@Timwi Я только что проверил это, и оно работает для меня. Вывод транспонирован, но в вопросе ориентация не указана.
Говард
Хорошо, я думаю, что я был слишком строгим тогда :)
Тимви
@ Говард Хм, вот как я понимаю, "и предыдущие области остаются неизменными". Он говорит, что первые два символа могут быть в любом углу, но он не говорит, что ориентация может измениться.
Мартин Эндер
7

Python 2.7 - 85 103

Это использует zip(*s)синтаксис, чтобы постоянно транспонировать список. Большое спасибо Даниэлю за его совет, который побрил 12 персонажей! Затем побрился еще немного, используя цифры вместо букв.

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)

Кроме того, это использует, 1<<xа не 2**xкак сдвиг бит имеет более низкий (?) Приоритет. Заметим:

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

И некоторый вывод:

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

источник
1
Ницца. Вы можете сократить это немного for i in s:print''.join(i).
Даниэль Любаров
5

Руби, 88

Читает N из стандартного ввода.

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

Пример использования для N = 8:

echo 8 | rectangular-pseudo-fractal.rb

Выход:

ABDDFFFFHHHHHHHH
CCDDFFFFHHHHHHHH
EEEEFFFFHHHHHHHH
EEEEFFFFHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH

N = 10

echo 10 | rectangular-pseudo-fractal.rb

Выход:

ABDDFFFFHHHHHHHHJJJJJJJJJJJJJJJJ
CCDDFFFFHHHHHHHHJJJJJJJJJJJJJJJJ
EEEEFFFFHHHHHHHHJJJJJJJJJJJJJJJJ
EEEEFFFFHHHHHHHHJJJJJJJJJJJJJJJJ
GGGGGGGGHHHHHHHHJJJJJJJJJJJJJJJJ
GGGGGGGGHHHHHHHHJJJJJJJJJJJJJJJJ
GGGGGGGGHHHHHHHHJJJJJJJJJJJJJJJJ
GGGGGGGGHHHHHHHHJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
Пол Престиж
источник
Как выглядит результат этого?
@LegoStormtroopr добавил несколько примеров, хотя это тот же формат, что и вопрос.
Пол Престиж
4

J, 57 43

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

Примеры:

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

7 (,`,.@.(=/@$@[)$${&a.@(66+2&^.@#@,)^:)1$'A'
ABDDFFFFHHHHHHHH
CCDDFFFFHHHHHHHH
EEEEFFFFHHHHHHHH
EEEEFFFFHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH
barbermot
источник
С и D оба проходят горизонтально. Они должны чередоваться по горизонтали и вертикали.
Hand-E-Food
@ Hand-E-Food ты прав. Спасибо что подметил это. Я исправил код (и пост).
Барбермот
4

MATLAB, 86 персонажей

Моя самая короткая попытка в MATLAB, pimped @flawr (дважды!):

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

Пример вывода:

>> disp(f(7))
ACEEGGGG
BCEEGGGG
DDEEGGGG
DDEEGGGG
FFFFGGGG
FFFFGGGG
FFFFGGGG
FFFFGGGG
knedlsepp
источник
Это сэкономит вам несколько байтов: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: О! Очевидно!
knedlsepp
Сохранить другой байт, заменяя аргумент fixс fix(n/2-[.5,1])PS: Действительно красивое решение с cat, не знал об этом использовании , где вы можете выбрать размер =)
flawr
@flawr: мне кажется, я довольно расточительный. ;-)
knedlsepp
Я только что заметил, что вы новичок здесь, так что добро пожаловать на codegolf.SE, приятно иметь.) Еще несколько наркоманов по матлаб, б.) Говорящих на немецком языке здесь (я предполагаю)!
flawr 30.01.15
3

q [73 символа]

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

пример

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

Скриптинг , 59 символов

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

(Эта программа могла бы быть немного короче, если бы у меня были инструкции для логарифма по основанию-2, но я этого не делаю, поэтому я делаю это вручную с помощью цикла.)

Аннотированный код

n это вход.

❶ | 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]
終

Выход

Для n= 6:

ABDDFFFF
CCDDFFFF
EEEEFFFF
EEEEFFFF

Конечно, вы можете изменить 뀀( @) на любой другой базовый символ, например, с помощью (пробела) и n= 7:

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

Самое большое число, которое не делает программу длиннее - (= 255), что дает нам ( n= 8 на этот раз):

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

Если мы сделаем программу на 1 символ длиннее, например, используем 냟및(= \u4DFF) и n= 9, мы получим:

一丁七七丅丅丅丅万万万万万万万万
丂丂七七丅丅丅丅万万万万万万万万
丄丄丄丄丅丅丅丅万万万万万万万万
丄丄丄丄丅丅丅丅万万万万万万万万
丆丆丆丆丆丆丆丆万万万万万万万万
丆丆丆丆丆丆丆丆万万万万万万万万
丆丆丆丆丆丆丆丆万万万万万万万万
丆丆丆丆丆丆丆丆万万万万万万万万
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
Timwi
источник
3

C #, 239 185 182 180 байт

C # не имеет ничего о менее многословных языках.

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":""));
    }
}

Вывод, символы выбраны для красивости:

!"$$&&&&((((((((****************
##$$&&&&((((((((****************
%%%%&&&&((((((((****************
%%%%&&&&((((((((****************
''''''''((((((((****************
''''''''((((((((****************
''''''''((((((((****************
''''''''((((((((****************
))))))))))))))))****************
))))))))))))))))****************
))))))))))))))))****************
))))))))))))))))****************
))))))))))))))))****************
))))))))))))))))****************
))))))))))))))))****************
))))))))))))))))****************
Hand-E-Food
источник
1
Не знаю, как вы сосчитали, но я сосчитал 184. Вы можете сохранить два символа, сняв фигурные скобки с внешнего forцикла, сделав 182.
Боб
Спасибо, Боб! Должно быть, я ошибся при микрооптимизации.
Hand-E-Food
2

PERL, 122 символа

$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

с добавленным пробелом:

$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

Выход:

$ echo 8 | perl pseudo-fractal.pl
ABDDFFFFHHHHHHHH
CCDDFFFFHHHHHHHH
EEEEFFFFHHHHHHHH
EEEEFFFFHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH
Tomas
источник
1

PERL,  94   81 символ

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

Он строит фрактал итеративно по буквам, добавляя новые строки и столбцы, а также строки и столбцы ... Для этого используются простые строковые операции. Обратите внимание, что я вместо стандартной буквы использую стандартную переменную, чтобы допустить синтаксический сахар (например, пропуски пробелов $:x2и т. Д.)

С добавленными пробелами и комментариями:

$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

Некоторый вывод:

$ echo 8 | perl -p pseudo-fractal.fill.pl.5a5
ABDDFFFFHHHHHHHH
CCDDFFFFHHHHHHHH
EEEEFFFFHHHHHHHH
EEEEFFFFHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH
Tomas
источник
1

Скриптинг , 45 символов

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

Это решение работает совершенно иначе, чем другое решение Sclipting. Это гораздо скучнее, но короче ...

аннотированный

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
источник
1

Delphi 348 || 449 с отступом

Без отступа

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.

С отступом

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) байтов

CJam на несколько месяцев моложе этой задачи, поэтому она не имеет права на зеленую галочку.

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

Проверьте это здесь.

ОП пояснил в комментарии, что разрешен любой набор уникальных печатных символов, поэтому я просто беру печатные символы ASCII с самого начала (с пробелом в углу, !рядом и так далее).

Если ориентация может измениться между четными и нечетными входами (что я не думаю, но это то, что делает представление GolfScript), я могу сделать это в 25 байтов:

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

Идея очень проста: начать с сетки, содержащей пробел, а затем N-1 раз транспонировать ее и удвоить все строки следующим символом.

Для длинной версии, в конце я также переставляю снова N-1 раз, чтобы гарантировать последовательную ориентацию.

Мартин Эндер
источник