Gerar sinal triangular

9

Tarefa:

Dado o índice amostral, x, calcule o valor amostral f (x) da onda triangular, com período de 4 amostras e amplitude 1. O deslocamento pode ser negativo e o valor da amostra pode ser {0, 1, -1}.

Casos de teste:

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

Pessoalmente, conheço duas abordagens em C - a primeira está usando a tabela de pesquisa, a segunda está usando instruções condicionais. Para pontos brownie, você poderia me impressionar com uma abordagem "matemática" pura? (Quero dizer uma abordagem funcional pura, por exemplo, não usar instruções condicionais ou usar memória para LUT.) Mas isso não é uma restrição. Se você não pode, ou o seu idioma não o suporta - basta postar qualquer solução

0 '
fonte
3
O que você quer dizer com "deslocamento pode ser negativo"? Além disso, isso é basicamente apenas uma função trigonométrica, então eu ficaria surpreso se não for um idiota de alguma coisa.
FryAmTheEggman 16/05
@JungHwanMin Isso tem regras muito mais relaxadas, então não é realmente um estúpido (embora peça a mesma coisa).
Mego 16/05
@Mego tudo bem. Recolhendo meu voto.
JungHwan Min
Relacionados: codegolf.stackexchange.com/q/5522/60043
JungHwan Min
A onda pode estar fora de fase em relação ao exemplo?
Maria

Respostas:

12

Mathematica, 8 bytes

Im[I^#]&

Explicação

Im[I^#]&
   I^#    (* Raise the imaginary unit to the input power *)
Im[   ]   (* Take the imaginary part *)
JungHwan Min
fonte
3
Ohh, linda abordagem. Como eu não vi isso? : D
HyperNeutrino
não pode ver algo como gerar unidade imaginária em C .. = (homem assembler im ^^ usando builtins em línguas exóticas não é a meu favor), porém, é uma resposta ..
7

TI-Básico, 7 5 4 bytes

sin(90Ans

(Modo Grau) -1 byte de @immibis da minha resposta antiga.


Resposta antiga

imag(i^Ans

Abordagem de matemática pura em uma calculadora. :)

Apenas por diversão, aqui está outra solução de matemática pura (ish) para 9 bytes (no modo radiano) ou 8 bytes (modo Grau)

2/πsin-1sin(πAns/2 # Radians
90-1sin-1sin(90Ans # Degrees
pizzapants184
fonte
sim, mas você acabou de esquecer uma implementação imag () .. mas usar outro código é bom, embora .. boa resposta :) #
2
@ xakepp35 Eu não entendo. imag()é uma função válida no TI-BASIC.
JungHwan Min
O que há de errado sin(90Ans? Por que você precisa do extra 90-1sin-1?
User253751 19/05
@immibis O 90 ^ -1sin ^ -1 torna uma onda triangular para todos os valores, mas o pecado (90Ans funciona para o que a pergunta pede.
pizzapants184
6

Python 2 , 20 bytes

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

Experimente online!

Estou executando uma pesquisa de força bruta por expressões aritméticas ou bit a bit mais curtas, vou ver se algo aparece. Este eu encontrei à mão.

xnor
fonte
2
Pesquisa de expressão de força bruta? Agradável!
Graviton 16/05
5

Julia 0,5 , 12 bytes

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

Eu gosto dessa abordagem porque é improvável que seja a mais curta em qualquer outro idioma.

Experimente online!

Como funciona

A precedência do operador de Julia é um pouco incomum: ao contrário da maioria dos outros idiomas, os operadores bit a bit têm a mesma precedência que suas contrapartes aritméticas, portanto &(multiplicação por bit) tem a mesma precedência que *.

Primeiro, n&3pega o módulo de entrada 4 , com sinal positivo.

O resultado - 0 , 1 , 2 ou 3 - é subtraído de 2 , produzindo 2 , 1 , 0 ou -1 .

Finalmente, pegamos o restante assinado da divisão por 2 , retornando 0 , 1 , 0 ou -1 .

Dennis
fonte
4

Gelatina , 3 bytes

ı*Ċ

Experimente online!

Como funciona

ı*Ċ  Main link. Argument: n

ı*   Elevate i, the imaginary unit, to the n-th power.
  Ċ  Take the imaginary part of the result.
Dennis
fonte
4

dc, 13

Não tenho certeza se você considera o %operador módulo como "matemática pura":

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

Experimente online . Observe que dcusa em _vez de -para indicar números negativos.

Explicação

?              # 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

Observe que dco %operador mod é a versão "CPU" padrão que mapeia valores negativos para valores negativos.

Trauma Digital
fonte
Você pode apenas fazer abs((x+1)%4)-1?
Magic Octopus Urn
2

brainfuck , 136 bytes

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

Experimente online!

Provavelmente há uma resposta mais trivial, mas isso essencialmente usa uma tabela de valores. Embora brainfuck leva entrada como caracteres ASCII com valores positivos de 0 a 127, ele ainda funciona como se fosse capaz de aceitar valores negativos (para teste, substitua o ,com nquantidade de -caracteres).

Como funciona

>,                                   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)
Graviton
fonte
1

Python, 26 24 21 bytes

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

-2 bytes graças ao ValueInk por perceber que o método matemático é realmente mais longo do que a abordagem trivial: P
-3 bytes graças a Dennis por apontar que não preciso do int(...), tornando assim mais curto :)

HyperNeutrino
fonte
lambda x:[0,1,0,-1][x%4]é na verdade menor do que a sua resposta lol coagido-int
Valor Ink
@ValueInk Oh ... hum isso é embaraçoso lol
HyperNeutrino
2
Por que você usaria int()em primeiro lugar?
Dennis
@ Dennis Porque .imagfornece um valor de ponto flutuante e não tenho certeza se isso é permitido pelas especificações. Não importa agora :)
HyperNeutrino
Se carros alegóricos não forem permitidos, o JavaScript não poderá competir.
Dennis
1

Mathematica, 18 bytes

#~JacobiSymbol~46&
J42161217
fonte
5
Isso não funciona: as entradas 9 e 11 fornecem 1 como saída, por exemplo. O período desta função é 184, não 4.
Greg Martin
11
No entanto, JacobiSymbol[-4,#]&funciona e custa apenas mais um byte. Boa ideia!
Greg Martin
novamente não posso ver uma algrithm (apenas builtines escrito por outros e par de código curto .. ah, tudo como de costume resposta bem embora.
1

PHP, 20 bytes

<?=2<=>($argn&3?:2);
user63956
fonte
1

Haskell , 19 bytes

A solução Julia do Porto da Dennis, só porque ele disse que não seria o mais curto em nenhum outro idioma. (Alguém ainda pode me provar que é o menor em Haskell.)

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

Experimente online!

Haskell tem duas funções remanescentes diferentes, uma ( rem) funciona como a Julia, enquanto a outra ( mod) fornece um resultado positivo mesmo quando o primeiro argumento é negativo e, portanto, é adequado para a tradução &3. (De Haskell reais & , chamados .&., infelizmente requer uma import Data.Bits.)

Ørjan Johansen
fonte
Pelo que sei, uma porta da solução Julia de Dennis também é ótima para JavaScript (14 bytes). Mostra que mesmo Dennis é falível!
Neil
0

Ruby, 20 bytes

Simples e limpo.

->x{[0,1,0,-1][x%4]}
Value Ink
fonte
0

C99, 27 bytes

Supondo que você queira que a onda seja centralizada na origem:

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

caso contrário f(n){return cpow(1i,n);}, fará. Eu originalmente tinha um cimaglá, mas aparentemente tentando retornar um intde um _Complex intproduz a parte real, então usei isso. Faz sentido, mas não é nada que eu tenha previsto. O comportamento é o mesmo gcceclang

algmyr
fonte
cpow é indefinido xD
alguns #inclui omitidos, não compilam)))))
mas +1 apenas para C
11
@ xakepp35 Na verdade, isso não é culpa das inclusões, é um problema do vinculador. Compilar com -std=c99 -lme deve funcionar. Funciona bem para mim, com gcce clangsem inclusão. Bem, quero dizer que não há erros, mas um grande número de avisos.
Algmyr #
0

05AB1E , 5 bytes

4%<Ä<

Experimente online!


A saída é invertida, mas pelo que entendi isso é permitido:

+1 byte para multiplicar a saída por -1 usando (.

   -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...
Urna de polvo mágico
fonte
o que eu entendi isso é permitido #
casos de teste não são aprovados ;-) #
mas +1 tentativa agradável
0

Pitão - 7 bytes (possivelmente 6)

ta2%tQ4

Tente

Se a fase da onda não for importante, 6 bytes:

ta2%Q4

Tente

Explicação:

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]
Maria
fonte
0

AWK , 26 bytes

{$0=(sqrt(($0%4)^2)-2)%2}1

Experimente online!

Essa é uma abordagem alternativa usando funções trigonométricas sem o operador de módulo.

{$0=int(sin($0*atan2(0,-1)/2))}1

Experimente online!

Robert Benson
fonte
0

Javascript ES6, 18 17 bytes

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

Primeiro, verifique se a entrada é par ou ímpar e retorne 0 para todos os valores pares. Para todas as entradas ímpares, incremente e bit a bit com 0b10para remover os bits que não nos interessam e, em seguida, retorne a resposta com um deslocamento.

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)}`;
}

Nit
fonte
11
Salve um byte, substituindo ? :0por #&&
Steve Bennett
@SteveBennett Obrigado, ótima idéia!
Nit
0

JavaScript, 15 bytes

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

Bitwise e 3 é equivalente ao módulo 4, exceto sem a regra estranha dos módulos de números negativos do JavaScript. Fiz uma regressão polinomial nos quatro primeiros pontos no início, mas depois percebi que estava sendo burro porque (1, 1), (2, 0) e (3, -1) são apenas 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)])

Kuilin Li
fonte
muito bem! +1 para a resposta