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


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 У этого правила гораздо более непринужденные, так что на самом деле это не обман (хотя он требует того же).
Мего

@ Хорошо, хорошо. Убираю мой голос.
JungHwan Мин


Может ли волна быть не в фазе относительно примера?
Мария,

Ответы:


12

Mathematica, 8 байт

Im[I^#]&

объяснение

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

3
О, прекрасный подход. Как я этого не увидел? : D
HyperNeutrino

Я не могу видеть, как создать мнимую единицу в C .. = (однако я ассемблер man ^^, использующий встроенные в экзотические языки, не в мою пользу), однако это ответ ..

7

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

sin(90Ans

(Градусный режим) -1 байт из @immibis из моего старого ответа.


Старый ответ

imag(i^Ans

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

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

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

да, но вы просто забыли реализацию imag () ... но с другим кодом все в порядке, хотя .. хороший ответ :)

2
@ xakepp35 Я не понимаю. imag()является действительной функцией на TI-BASIC.
JungHwan Мин

Что не так с sin(90Ans? Зачем вам нужно лишнее 90-1sin-1?
user253751

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

6

Python 2 , 20 байт

lambda n:n%2-n%4/3*2

Попробуйте онлайн!

Я провожу поиск грубой силы для более коротких арифметических или побитовых выражений, посмотрю, появится ли что-нибудь. Этот я нашел вручную.


2
Поиск грубой силы выражения? Ницца!
Гравитон

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

Python, 26 24 21 байт

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

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


lambda x:[0,1,0,-1][x%4]на самом деле короче, чем ваш вынужденный ответ lol
Value Ink

@ValueInk Ох ... эм, это смущает, лол
HyperNeutrino

2
Почему бы вы использовали int()в первую очередь, хотя?
Денис

@Dennis Потому что .imagдает значение с плавающей точкой, и я не уверен, что это разрешено спецификациями. Неважно сейчас :)
HyperNeutrino

Если поплавки не разрешены, JavaScript не сможет конкурировать.
Деннис


1

Mathematica, 18 байт

#~JacobiSymbol~46&

5
Это не совсем работает: например, входы 9 и 11 дают 1 в качестве выхода. Период этой функции - 184, а не 4.
Грег Мартин

1
Тем JacobiSymbol[-4,#]&не менее, работает, и просто стоит еще один байт. Хорошая идея!
Грег Мартин

снова не могу увидеть алгоритм (только встроенные функции, написанные другими и несколько коротких кодов .. ах, все как обычно. хороший ответ, хотя



1

Haskell , 19 байтов

Решение Джулии из Port of Dennis только потому, что он сказал, что оно не будет самым коротким на любом другом языке. (Кто-то может доказать, что я ошибаюсь, что он самый короткий в Хаскеле.)

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

Попробуйте онлайн!

В Haskell есть две разные функции остатка: одна ( rem) работает как функция Джулии, а другая ( mod) дает положительный результат, даже если первый аргумент отрицательный, и поэтому подходит для перевода &3. ( Фактически & , Haskell называется .&., увы, требует import Data.Bits.)


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



0

C99, 27 байт

Предполагая, что вы хотите, чтобы волна была центрирована в начале координат:

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

иначе f(n){return cpow(1i,n);}сделаем. Первоначально я был cimagтам, но , видимо , пытаясь возвращать intот А _Complex intдоходности вещественной части, так что я использовал это. Это имеет смысл, но я ничего не предсказал. Поведение же самое в gccиclang


процесс не определен xD

некоторые #include пропущены, не компилируется)))))

но +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.