Генерація трикутного сигналу


9

Завдання:

З огляду на індекс вибірки, x, обчисліть вибіркове значення f (x) трикутної хвилі з періодом 4 вибірки та амплітудою 1. Зсув може бути негативним, а значення вибірки може бути або {0, 1, -1}.

Тестові приклади:

   -5 -> -1
   -4 -> 0
   -3 -> 1
   -2 -> 0
   -1 -> -1
    0 -> 0
    1 -> 1
    2 -> 0
    3 -> -1
    4 -> 0
    5 -> 1

Особисто я знаю два підходи в C - перший використовує таблицю пошуку, другий - використання умовних інструкцій. Щодо окулярів брауні, чи можете ви вразити мене чистим "математичним" підходом? (Я маю на увазі чисто функціональний підхід, наприклад, не використання умовних інструкцій або використання пам'яті для LUT.) Але це не обмеження. Якщо ви не можете, або ваша мова не підтримує це, просто опублікуйте будь-яке рішення


3
Що ви маєте на увазі під «зсув може бути негативним»? Крім того, це в основному лише тригонометрична функція, тому я буду здивований, якщо це не дурень чогось.
FryAmTheEggman

@JungHwanMin Це набагато більш розслаблені правила, тож насправді це не дура (хоч і просить те саме).
Мего

@Mego добре Відкликання мого голосу.
JungHwan Min


Чи може хвиля вийти з фази відносно прикладу?
Марія

Відповіді:


12

Математика, 8 байт

Im[I^#]&

Пояснення

Im[I^#]&
   I^#    (* Raise the imaginary unit to the input power *)
Im[   ]   (* Take the imaginary part *)

3
О, прекрасний підхід. Як я цього не бачив? : D
HyperNeutrino

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

7

TI-Basic, 7 5 4 байти

sin(90Ans

(Режим ступеня) -1 байт від @immibis з моєї старої відповіді.


Стара відповідь

imag(i^Ans

Чисто-математичний підхід на калькуляторі. :)

Для задоволення, ось ще одне чисто математичне (іш) рішення на 9 байт (у радіановому режимі) або 8 байт (градусний режим)

2/πsin-1sin(πAns/2 # Radians
90-1sin-1sin(90Ans # Degrees

так, але ви просто забули реалізацію imag () .. але всі інші коди чудово, хоча .. хороша відповідь :)

2
@ xakepp35 Я не розумію. imag()є дійсною функцією на TI-BASIC.
JungHwan Min

Що не так sin(90Ans? Навіщо потрібна додаткова 90-1sin-1?
користувач253751

@immibis 90 ^ -1sin ^ -1 робить його трикутною хвилею для всіх значень, але гріх (90Ans працює на те, що задає питання.
pizzapants184,


5

Джулія 0,5 , 12 байт

!n=(2-n&3)%2

Мені подобається такий підхід, тому що навряд чи він буде найкоротшим в будь-якій іншій мові.

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

Як це працює

Операторський пріоритет Джулії є дещо незвичним: на відміну від більшості інших мов, побітові оператори мають той самий пріоритет, що й їхні арифметичні аналоги, тому &(порозрядне множення) має такий самий пріоритет, як і *.

Спочатку n&3бере вхідний модуль 4 , з позитивним знаком.

Результат - 0 , 1 , 2 або 3 - віднімається від 2 , даючи 2 , 1 , 0 або -1 .

Нарешті, ми беремо підписаний залишок ділення на 2 , повертаючи 0 , 1 , 0 або -1 .



4

постійний струм, 13

Не впевнений, чи вважаєте ви %оператор модуля "чистою математикою":

?1+d*v4%1-2%p

Спробуйте в Інтернеті . Зауважте, що dcвикористовується _замість -позначення від'ємних чисел.

Пояснення

?              # read input
 1+            # add 1
   d*v         # duplicate, multiply, square root (poor-mans abs())
      4%       # mod 4
        1-     # subtract 1
          2%   # mod 2
            p  # print

Зверніть увагу , що dc«S %мод оператором є стандартною" CPU "версія , яка відображає негативні значення до негативних значень.


Можна просто зробити abs((x+1)%4)-1замість цього?
Чарівна восьминога урна

2

мозковий ебать , 136 байт

>,>++++<[>->+<[>]>[<+>-]<<[<]>-]>>>>-[>+<-----]>--[-<+>>>+>>>+>>>+<<<<<<<<]<->>>>>>->--[>+<++++++]>++<<<<<<<<<<[[->>>+<<<]>>>-]>[.[-]]>.

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

Напевно, є більш тривіальна відповідь, але для цього по суті використовується таблиця значень. Хоча Brainfuck приймає вхідні дані як ASCII символи з позитивними значеннями від 0 до 127, він все ще працює , як якщо б він був в змозі прийняти негативні значення (для тестування, заміни ,з nкількістю- символів).

Як це працює

>,                                   take input (X)
>++++<                               take second input for modulo (4)
[>->+<[>]>[<+>-]<<[<]>-]             calculate X mod 4
>>>>-[>+<-----]>--                   create initial '1' character
[-<+>>>+>>>+>>>+<<<<<<<<]            duplicate '1' four times as 1,1,1,1
<->>>>>>->--[>+<++++++]>++<<<<<<<<<< change 1,1,1,1 to 0,1,0,-1 
[[->>>+<<<]>>>-]>[.[-]]>.            move to the right X%4 * 3 times, then print the following two characters ( 0, 1, 0,-1)

1

Пітон, 26 24 21 байт

lambda x:(1j**x).imag

-2 байти завдяки ValueInk за те, що він зрозумів, що математичний метод насправді довший тривіального підходу: P
-3 байт завдяки Деннісу за те, що він зазначив, що мені це не потрібно int(...), зробивши це коротшим :)


lambda x:[0,1,0,-1][x%4]насправді коротше вашої відповіді про примусовий відповідь lol
Чорнило значення

@ValueInk О ... гм це бентежить лол
HyperNeutrino

2
Чому б ти int()в першу чергу використовував?
Денніс

@Dennis Тому що .imagдає значення з плаваючою комою, і я не впевнений, чи дозволяють це специфікації. Зараз це не має значення :)
HyperNeutrino

Якщо плавки не дозволені, JavaScript не зможе конкурувати.
Денніс


1

Математика, 18 байт

#~JacobiSymbol~46&

5
Це не зовсім працює: обидва входи 9 та 11 дають 1 як вихід, наприклад. Період цієї функції 184, а не 4.
Грег Мартін

1
Однак JacobiSymbol[-4,#]&це працює, і просто коштує ще один байт. Хороша ідея!
Грег Мартін

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



1

Хаскелл , 19 байт

Рішення Джуліа Порта Денніса, просто тому, що він сказав, що це не буде найкоротшим у будь-якій іншій мові. (Хтось може все-таки довести мене неправильно, що це найкоротше в Хаскеллі.)

f n=rem(2-n`mod`4)2

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

Haskell має дві різні залишкові функції, одна ( rem) працює як Julia, а інша ( mod) дає позитивний результат навіть тоді, коли перший аргумент є негативним, і тому підходить для перекладу &3. ( Фактичний Haskell &, названий .&., на жаль, вимагає import Data.Bits.)


Наскільки я можу сказати, порт рішення Денніса Джулія є оптимальним і для JavaScript (14 байт). Показує, що навіть Денніс є помилковим!
Ніл



0

C99, 27 байт

Якщо припустити, що ви хочете, щоб хвиля була зосереджена на початку:

f(n){return cpow(1i,n)/1i;}

інакше f(n){return cpow(1i,n);}зробимо. Спочатку я був cimagтам, але , мабуть , намагаючись повертати intвід А _Complex intприбутковості дійсної частини, так що я використовував це. Це має сенс, але це нічого, що я б передбачив. Поведінка однакова в gccіclang


cpow не визначено xD

деякі #includes пропущено, не компілюється)))))

але +1 лише для C

1
@ xakepp35 Це насправді не винна включає, це проблема з лінкером. Компілюйте, -std=c99 -lmі це має працювати. Це добре працює для мене з обома gccі clangбез будь-яких включень. Ну, добре, я маю на увазі, що тут немає помилок, але велика кількість попереджень.
algmyr

0

05AB1E , 5 байт

4%<Ä<

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


Вихід є зворотним, але з того, що я зрозумів, це дозволено:

+1 байт, щоб помножити вихід на -1, використовуючи (.

   -5 -> 1
   -4 -> 0
   -3 -> -1
   -2 -> 0
   -1 -> 1
    0 -> 0
    1 -> -1
    2 -> 0
    3 -> 1
    4 -> 0
    5 -> -1

4%    # Amplitude of 4...
  <   # Period of 1...
   Ä  # Absolute value...
    < # Period of 1 centered at 0...

те, що я зрозумів, це дозволено

тестові справи не проходять ;-)

але +1 приємна спроба

0

Pyth - 7 байт (можливо 6)

ta2%tQ4

Спробуй це

Якщо фаза хвилі не важлива, 6 байт:

ta2%Q4

Спробуй це

Пояснення:

ta2%tQ4
     Q    # The input
    t     # Subtract 1 to get the phase right (might not be necessary)
   %  4   # Take mod 4
 a2       # Absolute value of the result - 2
t         # Subtract 1 so the result is in [-1,0,1]


0

Javascript ES6, 18 17 байт

n=>n&1&&(++n&2)-1

По-перше, перевірте, чи вхід парний чи непарний, і поверніть 0 для всіх парних значень. На всіх непарних введеннях, збільшуючи та побіжно, 0b10щоб видалити будь-які біти, які нас не цікавлять, поверніть відповідь зі зміщенням.

const f = n=>n&1&&(++n&2)-1;

for (let i = -5; i < 6; i++) {
  document.body.appendChild(document.createElement('pre')).innerHTML = `f(${i}) => ${f(i)}`;
}


1
Збережіть байт, замінивши ? :0на&&
Стів Беннетт

@SteveBennett Дякую, чудова ідея!
Ніт

0

JavaScript, 15 байт

n=>n&3&&2-(n&3)

Послідовий і 3 еквівалентний модулю 4, за винятком випадків, коли дивне правило про модулі JavaScript негативних чисел. Я спочатку зробив поліноміальну регресію на перших чотирьох точках, але потім зрозумів, що я німий, тому що (1, 1), (2, 0) і (3, -1) просто 2-n.

a=n=>n&1&&2-(n&3);
console.log([a(-5), a(-4), a(-3), a(-2), a(-1), a(0), a(1), a(2), a(3), a(4), a(5)])


дуже добре! +1 для відповіді

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