Ваша задача: сгенерировать снежинку Коха на n-ю глубину. Вам не нужно делать полную снежинку Коха, только одну сторону стартового треугольника. Википедия о хлопьях Коха: https://en.wikipedia.org/wiki/Koch_snowflake .
Правила:
- Программа должна генерировать одну сторону снежинки Коха на n-ю глубину.
- Выход должен быть ASCII.
- Вы можете создать целую снежинку; это не обязательно.
- Применяются стандартные правила ввода / вывода, лазейки и прочее.
- Пробел не имеет значения, пока все символы находятся в правильном месте относительно друг друга.
- Самый короткий код выигрывает!
Тестовые случаи:
п = 0:
__
п = 1:
__/\__
п = 2:
__/\__
\ /
__/\__/ \__/\__
п = 3:
__/\__
\ /
__/\__/ \__/\__
\ /
/_ _\
\ /
__/\__ __/ \__ __/\__
\ / \ / \ /
__/\__/ \__/\__/ \__/\__/ \__/\__
Я надеюсь в этом есть смысл. Обратите внимание, что в каждом тестовом случае фрактал можно разделить на три равные по длине части. Также обратите внимание, что ширина каждой снежинки в три раза больше ширины снежинки предыдущего поколения.
__/\__
с двумя подчеркиваниями, что делает каждую итерацию в 3 раза больше предыдущей. Использование только одного подчеркивания приводит к противоречиям, которые становятся неловкими при n = 3. Например, наружные части имеют ширину 12 , а в средней части имеет только ширину 10, как следствие ,/_
и_\
которые являются слишком тесно. И даже до этого у вас есть_
расширение в два раза шире/
и\
./_
и_\
единственная действительно фатальная часть - подчеркивания должны идти, потому что они должны быть в том же положении, что/
и\
. Как только это будет сделано, вещи могут увеличиться в 3 раза с n = 1 и далее (но n = 0 не подходит.)Ответы:
Haskell ,
308300299 байтРедактирование:
zipWith(+)
кzipWith(-)
и регулировочные кодировок и зачеты избавились от каждого знака отрицания.#
отбросить несколько имен переменных , используяr=reverse
вместо прямого сопоставления с образцом.zipWith(-)
.o=[0,0]
сокращения списка констант.?
.Попробуйте онлайн! (К сожалению, все, что больше n = 3, становится ужасно обёрнутым и нечитаемым, но вы можете скопировать его в другую программу, чтобы увидеть.)
вариации
[6]
в[6,4,4]
, вы получаете целую снежинку. Попробуйте онлайн!,3..gcd 3x
, вы получите кривую в стиле, с которым этот вопрос был изначально задан. Попробуйте онлайн!Как это устроено
k
является главной функцией, она принимаетInt
n
и возвращаетString
.iterate(>>=(:[1,4,1]))[6]
генерирует бесконечный список, содержащий для каждого n повороты между последовательными линиями в этой итерации кривой, стиль графики черепахи, как числа, номинально между0
и5
. Каждая итерация - просто предыдущая с1,4,1
чередованием ходов . Единственная причина, с которой начинаются списки,6
а не0
состоит в том, чтобы заставитьgcd
хитростьf
работать, избегаяf 0
.scanl1(+)
преобразует повороты в «абсолютные» направления, по модулю 6.0
Средство вправо, тогда каждое большее число на 60 градусов против часовой стрелки от предыдущего. (Ну, было бы 60 градусов, если бы это был правильный рисунок, а не ASCII.)f
преобразует абсолютное направление в список пар (кодировка символов, смещение), который кодирует, какие символы добавить к кривой (для горизонтальных направлений он генерирует две пары, в противном случае - одну), и как изменяется относительная позиция.#
операторе перебирает предыдущий список (характер, кодирование смещения) пар, генерируя фактический (координату, символ) пар._/\
номинально представляет линию, проведенную от начального угла через прямоугольную ячейку до другого конечного угла.[y,x]
сверху вниз, слева направо, так что они сортируются в том порядке, в котором мы хотим их напечатать. Столбцы основаны на 1. Списки используются вместо кортежей для более короткой векторной арифметики с(&)=zipWith(-)
.[y,x]
что и ячейка слева вверху. Это гарантирует, что все смещения от угла к соседним ячейкам неотрицательны, избегая отрицательных констант.[y1,x1,x2,y2]
где[y1,x1]
смещение координат от начального угла к ячейке символа и[y2,x2]
смещение от конечного угла к ячейке символа. Это означает:3
..5
являются только противоположностью списков для0
..2
, позволяя создавать их с помощью[id,r]<*>
.(&)=zipWith(-)
либо списка кодирования, либо его обратного.?
, иString
из них создается окончательный результат.x?l@(([_,w],c):r)
x
- это x-координата предыдущего символа, показанного в этой строке, или0
если в начале строки;l
это весь текущий список,w
это x-координата следующего добавляемогоc
символа, это символ иr
оставшийся список.\
и/
, поэтому оно сортируется последним, если перекрывается другим символом в той же позиции. Таким образом, избыточное подчеркивание обнаруживается путем проверки повторения x-координаты.источник