Dreieckssignal erzeugen

9

Aufgabe:

Berechnen Sie bei gegebenem Abtastindex x den Abtastwert f (x) der Dreieckwelle mit einer Periode von 4 Abtastwerten und der Amplitude 1. Der Versatz kann negativ sein und der Abtastwert kann entweder {0, 1, -1} sein.

Testfälle:

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

Persönlich kenne ich zwei Ansätze in C - der erste verwendet die Nachschlagetabelle, der zweite verwendet bedingte Anweisungen. Könnten Sie mich für Brownie-Punkte mit einem reinen "Mathe" -Ansatz beeindrucken? (Ich meine einen rein funktionalen Ansatz, z. B. keine bedingten Anweisungen oder Speicher für die LUT zu verwenden.) Dies ist jedoch keine Einschränkung. Wenn Sie dies nicht können oder Ihre Sprache dies nicht unterstützt, veröffentlichen Sie einfach eine Lösung

0 '
quelle
3
Was meinst du mit "Offset kann negativ sein"? Auch dies ist im Grunde nur eine trigonometrische Funktion, also wäre ich überrascht, wenn es nicht ein Betrug von etwas ist.
FryAmTheEggman
@JungHwanMin Dies hat viel entspanntere Regeln, so dass es nicht wirklich ein Betrug ist (obwohl es nach dem gleichen verlangt).
Mego
@ Mego in Ordnung. Meine Stimme zurückziehen.
JungHwan Min
Siehe auch
JungHwan Min
Kann die Welle relativ zum Beispiel phasenverschoben sein?
Maria

Antworten:

12

Mathematica, 8 Bytes

Im[I^#]&

Erläuterung

Im[I^#]&
   I^#    (* Raise the imaginary unit to the input power *)
Im[   ]   (* Take the imaginary part *)
JungHwan min
quelle
3
Ohh, schöner Ansatz. Wie habe ich das nicht gesehen? : D
HyperNeutrino
siehe algo kippt , wie zu erzeugen imaginäre Einheit in C .. = (im Assembler Mann ^^ mit builtins in exotischen Sprachen ist nicht zu meinen Gunsten) jedoch ist eine Antwort ..
7

TI-Basic, 7 5 4 Bytes

sin(90Ans

(Gradmodus) -1 Byte von @immibis aus meiner alten Antwort.


Alte Antwort

imag(i^Ans

Reinmathematischer Ansatz auf einem Taschenrechner. :) :)

Nur zum Spaß, hier ist eine andere rein mathematische (ish) Lösung für 9 Bytes (im Bogenmaßmodus) oder 8 Bytes (Gradmodus)

2/πsin-1sin(πAns/2 # Radians
90-1sin-1sin(90Ans # Degrees
pizzapants184
quelle
Ja, aber Sie vergessen einfach eine imag () - Implementierung. Aber die Verwendung von anderem Code ist in Ordnung. Gute Antwort :)
2
@ xakepp35 Ich verstehe nicht. imag()ist eine gültige Funktion in TI-BASIC.
JungHwan Min
Was ist los mit sin(90Ans? Warum brauchst du das extra 90-1sin-1?
user253751
@immibis Die 90 ^ -1sin ^ -1 macht es zu einer Dreieckswelle für alle Werte, aber sin (90Ans funktioniert für das, was die Frage stellt.
pizzapants184
6

Python 2 , 20 Bytes

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

Probieren Sie es online aus!

Ich führe eine Brute-Force-Suche nach kürzeren arithmetischen oder bitweisen Ausdrücken durch. Ich werde sehen, ob etwas auftaucht. Diesen habe ich von Hand gefunden.

xnor
quelle
2
Brute-Force-Ausdruckssuche? Nett!
Graviton
5

Julia 0,5 , 12 Bytes

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

Ich mag diesen Ansatz, weil es unwahrscheinlich ist, dass er in einer anderen Sprache der kürzeste ist.

Probieren Sie es online aus!

Wie es funktioniert

Julias Operatorpriorität ist etwas ungewöhnlich: Im Gegensatz zu den meisten anderen Sprachen haben bitweise Operatoren dieselbe Priorität wie ihre arithmetischen Gegenstücke, daher hat &(bitweise Multiplikation) dieselbe Priorität wie *.

Erstens n&3nimmt die Eingabe Modulo 4 , mit positivem Vorzeichen.

Das Ergebnis - 0 , 1 , 2 oder 3 - wird dann von 2 subtrahiert , was 2 , 1 , 0 oder -1 ergibt .

Schließlich nehmen wir den vorzeichenbehafteten Rest der Division durch 2 und geben 0 , 1 , 0 oder -1 zurück .

Dennis
quelle
4

Gelee , 3 Bytes

ı*Ċ

Probieren Sie es online aus!

Wie es funktioniert

ı*Ċ  Main link. Argument: n

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

dc, 13

Ich bin mir nicht sicher, ob Sie den Modulo- %Operator als "reine Mathematik" zählen:

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

Probieren Sie es online aus . Beachten Sie, dass dcAnwendungen _anstelle von -negativen Zahlen anzuzeigen.

Erläuterung

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

Beachten Sie, dass dcder %Mod-Operator die Standardversion "CPU" ist, die negative Werte negativen Werten zuordnet.

Digitales Trauma
quelle
Kannst du es abs((x+1)%4)-1stattdessen einfach tun ?
Magic Octopus Urn
2

Brainfuck , 136 Bytes

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

Probieren Sie es online aus!

Es gibt wahrscheinlich eine trivialere Antwort, aber diese verwendet im Wesentlichen eine Wertetabelle. Obwohl Brainfuck Eingaben als ASCII-Zeichen mit positiven Werten von 0 bis 127 akzeptiert, funktioniert es immer noch so, als ob es negative Werte akzeptieren könnte (zum Testen ersetzen Sie die ,durch die nAnzahl der -Zeichen).

Wie es funktioniert

>,                                   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
quelle
1

Python, 26 24 21 Bytes

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

-2 Bytes danke an ValueInk für die Erkenntnis, dass die mathematische Methode tatsächlich länger ist als der triviale Ansatz: P
-3 Bytes danke an Dennis für den Hinweis, dass ich das nicht brauche int(...), wodurch dies kürzer wird :)

HyperNeutrino
quelle
lambda x:[0,1,0,-1][x%4]ist tatsächlich kürzer als Ihre erzwungene Antwort lol
Value Ink
@ValueInk Oh ... ähm, das ist peinlich lol
HyperNeutrino
2
Warum sollten Sie überhaupt verwenden int()?
Dennis
@ Tennis Da .imaggibt einen Gleitkommawert an und ich bin mir nicht sicher, ob dies nach den Spezifikationen zulässig ist. Es ist jetzt egal :)
HyperNeutrino
Wenn Floats nicht erlaubt sind, kann JavaScript nicht mithalten.
Dennis
1

Mathematica, 18 Bytes

#~JacobiSymbol~46&
J42161217
quelle
5
Das funktioniert nicht ganz: Die Eingänge 9 und 11 geben zum Beispiel beide 1 als Ausgang. Die Periode dieser Funktion ist 184, nicht 4.
Greg Martin
1
Funktioniert jedoch JacobiSymbol[-4,#]&und kostet nur noch ein Byte. Gute Idee!
Greg Martin
Ich kann wieder keinen Algorithmus sehen (nur von anderen geschriebene Buildines und ein paar Kurzcodes. Ah, alles wie gewohnt.
1

PHP, 20 Bytes

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

Haskell , 19 Bytes

Port of Dennis 'Julia-Lösung, nur weil er sagte, dass sie in keiner anderen Sprache am kürzesten wäre. (Jemand könnte mir immer noch das Gegenteil beweisen, dass es in Haskell am kürzesten ist.)

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

Probieren Sie es online aus!

Haskell hat zwei verschiedene Restfunktionen, eine ( rem) funktioniert wie die Julia, während die andere ( mod) ein positives Ergebnis liefert, selbst wenn das erste Argument negativ ist, und daher für die Übersetzung geeignet ist &3. (Haskells tatsächliche & , genannt .&., erfordert leider eine import Data.Bits.)

Ørjan Johansen
quelle
Soweit ich das beurteilen kann, ist ein Port von Dennis 'Julia-Lösung auch für JavaScript optimal (14 Bytes). Zeigt, dass sogar Dennis fehlbar ist!
Neil
0

Ruby, 20 Bytes

Einfach und sauber.

->x{[0,1,0,-1][x%4]}
Wert Tinte
quelle
0

C99, 27 Bytes

Angenommen, Sie möchten, dass die Welle am Ursprung zentriert wird:

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

sonst reicht f(n){return cpow(1i,n);}es. Ich hatte ursprünglich einen cimagdrin, aber anscheinend habe ich versucht, einen intvon einem _Complex intErtrag den realen Teil zurückzugeben, also habe ich das benutzt. Es macht Sinn, aber es ist nichts, was ich vorhergesagt hätte. Verhalten ist das gleiche in gccundclang

Algmyr
quelle
cpow ist undefiniert xD
einige #includes weggelassen, nicht kompiliert)))))
aber +1 nur für C
1
@ xakepp35 Das ist eigentlich nicht die Schuld der Includes, es ist ein Linker-Problem. Kompilieren mit-std=c99 -lm und es sollte funktionieren. Es funktioniert gut für mich mit beiden gccund clangohne Includes. Nun, mit gut meine ich, es gibt keine Fehler, aber eine große Anzahl von Warnungen.
Algmyr
0

05AB1E , 5 Bytes

4%<Ä<

Probieren Sie es online aus!


Die Ausgabe ist umgekehrt, aber nach meinem Verständnis ist dies zulässig:

+1 Byte, um die Ausgabe mit -1 zu multiplizieren (.

   -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...
Magische Krakenurne
quelle
Was ich verstanden habe, ist erlaubt
Testfälle werden nicht bestanden ;-)
aber +1 netter Versuch
0

Pyth - 7 Bytes (möglicherweise 6)

ta2%tQ4

Versuch es

Wenn die Phase der Welle nicht wichtig ist, 6 Bytes:

ta2%Q4

Versuch es

Erläuterung:

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
quelle
0

Javascript ES6, 18 17 Bytes

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

Überprüfen Sie zunächst, ob die Eingabe gerade oder ungerade ist, und geben Sie für alle geraden Werte 0 zurück. Inkrementieren und bitweise mit für alle ungeraden Eingaben, 0b10um alle Bits zu entfernen, die uns nicht interessieren, und geben Sie die Antwort mit einem Offset zurück.

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
quelle
1
Speichern Sie ein Byte durch Ersetzen ? :0durch&&
Steve Bennett
@SteveBennett Danke, tolle Idee!
Nit
0

JavaScript, 15 Bytes

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

Bitweise und 3 entspricht Modulo 4, außer ohne die seltsame Regel für JavaScript-Modulos negativer Zahlen. Ich habe zuerst an den ersten vier Punkten eine polynomielle Regression durchgeführt, dann aber festgestellt, dass ich dumm bin, weil (1, 1), (2, 0) und (3, -1) nur 2-n sind.

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
quelle
sehr gut! +1 für die Antwort