Нарисуйте треугольник Серпинского


43

Треугольник Серпинского - это фрактал, созданный путем взятия треугольника, уменьшения высоты и ширины на 1/2, создания 3 копий получившегося треугольника и размещения их таким образом, чтобы каждый треугольник касался двух других по углу. Этот процесс повторяется снова и снова с полученными треугольниками для получения треугольника Серпинского, как показано ниже.

введите описание изображения здесь

Напишите программу для генерации треугольника Серпинского. Вы можете использовать любой метод, который вы хотите сгенерировать, либо рисуя фактические треугольники, либо используя случайный алгоритм для генерации изображения. Вы можете рисовать в пикселях, в ascii art или как угодно, при условии, что результат будет похож на последний рисунок, показанный выше. Побеждает несколько персонажей.


1
См. Также старую версию переполнения стека: stackoverflow.com/questions/1726698/…
dmckee

3
Я получил представление об этом после того, как увидел вопрос о треугольнике Паскаля и вспомнил пример программы для этого в своем руководстве к TI-86. Я решил преобразовать его в QBasic, а затем закодировать в гольф.
Кибби

Здесь нет проблем с выполнением задания, которое уже было выполнено в Stack Overflow, но многие люди не захотят представлять тот же материал снова. Поэтому я связываю их для назидания более поздних посетителей.
dmckee

Чтобы избежать дублирования, возможно, вам следует перейти к правилам, разрешающим только графические реализации.
Примо

Много идей от Вольфрама
luser droog

Ответы:


41

HTML + JavaScript, 150 символов (см. Примечания для 126 символов)

Пробелы вставлены для удобства чтения и не учитываются.

<title></title><canvas></canvas><script>
for(x=k=128;x--;)for(y=k;y--;)
  x&y||document.body.firstChild.getContext("2d").fillRect(x-~y/2,k-y,1,1)
</script>

Суть его заключается в применении правила раскраски пикселей, для которого x & y == 0по условию x&y||получается «прямоугольный треугольник Серпинского»; и x-~y/2,k-yпреобразование координат для получения приблизительно равностороннего отображения.

введите описание изображения здесь

Менее правильная (с точки зрения HTML) версия - 126 символов:

<canvas><script>
for(x=k=128;x--;)for(y=k;y--;)
  x&y||document.body.firstChild.getContext("2d").fillRect(x-~y/2,k-y,1,1)
</script>

(Способ, которым это менее верно, состоит в том, что он пропускает titleэлемент и конечный тег canvasэлемента, оба из которых требуются для правильного документа, даже если их пропуск не меняет интерпретацию документа.)

Три символа могут быть сохранены путем исключения kв пользу константы 64за счет меньшего результата; Я бы не посчитал 8вариант, так как в нем недостаточно деталей.

Обратите внимание, что размер 256 или выше требует атрибутов <canvas>для увеличения размера холста по умолчанию.


22
Никого не волнует, проверяет ли ваш HTML на codegolf :-) Некоторые улучшения: <canvas id=c>и потом c.getContext. Укоротить петли:for(x=k=128;x--;)for(y=k;y--;)
скопировать

4
Превращение идентификаторов в глобальные переменные является ужасной ошибкой, которую я отказываюсь признать, и WebKit не реализует ее в стандартном режиме. Спасибо за петлю
Кевин Рейд

1
Незначительное улучшение: x&y?0:можно заменить на x&y||В противном случае хорошее решение.
Примо

5
Браво, это просто замечательно.
Boothby

2
Поскольку он содержит скрипт, я бы рекомендовал назвать его как HTML + Javascript . Это станет понятнее тому, кто думает, что это за ответ.

30

GolfScript ( 43 42 символа)

' /\ /__\ '4/){.+\.{[2$.]*}%\{.+}%+\}3*;n*

Выход:

               /\               
              /__\              
             /\  /\             
            /__\/__\            
           /\      /\           
          /__\    /__\          
         /\  /\  /\  /\         
        /__\/__\/__\/__\        
       /\              /\       
      /__\            /__\      
     /\  /\          /\  /\     
    /__\/__\        /__\/__\    
   /\      /\      /\      /\   
  /__\    /__\    /__\    /__\  
 /\  /\  /\  /\  /\  /\  /\  /\ 
/__\/__\/__\/__\/__\/__\/__\/__\

Измените «3» на большее число для большего треугольника.


27

Python (234)

Максимальный гольф, крошечное изображение:

#!/usr/bin/env python3
from cairo import*
s=SVGSurface('_',97,84)
g=Context(s)
g.scale(97,84)
def f(w,x,y):
 v=w/2
 if w>.1:f(v,x,y);f(v,x+w/4,y-v);f(v,x+v,y)
 else:g.move_to(x,y);g.line_to(x+v,y-w);g.line_to(x+w,y);g.fill()
f(1,0,1)
s.write_to_png('s.png')

Требуется python3-cairo.

Чтобы получить хорошее большое изображение мне понадобилось 239 символов.

Треугольник Серпинского


1
import cairo as cчто бы спасти вас от нескольких персонажей
квазимодо

1
Этот ответ нуждается в большем количестве голосов
ixtmixilix

26

Mathematica - 32 персонажа

Nest[Subsuperscript[#,#,#]&,0,5]

введите описание изображения здесь

Mathematica - 37 символов

Grid@CellularAutomaton[90,{{1},0},31]

Это создаст 2D таблицу с 0 и 1, где 1s рисуют треугольник Серпинского.

введите описание изображения здесь


2
При стоимости 5 дополнительных символов ваше второе решение будет отображаться лучше с помощью ArrayPlot@CellularAutomaton[90, {{1}, 0}, 31]или MatrixPlot@CellularAutomaton[90, {{1}, 0}, 31].
DavidC

1
... или с ReliefPlot@...
DavidC

Я понял это . Как вы получили вывод без всех скобок?
Мистер Волшебник

@ Мистер Волшебник, хм ... откуда брекеты? Это даже работает здесь: mathics.net Попробуйте и дайте мне знать.
Виталий Кауров

1
@Vitaliy Kaurov Первичное (32-символьное) решение удивительно. Можете ли вы выполнить задачу «Фрактальное дерево» (в другом месте на PCG), используя ту же технику?
Майкл Стерн

22

Python, 101 86

Использует правило 90 автомат.

x=' '*31
x+='.'+x
exec"print x;x=''.join(' .'[x[i-1]!=x[i-62]]for i in range(63));"*32

Это длиннее, но красивее.

x=' '*31
x+=u'Δ'+x
exec u"print x;x=''.join(u' Δ'[x[i-1]!=x[i-62]]for i in range(63));"*32

Редактировать: играть со строками напрямую, избавиться от неприятно длинных срезов, сделать вывод более красивым.

Выход:

                               Δ                               
                              Δ Δ                              
                             Δ   Δ                             
                            Δ Δ Δ Δ                            
                           Δ       Δ                           
                          Δ Δ     Δ Δ                          
                         Δ   Δ   Δ   Δ                         
                        Δ Δ Δ Δ Δ Δ Δ Δ                        
                       Δ               Δ                       
                      Δ Δ             Δ Δ                      
                     Δ   Δ           Δ   Δ                     
                    Δ Δ Δ Δ         Δ Δ Δ Δ                    
                   Δ       Δ       Δ       Δ                   
                  Δ Δ     Δ Δ     Δ Δ     Δ Δ                  
                 Δ   Δ   Δ   Δ   Δ   Δ   Δ   Δ                 
                Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ                
               Δ                               Δ               
              Δ Δ                             Δ Δ              
             Δ   Δ                           Δ   Δ             
            Δ Δ Δ Δ                         Δ Δ Δ Δ            
           Δ       Δ                       Δ       Δ           
          Δ Δ     Δ Δ                     Δ Δ     Δ Δ          
         Δ   Δ   Δ   Δ                   Δ   Δ   Δ   Δ         
        Δ Δ Δ Δ Δ Δ Δ Δ                 Δ Δ Δ Δ Δ Δ Δ Δ        
       Δ               Δ               Δ               Δ       
      Δ Δ             Δ Δ             Δ Δ             Δ Δ      
     Δ   Δ           Δ   Δ           Δ   Δ           Δ   Δ     
    Δ Δ Δ Δ         Δ Δ Δ Δ         Δ Δ Δ Δ         Δ Δ Δ Δ    
   Δ       Δ       Δ       Δ       Δ       Δ       Δ       Δ   
  Δ Δ     Δ Δ     Δ Δ     Δ Δ     Δ Δ     Δ Δ     Δ Δ     Δ Δ  
 Δ   Δ   Δ   Δ   Δ   Δ   Δ   Δ   Δ   Δ   Δ   Δ   Δ   Δ   Δ   Δ 
Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ

Это выглядит действительно круто: D
beary605

Использование этой U + 0394 столицы Delta - действительно приятное прикосновение.
Дэвид Конрад

16

J

,/.(,~,.~)^:6,'o'

Не идеально, так как треугольник наклонен и сопровождается множеством пробелов - но, тем не менее, я подумал, что это интересно.

Выход:

o                                                               
oo                                                              
o o                                                             
oooo                                                            
o   o                                                           
oo  oo                                                          
o o o o                                                         
oooooooo                                                        
o       o                                                       
oo      oo                                                      
o o     o o                                                     
oooo    oooo                                                    
o   o   o   o                                                   
oo  oo  oo  oo                                                  
o o o o o o o o                                                 
oooooooooooooooo                                                
o               o                                               
oo              oo                                              
o o             o o                                             
oooo            oooo                                            
o   o           o   o                                           
oo  oo          oo  oo                                          
o o o o         o o o o                                         
oooooooo        oooooooo                                        
o       o       o       o                                       
oo      oo      oo      oo                                      
o o     o o     o o     o o                                     
oooo    oooo    oooo    oooo                                    
o   o   o   o   o   o   o   o                                   
oo  oo  oo  oo  oo  oo  oo  oo                                  
o o o o o o o o o o o o o o o o                                 
oooooooooooooooooooooooooooooooo                                
o                               o                               
oo                              oo                              
o o                             o o                             
oooo                            oooo                            
o   o                           o   o                           
oo  oo                          oo  oo                          
o o o o                         o o o o                         
oooooooo                        oooooooo                        
o       o                       o       o                       
oo      oo                      oo      oo                      
o o     o o                     o o     o o                     
oooo    oooo                    oooo    oooo                    
o   o   o   o                   o   o   o   o                   
oo  oo  oo  oo                  oo  oo  oo  oo                  
o o o o o o o o                 o o o o o o o o                 
oooooooooooooooo                oooooooooooooooo                
o               o               o               o               
oo              oo              oo              oo              
o o             o o             o o             o o             
oooo            oooo            oooo            oooo            
o   o           o   o           o   o           o   o           
oo  oo          oo  oo          oo  oo          oo  oo          
o o o o         o o o o         o o o o         o o o o         
oooooooo        oooooooo        oooooooo        oooooooo        
o       o       o       o       o       o       o       o       
oo      oo      oo      oo      oo      oo      oo      oo      
o o     o o     o o     o o     o o     o o     o o     o o     
oooo    oooo    oooo    oooo    oooo    oooo    oooo    oooo    
o   o   o   o   o   o   o   o   o   o   o   o   o   o   o   o   
oo  oo  oo  oo  oo  oo  oo  oo  oo  oo  oo  oo  oo  oo  oo  oo  
o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o 
oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo

Быстрое объяснение:

Глагол (,~,.~)- это то, что делает работу здесь. Это хук, который сначала ,.присоединяет аргумент к себе ( o-> oo), а затем добавляет исходный аргумент к выводу:

oo

становится

oo
o

Этот глагол повторяется 6 раз, ^:6и выходные данные каждой итерации становятся входными данными следующей итерации. Так

oo
o

становится

oooo
o o
oo
o

который в свою очередь становится

oooooooo
o o o o 
oo  oo
o   o
oooo
o o
oo
o

и т. д. Затем я использовал косое наречие при добавлении, ,/.чтобы прочитать строки по диагонали, чтобы выпрямить треугольник. Мне не нужно было этого делать, как указывает Рандомера . Я мог бы просто перевернуть |.все, чтобы получить тот же результат. Даже лучше, я мог бы просто (,,.~)^:6,'o'сохранить полностью обратный шаг.

Ах, хорошо, вы живете и учитесь. :-)


1
Не могли бы вы вкратце объяснить, как это работает? Я не знаком с J
aditsu

1
|.(,~,.~)^:6,'o'короче и без лишних пробелов. А (,~,.~)^:6,1также дает достойный вклад всего в 12 символов!
Рандомра

@aditsu Я добавил объяснение.
Гарет

Так что, если я получу это, этот оператор объединяет два 2d массива?
MaiaVictor

13

APL (51)

      A←67⍴0⋄A[34]←1⋄' ○'[1+32 67⍴{~⊃⍵:⍵,∇(1⌽⍵)≠¯1⌽⍵⋄⍬}A]

Объяснение:

  • A←67⍴0: A - вектор из 67 нулей
  • A[34]←1: 34-й элемент равен 1
  • {...}A: начиная с A, сделайте:
  • ~⊃⍵:: если первый элемент текущей строки равен нулю
  • ⍵,∇: добавьте текущую строку к ответу и повторите с:
  • (1⌽⍵)≠¯1⌽⍵: вектор, где каждый элемент является XOR своих соседей в предыдущем поколении
  • ⋄⍬: иначе мы закончили
  • 32 67⍴: отформатировать в матрице 67x32
  • 1+: добавьте единицу, чтобы выбрать правильное значение из массива символов
  • ' ○'[... ]: вывести либо пробел (не являющийся частью треугольника), либо круг (если он является частью треугольника)

Выход:

                                 ○                                 
                                ○ ○                                
                               ○ ○                               
                              ○ ○ ○ ○                              
                             ○ ○                             
                            ○ ○ ○ ○                            
                           ○ ○ ○ ○                           
                          ○ ○ ○ ○ ○ ○ ○ ○                          
                         ○ ○                         
                        ○ ○ ○ ○                        
                       ○ ○ ○ ○                       
                      ○ ○ ○ ○ ○ ○ ○ ○                      
                     ○ ○ ○ ○                     
                    ○ ○ ○ ○ ○ ○ ○ ○                    
                   ○ ○ ○ ○ ○ ○ ○ ○                   
                  ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○                  
                 ○ ○                 
                ○ ○ ○ ○                
               ○ ○ ○ ○               
              ○ ○ ○ ○ ○ ○ ○ ○              
             ○ ○ ○ ○             
            ○ ○ ○ ○ ○ ○ ○ ○            
           ○ ○ ○ ○ ○ ○ ○ ○           
          ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○          
         ○ ○ ○ ○         
        ○ ○ ○ ○ ○ ○ ○ ○        
       ○ ○ ○ ○ ○ ○ ○ ○       
      ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○      
     ○ ○ ○ ○ ○ ○ ○ ○     
    ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○    
   ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○   
  • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • •  

1
Хлоп. Я ожидал, что это будет 4 символа, используя биномиальный мод 2 ... (хорошо ... может быть, немного дольше)
boothby

13

Хаскелл (291)

Я не очень хорошо разбираюсь в гольфе.

solve n = tri (putStrLn "") [2^n] n
tri m xs 1 =
  do putStrLn (l1 1 xs "/\\" 0)
     putStrLn (l1 1 xs "/__\\" 1)
     m
tri m xs n=tri m' xs (n-1)
  where m'=tri m (concat[[x-o,x+o]|x<-xs]) (n-1)
        o=2^(n-1)
l1 o [] s t=""
l1 o (x:xs) s t=replicate (x-o-t) ' '++s++l1 (x+2+t) xs s t

Выход solve 4составляет:

               /\
              /__\
             /\  /\
            /__\/__\
           /\      /\
          /__\    /__\
         /\  /\  /\  /\
        /__\/__\/__\/__\
       /\              /\
      /__\            /__\
     /\  /\          /\  /\
    /__\/__\        /__\/__\
   /\      /\      /\      /\
  /__\    /__\    /__\    /__\
 /\  /\  /\  /\  /\  /\  /\  /\
/__\/__\/__\/__\/__\/__\/__\/__\

13

QBasic 151 символов

В качестве примера, вот как это можно сделать в QBasic.

SCREEN 9
H=.5
P=300
FOR I=1 TO 9^6
    N=RND
    IF N > 2/3 THEN
        X=H+X*H:Y=Y*H
    ELSEIF N > 1/3 THEN
        X=H^2+X*H:Y=H+Y*H    
    ELSE
        X=X*H:Y=Y*H
    END IF
    PSET(P-X*P,P-Y*P)
NEXT

введите описание изображения здесь


Не могли бы вы описать меру, по которой эта программа составляет 129 символов? Я получу 151, если уберу все ненужные пробелы. (Я не знаком с QBasic.)
Кевин Рейд

Я убрал все пустое место для моего счета. Я думаю, что я мог бы считать только несущественные пробелы. Я не уверен, что такое «официальное» правило для кода гольф.
Кибби

4
Вы должны посчитать фактическое количество символов, включая пробелы, в программе, которая запускается и выдает правильный вывод . Естественно, вы хотите, чтобы не было лишних пробелов.
Кевин Рейд

1
Исправлено количество персонажей.
Кибби

13

Python (42)

Первоначально я хотел опубликовать несколько предложений по решению Boothbys (которое на самом деле использует правило 18 :), но у меня не было достаточно репутации, чтобы комментировать, поэтому я перешел к другому ответу. Поскольку он изменил свой подход, я добавил некоторые объяснения. Мои предложения были бы:

  1. используйте '% d' * 64% tuple (x) вместо '' .join (map (str, x)
  2. сдвигать нули вместо того, чтобы оборачивать список

что привело бы к следующему коду (93 символа):

x=[0]*63
x[31]=1
exec"print'%d'*63%tuple(x);x=[a^b for a,b in zip(x[1:]+[0],[0]+x[:-1])];"*32

Но я оптимизировал дальше, сначала используя longint вместо целочисленного массива и просто печатая двоичное представление (75 символов):

x=2**31
exec"print'%d'*63%tuple(1&x>>i for i in range(63));x=x<<1^x>>1;"*32

И наконец, печатая восьмеричное представление, которое уже поддерживается интерполяцией printf (42 символа):

x=8**31
exec"print'%063o'%x;x=x*8^x/8;"*32

Все они напечатают:

000000000000000000000000000000010000000000000000000000000000000
000000000000000000000000000000101000000000000000000000000000000
000000000000000000000000000001000100000000000000000000000000000
000000000000000000000000000010101010000000000000000000000000000
000000000000000000000000000100000001000000000000000000000000000
000000000000000000000000001010000010100000000000000000000000000
000000000000000000000000010001000100010000000000000000000000000
000000000000000000000000101010101010101000000000000000000000000
000000000000000000000001000000000000000100000000000000000000000
000000000000000000000010100000000000001010000000000000000000000
000000000000000000000100010000000000010001000000000000000000000
000000000000000000001010101000000000101010100000000000000000000
000000000000000000010000000100000001000000010000000000000000000
000000000000000000101000001010000010100000101000000000000000000
000000000000000001000100010001000100010001000100000000000000000
000000000000000010101010101010101010101010101010000000000000000
000000000000000100000000000000000000000000000001000000000000000
000000000000001010000000000000000000000000000010100000000000000
000000000000010001000000000000000000000000000100010000000000000
000000000000101010100000000000000000000000001010101000000000000
000000000001000000010000000000000000000000010000000100000000000
000000000010100000101000000000000000000000101000001010000000000
000000000100010001000100000000000000000001000100010001000000000
000000001010101010101010000000000000000010101010101010100000000
000000010000000000000001000000000000000100000000000000010000000
000000101000000000000010100000000000001010000000000000101000000
000001000100000000000100010000000000010001000000000001000100000
000010101010000000001010101000000000101010100000000010101010000
000100000001000000010000000100000001000000010000000100000001000
001010000010100000101000001010000010100000101000001010000010100
010001000100010001000100010001000100010001000100010001000100010
101010101010101010101010101010101010101010101010101010101010101

Конечно, есть и графическое решение (131 символ):

from PIL.Image import*
from struct import*
a=''
x=2**31
exec"a+=pack('>Q',x);x=x*2^x/2;"*32
fromstring('1',(64,32),a).save('s.png')

очень маленький серпинский треугольник : D


1
36:x=8**31;exec"print'%o'%x;x^=x/8;"*32
aditsu

13

8086 Машинный код - 30 байт.

ПРИМЕЧАНИЕ. Это не мой код, и его не следует принимать в качестве ответа . Я нашел это во время работы над другой проблемой CG для эмуляции процессора 8086 . Включенный текстовый файл относится к Дэвиду Стаффорду , но это лучшее, что я мог придумать.

Я публикую это, потому что это умно, коротко, и я подумал, что вы захотите это увидеть.

Он использует перекрывающиеся коды операций, чтобы упаковать больше инструкций в меньшем пространстве. Удивительно умный Вот машинный код:

B0 13 CD 10 B3 03 BE A0 A0 8E DE B9 8B 0C 32 28 88 AC C2 FE 4E 75 F5 CD 16 87 C3 CD 10 C3

Прямое декодирование выглядит так:

0100: B0 13              mov AL, 13h
0102: CD 10              int 10h
0104: B3 03              mov BL, 3h
0106: BE A0 A0           mov SI, A0A0h
0109: 8E DE              mov  DS, SI
010B: B9 8B 0C           mov CX, C8Bh
010E: 32 28              xor  CH, [BX+SI]
0110: 88 AC C2 FE        mov  [SI+FEC2h], CH
0114: 4E                 dec SI
0115: 75 F5              jne/jnz -11

При запуске, когда происходит переход на 0x0115, обратите внимание, что он возвращается к 0x010C, прямо в середину предыдущей инструкции:

0100: B0 13              mov AL, 13h
0102: CD 10              int 10h
0104: B3 03              mov BL, 3h
0106: BE A0 A0           mov SI, A0A0h
0109: 8E DE              mov  DS, SI
010B: B9 8B 0C           mov CX, C8Bh
010E: 32 28              xor  CH, [BX+SI]
0110: 88 AC C2 FE        mov  [SI+FEC2h], CH
0114: 4E                 dec SI
0115: 75 F5              jne/jnz -11
010C: 8B 0C              mov  CX, [SI]
010E: 32 28              xor  CH, [BX+SI]
0110: 88 AC C2 FE        mov  [SI+FEC2h], CH
0114: 4E                 dec SI
0115: 75 F5              jne/jnz -11
010C: 8B 0C              mov  CX, [SI]

Brilliant! Надеюсь, вы, ребята, не возражаете, я поделюсь этим. Я знаю, что это не ответ сам по себе, но он представляет интерес для вызова.

Вот оно в действии:

Бег


11

C 127 119 116 108 65

В этом случае используется хитрость HTML-ответа, заключающаяся в ^ i & jтом, что для вывода симпатичных выходных данных потребуется еще 1 символ (вы можете получить действительно ужасный вывод, пожертвовав a^).

a=32,j;main(i){for(;++i<a;)putchar(a^i&j);++j<a&&main(puts(""));}

Чтобы сделать это довольно повернуть (32^i&j)к (32|!(i&j))и повернуть его от ++i<aк ++i<=a. Однако тратить впустую символы на внешность кажется мне нелепым.

Уродливый вывод:

 ! ! ! ! ! ! ! ! ! ! ! ! ! ! !
""  ""  ""  ""  ""  ""  ""  ""
"# !"# !"# !"# !"# !"# !"# !"#
  $$$$    $$$$    $$$$    $$$$
 !$%$% ! !$%$% ! !$%$% ! !$%$%
""$$&&  ""$$&&  ""$$&&  ""$$&&
"#$%&' !"#$%&' !"#$%&' !"#$%&'
      ((((((((        ((((((((
 ! ! !()()()() ! ! ! !()()()()
""  ""((**((**  ""  ""((**((**
"# !"#()*+()*+ !"# !"#()*+()*+
  $$$$((((,,,,    $$$$((((,,,,
 !$%$%()(),-,- ! !$%$%()(),-,-
""$$&&((**,,..  ""$$&&((**,,..
"#$%&'()*+,-./ !"#$%&'()*+,-./
              0000000000000000
 ! ! ! ! ! ! !0101010101010101
""  ""  ""  ""0022002200220022
"# !"# !"# !"#0123012301230123
  $$$$    $$$$0000444400004444
 !$%$% ! !$%$%0101454501014545
""$$&&  ""$$&&0022446600224466
"#$%&' !"#$%&'0123456701234567
      ((((((((0000000088888888
 ! ! !()()()()0101010189898989
""  ""((**((**0022002288::88::
"# !"#()*+()*+0123012389:;89:;
  $$$$((((,,,,000044448888<<<<
 !$%$%()(),-,-010145458989<=<=
""$$&&((**,,..0022446688::<<>>
"#$%&'()*+,-./0123456789:;<=>?

Мне действительно нравится, как это выглядит. Но если вы настаиваете на том, чтобы это было красиво, вы можете состыковать четыре символа. Симпатичный выход:

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !
  !!  !!  !!  !!  !!  !!  !!  !
  !   !   !   !   !   !   !   !
!!    !!!!    !!!!    !!!!    !
!     ! !     ! !     ! !     !
      !!      !!      !!      !
      !       !       !       !
!!!!!!        !!!!!!!!        !
! ! !         ! ! ! !         !
  !!          !!  !!          !
  !           !   !           !
!!            !!!!            !
!             ! !             !
              !!              !
              !               !
!!!!!!!!!!!!!!                !
! ! ! ! ! ! !                 !
  !!  !!  !!                  !
  !   !   !                   !
!!    !!!!                    !
!     ! !                     !
      !!                      !
      !                       !
!!!!!!                        !
! ! !                         !
  !!                          !
  !                           !
!!                            !
!                             !
                              !
                              !

Оставив старшие 108 символов, версия сотовых автоматов.

j,d[99][99];main(i){d[0][31]=3;for(;i<64;)d[j+1][i]=putchar(32|d[j][i+2]^d[j][i++]);++j<32&&main(puts(""));}

Так что я не думаю, что получу это намного короче, поэтому объясню код. Я оставлю это объяснение, так как некоторые уловки могут быть полезны.

j,d[99][99]; // these init as 0
main(i){ //starts at 1 (argc)
  d[0][48]=3; //seed the automata (3 gives us # instead of !)
  for(;i<98;) // print a row
    d[j+1][i]=putchar(32|d[j][i+2]]^d[j][i++]);
    //relies on undefined behavoir. Works on ubuntu with gcc ix864
    //does the automata rule. 32 + (bitwise or can serve as + if you know
    //that (a|b)==(a^b)), putchar returns the char it prints
  ++j<32&&main(puts(""));
  // repeat 32 times
  // puts("") prints a newline and returns 1, which is nice
}

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

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

1
Это не похоже на треугольник Серпинского; он разделяется на три суб-треугольника (идущих вниз), а не на два, и видно, что это не приводит к появлению большого центрального пустого треугольника.
Кевин Рейд

1
Это потому, что я использовал неправильное правило: O. Исправил и побрил пару символов.
Walpen

9

Код 80x86 / MsDos - 10 байт

В качестве кодировщика размеров, специализирующегося на очень маленьких вступлениях на MsDos, мне удалось создать программу, занимающую всего 10 байт.

в шестнадцатеричном виде:

04 13 CD 10 20 E9 B4 0C E2 F6

введите описание изображения здесь

в ассм:

X: add al,0x13
int 0x10
and cl,ch
mov ah,0x0C
loop X

Первой версией, которую я кодировал, была «Colpinski», которая имеет размер 16 байт и даже интерактивна, так что вы можете изменить цвет с помощью клавиатуры и мыши. Вместе с «Frag» - еще одним кодировщиком размеров - мы сократили его до 13 байт, что позволило создать 10-байтовую программу, которая содержит только базовую подпрограмму.

Это становится немного интереснее, когда вещи анимированы, поэтому я упомяну другую версию, Zoompinski 64 - пытающуюся имитировать точное поведение «Zoompinski C64» в 512 байтах - также для MsDos, размером 64 байта, как следует из названия.

Это можно оптимизировать до 31 байта, потеряв при этом элегантность, цвета и симметрию (исходные и исполняемые файлы доступны по ссылке выше)

Скачайте оригинал и комментируйте "Pouet"


2
Вы должны опубликовать шестнадцатеричный дамп своего кода, чтобы мы могли видеть фактические байты.
mbomb007

8

PostScript, 120 символов

-7 -4 moveto
14 0 rlineto
7{true upath dup
2{120 rotate uappend}repeat[2 0 0 2 7 4]concat}repeat
matrix setmatrix
stroke

Вывод Ghostscript:

Визуализированный вывод Ghostscript

Это рисует фигуру путем рекурсивного утроения того, что уже нарисовано.

Первым шагом является рисование линии. Строка сохраняется как пользовательский путь, затем пользовательский путь добавляется еще два раза после поворота на 120 градусов каждый раз. [2 0 0 2 7 4]concatперемещает «точку вращения» в центр следующего большого белого «центрального треугольника», который должен быть заключен в копии того треугольника, который у нас уже есть. Здесь мы возвращаемся к шагу 1 (создание upath, которое утроено вращением).

Количество итераций контролируется первым числом в строке 3.


+1 Очень мило. Я понятия не имел, что можно использовать таким образом.
Люзер Дрог

Эй, у вас есть представитель, чтобы добавить это изображение сейчас!
luser droog

@luserdroog: Это верно (даже отчасти благодаря вам)!
Томас В.

7

J (9 знаков)

Без сомнения, вам действительно нужно щуриться, чтобы увидеть результат;)

2|!/~i.32

производит вывод

1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1
0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1
0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1
0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 1
0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1
0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1
0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1
0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1
0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1

Конечно, вы можете отобразить это графически:

load 'viewmat'
viewmat 2|!/~i.32

Образ


как ... что?
помощник

4
Код использует свойство треугольника Паскаля: если вы раскрасите все нечетные (четные) числа в черный (белый), вы получите треугольник Серпинского. (см. это изображение). i.32 генерирует список 0 1 2 ... 31. Затем! / ~ вычисляет биномиальные коэффициенты каждого элемента в списке против себя, то есть создает матрицу 32 x 32, в которую встроен треугольник Паскаля. Тогда 2 | просто каждый элемент в этой матрице мод 2, производящий треугольник Серпинского.
Марк Аллен

4

APL, 37 32 ( 28 23)

Вертикальный треугольник ( 37 32 символа)

({((-1⌷⍴⍵)⌽⍵,∊⍵)⍪⍵,⍵}⍣⎕)1 2⍴'/\'

объяснение

  • 1 2⍴'/\': Создать матрицу символов 1 × 2 /\
  • {((-1⌷⍴⍵)⌽⍵,∊⍵)⍪⍵,⍵}: Функция, которая дополняет правый аргумент с обеих сторон пробелами, чтобы создать матрицу, удваивающую ширину, а затем ламинирует сам правый аргумент, удвоенный вниз.
    Например /\стал бы
 / \ 
/ \ / \
  • ⍣⎕: Повторить функцию (пользовательский ввод) раз.

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

               /\               
              /\/\              
             /\  /\             
            /\/\/\/\            
           /\      /\           
          /\/\    /\/\          
         /\  /\  /\  /\         
        /\/\/\/\/\/\/\/\        
       /\              /\       
      /\/\            /\/\      
     /\  /\          /\  /\     
    /\/\/\/\        /\/\/\/\    
   /\      /\      /\      /\   
  /\/\    /\/\    /\/\    /\/\  
 /\  /\  /\  /\  /\  /\  /\  /\ 
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\

Перекошенный треугольник ( 28 23 знака)

({(⍵,∊⍵)⍪⍵,⍵}⍣⎕)1 1⍴'○'

Explaination

  • 1 1⍴'○': Создать матрицу символов 1 × 1
  • {(⍵,∊⍵)⍪⍵,⍵}: Функция, которая дополняет правый аргумент справа пробелами, чтобы создать матрицу, удваивающую ширину, а затем ламинирует сам правый аргумент, удвоенный снизу.
    Например стал бы
○ 
○○
  • ⍣⎕: Повторить функцию (пользовательский ввод) раз.

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

○               
○○              
○ ○             
○○○○            
○   ○           
○○  ○○          
○ ○ ○ ○         
○○○○○○○○        
○       ○       
○○      ○○      
○ ○     ○ ○     
○○○○    ○○○○    
○   ○   ○   ○   
○○  ○○  ○○  ○○  
○ ○ ○ ○ ○ ○ ○ ○ 
○○○○○○○○○○○○○○○○

4

Python (75)

Я опоздал на вечеринку на два года, но я удивлен, что никто еще не использовал этот подход

from pylab import*
x=[[1,1],[1,0]]
for i in'123':x=kron(x,x)
imsave('a',x)

level7

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

Я мог бы сохранить два символа, используя x=kron(x,x);x=kron(x,x)в третьей строке, чтобы получить изображение 16x16 пикселей с тремя видимыми уровнями, или добавить еще один символ в итератор и в итоге получить изображение размером 2 ^ 16 x 2 ^ 16 = 4,3 гигапикселя и 15 уровней треугольника.


3

Логотип, 75 знаков

59 символов только для первой функции, вторая вызывает первую с размером и глубиной / числом итераций. Таким образом, вы можете просто вызвать первую функцию из интерпретатора с помощью команды: e 99 5 или любой другой размер, который вы хотите вывести

to e :s :l
if :l>0[repeat 3[e :s/2 :l-1 fd :s rt 120]]
end
to f
e 99 5
end

+1 Я читал о логотипе. Какой переводчик вы используете? ... Логотип может быть естественным подспорьем для моей задачи в системе l .
luser droog

Если вы просто удалите to fи endвокруг e 99 5, у вас будет полная работоспособная программа с меньшим количеством символов. Кроме того, в UCBLogo (но не в других версиях) вы можете потерять двоеточия для переменных, чтобы сохранить больше символов.
Марк Рид


3

J (18 знаков)

' *'{~(,,.~)^:9 ,1

Результат

*                               
**                              
* *                             
****                            
*   *                           
**  **                          
* * * *                         
********                        
*       *                       
**      **                      
* *     * *                     
****    ****                    
*   *   *   *                   
**  **  **  **                  
* * * * * * * *                 
****************                
*               *               
**              **              
* *             * *             
****            ****            
*   *           *   *           
**  **          **  **          
* * * *         * * * *         
********        ********        
*       *       *       *       
**      **      **      **      
* *     * *     * *     * *     
****    ****    ****    ****    
*   *   *   *   *   *   *   *   
**  **  **  **  **  **  **  **  
* * * * * * * * * * * * * * * * 
********************************

3

Питон (90 символов)

from turtle import*
def l():left(60)
def r():right(60)
def f():forward(1)
def L(n):
 if n:n-=1;R(n);l();L(n);l();R(n)
 else:f()
def R(n):
 if n:n-=1;L(n);r();R(n);r();L(n)
 else:f()
l();L(8)

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

Нарисуйте фрактальную линию заливки Серпинского треугольника


Перед запуском рекомендую вставить ht();speed(0);up();goto(20-window_width()/2, 20-window_height()/2);down()после импорта. Это запустит его намного быстрее и гарантирует, что вывод помещается на холст.
mbomb007

3

Mathematica 67

ListPlot@NestList[(#+RandomChoice@{{0,0},{2,0},{1,2}})/2&,{0,0},8!]

введите описание изображения здесь

Mathematica 92

Graphics@Polygon@Nest[Join@@(Mean/@#&/@#~Tuples~2~Partition~3&/@#)&,{{{0,0},{2,0},{1,1}}},3]

введите описание изображения здесь


3

Mathematica , 29 байт

Image@Array[BitAnd,{2,2}^9,0]

Image @ Array [BitAnd, {2,2} ^ 9,0]

Тетраэдр Серпинского можно нарисовать аналогичным образом:

Image3D[1-Array[BitXor,{2,2,2}^7,0]]

Image3D [1-Массив [BitXor, {2,2,2} ^ 7,0]]


3

J , 37 35 байт

-2 байта благодаря FrownyFrog

(,.~,~' '&,.^:#)@[&0' /\',:'/__\'"_

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

Это художественная версия ascii Питера Тейлора, преобразованная в J. Могли бы сэкономить байты с менее симпатичной версией, но почему?

       /\       
      /__\      
     /\  /\     
    /__\/__\    
   /\      /\   
  /__\    /__\  
 /\  /\  /\  /\ 
/__\/__\/__\/__\

@]^:[-> @[&0и ' /\ '->' /\'
FrownyFrog

Вы случайно не знаете, где &0описан трюк?
Иона

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

О, вы должны быть в состоянии поменять местами операнды ,~.
FrownyFrog

3

Скрипт Lua на Golly , 54 байта

g=golly()
g.setrule("W60")
g.setcell(0,0,1)
g.run(512)

Golly - это симулятор сотовых автоматов с поддержкой сценариев Lua и Python.

Этот сценарий устанавливает правило для правила Вольфрама 60, устанавливает ячейку с (0,0) в 1 и выполняет 512 шагов.

введите описание изображения здесь


2

Постскриптум, 205 203

[48(0-1+0+1-0)49(11)43(+)45(-)/s{dup
0 eq{exch{[48{1 0 rlineto}49 1 index
43{240 rotate}45{120 rotate}>>exch
get exec}forall}{exch{load
exch 1 sub s}forall}ifelse 1 add}>>begin
9 9 moveto(0-1-1)9 s fill

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

Изменить: fill короче, чем stroke.

Отступы и комментарии.

%!
[   % begin dictionary
    48(0-1+0+1-0) % 0
    49(11)        % 1
    43(+)         % +
    45(-)         % -
    /s{ % string recursion-level
        dup 0 eq{ % level=0
            exch{  % iterate through string
                [
                    48{1 0 rlineto} % 0
                    49 1 index      % 1 
                    43{240 rotate}  % +
                    45{120 rotate}  % -
                >>exch get exec % interpret turtle command
            }forall
        }{ % level>0
            exch{  % iterate through string
                load exch  % lookup charcode
                1 sub s    % recurse with level-1
            }forall
        }ifelse
        1 add  % return recursion-level+1
    }
>>begin
9 9 moveto(0-1-1)9 s fill % execute and fill

Добавление 0 setlinewidthдает лучшее представление о том, как глубоко это заходит.

пересмотреть изображение, используя <code> fill </ code> (почти то же самое)


Это мой любимый.
cjfaure

Есть способ сделать это короче с этой внешней библиотекой, которую я написал после факта и не могу использовать. : P
luser droog


2

Асимптота, 152 байта

Я добавлю это, в основном, потому что я видел более-менее нет ответов в асимптоте на этом сайте. Несколько потраченных впустую байтов для хорошего форматирования и обобщения, но я могу жить с этим. Изменение A, B и C изменит расположение углов содержащего треугольника, но, вероятно, не так, как вы думаете. Увеличьте число в неравенстве, чтобы увеличить глубину.

pair A=(0,0),B=(1,0),C=(.5,1);void f(pair p,int d){if(++d<7){p*=2;f(p+A*2,d);f(p+B*2,d);f(p+C*2,d);}else{fill(shift(p/2)*(A--B--C--cycle));}}f((0,0),0);

или негольфированный и читаемый

pair A=(0,0), B=(1,0), C=(.5,1);

void f(pair p, int d) {
    if (++d<7) {
        p *= 2;
        f(p+A*2,d);
        f(p+B*2,d);
        f(p+C*2,d);
    } else {
        fill(shift(p/2)*(A--B--C--cycle));
    }
}

f((0,0),0);

Таким образом, asymptote - это аккуратный язык векторной графики с несколько C-подобным синтаксисом. Весьма полезно для несколько технических диаграмм. Вывод, конечно, по умолчанию в векторном формате (eps, pdf, svg), но его можно конвертировать практически во все, что поддерживает imagemagick. Выход:

Треугольник Серпинского


2

Haskell , 166 154 байта

(-12 байт, благодаря Laikoni, (понимание zip и списка вместо zipWith и lambda, лучший способ генерации первой строки))

i#n|let k!p=p:(k+1)![m*l*r+(m*(l*r-l-r)+1)*0^mod k(2^(n-i))|(l,m,r)<-zip3(1:p)p$tail p++[1]];x=1<$[2..2^n]=mapM(putStrLn.map("M "!!))$take(2^n)$1!(x++0:x)

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

Объяснение:

Функция i#nрисует ASCII-треугольник высоты 2^nпосле iшагов итерации.

Используемое внутреннее кодирование кодирует пустые позиции как 1и полные позиции как 0. Поэтому первая линия треугольника закодирована так же, как и [1,1,1..0..1,1,1]с 2^n-1обеих сторон от нуля. Чтобы построить этот список, мы начнем со списка x=1<$[2..2^n], то есть со списком, [2..2^n]на который все сопоставлено 1. Затем мы строим полный список какx++0:x

Оператор k!p(подробное объяснение ниже), учитывая индекс строки kи соответствующий ей, pгенерирует бесконечный список следующих строк p. Мы вызываем его с 1помощью стартовой линии, описанной выше, чтобы получить весь треугольник, а затем только первые 2^nстроки. Затем мы просто печатаем каждую строку, заменяя ее 1пробелом и 0на M(путем доступа к списку "M "в местоположении 0или 1).

Оператор k!pопределяется следующим образом:

k!p=p:(k+1)![m*l*r+(m*(l*r-l-r)+1)*0^mod k(2^(n-i))|(l,m,r)<-zip3(1:p)p$tail p++[1]]

Во- первых, мы создаем три версии p: 1:pчто является pс 1префиксом, pсебя и tail p++[1]что все , кроме первого элемента p, с 1прилагается. Затем мы упаковываем эти три списка, давая нам эффективно все элементы pсо своими левыми и правыми соседями, как (l,m,r). Мы используем понимание списка, чтобы затем вычислить соответствующее значение в новой строке:

m*l*r+(m*(l*r-l-r)+1)*0^mod k(2^(n-i))    

Чтобы понять это выражение, нам нужно понять, что нужно рассмотреть два основных случая: либо мы просто расширяем предыдущую строку, либо мы находимся в точке, где начинается пустое место в треугольнике. В первом случае мы имеем заполненное пятно, если любое из соседних пятен заполнено. Это можно рассчитать как m*l*r; если любой из этих трех равен нулю, то новое значение равно нулю. Другой случай немного сложнее. Здесь нам в основном нужно обнаружение краев. В следующей таблице приведены восемь возможных окрестностей с результирующим значением в новой строке:

000 001 010 011 100 101 110 111
 1   1   1   0   1   1   0   1

Простая формула для получения этой таблицы будет 1-m*r*(1-l)-m*l*(1-r)упрощена до m*(2*l*r-l-r)+1. Теперь нам нужно выбрать между этими двумя случаями, где мы используем номер строки k. Если mod k (2^(n-i)) == 0мы должны использовать второй случай, в противном случае мы используем первый случай. Таким 0^(mod k(2^n-i))образом, этот термин означает, 0что мы должны использовать первый случай и 1если мы должны использовать второй случай. В результате мы можем использовать

m*l*r+(m*(l*r-l-r)+1)*0^mod k(2^(n-i)) 

в общем - если мы используем первый случай, мы просто получаем m*l*r, а во втором случае добавляется дополнительный термин, давая общую сумму m*(2*l*r-l-r)+1.


1
154 байта: попробуйте онлайн! Кстати, хорошее объяснение!
Лайкони

@Laikoni О, там очень хорошие улучшения!
Саччан

1

C 106 символов

i,j;main(){for(;i<32;j>i/2?puts(""),j=!++i:0)
printf("%*s",j++?4:33-i+i%2*2,i/2&j^j?"":i%2?"/__\\":"/\\");}

(Меня до сих пор удивляет, что puts("")это самый короткий способ вывода новой строки в C.)

Обратите внимание, что вы можете создать большие (или меньшие) прокладки, заменив тест 32в forцикле на большую (меньшую) мощность, равную двум, при условии, что вы также замените 33середину на printf()степень двойки плюс один.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.