Générer un signal triangulaire

9

Tâche:

Étant donné l'indice d'échantillon, x, calculez la valeur d'échantillon f (x) de l'onde triangulaire, avec une période de 4 échantillons et une amplitude 1. Le décalage peut être négatif et la valeur d'échantillon peut être soit {0, 1, -1}.

Cas de test:

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

Personnellement, je connais deux approches en C - la première utilise une table de recherche, la seconde utilise des instructions conditionnelles. Pour les points brownie, pourriez-vous m'impressionner avec une approche "mathématique" pure? (Je veux dire une approche fonctionnelle pure, par exemple ne pas utiliser d'instructions conditionnelles ou utiliser de la mémoire pour LUT.) Mais ce n'est pas une restriction. Si vous ne le pouvez pas ou que votre langue ne le prend pas en charge, il vous suffit de poster une solution

0 '
la source
3
Qu'entendez-vous par «l'offset peut être négatif»? De plus, il s'agit simplement d'une fonction trigonométrique, donc je serais surpris si ce n'est pas une dupe de quelque chose.
FryAmTheEggman
@JungHwanMin Cela a des règles beaucoup plus détendues, donc ce n'est pas vraiment dupe (bien qu'il demande la même chose).
Mego
@Mego bien. Retrait de mon vote.
JungHwan Min
L'onde peut-elle être déphasée par rapport à l'exemple?
Maria

Réponses:

12

Mathematica, 8 octets

Im[I^#]&

Explication

Im[I^#]&
   I^#    (* Raise the imaginary unit to the input power *)
Im[   ]   (* Take the imaginary part *)
JungHwan Min
la source
3
Ohh, belle approche. Comment n'ai-je pas vu ça? : D
HyperNeutrino
ne peux pas voir algo comment générer une unité imaginaire en C .. = (im assembler man ^^ utilisant des builtins dans des langues exotiques n'est pas en ma faveur) est cependant une réponse ..
7

TI-Basic, 7 5 4 octets

sin(90Ans

(Mode degrés) -1 octet de @immibis de mon ancienne réponse.


Ancienne réponse

imag(i^Ans

Approche mathématique pure sur une calculatrice. :)

Juste pour le plaisir, voici une autre solution pure-math (ish) pour 9 octets (en mode radian) ou 8 octets (mode degré)

2/πsin-1sin(πAns/2 # Radians
90-1sin-1sin(90Ans # Degrees
pizzapants184
la source
oui, mais vous oubliez juste une implémentation imag () .. mais le code usin d'autres est correct, cependant .. bonne réponse :)
2
@ xakepp35 Je ne comprends pas. imag()est une fonction valide sur TI-BASIC.
JungHwan Min
Qu'est-ce qui ne va pas sin(90Ans? Pourquoi avez-vous besoin du supplément 90-1sin-1?
user253751
@immibis Le 90 ^ -1sin ^ -1 en fait une onde triangulaire pour toutes les valeurs, mais sin (90Ans fonctionne pour ce que la question demande.
pizzapants184
6

Python 2 , 20 octets

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

Essayez-le en ligne!

J'exécute une recherche par force brute pour des expressions arithmétiques ou au niveau du bit plus courtes, je vais voir si quelque chose se présente. Celui-ci, je l'ai trouvé à la main.

xnor
la source
2
Recherche d'expression de force brute? Agréable!
Graviton
5

Julia 0,5 , 12 octets

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

J'aime cette approche car il est peu probable qu'elle soit la plus courte dans une autre langue.

Essayez-le en ligne!

Comment ça fonctionne

La priorité des opérateurs de Julia est un peu inhabituelle: contrairement à la plupart des autres langues, les opérateurs au niveau du bit ont la même priorité que leurs homologues arithmétiques, donc &(multiplication au niveau du bit) a la même priorité que *.

Tout d'abord, n&3prend le module d'entrée 4 , avec signe positif.

Le résultat - 0 , 1 , 2 ou 3 - est ensuite soustrait de 2 , ce qui donne 2 , 1 , 0 ou -1 .

Enfin, nous prenons le reste signé de la division par 2 , retournant 0 , 1 , 0 ou -1 .

Dennis
la source
4

Gelée , 3 octets

ı*Ċ

Essayez-le en ligne!

Comment ça fonctionne

ı*Ċ  Main link. Argument: n

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

dc, 13

Vous ne savez pas si vous comptez l' %opérateur modulo comme "mathématiques pures":

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

Essayez-le en ligne . Notez que dcutilise _au lieu de- pour indiquer des nombres négatifs.

Explication

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

Notez que dcl' %opérateur mod est la version standard "CPU" qui mappe les valeurs négatives aux valeurs négatives.

Traumatisme numérique
la source
Pouvez-vous simplement faire à la abs((x+1)%4)-1place?
Urne de poulpe magique
2

brainfuck , 136 octets

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

Essayez-le en ligne!

Il y a probablement une réponse plus triviale, mais cela utilise essentiellement une table de valeurs. Bien que brainfuck accepte les entrées sous forme de caractères ASCII avec des valeurs positives de 0 à 127, cela fonctionne toujours comme s'il était capable d'accepter des valeurs négatives (pour tester, remplacer le ,par une nquantité de- caractères).

Comment ça fonctionne

>,                                   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
la source
1

Python, 26 24 21 octets

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

-2 octets grâce à ValueInk pour s'être rendu compte que la méthode mathématique est en fait plus longue que l'approche triviale: P
-3 octets merci à Dennis d'avoir souligné que je n'ai pas besoin de la int(...), ce qui raccourcit donc :)

HyperNeutrino
la source
lambda x:[0,1,0,-1][x%4]est en fait plus court que votre réponse intolérée lol
Value Ink
@ValueInk Oh ... euh c'est embarrassant lol
HyperNeutrino
2
Pourquoi voudriez-vous utiliser int()en premier lieu cependant?
Dennis
@Dennis Parce que .imagdonne une valeur à virgule flottante et je ne sais pas si cela est autorisé par les spécifications. Cela n'a plus d'importance maintenant :)
HyperNeutrino
Si les flottants ne sont pas autorisés, JavaScript ne pourra pas rivaliser.
Dennis
1

Mathematica, 18 octets

#~JacobiSymbol~46&
J42161217
la source
5
Cela ne fonctionne pas vraiment: les entrées 9 et 11 donnent toutes les deux 1 en sortie, par exemple. La période de cette fonction est 184, pas 4.
Greg Martin
1
Cependant, JacobiSymbol[-4,#]&cela fonctionne et ne coûte qu'un octet de plus. Bonne idée!
Greg Martin
encore une fois, je ne peux pas voir un algrithme (juste des codes écrits par d'autres et quelques codes courts .. ah, tout comme d'habitude. bonne réponse cependant
1

PHP, 20 octets

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

Haskell , 19 octets

La solution Julia de Port of Dennis, juste parce qu'il a dit qu'elle ne serait pas la plus courte dans une autre langue. (Quelqu'un pourrait encore me prouver que c'est le plus court à Haskell.)

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

Essayez-le en ligne!

Haskell a deux fonctions de reste différentes, l'une ( rem) fonctionne comme la Julia, tandis que l'autre ( mod) donne un résultat positif même lorsque le premier argument est négatif, et convient donc à la traduction &3. (Le réel & , appelé .&., de Haskell nécessite hélas un import Data.Bits.)

Ørjan Johansen
la source
Pour autant que je sache, un portage de la solution Julia de Dennis est également optimal pour JavaScript (14 octets). Montre que même Dennis est faillible!
Neil
0

Ruby, 20 octets

Simple et propre.

->x{[0,1,0,-1][x%4]}
Encre de valeur
la source
0

C99, 27 octets

En supposant que vous voulez que l'onde soit centrée à l'origine:

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

sinon f(n){return cpow(1i,n);}fera l'affaire. J'avais à l'origine une cimagentrée là-dedans, mais apparemment, j'essaie de récupérer une partie intde _Complex intla partie réelle, alors je l'ai utilisée. C'est logique, mais ce n'est rien que j'aurais prévu. Le comportement est le même dans gccetclang

algmyr
la source
cpow n'est pas défini xD
certains #inclut omis, ne compile pas)))))
mais +1 uniquement pour C
1
@ xakepp35 Ce n'est en fait pas la faute des inclusions, c'est un problème de linker. Compilez avec -std=c99 -lmet cela devrait fonctionner. Cela fonctionne bien pour moi avec les deux gccet clangsans aucun inclus. Eh bien, je veux dire par là qu'il n'y a pas d'erreurs, mais un grand nombre d'avertissements.
algmyr
0

05AB1E , 5 octets

4%<Ä<

Essayez-le en ligne!


La sortie est inversée, mais d'après ce que j'ai compris, cela est autorisé:

+1 octet pour multiplier la sortie par -1 en utilisant (.

   -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...
Urne de poulpe magique
la source
ce que j'ai compris c'est autorisé
les cas de test ne sont pas passés ;-)
mais +1 bel essai
0

Pyth - 7 octets (éventuellement 6)

ta2%tQ4

Essayez-le

Si la phase de l'onde n'est pas importante, 6 octets:

ta2%Q4

Essayez-le

Explication:

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
la source
0

Javascript ES6, 18 17 octets

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

Tout d'abord, vérifiez si l'entrée est paire ou impaire et retournez 0 pour toutes les valeurs paires. Pour toutes les entrées impaires, incrémentez et au niveau du bit avec 0b10pour supprimer tous les bits qui ne nous intéressent pas, puis renvoyez la réponse avec un décalage.

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

Lente
la source
1
Enregistrer un octet en le remplaçant ? :0par&&
Steve Bennett
@SteveBennett Merci, bonne idée!
Nit
0

JavaScript, 15 octets

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

Bitwise et 3 est équivalent à modulo 4 sauf sans la règle bizarre sur les modules de nombres négatifs de JavaScript. J'ai d'abord fait une régression polynomiale sur les quatre premiers points, mais j'ai ensuite réalisé que j'étais stupide parce que (1, 1), (2, 0) et (3, -1) ne sont que 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
la source
très bien! +1 pour la réponse