Vorwort
In dem bekannten Weihnachtslied The Twelve Days of Christmas werden dem Erzähler täglich mehrere Geschenke überreicht. Das Lied ist kumulativ - in jedem Vers wird ein neues Geschenk hinzugefügt, dessen Menge um eins höher ist als die des vorangegangenen Geschenks. Ein Rebhuhn, zwei Turteltauben, drei französische Hühner und so weiter.
In jedem Vers N können wir die kumulative Summe der bisher im Lied vorhandenen Geschenke berechnen, indem wir die N- te tetraedrische Zahl ermitteln , die die folgenden Ergebnisse liefert:
Verse 1: 1
Verse 2: 4
Verse 3: 10
Verse 4: 20
Verse 5: 35
Verse 6: 56
Verse 7: 84
Verse 8: 120
Verse 9: 165
Verse 10: 220
Verse 11: 286
Verse 12: 364
Zum Beispiel hatten wir nach Vers 4 4 * (1 Rebhuhn) , 3 * (2 Turteltauben) , 2 * (3 französische Hühner) und 1 * (4 rufende Vögel) . Wenn wir diese addieren, erhalten wir 4(1) + 3(2) + 2(3) + 1(4) = 20
.
Die Herausforderung
Ihre Aufgabe ist es, ein Programm oder eine Funktion zu schreiben, die bei einer positiven Ganzzahl, die die Anzahl der Geschenke 364 ≥ p ≥ 1 darstellt , bestimmt, welcher Tag (Vers) von Weihnachten es ist.
Wenn zum Beispiel p = 286 ist , sind wir am 11. Weihnachtstag. Wenn jedoch p = 287 ist , dann hat die nächste Ladung Geschenke begonnen, was bedeutet, dass es der 12. Tag ist.
Mathematisch bedeutet dies, die nächste tetraedrische Zahl zu finden und ihre Position in der gesamten Folge der tetraedrischen Zahlen zurückzugeben.
Regeln:
- Das ist Code-Golf , also gewinnt die kürzeste Lösung (in Bytes).
- Es gelten Standard-Golflöcher.
- Wenn es um Tage geht, muss Ihr Programm 1-indiziert sein.
- Ihre Einreichung muss ein vollständiges Programm oder eine Funktion sein - aber kein Ausschnitt.
Testfälle
1 -> 1
5 -> 3
75 -> 7
100 -> 8
220 -> 10
221 -> 11
364 -> 12
quelle
x=>{while(x>p)p+=r+=++i;return i}
Ich bin sicher, dass es in einer Sprache wie JavaScript kürzer gemacht werden kann.Antworten:
Gelee ,
76 Bytes-1 Byte dank Dennis (benutze vektorisiertes Minimum,,
«
und ersten Index,i
)TryItOnline
Wie?
Nicht allzu effizient - berechnet die 1. bis n-te Tetraederzahl in einer Liste und gibt den auf 1 basierenden Index der ersten Zahl zurück, der gleich oder größer ist.
Zurück 7 byters abgesenkten Bereich verwendet
[0,1,2,3,...,n-1]
und Zählen tetrahedrals weniger als n:Ḷ+\⁺<µS
,Ḷ+\⁺<ḅ1
,Ḷ+\⁺<ċ1
, undḶ+\⁺<¹S
quelle
Python , 27 Bytes
Probieren Sie es online!
Eine direkte Formel mit einer gewissen Kurvenanpassung, die der ursprünglichen von Level River St. entspricht.
Die verschobene Gleichung
i**3-i==n*6
isti**3==n*6
für große nahei
. Es löst sich aufi=(n*6)**(1/3)
. Nehmen Sie den Boden die Runden nach Bedarf herunter, um das Off-by-One zu kompensieren.Es gibt jedoch 6 Eingaben an Grenzen, bei denen der Fehler unter einer Ganzzahl liegt, über der er liegen sollte. All dies kann durch leichtes Erhöhen des Exponenten behoben werden, ohne dass weitere Fehler auftreten.
Python , 38 Bytes
Die Formel
n=i*(i+1)*(i+2)/6
für tetraedrische Zahlen kann besser geschrieben werdeni+1
alsn*6=(i+1)**3-(i+1)
. Also finden wir die niedrigsteni
für diei**3-i<n*6
. Jedes Mal, wenn wiri
ab 1 inkrementieren , werden die rekursiven Aufrufe1
zur Ausgabe hinzugefügt. Ausgehend von,i=1
anstatti=0
die Verschiebung zu kompensieren.quelle
**.33359
arbeitet für ein zusätzliches Byte.lambda n:n**.3336//.5501
spart ein paar Bytes.J , 12 Bytes
Es gibt vielleicht eine bessere Möglichkeit, dies zu tun, aber dies ist eine wunderbare Gelegenheit, die in J integrierte Funktionsumkehrung zu verwenden.
Probieren Sie es online!
Wie es funktioniert
quelle
Python , 22 Bytes
Stark inspiriert von @ xnors Python-Antwort .
Probieren Sie es online!
quelle
Gelee , 7 Bytes
Probieren Sie es online!
Wie es funktioniert
quelle
JavaScript (ES6), 33 Byte
Basierend auf der rekursiven Formel:
Der zweite Ausdruck kann auch geschrieben werden als ...
... das ist das, was wir hier verwenden.
a(i - 1)
wird tatsächlich in derk
Variablen gespeichert und an die nächste Iteration übergeben, bisk >= n
.Testfälle
Code-Snippet anzeigen
quelle
Ruby, 26 Bytes
Bearbeiten: alternative Version, noch 26 Bytes
Originalfassung
Nutzt die Tatsache, dass
T(x) = x(x+1)(x+2)/6 = ((x+1)**3-(x+1))/6
was sehr nahe ist(x+1)**3/6
.Die Funktion multipliziert einfach mit 6, findet eine leicht überarbeitete Version der Kubikwurzel (ja, es sind 5 Dezimalstellen erforderlich) und gibt das Ergebnis abgeschnitten auf eine Ganzzahl zurück.
Testprogramm und Ausgabe
quelle
0.3336
scheint für die original version zu funktionieren. (Edit:JavaScript,
3633 Bytes-3 bytes dank luke
Dies ist eine unbenannte Lambda-Funktion, die zugewiesen
func
und mit aufgerufen werden kannfunc(220)()
, wie in diesem Meta-Beitrag beschrieben . Meine ursprüngliche Funktion ohne Curry sieht folgendermaßen aus:Diese Antwort basiert auf der Tatsache, dass die x- te Tetraedernummer mit der folgenden Funktion gefunden werden kann:
Die Übermittlung funktioniert durch rekursives Erhöhen
i
und Findentetrahedral(i)
, bis sie größer oder gleich istn
(der Anzahl der gegebenen Geschenke) ist.Wird wie erwartet mit einem Argument aufgerufen
i = undefined
und ist daher nicht größer alsn
. Dies bedeutet, dassf(n,-~i)
ausgeführt und-~undefined
ausgewertet wird1
, wodurch die Rekursion ausgelöst wird.Testschnipsel:
quelle
n=>g=i=>n<=i/6*++i*++i?i-2:g(~-i)
. Du würdest es so nennenf(2)()
.i=>n<=i
Schön ;-)MATL ,
1211 BytesProbieren Sie es online!
Erläuterung
quelle
05AB1E , 10 Bytes
Probieren Sie es online!
Erläuterung
quelle
[N2Ý+P6÷¹Q#N>
, nett.Pyke, 11 Bytes
Probieren Sie es hier aus!
quelle
Mathematica, 26 Bytes
Unbenannte Funktion, die ein nichtnegatives Ganzzahlargument verwendet und eine nichtnegative Ganzzahl zurückgibt (ja, es funktioniert auch für den Tag
0
). Wir wollen die kleinste Ganzzahl finden,i
für die die Eingabe#
höchstensi(i+1)(i+2)/6
ist. Dies ist die Formel für die Anzahl der Geschenke, die an den ersteni
Tagen gegeben wurden. Durch leichte algebraische Täuschung ist die Ungleichung# ≤ i(i+1)(i+2)/6
gleichbedeutend mit(i+1) + 6# ≤ (i+1)^3
. Die Struktur0//.i_/;i+6#>i^3:>i+1
beginnt also mit a0
und fügt1
so lange hinzu, wie der Testi+6#>i^3
erfüllt ist.(...)-1&
subtrahiert dann1
am Ende (anstatt Bytes mit Klammern innerhalb der Ungleichung auszugeben).Wenn wir die 12 Tage von Weihnachten weiterlaufen lassen, können wir ungefähr 65536 Tage verarbeiten, bevor die eingebaute Rekursionsgrenze
//.
den Prozess anhält ... das sind ungefähr 4,7 * 10 ^ 13 Tage oder ungefähr das Zehnfache des bisherigen Alters des Universums ....quelle
J 9 Bytes
Probieren Sie es online!
Dies ist ineffizienter als die Inverse der Fakultät, ist aber zufällig kürzer.
Wenn die Eingabe-Ganzzahl beispielsweise n = 5 ist, legen Sie den Bereich fest
[2, n+1]
.Dies sind die ersten 5 Tetraederzahlen. Der nächste Schritt besteht darin, festzustellen, zu welchem Intervall (Tag) n gehört. Es gibt n + 1 = 6 Intervalle.
Dann gehört n = 5 zu Intervall 3
(4, 10]
und das Ergebnis ist 3.Erläuterung
quelle
Python, 43 Bytes
5 Bytes dank @FlipTack und weitere 3 dank @xnor !
quelle
f(220)=11
, was soll seinf(220)=10
.and-~f(n,i+1)
fürand f(n,i+1)or i
. Seltsamerweise ist es normalerweise kürzer, wenn Sie eine Variable rekursiv hochzählen, um sie nicht zurückzugeben, sondern die Ausgabe rekursiv zu erhöhen.Japt , 12 Bytes
Online testen! oder Überprüfen Sie alle Testfälle auf einmal
Wie es funktioniert
Dies ist eine Vereinfachung der Tetraederformel, die mehrere andere Antworten verwenden:
Durch den Ersatz
x - 1
vonx
können wir dies erheblich vereinfachen:Daher ist das richtige Ergebnis eins weniger als die kleinste Ganzzahl
x
, sodass sie(x^3 - x) / 6
größer oder gleich der Eingabe ist.13-Byte-Lösung, inspiriert von der Antwort von @ xnor :
Noch ein paar Lösungen @ETHproductions und ich haben rumgespielt
Teste es hier .
quelle
SmileBASIC, 43 Bytes
I
ist der Tag,R
ist diei
th Dreieckszahl undP
ist diei
tetraedrische Zahl (Anzahl der Geschenke).Ich denke, eine ähnliche Antwort in einer anderen Sprache
x=>{while(x>p)p+=r+=++i;return i}
könnte vielleicht ziemlich gut sein.quelle
?I
am Ende, nicht wahr?Python 3,
4846 Bytesquelle
221
wird es zum Absturz bringen.Mathematica,
3125 Bytesquelle
Haskell,
2123 BytesBearbeiten: Wie xnor betonte, funktionierte die ursprüngliche Lösung (
floor.(/0.82).(**0.4)
) zwischen den Weihnachtstagen nichtquelle
Batch, 69 Bytes
Berechnet manuell Tetraederzahlen.
quelle
Pyth 11 Bytes
Probieren Sie es online!
Dennis 'Antwort wurde so ziemlich nur in Pyth übersetzt
quelle
R, 19 Zeichen
basierend auf der Antwort von xnor in
Python
.quelle
QBIC , 19 Bytes
Dies stiehlt @xnors Formel:
Ich habe versucht, die Auflösung auf .3336 herunter zu wählen, um ein Byte zu speichern, aber das schlägt im letzten Testfall fehl.
quelle
Bash + Bc, 44 Bytes
quelle