Фрактальный собор

22

Учитывая положительное целое число n >= 1, выведите первые nстроки следующей структуры:

   #
  # #
  ###
 #   #
 # # #
 ## ##
 #####
#     #
#  #  #
# # # #
# ### #
##   ##
## # ##
### ###
#######

n-Й 1-индексированный строка является двоичным представлением n, зеркальным без копирования последнего символа, с #вместо 1 и <space>вместо 0. Всех строк центрируются.

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

Вы можете просмотреть первые 1023 ряда фрактального собора здесь .

Чтобы сгенерировать более крупные тесты, вот нерегламентированная эталонная реализация в Python

HyperNeutrino
источник
Хорошая идея. Я бы не догадался, что двоичные числа создали такое красивое искусство ascii.
Иона
@Jonah Спасибо :) Рад, что тебе нравится
HyperNeutrino
7
Обе ссылки указывают на сгенерированный собор.
Отавио
@ Otávio: я исправлю, спасибо
HyperNeutrino

Ответы:

6

MATL , 10 байт

:B2&Zv35*c

Попробуйте онлайн!

объяснение

:      % Implicitly input n. Push range [1 2 ... n]
B      % Convert to binary. Gives a matrix where each row corresponds to
       % a number. Rows have left-padding zeros if needed
2      % Push 2
&Zv    % Symmetrize along sepecified dimension (2nd means horizontally),
       % without repeating the last element
35*    % Multiply by 35 (ASCII code for '#')
c      % Convert to char. Char 0 is shown as space. Implicitly display
Луис Мендо
источник
1
Интересно, было бы полезно добавить какую-то встроенную функцию, которая соответствует умножению на 35 и преобразованию в char. Кажется, его часто используют
Конор О'Брайен,
@ ConorO'Brien Это часто используется, да. Но это будет встроенный
Луис Мендо
Нет выгоды? 35*cэто 4 персонажа
Конор О'Брайен
@ ConorO'Brien Ах, ты имеешь в виду с 35фиксированной? Это кажется немного конкретным. С другой стороны, некоторые задачи допускают любой символ, поэтому это может быть хорошей идеей. Как вы думаете, #является наиболее распространенным?
Луис Мендо
2
Для справки, эта функция была реализована (функция Zcс символом 35, т.е. #). Спасибо, @ ConorO'Brien!
Луис Мендо
5

05AB1E , 9 байтов

Код:

Lb€û.c0ð:

Использует кодировку 05AB1E . Попробуйте онлайн!

Объяснение:

L              # List [1, .., input]
 b             # Convert each to binary
  €û           # Palindromize each binary number
    .c         # Join the array by newlines and centralize
      0ð:      # Replace zeroes by spaces
Аднан
источник
4

Желе , 12 байт

RBUz0ZUŒBo⁶Y

Попробуйте онлайн!

Дрянная Монахиня
источник
1
Я также должен идти, поэтому я буду читать комментарии, когда вернусь. Не стесняйтесь обгонять меня.
Утренняя монахиня
+1 за «не стесняйся обгонять меня» и за хороший ответ.
Волшебная Урна Осьминога
3

Python 2 , 92 байта

n=input()
for x in range(n):s=bin(2**len(bin(n))/4+x+1)[3:].replace(*'0 ');print s+s[-2::-1]

Попробуйте онлайн!

В Python 3 s=f'{x+1:0{len(bin(n))-2}b}'.replace(*'0 ')он короче, но аргументы int(input())вокруг printаргумента увеличивают его до 95 байтов.

Линн
источник
Это моя копия :) (но в 2**len(bin(n))/4любом случае
Эрик Аутгольфер
3

JavaScript (ES6), 106 байт

Используется 1как непробельный символ.

f=(n,k=0)=>k++<n?[...Array(32-Math.clz32(n))].reduce((s,_,i)=>(c=k>>i&1||' ')+s+(i?c:''),'')+`
`+f(n,k):''

демонстрация

Альтернативная версия (тот же размер)

Без Math.clz32():

f=(n,a=[k=i=0])=>n>>i+1?f(n,a,a[++i]=i):k++<n?a.reduce((s,i)=>(c=k>>i&1||' ')+s+(i?c:''),'')+`
`+f(n,a):''
Arnauld
источник
1
Очень хорошо! Впервые увидела Math.clz32- я даже не знала, что она существует!
Birjolaxew
@Birjolaxew Да, это дополнение ES6. Это бывает удобно время от времени.
Арно
3

Шелуха , 21 20 18 байт

Спасибо @Zgarb за 2 байта!

S↑(tfS=↔ΠR" #"←DLḋ

Попробуйте онлайн!

Ungolfed / Пояснение

Чтобы избежать длинного заполнения, это определяет ширину фрактала, который задан как, 2*len(bin(N))-1и генерирует все последовательности этой длины с символами #,_('_' обозначает пробел).

Поскольку декартова мощность генерируется по порядку, а двоичные числа тоже, это нормально. Все, что нам нужно сделать, чтобы получить фрактал на этом этапе, это отфильтровать все палиндромы, и это в основном так:

                    -- implicit input N
S↑(                 -- take N from the following list
        ΠR" #"      --   Cartesian power of [" #"] to
                Lḋ  --     number of bits in bin(N)
               D    --     2*
              ←     --     -1
    fS=↔            --   filter out palindromes
   t                --   drop the first line (all spaces)
ბიმო
источник
1
Ṙ;может быть справедливым Rи ȯненужным. Хорошая идея ответа!
Згарб
2

Mathematica, 94 байта

Column[Row/@Table[s=IntegerDigits[i,2];Join[s,Reverse@Most@s]/.{0->" ",1->"#"},{i,#}],Center]&
J42161217
источник
2
Я действительно должен идти тоже ...
J42161217
2

Mathematica, 98 байт

Riffle[Nest[ArrayFlatten@{{0,#,0},{1,0,1},{1,#,1}}&,{1},⌊Log2@#⌋]~Take~#"#"/. 0->" ","
"]<>""&

Попробуйте в песочнице Wolfram ! И три байта каждый.

Пока что этот подход отличается от других ответов с использованием фрактальной природы шаблона. Ключевой шаг ArrayFlatten@{{0,#,0},{1,0,1},{1,#,1}}&, который делает фрактальную вещь, лучше всего объясняется в форме изображения:

                 [    ]
                 [grid]
[    ]           [    ]
[grid]   --->   #      #
[    ]          #[    ]#
                #[grid]#
                #[    ]#

Код повторяет этот шаг достаточное количество раз, чтобы получить как минимум n строк, затем обрезает лишние строки и отображает их корректно.

Не дерево
источник
2

Gaia , 11 байт

 #”B¦ₔṫ¦€|ṣ

Попробуйте онлайн!

объяснение

    ¦ₔ       For each number 1..input:
 #”B          Convert it to base 2 and use space as 0 and # as 1
      ṫ¦     Palindromize each
        €|   Centre the lines
          ṣ  Join with newlines
Бизнес Кот
источник
2

Python 2 , 120 118 107 байт

спасибо @luismendo, @officialaimm, @ Halvard-Hummel

def f(l):
 for a in range(1,l+1):print(bin(a)[2:]+bin(a)[-2:1:-1]).replace(*'0 ').center(len(bin(l+1))*2-4)

Попробуйте онлайн!

wrymug
источник
2
replace(*'0 ')за 2 байта
officialaimm
2
107 байт
Халвард Хаммель
2

C # (.NET Core) , 192 178 байт, 168 + 23

Спасибо TheLethalCoder за помощь.

x=>new int[x].Select((_,z)=>Convert.ToString(z+1,2).PadLeft((int)Math.Log(x,2)+2).Replace('0',' ')).Aggregate((y,z)=>y+"\n"+z+new string(z.Reverse().Skip(1).ToArray()))

Попробуйте онлайн!

Я уверен, что это может быть значительно уменьшено, скорее всего, при заполнении и обращении строки.

Dennis.Verweij
источник
Добро пожаловать в PPCG! На данный момент этот ответ - всего лишь фрагмент кода. Это можно исправить, добавив число x=>байтов и заметив, что вам не нужно включать конечную точку с запятой. Enumerable.Range(1,x).Select(zкороче как new int[x].Select((_,z)(думаю это правильно). Поскольку вы используете Linq, вы должны включить using System.Linq;в свой счетчик байтов. Вы также используете, Mathпоэтому вы должны включить using System;или полностью квалифицировать его. Обратите внимание, что это тогда короче, какnamespace System.Linq{}
TheLethalCoder
Вам не нужно включать ,' 'в PadLeftвызов, так как пробел по умолчанию.
TheLethalCoder
@TheLethalCoder извините за неудобства, теперь это исправлено.
Dennis.Verweij
Не беспокойся +1 от меня, это хороший ответ :)
TheLethalCoder
1

Древесный уголь , 28 байт

A…·¹NθW⌈θ«Eθ§ #κ↓⸿AEθ÷κ²θ»‖O

Попробуйте онлайн! Ссылка на подробную версию кода. Объяснение:

A…·¹Nθ

Создайте список первых nнатуральных чисел.

W⌈θ«

Повторяйте, пока все элементы не станут равны нулю.

Eθ§ #κ

Выведите последнюю двоичную цифру каждого элемента списка в виде или #.

↓⸿

Перейти к предыдущему столбцу.

AEθ÷κ²θ

Разделите все элементы списка на два.

»‖O

Как только левая половина была нарисована, отразите это.

Нил
источник
Текущие версии Charcoal имеют MapAssignRight(IntDivide, 2, q);3 байта.
Нил
1

J, 29 байт

' #'{~(],}.@|.)"1@(#.^:_1)@i.

Попробуйте онлайн!

объяснение

  • i. целые числа до n, вход
  • (#.^:_1) преобразован в базу 2
  • (],}.@|.)строка за строкой ( "1выполняет эту часть), возьмите двоичное число ( ]это тождество fn) и cat it ( ,) с его reverse ( |.), где обратная сторона обезглавлена ​​( }.).
  • ' #'{~преобразует 1s и 0s в хэши и пробелы.
Ион
источник
Вы можете использовать #.invвместо #.^:_1.
Конор О'Брайен
@ ConorO'Брайен, спасибо, не знал об этом.
Иона
Разве это не один? Для n = 1, вы не печатать ничего. В любом случае, вы можете сбрить несколько байтов с некоторыми изменениями, например, так ' #'{~(,|.@}:)"1@#:@:>:@i.(если вам разрешено отключить один, вы можете удалить еще 4 байта). В основном, используйте ловушку, потому что она работает как вилка, когда левый зубец, ]и используйте встроенный, в #:котором AFAIK примерно такой же, как #.inv. РЕДАКТИРОВАТЬ: я думаю, мой ответ достаточно похож, чтобы оправдать быть комментарием, дайте мне знать, если вы думаете, что это должен быть ответ самостоятельно.
Коул
@cole, спасибо! Я обновлю это немного позже. Я думал, что пытался, #:и это не сработало, но я, должно быть, помнил неправильно, потому что вы правы, что это работает.
Иона
@ Джона, возможно, ты пробовал, и 2 #:получишь только самую правую цифру. Монадические #:функции так же, как #.inv(или #.&:_1). Это отличается от двоичного #:, который дает столько цифр, сколько атомов в его левом аргументе.
Коул
1

Протон , 95 байт

r=>{for i:range(1,r)print(((bin(i)[2to]).rjust(len(bin(r))-2)[to-1,to by-1]).replace('0',' '))}

Попробуйте онлайн!

Слишком много ошибок, чтобы не было слишком много скобок ... Мне нужно исправить парсер ...

HyperNeutrino
источник
1

PHP, 98 97 95 94 + 1 байт

while($r++<$argn)echo$s=strtr(sprintf("%".-~log($argn,2).b,$r),0," "),substr(strrev("
$s"),1);

Запустите как трубу с -nRили попробуйте онлайн . Используется 1как не пропуски.

Titus
источник
Извините, что испортил это, но что-то здесь не так. вывод для $argn=1и $argn=3не является правильным, и $argnосновывается на 0 (задано было на основе 1)
Феликс Пальмен
1
@FelixPalmen исправлено. Неправильность была вызвана неправильной базой. Спасибо, что заметили.
Титус
0

C (gcc) , 146 108 105 байт

#define o putchar(33-!(c&(1<<n)))
b;c;p(n){--n?o,p(n),o:o;}f(n){while(n>>++b);while(c++<n)p(b),puts("");}

Попробуйте онлайн!

Эта функция вызывается f(n)с количеством строк n, используя восклицательный знак (! ) в качестве непробельного символа.

Пояснение :

#define o putchar(33-!(c&(1<<n)))
b;c;
p(n)
{
    // least significant bit not yet reached?
    --n?
            // print bit twice with recursive step between
            o,
            p(n),
            o
        // for least significant, just print this bit
        :o;
}

// the main "cathedral function":
f(r)
{
    // determine max number of bits to shift
    while(r>>++b);

    // iterate over rows
    while(c++<r)

        // print row recursively
        p(b),

        // newline
        puts("");
}

/**
 * footer, just calling the function
 */
main(int argc, char **argv)
{
    f(atoi(argv[1]));
}
Феликс Палмен
источник
Предлагаю --n&&o+p(n);o;вместо --n?o,p(n),o:o;и for(;c++<n;puts(""))p(b);вместоwhile(c++<n)p(b),puts("");
потолок кошка
0

JavaScript (Node.js) , 156 149 байт

-7 байт @ ConorO'Brien

f=(n,w=n.toString(2).length,b=n.toString(2).replace(/0/g," "),s=" ".repeat(w-b.length))=>`${--n?f(n,w)+s+b+[...b].reverse().join``.substr(1):s+"1"}
`

Попробуйте онлайн!

Рекурсивная функция. К сожалению, JS не поддерживает реверсирование строки, поэтому при преобразовании ее в массив и обратно используется 19 байтов.

Birjolaxew
источник
1
Вы можете использовать [...b]вместо b.split(""); Вы также можете использовать .join``.substr(1)вместо .join("").substr(1); наконец, я думаю, что вы можете использовать s+1вместоs+"1"
Конор О'Брайен
0

Perl 5 , 77 + 1 (-n) = 78 байт

$x=1+(log$_)/log 2;map{$_=sprintf"%0${x}b",$_;y/0/ /;say$_.chop.reverse}1..$_

Попробуйте онлайн!

Использование '1' вместо '#', потому что это экономит пару байтов.

Xcali
источник