Створіть спіраль ASCII Padovan


22

Це версія ASCII цього виклику . Початковий пост був відокремлений на запит Мартіна Ендера

Вступ

Подібно до послідовності Фібоначчі, послідовність Падована ( OEIS A000931 ) - це послідовність чисел, яка утворюється додаванням попередніх термінів у послідовність. Початкові значення визначаються як:

P(0) = P(1) = P(2) = 1

0-й, 1-й та 2-й члени - всі 1. Відношення рецидивів наведено нижче:

P(n) = P(n - 2) + P(n - 3)

Таким чином, виходить така послідовність:

1, 1, 1, 2, 2, 3, 4, 5, 7, 9, 12, 16, 21, 28, 37, 49, 65, 86, 114, 151, 200, 265, 351, ...

Використання цих чисел як бічних довжин рівносторонніх трикутників дає хорошу спіраль, коли ви розміщуєте їх разом, як і спіраль Фібоначчі:

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

Зображення надано Вікіпедією


Завдання

Ваше завдання - написати програму, яка відтворює цю спіраль мистецтвом ASCII, із введенням відповідного терміну. Оскільки трикутник довжиною сторони 1 (1 символ) неможливо добре зобразити в ASCII, довжини бічних сторін були розширені на коефіцієнт 2. Таким чином, трикутник довжини сторони 1 насправді представлений так:

 /\
/__\

Так, наприклад, якщо вхід був 5 (5-й доданок), вихід повинен бути:

   /\
  /  \
 /    \
/______\
\      /\
 \    /__\ 
  \  /\  /
   \/__\/

Перші 5 доданків складали 1, 1, 1, 2, 2, тому трикутник мав довжини сторін 2, 2, 2, 4, 4 через дилатацію. Ще один приклад для введення 8:

     __________
   /\          /\
  /  \        /  \
 /    \      /    \
/______\    /      \
\      /\  /        \
 \    /__\/          \
  \  /\  /            \
   \/__\/______________\
    \                  /
     \                /
      \              /
       \            /
        \          /
         \        /
          \      /
           \    /
            \  /
             \/

Правила

  • Ви повинні надрукувати результат, а вхід повинен бути цілим числом, що відповідає номеру терміна
  • Дозволені трейлінг та провідні рядки, також допускаються пробіли після рядків
  • Ваша заявка повинна мати змогу обробляти принаймні до 10-го терміну (9)
  • Подання повинно бути повноцінною програмою або функцією, яка приймає дані та друкує результат
  • Допускаються обертання виводу у кратних значеннях 60 градусів, але розмір трикутників повинен залишатися однаковим, поряд із поданням
  • Допускається також проти годинникової стрілки
  • Стандартні лазівки заборонені

Ви можете припустити, що вхід буде> 0 і буде надано правильний формат введення.

Оцінка балів

Це , тому найкоротший код у байтах виграє. З новим роком усім!


1
моя мова Turtlèd може взяти базовий вхід 10 та обробити його чудово, але ця проблема буде набагато простішою, якби вона брала вклад як не одинакова. це було б дозволено?
Руйнуючий лимон

1
@DestructibleWatermelon Так. Вхід просто має бути цілим, у якійсь формі.
Андрій Лі

круто. Я почну працювати над цим зараз
руйнуючий лимон

3
чекати насправді все ще дуже важко
Руйнуючий лимон

Відповіді:


13

Befunge, 871 836 798 байт

&00p45*:10p20p030p240p050p060p9010gp9110gp1910gp1-91+10gpv
<v-g03+g06*2g041g055_v#!:%6:p06p05+p04g05g06:g04<p*54+292<
->10g:1\g3+:70p110gv >:5- #v_550g:01-\2*40g+1-30g
/\110:\-g03:\1:g055 _v#!-4:<vp01:-1g01-g03-1\-
^1<v07+1:g07< p08p < >:1-#v_550g:01-\40g+60g+1-30g-50g>v
 _0>p80gp:5-|v1\+66\:p\0\9:$<:p02:+1g02-g03+g06-\g04\1:<
0v|-g00:+1$$<>\p907^>p:!7v>3-#v_550g:30g+:30p1\0\-
1>10g+::0\g3-:70p\0^^07<v<>50#<g::30g+:30p-1-01-\
v >\$0gg> :1+10gg1- #v_^>0g10gg*+\:!2*-70g2+10gv>:#->#,"_"$#1_:1#<p
+1+g03$_^#`gg011+3:+3<g07\+*2+*`0:-\gg01+5g07:g<>1#,-#*:#8>#4_$#:^#
>55+,p30g40p10gg10g1>#v_
#v:#p0$#8_:$#<g!#@_0^ >
 >>:180gg`>>#|_:2+80gg:!v
3+^g\0p08:<vgg08+2::+3<$_100p1-v>g,\80gg+\80gp:2+90g:!01p\80gp
!#^_80g:1+^>\180gg`+!#^_20g80g`
5*g10!g09p04-1-\0\+g04:gg08:p09<^3`0:gg08+1:::$$_1#!-#\\:,#\<g

Спробуйте в Інтернеті!

Як це часто буває з Befunge, фокус полягає в розробці алгоритму, який дозволяє нам виводити шаблон зверху вниз, оскільки просто неможливо спочатку зробити його в пам'ять при обмеженому просторі.

Спосіб цього полягає в тому, щоб спочатку створити просту структуру даних, що представляє краї, необхідні для малювання спіралі. Потім другий етап аналізує цю структуру зверху вниз, надаючи крайові фрагменти, необхідні для кожного рядка виводу.

Використовуючи цю методику, ми можемо підтримати до n = 15 у виконанні посилань, перш ніж ми почнемо мати проблеми із переповненням у 8-бітових осередках пам'яті. Перекладачі з більшим розміром комірок повинні мати можливість підтримувати до n = 25, перш ніж вичерпається пам'ять.


це дуже вражає ... але чи вважаєте ви, що можете читати ці програми? LOL для мене це виглядає так випадково. як вона будує структуру даних? яку структуру даних він використовує? Спасибі!
нехай яскравий

1

йти, 768 байт

func 卷(n int){
    数:=0
    p:=[]int{1,1,1}
    for i:=3;i<n;i++ {p=append(p,p[i-2]+p[i-3])}
    宽:=p[len(p)-1]*10+10
    素:=make([]int,宽*宽)
    for 数=range 素 {素[数]=32}
    for i:=0;i<数;i+=宽 {素[i]=10}
    态:=[]int{1,1,宽/2,宽/2,92}
    表:=[70]int{}
    s:="SRSQTSPQQ!QOQP~QQQQQQSQR~ORQR!OPOPTSQRQ$QPPQNQPPPXQQQQQQRRQXQRRRNOQPQ$"
    for i:=range s {表[i]=int(s[i])-33-48}
    表[49],表[59]=48,48
    for i:=0;i<4*n;i++ {
        梴:=p[i/4]*2
        if 态[1]==0 {梴=梴*2-2}
        for k:=0;k<梴;k++ {
            址:=(态[2]+态[3]*宽)%len(素)
            if 素[址]==32 {素[址]=态[4]}
            态[2]+=态[0]
            态[3]+=态[1]
        }
        数=((态[0]+1)*2+态[1]+1)*5
        if i%4>2 {数+=35}
        for k:=0;k<5;k++ {态[k]+=表[数+k]}
    }
    for i:=0;i<宽*宽;i++ {fmt.Printf("%c",rune(素[i]))}
}

Це, звичайно, не оптимально, але це не поганий старт. Я знаю, що це, мабуть, трохи просто для стандартів у гольфі, але це було весело, і я сподіваюся, що це не проти, якщо я залишу кілька записок майбутньому самості.

Як це працює

В основному я імітую "малюнок черепашки", як у LOGO, на піксельній сітці ASCII, але черепаха може виконувати лише ці три команди:

rt   - right turn, turn 120 degrees right (1/3 of a Turn)
rth  - right turn half, turn  60 degrees right (1/6 of a Turn)
fd n - forward, go forward n steps, drawing a trail of _, /, or \

Тепер для кожного трикутника я переходжу так, де P - 2-е число числа Падована:

fd P
rt
fd P
rt 
fd P
rt
fd P
rth

Четверте "fd" означає, що я повторно простежую першу сторону кожного трикутника. Це допомагає повернутися до приємної вихідної точки для наступного трикутника. Пів-правий поворот гарантує, що наступний трикутник буде в правильній орієнтації.


Для гольфу на черепаху я зберігаю 5 змінних стану в масиві 态: х положення, положення y, швидкість, швидкість y та "малювання руни". На кожному кадрі анімації намальована швидкість x + = x, швидкість y + = y, і руна намальована.

Потім я встановив таблицю 表, яка розповідає, як насправді виконати поворот. Поворотний код складний через те, як працює мистецтво ASCII. Це не прямий рух, як на піксельному дисплеї. Напрямок черепахи, визначений швидкістю х і у, визначають зміни, необхідні для того, щоб виток виглядав належним чином.

Щоб повернути, він переглядає поточну швидкість x і y та об'єднує їх в індекс.

xv = x velocity, yv = y velocity. 
i.e. a turtle facing down and to the right has 
xv of 1, and yv of 1. It can only face 6 
different directions. Formula is (xv+1)*2+yv+1

xv  yv    index
-1  -1    0
-1   0    1
-1   1    2
 1  -1    4
 1   0    5
 1   1    6

Цей індекс використовується для пошуку набору з 5 значень у таблиці 表. Ці 5 значень у таблиці then потім додаються до кожної з 5 змінних у стані 态. Потім черепаха ефективно повертається і готова до наступного 'fd'.

По-перше, на половину правого повороту, є окремий розділ 表 таблиці. Він зміщений на 7 * 5 або 35 записів з першої таблиці у 表.

Нарешті, я зробив просте кодування цілих чисел таблиці в рядок ascii.

Я знаю, що міг би "зберегти байти", видаливши Ханзі, але, як я вже сказав, це не є оптимальним, і можливе більше гольфу ... Я видаляю їх, коли немає іншої можливої ​​оптимізації. Ті, хто насправді має Ханзі, мають сенс, заснований на їхньому фактичному значенні, і хоча я не знаю китайської мови, це допомагає мені думати про програму.

数  index number
宽  screen width
素  pixel data
梴  length of side of triangle
态  current state
址  address of pixel
表  state transition table

Для тестування коду вам знадобиться повний голанг-файл із цим заголовком

package main
import "fmt"

і цей колонтитул

func main ()  {
    for i := 0; i<15; i++ {
       卷(i)
    }
}

Спасибі

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.