Lass uns zählen...
Zähle bis zu 2 und zurück bis zu 1
Zähle bis zu 4 und zurück bis zu 1
Zähle bis zu 6 und zurück bis zu 1
... ok du hast es verstanden ...
Füge all diese zusammen und du erhältst die folgende Sequenz
{1,2,1,2,3,4,3,2,1,2,3,4,5,6,5,4,3,2,1,2,3,4,5,6,7,8,7,6,5,4,3,2,1,2,3...}
Herausforderung
Geben Sie bei einer Ganzzahl n>0
für 1-indiziert (oder n>=0
für 0-indiziert) den n-ten Term dieser Sequenz aus
Testfälle
Input->Output
1->1
68->6
668->20
6667->63
10000->84
Regeln
Ihr Programm muss in der Lage sein, in weniger als einer Minute Lösungen bis zu n = 10000 zu berechnen
Das ist Code-Golf , also gewinnt der kürzeste Code in Bytes!
Antworten:
JavaScript (ES7),
59 ... 4443 BytesDank Titus 1 Byte gespeichert
Erwartete Eingabe: 1-indiziert.
Anfänglich inspiriert von einer Formel für A004738 , die eine ähnliche Sequenz darstellt. Aber am Ende habe ich es komplett umgeschrieben.
Testfälle
Code-Snippet anzeigen
Wie?
Die Sequenz kann als Dreieck angeordnet werden, wobei der linke Teil in aufsteigender Reihenfolge und der rechte Teil in absteigender Reihenfolge angeordnet werden.
Unten sind die ersten 4 Zeilen mit den ersten 32 Begriffen aufgeführt:
Lassen Sie uns nun einige Variablen einführen:
Wir beginnen mit 2 Elementen oben und fügen jeder neuen Zeile 4 Elemente hinzu. Daher kann die Anzahl der Elemente in der mit 0 indizierten Zeile r ausgedrückt werden als:
Die 1-indizierte Startposition x der Zeile r ergibt sich aus der Summe aller vorangegangenen Terme dieser Rechenreihe plus eins, was zu Folgendem führt:
Umgekehrt kann bei einer 1-indizierten Position n in der Sequenz die entsprechende Zeile gefunden werden mit:
oder als JS-Code:
Sobald wir r (n) kennen , subtrahieren wir die Startposition x (r) minus eins von n :
Wir vergleichen n mit a (r) / 2 + 1 = 2r + 2, um herauszufinden, ob wir uns im aufsteigenden Teil oder im absteigenden Teil befinden:
Wenn dieser Ausdruck wahr ist, geben wir n zurück . Andernfalls geben wir 4 (r + 1) - n zurück . Da jedoch r bereits in der letzten Anweisung inkrementiert wurde, wird dies vereinfacht als:
quelle
Haskell , 37 Bytes
Probieren Sie es online!
Nullindexiert. Erzeugt die Liste und indiziert sie. Vielen Dank an Ørjan Johansen für das Speichern von 2 Bytes!
Haskell , 38 Bytes
Probieren Sie es online!
Nullindexiert. Erzeugt die Liste und indiziert sie.
Haskell , 39 Bytes
Probieren Sie es online!
Nullindexiert. Eine rekursive Methode.
quelle
Python , 46 Bytes
Probieren Sie es online!
Null indiziert.
quelle
Schale , 8 Bytes
1-indiziert. Probieren Sie es online!
Erläuterung
quelle
Perl 6 , 29 Bytes
Probieren Sie es online aus
0-basiert
Erweitert:
Die innere Sequenz
1...$+=2...2
erzeugtFügen Sie
0,
vor dem zweiten{
oder-1
nach dem zweiten hinzu , damit es 1-basiert wird$_
quelle
R, 64 Bytes
Funktion, die ein Argument annimmt
n
. Es wird ein Vektor2:n
mit Inkrementen von 2 erstellt. Für jeden von diesen wird der Vektor1:(x-1)
undx:2
erstellt. Dies wird insgesamt länger sein alsn
. Wirunlist
es, einen Vektor zu bekommen und denn
-ten Eintrag zu nehmen.quelle
1:n*2
anstelle von tunseq(2,n,2)
? Es wird größer als Sie brauchen, aber das sollte in Ordnung sein! Auch ich glaube nicht, dass dasseq(2,n,2)
fürn=1
sowieso geklappt hat!Python 2 , 56 Bytes
Probieren Sie es online!
Dies ist 0-indiziert.
-1 Byte dank @JustinMariner
Wie das funktioniert
Wir stellen fest, dass die 1-indizierte-
n
te Gruppe (1, 2, ... 2n ..., 2, 1
) aus Elementen besteht, die mit 0-indiziert2(n-1)^2
bis nummeriert sind2n^2
.Um das Element am Index zu finden
x
, können wir die Gruppennummer finden, in dern
es sichx
befindet. Daraus berechnen wir den Abstand vom Mittelpunkt der Gruppe, die sichx
befindet. (Dieser Abstand istabs(2*n**2+2*n+2-x)
).Da die Elemente jedoch weiter vom Zentrum einer Gruppe entfernt abnehmen , subtrahieren wir den Abstand vom Maximalwert der Gruppe.
quelle
print 2*n-abs(2*n*n+2*n+1-x)+2
-2*n*n+2*n
Kann sein2*n*-~n
und+2+2*n
kann verwandelt werden-~n*2
, wodurch wir ihn an den Anfang verschieben können, wodurch Bytes ( 53 Bytes ) gespart werden.05AB1E , 8 Bytes
Code:
Verwendet die 05AB1E- Codierung. Probieren Sie es online!
Erläuterung:
quelle
€1
ist komisch ...JavaScript, 39 Bytes
quelle
Jelly ,
10, 9 BytesProbieren Sie es online!
Auch 1 indiziert und endet ziemlich schnell.
Ein Byte gespart dank @ErikTheOutgolfer!
Erläuterung:
Nehmen wir an, die Eingabe (
a
) ist hypothetisch 3.quelle
Ḥ€ŒḄ€Ṗ€Fị@
, so können Sieµ€
für -1 (drei oder mehr Monaden mit€
am Anfang) verwenden:ḤŒḄṖµ€Fị@
ḤŒḄṖ
<newline>½ĊÇ€Fị@
für 12 sein, um die 10.000-Anforderung zu erfüllen (das Ausführen des 9-Byte-Codes vor Ort dauert auf meinem i7 etwa 2:20 und verwendet 7 GB)MATL , 15 Bytes
1-basiert.
Probieren Sie es online!
Dies ist eine Zeitüberschreitung für die größten Testfälle in TIO, die jedoch auf meinem Desktop-Computer (Compiler unter MATLAB R2017a) rechtzeitig beendet wird. Fügen Sie
Z`
am Ende des Codes hinzu, um die abgelaufene Zeit anzuzeigen .Erläuterung
Der Code generiert viel mehr Begriffe als nötig. Insbesondere werden
n
"Stücke" der Sequenz berechnet , wobei jedes Stück hoch und zurück zu 1 gezählt wird.quelle
Schale ,
1210 BytesProbieren Sie es online!
1-indiziert, arbeitet recht schnell
Erläuterung
quelle
…
Mathematica, 90 Bytes
Probieren Sie es online!
quelle
Netzhaut , 62 Bytes
Probieren Sie es online! Link enthält Testfälle. Die Eingabe ist 1-indiziert. Die erste Stufe ist nur eine Dezimalzahl zur unären Konvertierung. In der zweiten Stufe liegt die höchste Quadratzahl bei
s
genau weniger als der Hälften
;$1
ists²
, während$2
ist2s-1
. Es berechnet zwei Werte, zunächst die Anzahl der Zahlen in der aktuellen Aufwärts- / Abwärtsfahrt, die ist4(s+1) = 4s+4 = 2$2+6
, und zweitens die Position innerhalb dieses Laufes, das istn-2s² = n-(2$1+1)+1 = n-$&+1
, was nur erfordert1
für die zu machen ,1
die strenge Ungleichheit zu erzwingen verwendet. Die letzte Stufe zählt dann von dieser Position bis zum Start und zum Ende des Laufs, nimmt das niedrigere Ergebnis und konvertiert es in Dezimalzahlen.quelle
Mathematica, 67 Bytes
Probieren Sie es online!
quelle
Perl 5 , 43 + 1 (-p) = 44 Bytes
Probieren Sie es online!
Ich arbeitete an einer Formel, um das n-te Element direkt zu berechnen. Dann sah ich, dass @ fireflame241 diese Arbeit erledigt hatte, und ich spielte sie in Perl ein.
# Perl 5 , 50 + 1 (-n) = 51 BytesProbieren Sie es online!
Die Ergebnisse sind 0 indiziert.
quelle
Haskell ,
115-81BytesProbieren Sie es online!
Hier ist etwas Magisches los. Könnte wahrscheinlich kürzer sein, wenn ich einen normalen Ansatz hätte.
Erläuterung
Zuerst definieren wir
%
.%
ist eine Funktion, die zwei Variablen akzeptiertx
, undy
. Es erstellt eine Listescanl(+)y[y+1,y+3..]
und findet das erste Element dieser Liste größer alsx
.scanl(+)
Führt einfach iterative Summen durch, um die dreieckigen Zahlen zu erhalten, die wir machen würdenscanl(+)0[1..]
, um die quadratischen Zahlen zu erhalten, die wir machen würdenscanl(+)0[1,3..]
. Insbesondere die beiden Listen, die wir erstellen werden, sindscanl(+)2[3,5..]
undscanl(+)1[2,4..]
dies sind die Wendepunkte des Musters.Nun definieren wir die Hauptfunktion,
g
die einex
. Wennx
es eins ist, kehren wir zurück,1
weil das der erste Wert ist. Andernfalls überprüfen wir die nächsten beiden Wendepunkte. Wenn die Abwärtswende größer ist, geben1%x>2x
wir den Nachfolger von zurück.g$x-1
Andernfalls geben wir den Vorgänger von zurückg$x-1
.Ok, aber warum funktioniert das?
Zuallererst "Was ist mit der Art und Weise, wie wir Eckpunkte finden?". Es ist wichtig, den Abstand zwischen aufeinanderfolgenden Scheitelpunkten des gleichen Typs zu notieren. Sie werden feststellen, dass die Unterschiede jedes Mal um 2 zunehmen. Dies ist sinnvoll, da die Basis der Dreiecke jedes Mal um 2 breiter wird. Wir können mit einem Listenliteral wie diesem einen konstanten Unterschied zwischen Listen machen
[2,4..]
und verwendenscanl(+)
Listen machen und diese Listen anhand der Position des ersten Scheitelpunkts und des ersten Unterschieds in unsere Scheitelpunktlisten umwandeln.Nachdem wir nun die Möglichkeit haben, Scheitelpunkte nach oben und unten zu finden, können wir diese Informationen verwenden, um die Werte abzurufen. Wir sagen, der erste Wert ist, dass
1
wir entweder den Nachfolger oder den Vorgänger nehmen müssen. Wenn der nächste Eckpunkt aufwärts ist, möchten wir den Vorgänger übernehmen, andernfalls übernehmen wir den Nachfolger.Haskell ,
565146 BytesHier ist meine bessere Lösung mit weniger Mathematik und weniger Bytes.
Probieren Sie es online!
quelle
Pyke , 14 Bytes
Probieren Sie es hier aus!
quelle
C # (.NET Core) , 120 Byte
Erklärung: Ziemlich einfach, die erste verschachtelte Schleife steigt bis zu unserem Maximum an, die zweite steigt bis zu 2 zurück. Die Wiederholung für jedes Vielfache von 2.
Probieren Sie es online!
quelle
Ruby ,
7875 Bytes1 Byte dank Step Hen gespeichert
1 Byte gespart dank Mr. Xcoder
Probieren Sie es online!
Hoffentlich kann ich ein paar Tipps bekommen, um den bytecount weiter herunter zu ziehen. Ich habe versucht, einen einfachen Ansatz zu wählen.
quelle
c=1 if
kann golfen werdenc=1if
->n{a=0;b=2;c=1;n.times{if a==b then c=0;b+=2;end;c=1if a==1;a+=c<1?-1:1};a}
Java (OpenJDK 8) , 53 Byte
Probieren Sie es online!
-2 Bytes dank Nevay.
1-indiziert.
TL; DR Wir teilen die Sequenz in bequeme Chunks auf, finden den Chunk
n
und dann dienth
Position im Chunk.Hier können wir die Sequenz wie
[[1,2],[1,2,3,4,3,2],[1,2,3,4,5,6,5,4,3,2],...]
folgt aufteilen , wodurch wir Brockengrößen von erhalten4i-2
. Beginnend miti=2
, subtrahieren wiri
vonn
, im wesentlichen nach oben ein Stück zu einer Zeit bewegen. Sobald wir zufrieden sindn<=i
, wissen wir, dassn
jetzt die Position des korrekten Werts im aktuellen Block ist.Wir erhalten dann den Wert, indem wir ihn
n
miti
der Größe des Blocks vergleichen. Der Mittelpunkt jedes Chunks ist gleichi/2+1
; Wennn
weniger ist, kehren wir einfach zurückn
. Wennn
größer ist, kehren wir zurücki-n+2
.Beispiel
quelle
+1
,return n>i/2?i-n+2:n
reicht aus.Python 2 , 5! Bytes (120 Bytes: P)
Probieren Sie es online!
Einfach, macht die Liste und nimmt dann das eingabe'te Element
quelle
Python 3 ,
184156 BytesProbieren Sie es online!
Golf mit Python-Generator für "faule" Auswertung
quelle
QBIC , 47 Bytes
Erläuterung
quelle
Röda , 54 Bytes
Probieren Sie es online!
Rufen Sie an mit:
try f(n)
Diese Funktion gibt schnell die Antwort zurück, führt danach jedoch einige unnötige Berechnungen durch und hat möglicherweise keinen Speicher mehr.
Da die Funktion die eigentliche Antwort kurz nach dem Aufruf zurückgibt (deutlich unter einer Minute), halte ich diese Antwort für gültig.
(In Röda können Funktionen Werte zurückgeben, bevor sie aufgrund von Parallelität beendet werden.)
quelle
C # (.NET Core) ,
99 9586 BytesProbieren Sie es online!
Lambda-Funktion, die eine Ganzzahl annimmt und zurückgibt. Einzelne Schleife, die das Auf- und Abzählen übernimmt.
quelle
PHP, 65 + 1 Bytes
Laufen Sie als Pipe mit
-R
oder versuchen Sie es online (oder entfernen Sie eine der anderen Versionen).Ein Port von tshs rekursivem JavaScript benötigt 66 Bytes:
Ein Port von Arnauld´s Lösung benötigt 62 + 1:
Ein Golf-Port von Xanderhalls Java hat den bisher kürzesten Code (55 + 1 Byte):
quelle
Pyth ,
1918 BytesProbieren Sie es hier aus!
quelle