ASCII art square аффинные фракталы

9

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

Ваша программа будет принимать два входа, первый для определения шаблона в формате, 074состоящем из трех цифр от 0 до 7. Второй вход будет определять размер, 3будет 8x8, 4будет 16x16 и т. Д. (2 ^ n). Ваша программа должна вывести правильный результат для всех размеров от 0 (1x1) до как минимум 5 (32x32). Если он выдает какой-либо вывод для больших чисел, он должен быть правильным, то есть он должен вырабатывать правильный вывод до определенного размера, но не производить вывод выше этого размера, если он будет неправильным. Вы можете принять максимальный размер 15 (32768x32768), поскольку это уже безумный размер для ASCII-графики (1 ГБ)!

Шаблон 8х8 будет выглядеть примерно так (правило 160). Самая левая цифра будет для блока A, средняя цифра (без грубых мыслей, пожалуйста!) Для блока Bи крайняя правая цифра для блока C. Чтобы построить фрактал, уменьшите его наполовину в обоих измерениях и примените правило вращения / зеркального отражения для блока. Чтобы уменьшить рисунок, разделите его равномерно на 2x2 области. В каждой области будет либо 3 видимых символа, либо ни одного. Если есть видимые символы, поместите символ в соответствующее место в меньшем блоке, в противном случае поместите пробел. Правила 0- 3не отражаются, правила 4- 7отражаются. Правила 0и 4не повернуты, 1а 5повернуты на 90 градусов по часовой стрелке, 2и6повернуты на 180 градусов 3и 7повернуты на 270 градусов по часовой стрелке. Сшить три блока вместе в указанном порядке, Aв верхнем левом углу, Bнижнем левом и Cнижнем правом.

 AAA    
AA A    
AA      
A       
BBB CC  
B BBC   
  BBCCC 
   B CCC

Сокращается, поворачивается и отражается по номеру правила:

 0       1       2       3       4       5       6       7  
----    ----    ----    ----    ----    ----    ----    ----
AA       BAA    CCB        C    C        BCC    AAB       AA
A       BB A     CBB      CC    CC      BBC     A BB       A
BBC     CC         A    A BB    BB A    A         CC     CBB
 BCC    C         AA    AAB      BAA    AA         C    CCB 

Правила:

  1. Не отражается, повернут на 90 градусов по часовой стрелке
  2. Не отражено, повернуто на 180 градусов по часовой стрелке
  3. Не отражено, повернуто на 270 градусов по часовой стрелке
  4. Зеркальный, но не повернутый
  5. Зеркальный, затем повернутый на 90 градусов по часовой стрелке
  6. Зеркальный, затем повернутый на 180 градусов по часовой стрелке
  7. Зеркальный, затем повернутый на 270 градусов по часовой стрелке
  8. Правило 0: не отражается, не вращается

Зеркалирование всегда выполняется первым и выполняется по диагонали через пустой угол, например, правило 0 против правила 4:

 0       4  
----    ----
AA /    C  /
A /     CC/ 
BBC     BB A
/BCC    /BAA

Только правила 1, 6и 0используются в приведенном выше шаблоне, в этом порядке. После применения преобразований и сшивания блоков это будет выглядеть так, как показано ниже, за исключением того, что каждый блок разнесен на один интервал. В вашем коде не будет лишнего пространства. Если вы сравните его с «родительским» изображением, вы увидите, что оно имеет видимые символы в тех же позициях.

 BAA
BB A
CC  
C   

AAB  AA  
A BB A   
  CC BBC 
   C  BCC

Другой способ создания изображения без сжатия заключается в следующем: начните с одного символа:

X

Примените преобразования для каждого из трех блоков (ни одного, поскольку это всего лишь один символ) и объедините блоки:

X
XX

Примените преобразования для каждого из трех блоков снова:

1 
--
XX
X 

6     0 
--    --
XX    X 
 X    XX

Сшить их вместе:

XX
X 
XXX 
 XXX

Примените преобразования для каждого из трех блоков снова:

 1  
----
 XXX
XX X
XX  
X   

 6       0  
----    ----
XXX     XX  
X XX    X   
  XX    XXX 
   X     XXX

Сшить их вместе:

 XXX    
XX X    
XX      
X       
XXX XX  
X XXX   
  XXXXX 
   X XXX

Вы можете использовать любой печатный символ или символы (0x21 - 0x7E) для видимой части шаблона, но только пробел (0x20) для пробелов. Конечные пробелы разрешены, но за пределами квадрата не должно быть пробелов (т. Е. Для квадрата 8x8 не должно быть символов после столбца 8).

Существует 512 различных правил, но некоторые из них производят одинаковый шаблон. Как примечание стороны, любой образец, содержащий только 0и 4будет производить треугольник Серпинского (8 различных правил).

При желании вы можете опубликовать свой любимый шаблон и правило, которое его генерирует. Если вы это сделаете, убедитесь, что размер не менее 3 (8x8), чтобы отличить его от аналогичных правил.

CJ Деннис
источник
@trichoplax Вы можете начать с полностью заполненного квадрата или квадрата, содержащего только 1 видимый символ. В любом случае, повторение правил n раз, где n - размер ввода, гарантирует одинаковые результаты. Тем не менее, вам не нужно генерировать шаблон таким образом, только генерировать тот же шаблон, что и при этом.
CJ Деннис
@ trichoplax Я ценю ваш вклад. То, как я вижу вещи, не обязательно означает, что другие люди видят вещи, и я не знаю, что мне это тяжело!
CJ Dennis
2
+1 Спасибо, вы сделали объяснение намного яснее! В будущем я бы порекомендовал вам запускать вещи через нашу песочницу, чтобы люди могли получить более четкое представление о том, что вы просите заранее. Я буду работать над этим испытанием в ближайшее время :)
BrainSteel
Да, все видят вещи по-разному. Рад дать отзыв - хороший вопрос стоит уточнить. Теперь это хорошо читается.
трихоплакс
@BrainSteel Спасибо, сделаем! Я был на SE много лет, но я все еще относительно новичок в PCG!
CJ Деннис

Ответы:

1

CJam, 63 57 54 52 байта

0aarari*{\f{\~7"W%z"a*3"Wf%"t<s~}({__Ser+}%\~.++}/N*

Как это работает :

Основная идея заключается в том, что вы запускаете цикл, второй вход количество раз. В каждом цикле, начиная с одного массива array, содержащего 0( [[0]]), мы строим фрактал для следующего шага, используя три правила, заполняем пустой квадрант и подготавливаем квадранты для следующего цикла.

0aa                           e# Starting condition, equivalent to a single A
   ra                         e# Read the rule string and wrap it in an array
     ri*                      e# Repeat the rule array, second input number of times
        { ...  }/             e# Loop for each rule in the rule array
                              e# In each loop, we will have the current fractal and
                              e# then the rule on stack
\f{\~7"W%z"a*3"Wf%"t<s~}      
\f{                    }      e# Move the rule on top of stack and for each of the rule
                              e# character, run this loop on the current fractal
   \~                         e# Move the rule char on top and convert to int by face value
     7"W%z"a*3"Wf%"t          e# This is the array which has the logic to perform the rules
                              e# ["W%z" "W%z" "W%z" "Wf%" "W%z" "W%z" "W%z"]
                    <s        e# Based on the rule number value, take that many first items
                              e# from the above array and do a toString on the array
                              e# For rule 0 through 7, you will get the following strings:
                              e# 0: "", 1: "W%z", 2: "W%zW%z", 3: "W%zW%zW%z",
                              e# 4: "W%zW%zW%zWf%", 5: "W%zW%zW%zWf%W%z",
                              e# 6: "W%zW%zW%zWf%W%zW%z", 7: "W%zW%zW%zWf%W%zW%zW%z"
                              e# This works because each W%z will rotate the block of
                              e# fractal 90 degrees in clockwise direction.
                              e# For rule 4, where we need to mirror diagonally, we first
                              e# rotate it 279 degrees clock wise and then reverse each row
                              e# of the block. The rest of the rules after 4 take that
                              e# mirroring as base and rotate 90 degrees additionally
                      ~       e# Simply evaluate the string to apply the rule.
\f{ ... }                     e# After this for each loop, we get 3 copies of the fractal
                              e# block before the for loop. Each copy gets each one of the
                              e# three rule gets applied.
         ({      }%           e# We take out the first part corresponding to the 1st
                              e# quadrant and run each row through this loop to fill the
                              e# second quadrant with spaces
           __Ser              e# Take a copy of the row and replace everything in the
                              e# copy with spaces
                +             e# Append it to the original row
                   \~         e# Bring the last two quadrant array on top and unwrap it
                     .+       e# Append corresponding rows from the 4th quadrant to 3rd
                       +      e# Append the rows from lower half to the upper half
                              e# Now we have a full block ready to be run through
                              e# the next iteration which will double its size
                          N*  e# Finally, we join the rows of final fractal block with
                              e# newlines and automatically print the result

Попробуйте онлайн здесь

оптимизатор
источник
Очень хорошенькая! Он выдает слишком мало печатных символов, если шаблон начинается с, 0и у Джеймса Бонда есть лицензия на убийство. 007: IndexOutOfBoundsException
CJ Деннис
@CJDennis Ошибка с ведущими нулями. Исправлено сейчас.
Оптимизатор
Отлично сработано! Результат выглядит отлично сейчас!
CJ Деннис