Напад, занепад, затримка, звільнення


47

Синтезатори звуку використовують генератори конвертів, щоб контролювати, як певні параметри звуку (наприклад, загальна гучність) змінюються з часом. У багатьох синтезаторах конверт визначається чотирма параметрами, як це представлено на наступному малюнку з Вікіпедії :

  • Час атаки (А) : час, необхідний для досягнення конвертів максимальним рівнем, починаючи з нуля, коли клавіша вперше натиснута.
  • Час занепаду (D) : час, необхідний для досягнення конвертів заданого рівня підтримки.
  • Підтримуючий рівень (S) : рівень, який підтримується після першої атаки та занепаду, до тих пір, поки натискається клавіша.
  • Час випуску (R) : час, необхідний, щоб конверт досяг нуля, коли ключ відпущений.

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

Змагання

Введіть чотири параметри A, D, S, R та побудуйте конверт .

Параметри будуть цілими значеннями від 0 до 127 .

Максимальний рівень передбачатиметься (досягнуто в кінці фази атаки) , щоб бути 127 .

Горизонтальний відрізок на рівні підтримки передбачатиметься , щоб мати тривалість 64 (у фактичному звуку ця тривалість не фіксується, а визначається кількістю часу , що ключ утримується).

Формат та інші деталі

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

Зображення може бути відображене або створене у вигляді файлу у стандартному форматі зображення. Файл може бути записаний на диск, або його точний вміст може бути виведений або в STDERR, або як аргумент повернення функції.

Графік повинен містити лише багатокутну лінію, яка визначає конверт. Шкала кожної осі можна вільно обирати. Інші елементи, такі як лінії осі, числові мітки або кольори ліній, необов’язкові.

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

Виграє найкоротший код у байтах.

Тестові справи

Введення у форматі [A D S R]. Зауважте, що масштаб у кожної фігури різний (відповідно до правила, що шкалу можна вільно обирати)

[15 30 70 40]

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

[64 64 64 64]

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

[0 10 50 80]

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

[0 0 90 80]

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

[5 50 0 0]

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

[5 50 0 80]

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

[24 32 127 48]

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



@Ben Ця посилання також була призначена :-) Я люблю позбавлення сну !
Луїс Мендо

Відповіді:


7

MATL, 31 22 байт

Oii64ivYsO127itO5$h&XG

Приймає чотири окремі входи замовлений як A, D, R,S

Спробуйте це на сайті MATL Online

Пояснення

0   % Push a literal 0 to the stack
ii  % Grab the first two inputs
64  % Push the number literal 64 to the stack
i   % Grab the third input
v   % Vertically concatenate all values
Ys  % Compute the cumulative sum
0   % Push the number literal 0 to the stack
127 % Push the number literal 127 to the stack
i   % Grab the fourth input
t   % Duplicate the fourth input
O   % Push the number literal 0 to the stack
5$h % Concatenate the last 5 elements on the stack
&XG % Plot the result using the first array as x and second array as y

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


43

TikZ, 195 193 181 177 172 167 163 160 159 байт

Дякуємо Девіду Карлайлу за його корисну відповідь тут

\documentclass[tikz]{standalone}\begin{document}\tikz\def~#1{\typein[#1];}~\a~\s~\d~\r\def\u{)--(\a+\d}\draw(,)--(\a,127\u,\s\u+64,\s\u+\r+64,);\end{document}

Так, ти чув правильно TikZ .

Пояснення

При цьому використовується пара прийомів для досягнення своєї мети. Перше, що вводиться. Більшість людей може не знати, що L A T E X може взяти вклад. Ну це може. Це досягається командою \typein. Це зупинить компілятор і запитує введення від користувача, як призначити його змінній.

Інша основна методика - використання \def. \defу Тікза абсурдно потужний. Він по суті визначає фрагмент коду і вставляє його скрізь, де ви називаєте змінну. У цьому коді ми визначаємо дві речі, \typein[#1]{}щоб ми могли присвоїти своїм змінним в гольф і )--(\a+\dтому, що цей код відображається ще чимало разів у версії, що не має волі.

Ось дві версії коду (без обгортки):

Гольф:

\documentclass[tikz]{standalone}\begin{document}\tikz\def~#1{\typein[#1];}~\a~\s~\d~\r\def\u{)--(\a+\d}\draw(,)--(\a,127\u,\s\u+64,\s\u+\r+64,);\end{document}

Безголівки:

\typein[\a]{}\typein[\s]{}\typein[\d]{}\typein[\r]{}\draw(0,0)--(\a,127)--(\a+\d,)--(\a+\d+64,)--(\a+\d+\r+64,0);

Зображення:

Оскільки я не можу безпосередньо завантажувати зображення у форматі PDF, а перетворення його у будь-який інший формат, як видається, може повністю зникнути лінії, ось що може виглядати зображення, відкриваючись у Preview (вхід для цього зображення [64 64 64 64]):

Попередній перегляд зображення

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


12
Я щиро захоплююся тим, що ти так добре знаєш TikZ, що це перше рішення, яке приходить тобі в голову. (А якщо цього не було, то запам’ятається легенда)
Права нога

1
Не input tikz\begin{document}працює?
Фаталізувати

5
як щодо фотографій? 😉
Борщ

Як ви насправді це рендеруєте? pdflatex adsr.texСхоже, не працює. - О, зачекайте, це працює, я просто не очікував, що він вимагатиме інтерактивного введення!
перестала повертати проти годинника,

@WheatWizard imagemagick може досить добре перетворити PDF, якщо ви зробите це правильно
Sarge Borsch

20

Python 2, 83 80 79 байт

from turtle import*
def f(A,D,S,R):X=A+D+64;map(goto,[A,A+D,X,X+R],[127,S,S,0])

Спробуйте в Інтернеті (83-байтна версія, оскільки вона працює в Інтернеті)

Зауважте, що певні виходи можуть бути не повністю видимими за допомогою Trinket через те, як працює полотно. Вам потрібно буде завантажити та встановити Python, якщо ви хочете, щоб він працював краще.

Безголівки:

from turtle import*
A,D,S,R=input()
goto(A,127)
goto(A+D,S)
goto(A+D+64,S)
goto(A+D+64+R,0)

Ця версія не працює в Trinket, оскільки Trinket не підтримує розпакування значень.


Ви можете використовувати mapв Python 2:lambda A,D,S,R:map(goto,[A,A+D,A+D+64,A+D+R+64],[127,S,S,0])
xnor

@xnor Я потрапляю SuspensionError: Cannot call a function that blocks or suspends here on line undefined in main.pyна Trinket . Ви підтвердили, що це працює? Я не впевнений, унікальна помилка Trinket чи ні.
mbomb007

Для мене працює в 2.7.12.
xnor

@xnor Mmk, спасибі Ймовірно, це обмеження в Skulpt.
mbomb007

Я подав більш просту версію цієї програми в якості прикладу до Skulpt github repo, і вони подумали, що це приємна знахідка. Сподіваємось, їм вдасться це виправити, але темп їхнього «черепашкового спринту», здається, більше ходить.
mbomb007

17

Математика, 61 58 байт

ListLinePlot[{Accumulate@{0,##3,64,#2},{0,127,#,#,0}}]&

є оператором для Transposeі відображається в якості надрисовки TMathematica.

Бере аргументи в порядку S, R, A, Dі повертає векторний графічний об’єкт.

Результати для всіх семи тестових випадків:

введіть тут опис зображення Клацніть для збільшення версії.


Це було швидко!
Луїс Мендо

+1 для того, щоб навчати мене ListLinePlot:) І є ListStepPlotтакож - так корисно!
Грег Мартін

12

R, 66 63 байт

function(A,D,S,R)plot(cumsum(c(0,A,D,64,R)),c(0,127,S,S,0),"l")

Відображає зображення з осі лабораторіями, cumsum(c(0,A,D,64,R))а c(0,127,S,S,0)також вісячими лініями та цифровими мітками.

Дякуємо @Zahiro Mor за бриття 3-х байт !

Попередня відповідь:

function(A,D,S,R)plot(c(0,A,A+D,b<-A+D+64,b+R),c(0,127,S,S,0),"l")

2
ви можете використовувати cumsum(c(0,A,D,64,R)) для заміни першого терміна в сюжеті. з закінченням вам не знадобиться трюк і все-таки function(A,D,S,R)plot(cumsum(c(0,A,D,64,R)),c(0,127,S,S,0),"l")
голіть

11

Матлаб, 50 байт

@(A,D,S,R)plot(cumsum([0,A,D,64,R]),[0,127,S,S,0])

Це дає анонімну функцію "ans", яку потрібно називати ans (A, D, S, R).


9

JavaScript (ES6) + HTML, 126 + 23 = 149

c=O.getContext`2d`;c.moveTo(a=0,z=O.height=128);g=(y,x=prompt())=>c.lineTo(a+=+x,y)||g;g(0)(s=z+~prompt())(s,64)(z);c.stroke()
<canvas id=O width=512>

Здійснює введення по черзі в порядку A, S, D, R.


9

JavaScript (ES6), 114 111 байт

f=(a,d,s,r)=>`<svg width=446 height=128><path stroke=red fill=none d=M0,127L${a},0l${d},${127-s}h64l${r},${s}>`
<div oninput=o.innerHTML=f(a.value,d.value,s.value,r.value)><input type=number value=0 min=0 max=127 id=a><input type=number value=63 min=0 max=127 id=d><input type=number value=127 min=0 max=127 id=s><input type=number value=0 min=0 max=127 id=r><div id=o><svg width=446 height=128><path stroke=red fill=none d=M0,127L0,0l63,0h64l0,127 /></svg>

Повертає SVG-зображення, придатне для innerHTML. Додайте 18 байт для дійсного XML.


Чудово, як цифра оновлюється в режимі реального часу!
Луїс Мендо

Це чудово, я мушу колись засвоїти синтаксис SVG. Можливо, додати значення <input>s за замовчуванням у s?
ETHproductions

@ETHproductions Чи були у вас якісь типові дефолти на увазі? (З огляду на те, що налаштування за замовчуванням насправді не запустить початковий графік ...)
Ніл,

Я думав, можливо, просто 64,64,64,64. Зазвичай я б
жорсткий код

8

Haskell, 112 110 байт

import Graphics.Gloss
(a#d)s r=display(InWindow""(600,300)(0,0))red$line$zip(scanl(+)0[a,d,64,r])[0,127,s,s,0]

Приклад використання: (0#10) 50 80.

конверт adsr

Для цього використовується Glossбібліотека. displayФункція очікує вікно замишляє (тут: вікно без заголовка ( ""), розміру 600x300, положення (0,0)на робочому столі), колір фону ( red) і зображення відьму є лінією , уздовж шляху , зробленого пролітаючи кумулятивної суми [0,a,d,64,r]= [0,a,a+d,a+d+64,a+d+64+r]як x координати і [0,127,s,s,0]як y координати.

Редагувати: Дякую @xnor за 2 байти!


Слід коротше писатиscanl(+)0[a,d,64,r]
xnor

5

Обробка, 134 108 + 14 (дзвінок до size) = 148 122 байт

Спочатку нам потрібен дзвінок sizeкудись у програму, щоб висновок помістився у вікні (за замовчуванням 100x100).

size(400,400);

І ось фактична функція:

void g(int a,int b,int c,int d){line(0,127,a,0);line(a,0,b+=a,c=127-c);line(b,c,b+=64,c);line(b,c,b+d,127);}

Називай це так f(15,20,70,40);

Знімок екрана

15, 20, 70, 40

зображення


Моя нова відповідь простіша, ніж старша відповідь, але мені подобається старша (навіть якщо вона більша).

Стара відповідь (148 байт)

size(400,400);

і дві функції

void f(int[]v){translate(0,127);l(v[0],-127);l(v[1],127-v[2]);l(64,0);l(v[3],v[2]);}void l(int x,int y){line(0,0,x,y);translate(x,y);}

Назвіть це так, f(int_array_containing_values);і результат буде виглядати приблизно так:f(new int[]{15,20,70,40});


4

SmileBASIC, 90 байт

INPUT A,D,S,R
B=A+D+64W=#Y-S
GLINE.,#Y,A,0GLINE A,0,A+D,W
GLINE A+D,W,B,W
GLINE B,W,B+R,#Y

4

PHP, 149 130 байт

[,$a,$d,$s,$r]=$argv;imagepolygon($i=imagecreatetruecolor(446,127),[0,127,$a,0,$d+=$a,$s,$d+=64,$s,$d+$r,127],5,999);imagepng($i);

приймає дані з аргументів командного рядка, записує зображення (PNG з графіком синього на чорному) у stdout. Потрібна PHP 7.1 або новіша версія.

використання, наприклад

# any OS with ImageMagick:
php -r '<code>' <parameters> | display

# linux with feh:
php -r '<code>' <parameters> | feh

+4 байти для старшого PHP: замінити [,$a,$d,$s,$r]на list(,$a,$d,$s,$r).


Там є невеликий злом: замість того, imageopenpolygonщоб приховати базову лінію, обробну лінію багатокутника малюють поза полотном. (y = 127 відображатиметься лише на зображенні з висотою> = 128.)

Я міг би більше заощадити з кольором 99 або 9 замість 999; але їх досить важко помітити на чорному. :)


3

Баш + грація , 70 байт

t=$[$1+$2]
echo "0 0
$1 127
$t $3
$[t+64] $3
$[t+64+$4] 0">f
xmgrace f

Сценарій пише, щоб подати fкоординати кожної точки, а xmgrace (версія GUI) зчитує файл і відображає графік, використовуючи лінії за замовчуванням.

Виконати :

./plot_ADSR.sh 15 30 70 40

Вихід: (екран друку)

15 30 70 40

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

Пояснення:

t=$[$1+$2]          # store the value of (A+D) for later usage
echo "0 0           # start writing the coordinates to file "f", first the origin
$1 127              # then (A, 127)
$t $3               # then (A + D, S)
$[t+64] $3          # then (A + D + 64, S)
$[t+64+$4] 0">f     # then (A + D + 64 + R, 0)
xmgrace f           # call xmgrace to plot the generated XY file

2

Ідіть, 947 915 506 байт

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

нерухоме зображення

Конденсований:

package main;import (."os";."image";k"image/png";c"image/color";."strconv";."math");func main(){g:=NewRGBA(Rect(0,0,127*4,127));a,_:=ParseFloat(Args[1],4);d,_:=ParseFloat(Args[2],4);s,_:=ParseFloat(Args[3],4);r,_:=ParseFloat(Args[4],4);z:=[5][]float64{{0,0},{a,127},{a+d,s},{a+d+64,s},{a+d+64+r,0}};for i:=1;i<len(z);i++{v,w,x,y:=z[i-1][0],z[i-1][1],z[i][0],z[i][1];m:=(y-w)/(x-v);t:=y-m*x;for v<=x{g.Set(int(Ceil(v)),127-int(Ceil(w)),c.RGBA{0,0,0,255});v+=.01;w=m*v+t}};f,_:=Create("o.png");k.Encode(f,g)}

Беззастережно:

package main

import (
    ."os"
    ."image"
    k"image/png"
    c"image/color"
    ."strconv"
    ."math"
    "fmt"
)

func main(){
    g := NewRGBA(Rect(0, 0, 127*4, 127))

    a, _ := ParseFloat(Args[1], 4)
    d, _ := ParseFloat(Args[2], 4)
    s, _ := ParseFloat(Args[3], 4)
    r, _ := ParseFloat(Args[4], 4)

    z := [5][]float64{{0,0},{a,127},{a+d,s},{a+d+64,s},{a+d+64+r,0}}
    for i:=1;i<len(z);i++{
        v,w,x,y:=z[i-1][0],z[i-1][1],z[i][0],z[i][1]
        m:=(y-w)/(x-v)
        t:=y-m*x
        for v<=x{
            g.Set(int(Ceil(v)),127-int(Ceil(w)), c.RGBA{0,0,0,255})
            v+=.01
            w=m*v+t
        }
    }
    f,_:=Create("o.png")
    k.Encode(f,g)
}

@LuisMendo це так. За замовчуванням 0,0 - лівий верхній кут. Я перевертаю все, як тільки можу.
kemicofa

1
Я ніколи не кодував ходу, тому не знаю. Користувачі тут гольфують свій код вручну, оскільки вони можуть економити більше байтів, ніж звичайний міні-програвач. Тут вітаються погані практики кодування та хитрощі. Наприклад, чи не замінити об'єкти структури змінними (наприклад, l1x, l1y, l1X, l1Y) може бути гольфіст?
seshoumara

1
@rugdealer Це може допомогти, якщо ви цього не бачили
Луїс Мендо

1
Втратили майже 400 байт завдяки вашому посиланню @LuisMendo
kemicofa

1
@rugdealer Вау, це багато \ о /
Луїс Мендо

1

постійного струму, 120 байт

Спочатку я думав, що не можу відповісти на постійному струмі, але бачу, що друк синтаксису векторного зображення дозволений.

?sR127r-sS[<svg><path d="M0 127 L]nrdn[ 0 L]n+dn32PlSn[ L]n64+dn32PlSn[ L]nlR+n[ 127" fill="none" stroke="red"/></svg>]p

Код обчислює переведені координати кожної точки і генерує синтаксис SVG для сюжету. Оскільки редактор зображень має початок у лівому верхньому куті, мені довелося відняти yзначення height127 в цьому випадку, щоб зображення відображалося так, ніби джерело знаходиться в лівому нижньому куті.

Приклад: або спробуйте в Інтернеті!

dc -f plot_ADSR.dc <<< "15 30 70 40"

Вихід:

<svg><path d="M0 127 L15 0 L45 57 L109 57 L149 127" fill="none" stroke="red"/></svg>

Щоб відобразити графік зображення, збережіть такий точний вихід у файл і відкрийте його, наприклад, Gimp, або введіть текст на сторінці HTML, як я це робив вище.

Пояснення: dc це зворотна полірна мова стека d esk c alculator

Сценарій - це довге з'єднання рядка синтаксису SVG. Ключове слово Mпозначає рух до координати і Lпозначає лінію малювання від поточної позиції до заданої координати .

?                           # read input (in reverse order by default). Stack: RSDA
sR                          # pop top value, store it in register 'R'. Stack: SDA
127r-sS                     # push 127, swap top 2 values, pop them and push
                            #subtracting result, save it to 'S', pop it. Stack: DA
[<svg><path d="M0 127 L]n   # [..]n print string (push then pop). Stack: unchanged
rdn                         # swap, duplicate top, print (A) and pop it. Stack: AD
[ 0 L]n                     # printing
+dn                         # pop top 2 values, push addition result, duplicate it,
                            #print and pop it. Stack: (A+D)
32P                         # print a space
lSn                         # push value from register 'S', print and pop it.
                            #Stack: unchanged
[ L]n                       # printing
64+dn                       # push 64, pop top 2 values, push addition result,
                            #duplicate it, print and pop it. Stack: (A+D+64)
32PlSn[ L]n                 # print space, print register 'S', more printing
lR+n                        #push value from register 'R', pop top 2 values, push
                            #addition result, print it and pop it. Stack: empty
[ 127" fill="none" stroke="red"/></svg>]p   # printing
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.