Анімуйте обертову фігуру Лісая


15

Заявки на цей виклик покажуть анімовану фігуру Ліссайюса, що обертається . Поява 3d обертання відбувається, коли параметр x послідовно зміщується по фазі у кожному кадрі.

Вхід:

Параметри aта bпараметри (відповідно до статті wikipedia ) будуть вказані в командному рядку або прочитані з stdin.

Вихід:

Це , тому висновок відображатиметься у вікні емулятора терміналу чи еквіваленті. Розмір виводу може бути жорстким кодом, але цифра Ліссайюса повинна бути принаймні великою, щоб заповнити вікно розміром 80х24.

Частота кадрів анімації буде приблизно 50 кадрів в секунду. Спати протягом 20 мс між кожним кадром добре, доки час для обчислення кожного кадру невеликий порівняно з фіксованим часом сну. Якщо ваш вибір мови не може обчислити достатньо швидко на вибраній вами платформі, то вам доведеться обчислити час для динамічного сну.

Кожен кадр не відображатиметься до тих пір, поки не буде завершено весь розрахунок для цього кадру. Немає необхідності очищати екран між кожним кадром.

Фігура здійснюватиме повне 2*Piобертання приблизно кожні 4 секунди.

Для кожного кадру необхідно генерувати повну закриту криву. Принаймні 1000 балів необхідно обчислити по кривій. Накреслення ліній між точками не потрібно.

Точки кривої будуть зображені як #символи. Решта області відображення буде порожньою / пробільною.

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


Ungolfed посилання відповідь .


1
Чи дозволяється нам малювати його за допомогою графічно орієнтованої мови?
TheDoctor

@ TheDoctor Мене розірвало на цьому, але вирішив обмежитися ascii-art . Можливо, ми можемо прослідкувати графічний вихід , якщо це виявиться популярним.
Цифрова травма

1
Як і у багатьох обертових фігур, ці фігури обертаються різними способами залежно від того, як ви дивитесь на них. Наприклад, ваша відповідь, здається, хитається вперед і назад. Але коли я дуже стараюся, я бачу регулярне обертання.
Джастін

Відповіді:


7

Перл - 177

while($d+=.1){print"\e[H\e[2J";$a=0;while(($a+=.01)<4*atan2 1,0){$x=$==40+40*cos$d+$a*$ARGV[0];$y=$==13+13*sin$d+$a*$ARGV[1];print"\e[$y;$x"."H#";}print$/;select($v,$v,$v,.03);}

Коефіцієнти передаються через аргументи. Наведений вище gif виробляється зperl % 2 3


1
@DigitalTrauma У мене є власний інструмент для запису екрану в X11
МНІІП

7

C (відповідь на відповідь - не гольф)

Вихід з ./lissajous 2 3:

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

/*
 * lissajous.c
 *
 * Compile with:
 *   cc lissajous.c -lm -o lissajous
 *
 * Usage:
 *   ./lissajous a b
 *
 * a and b are the parameters as described in:
 * http://en.wikipedia.org/wiki/Lissajous_curve
 */

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <unistd.h>

int main (int argc, char **argv) {
    char buffer[25][80];
    double t, p;
    int x, y;
    int a, b;

    if (argc != 3) return 1;

    a = atoi(argv[1]);
    b = atoi(argv[2]);

    for (;;) {
        for (p = 0; p < 2 * M_PI; p += M_PI / 100) {
            memset(buffer, ' ', sizeof(buffer));
            /* Set 1st char of final line to nul.  Then we can printf
             * the whole 2d array as if it were one long 1d buffer.
             * Line wraps at 80 chars are assumed */
            buffer[24][0] = 0;
            for (t = 0; t < 2 * M_PI; t += M_PI / 500) {
                x = 39.5 * (1 + sin(a * t + p));
                y = 11.5 * (1 + sin(b * t)); 
                buffer[y][x] = '#';
            }
            printf("%s\n", &buffer[0][0]);
            usleep(20000);
        }
    }
    return (0);
}

C, 257 байт

Гаразд, я не міг трохи протистояти гольфу. Я думаю, що на цьому все ще можна зробити багато гольфу:

#include<math.h>
main(int a,char**v){char x,y,b,d[25][80];double t,p,q=2*M_PI;a=atoi(v[1]);b=atoi(v[2]);for(p=0;memset(d,32,2000);p+=q/100){p=p<q?p:0;d[24][0]=0;for(t=0;t<q;y=11.5*sin(b*t)+12,d[y][x]=35,t+=q/1e3)x=39.5*sin(a*t+p)+40;puts(d);usleep(20000);}}

2
Смішно, як довідкова відповідь отримує відгуки ...
TheDoctor

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

Якщо ви їдете usleepна 20000 мс, чому б не просто sleepза 20 років?
користувач12205

@ace usleep (20000) == 20000 мікросекунд , а не 20000 мілі секунд
Digital Trauma

На жаль, вибачте, моя погана. Про що usleep(2e4);?
користувач12205

2

Пітон 3 - 280

Не майте жодного з цих фантазійних анімованих gif-файлів для вас, вибачте. Друк консолі Windows повільний: P

Не впевнений, що це відповідає вимозі 50 кадрів в секунду, хоча я не впевнений, що це справді можливо з Python. Ви можете скорегувати 1000 у другому рядку для кількості балів для обчислення (у списку - ширина виводу, висота виводу, точки пошуку, прогресія на кадр (pi * 2 / n) та початкова точка). Або ви можете їх видалити та вказати також у вводі.

import math as m
a,b,w,h,p,r,t=list(map(int,input().split()))+[79,24,1000,100,0]
while 1:v,z=w/2,h/2;d=[[int(m.sin(a*k+t)*v+v),int(m.sin(b*k)*z+z)]for k in[m.pi*2/p*l for l in range(p)]];print('\n'.join(''.join([' ','#'][[i,j]in d]for i in range(w))for j in range(h)));t+=m.pi*2/r

БІЛЬШЕ ВАЖЛИВО ЗМІНУВАННЯ: Введення через stdin, розділене пробілом, закінчується новий рядок. Чекатиме вашого введення.

Редагувати: Знімок екрана. Для цього змінив висоту до 40.

Ліссайський рендерінг


Хм, він просто зависає на python 3.2.3 (і 2.7.3) на Ubuntu. Я думаю, мені потрібно звідкись викопати вікно VM. Або вивчити пітон.
Цифрова травма

@DigitalTrauma Hm. Я бігаю 3.3.2. Дивно, що це не працює, але в моєму коді не бачите жодних конкретних платформних процедур.
cjfaure

Збережіть як lissajous.py, тоді запуск python3 lissajous.py 2 3повинен бути достатнім, правда?
Цифрова травма

@DigitalTrauma О, о, вибачте. Він бере дані stdin, а не аргументи (не вдалося вказати, що ... ой). Простір розділений.
cjfaure

Ага - я думаю, я мав би це бачити input()і здогадуватися. Зараз для мене добре працює з 3.2.3. +1
Цифрова травма

1

C # - 360 352 (кросова платформа - 332 лише для Windows)

Відредаговано після мікро-гольфу та округлення виправлення помилок + пропозиція Ypnypn

Не зовсім претендент на такій довжині - і це майже дослівна копія посилання - але о добре. :)

namespace System{class P{static int Main(string[]m){double p=Math.PI*2,a=int.Parse(m[0]),b=int.Parse(m[1]),q,t;for(;;)for(q=0;q<p;q+=p/200){var s=new string(' ',1920).ToCharArray();for(t=0;t<p;t+=p/1000)s[(int)(39.5*Math.Sin(a*t+q)+40)+(int)(11.5*Math.Sin(b*t)+12)*80]='#';Console.SetCursorPosition(0,0);Console.Write(s);Threading.Thread.Sleep(20);}}}}

Hog пам'яті, створюючи новий масив для кожного оновлення - спочатку (пере) використовував StringBuilder, але жертвував ним на короткість. Але принаймні оновлення займає менше 1 мс на моєму старому Core2.

Вилучивши кілька теперішніх пошкоджених старих гольфів, тим самим зменшивши його на 8 символів, я спробував повернути його до «поетичного» 360, повернувшись до подвоєного, а не до розбору int, і повернувся до 80 * 24 замість 1920. Це все ще лише 359 - і жодне інше додавання єдиного символу, яке я можу придумати, дійсно не додає коду ніякого значення. Тож ми просто дотримуємось 352. :-)

Не скачували (втратили код перед гольфом):

namespace System
{
    class P
    {
        static int Main(string[] m)
        {
            double p = Math.PI * 2,
                   a = int.Parse(m[0]),
                   b = int.Parse(m[1]),
                   q, t;

            for (;;)
            {
                for (q = 0; q < p; q += p/200)
                {
                    var s = new string(' ', 1920).ToCharArray();
                    // Alternative - Windows console only:
                    // var s = new char[1920];

                    for (t = 0; t < p; t += p/1000)
                    {
                        s[
                            (int) (39.5*Math.Sin(a * t + q) + 40)
                          + (int) (11.5*Math.Sin(b * t) + 12) * 80
                        ] = '#';
                    }
                    Console.SetCursorPosition(0, 0);
                    Console.Write(s);
                    Threading.Thread.Sleep(20);
                }
            }
        }
    }
}

Консоль Windows фактично приймає виведення безлічі нульових символів, що призводить до виводу, який (графічно) ідентичний використанню фактичного символу пробілу - що дозволяє на кілька символів менше ініціалізувати масив символів.

Немає фантазійної анімації, вибачте :-)


Консоль Windows фактично приймає виведення безлічі нульових символів . Ну, можливо, це пояснює, чому це не так добре з моно на Ubuntu. Зараз у мене немає зручності windows / .net, тому я візьму слово, щоб воно працювало.
Цифрова травма

Щойно додали скріншот - слід зробити його крос-платформою, але з огляду на статус, який він вже не має, - і "поетичну" кількість символів, можливо, його слід просто залишити як є. :-)
JimmiTh

Немає необхідності, щоб усі відповіді були платформою IMO. Якщо відповіді залежать від платформи, добре згадати платформу, хоча C # настільки відома, що її вже очевидно.
Цифрова травма

Чи using C = Consoleсправді рятує будь-яких персонажів?
Ypnypn

@Ypnypn - не після вторгнення в простір імен системи, ні. Не змінювали його і не шукали, тому що самовизначена мета полягала в тому, щоб дістатися до тих же 360 символів, використовуючи при цьому «належну» ініціалізацію масиву char. Спасибі. :-)
JimmiTh

1

Пітон 2,7 - 214

Я думаю, що я буду ще раз поглянути на це. У мене є відчуття, що це може бути знижено ще більше, але важко буде вразити кількість байтів Perl. Математика, здається, є моїм найбільшим обмеженням тут.

Попередження: може вийти з ладу будь-який термінал, який ви використовуєте. Я перевірив це в командному рядку Windows за допомогою lissajous.py 2 3. Через швидке записування до командного рядка очікуйте, що кадри трохи підскочать. Це можна вирішити здебільшого (ціною швидкості), використовуючи більшу sв range(s)і t=2*pi*i.

Я не використовую \rабо \bтут цілеспрямовано, тому що я запускаю його в Windows, і це коштувало б додаткових символів.

from math import*;import sys;a,b=sys.argv[1:];p=s=1920
while p:
 c = [" "]*s
 for i in range(s):
    t=2*pi*i/s;c[int(round((39.5*(1+sin(eval(a)*t+p))))+round(11.5*(1+sin(eval(b)*t)))*80)]="#"
 print ''.join(c)
 p+=.1

+1 Працює на Ubuntu, хоча вихід трохи стрибає
Digital Trauma

@DigitalTrauma Так, хитрість викликана тим, що це крос-платформене рішення (тобто, робота в командному рядку Windows).
гаїNL
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.