Che giorno di Natale è?


27

Prefazione

Nel noto canto natalizio , I dodici giorni di Natale , il narratore viene presentato con diversi doni ogni giorno. La canzone è cumulativa : in ogni verso viene aggiunto un nuovo regalo, con una quantità superiore a quella del regalo precedente. Una pernice, due tortore, tre galline francesi e così via.

In qualsiasi verso, N , possiamo calcolare la somma cumulativa di regali finora nella canzone trovando il N ° numero tetraedrico , che dà i risultati:

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

Ad esempio, dopo il versetto 4, abbiamo avuto 4 * (1 pernice) , 3 * (2 tortore) , 2 * (3 galline francesi) e 1 * (4 uccelli chiamanti) . Sommando questi, otteniamo 4(1) + 3(2) + 2(3) + 1(4) = 20.

La sfida

Il tuo compito è di scrivere un programma o una funzione che, dato un numero intero positivo che rappresenta il numero di regali 364 ≥ p ≥ 1 , determina quale giorno (verso) di Natale è.

Ad esempio, se p = 286 , siamo l'11 ° giorno di Natale. Tuttavia, se p = 287 , è iniziato il prossimo carico di regali, il che significa che è il 12 ° giorno.

Matematicamente, questo sta trovando il prossimo numero tetraedrico e sta riportando la sua posizione nell'intera sequenza di numeri tetraedrici.

Regole:

  • Questo è , quindi vince la soluzione più breve (in byte).
  • Si applicano scappatoie da golf standard.
  • Quando si tratta di giorni, il programma deve essere 1 indicizzato.
  • L'invio deve essere un programma completo o una funzione, ma non uno snippet.

Casi test

1   ->  1
5   ->  3
75  ->  7
100 ->  8
220 ->  10
221 ->  11
364 ->  12

5
Nel caso in cui aiuti qualcuno, l' ennesimo numero tetraedrico è anche la somma dei primi n numeri triangolari.
DJMcMayhem

Questo potrebbe aiutare: x=>{while(x>p)p+=r+=++i;return i}sono sicuro che può essere ridotto in una lingua come JavaScript.
Mee

1
Questa è la prima sfida natalizia di sempre, giusto? :)
inserireusernamehere il

Risposte:


7

Gelatina , 7 6 byte

-1 byte grazie a Dennis (utilizzare il minimo vettoriale «e il primo indice i)

R+\⁺«i

TryItOnline

Come?

Non altrettanto efficiente: calcola i numeri dal 1 ° all'ennesimo tetraedrico in ordine in un elenco e restituisce l'indice in base 1 del primo che è uguale o maggiore.

R+\⁺«i - main link: n
R      - range                          [1,2,3,4,...,n]
 +\    - cumulative reduce by addition  [1,3,6,10,...,sum([1,2,3,4,...n])] i.e. triangle numbers
   ⁺   - duplicate previous link - another cumulative reduce by addition
                                        [1,4,10,20,...,nth tetrahedral]
    «  - min(that, n)                   [1,4,10,20,...,n,n,n]
     i - first index of n (e.g. if n=12:[1,4,10,12,12,12,12,12,12,12,12,12] -> 4)

Precedente 7 byters utilizzando gamma abbassata [0,1,2,3,...,n-1]e conteggio tetrahedrals meno di n:
Ḷ+\⁺<µS,
Ḷ+\⁺<ḅ1,
Ḷ+\⁺<ċ1, e
Ḷ+\⁺<¹S


19

Python , 27 byte

lambda n:int((n*6)**.33359)

Provalo online!

Una formula diretta con un po 'di adattamento alla curva, uguale a quella originale trovata da Level River St.

L'equazione spostata i**3-i==n*6è vicina i**3==n*6per grandi i. Risolve i=(n*6)**(1/3). Prendendo il pavimento gli arrotondamenti in base alle esigenze, compensando l'off-by-one.

Ma ci sono 6 input sui limiti in cui l'errore lo porta sotto un numero intero che dovrebbe essere sopra. Tutti questi possono essere risolti aumentando leggermente l'esponente senza introdurre ulteriori errori.


Python , 38 byte

f=lambda n,i=1:i**3-i<n*6and-~f(n,i+1)

La formula n=i*(i+1)*(i+2)/6per i numeri tetraedrici può essere scritta più facilmente in i+1as n*6=(i+1)**3-(i+1). Quindi, troviamo il più basso iper il quale i**3-i<n*6. Ogni volta che incrementiamo a ipartire da 1, le chiamate ricorsive si aggiungono 1all'output. A partire i=1piuttosto che i=0compensare il turno.


Bello. Ho pensato di giocare a golf in questo modo, ma non l'ho fatto. Tuttavia, proverò a cambiare; le nostre risposte saranno ancora diverse.
0WJYxL9FMN,

1
Woah. Il tuo nuovo è fantastico.
0WJYxL9FMN,

1
La versione a 26 byte non riesce per 364, che è escluso dall'intervallo di test. **.33359funziona per un byte aggiuntivo.
Dennis,

@Dennis Grazie. Le gamme esclusive Python colpiscono ancora!
xnor

1
lambda n:n**.3336//.5501salva qualche byte.
Dennis,

10

J , 12 byte

2>.@-~3!inv]

Potrebbe esserci un modo più golfoso per farlo, ma questa è una bella opportunità per usare l'inversione della funzione integrata di J.

Provalo online!

Come funziona

2>.@-~3!inv]  Monadic verb. Argument: n

           ]  Right argument; yield n.
      3       Yield 3.
       !inv   Apply the inverse of the ! verb to n and 3. This yields a real number.
              x!y computes Π(y)/(Π(y-x)Π(x)), where Π is the extnsion of the 
              factorial function to the real numbers. When x and y are non-negative
              integers, this equals yCx, the x-combinations of a set of order y.
 >.@-~        Combine the ceil verb (>.) atop (@) the subtraction verb (-) with
              swapped arguments (~).
2             Call it the combined verbs on the previous result and 2.


7

Gelatina , 7 byte

R‘c3<¹S

Provalo online!

Come funziona

R‘c3<¹S  Main link. Argument: n

R        Range; yield [1, ..., n].
 ‘       Increment; yield [2, ..., n+1].
  c3     Combinations; yield [C(2,3), ..., C(n+1,3)].
    <¹   Yield [C(2,3) < n, ..., C(n+1,3) < n].
      S  Sum; count the non-negative values of k for which C(k+2,3) < n.

2
A volte mi chiedo, che cosa può Jelly non fare?
Sombrero Chicken,

1
Uno di questi giorni qualcuno sarà come "Code Golf un MMO completo" e Dennis pubblicherà "Jelly, 29 byte" o qualcosa di stupido come quello.
corsiKa

6

JavaScript (ES6), 33 byte

n=>(F=k=>k<n?F(k+3*k/i++):i)(i=1)

Basato sulla formula ricorsiva:

a(1) = 1
a(i) = (i + 3) * a(i - 1) / i

La seconda espressione può anche essere scritta come ...

a(i) = a(i - 1) + 3 * a(i - 1) / i

... che è quello che stiamo usando qui.

a(i - 1)viene effettivamente memorizzato nella kvariabile e passato alla successiva iterazione fino a k >= n.

Casi test


Questo è subdolo! Buon lavoro.
FlipTack

@FlipTack Il mio primo tentativo si basava sulla formula che hai usato. Ho dovuto cambiare i miei piani. ;-)
Arnauld il

6

Rubino, 26 byte

Modifica: versione alternativa, ancora 26 byte

->n{(n**0.3333*1.82).to_i}

Versione originale

->n{((n*6)**0.33355).to_i}

Usa il fatto che T(x) = x(x+1)(x+2)/6 = ((x+1)**3-(x+1))/6è molto vicino (x+1)**3/6.

La funzione si moltiplica semplicemente per 6, trova una versione leggermente ottimizzata della radice del cubo (sono necessarie 5 cifre decimali) e restituisce il risultato troncato a un numero intero.

Programma di test e output

f=->n{((n*6)**0.33355).to_i}
[1,4,10,20,35,56,84,120,165,220,286,364].map{|i|p [i,f[i],f[i+1]]}

[1, 1, 2]
[4, 2, 3]
[10, 3, 4]
[20, 4, 5]
[35, 5, 6]
[56, 6, 7]
[84, 7, 8]
[120, 8, 9]
[165, 9, 10]
[220, 10, 11]
[286, 11, 12]
[364, 12, 13]

0.3336sembra funzionare per la versione originale. (Modifica: non importa, Dennis sottolinea che stavo dimenticando il 364.)
xnor

5

JavaScript, 36 33 byte

-3 byte grazie a Luke (rendendo la funzione al curry)

n=>f=i=>n<=i/6*-~i*(i+2)?i:f(-~i)

Questa è una funzione lambda senza nome che può essere assegnata funce chiamata con func(220)(), come descritto in questo meta post . La mia funzione originale e non curry è simile alla seguente:

f=(n,i)=>n<=-~i*i/6*(i+2)?i:f(n,-~i)

Questa risposta usa il fatto che x il numero tetraedrico può essere trovato con la seguente funzione:

f (x) = x / 6 (x + 1) (x + 2)

L'invio funziona aumentando in modo ricorsivo ie trovando tetrahedral(i), fino a quando non è maggiore o uguale a n(il numero di regali dati).

Quando viene chiamato con un argomento come previsto i = undefined, e quindi non è maggiore di n. Questo significa che f(n,-~i)viene eseguito e -~undefinedvalutato a 1, che avvia la ricorsione.


Snippet di prova:

func = n=>f=i=>n<=i/6*-~i*(i+2)?i:f(-~i)

var tests = [1, 5, 75, 100, 220, 221, 364];
tests.forEach(n => console.log(n + ' => ' + func(n)()));


Stavo per pubblicare la stessa identica risposta. Battimi di 2 minuti. Buon lavoro!
Luca

È possibile salvare 3 byte per accattivarsi: n=>g=i=>n<=i/6*++i*++i?i-2:g(~-i). Lo chiameresti come f(2)().
Luca

@Luke buon posto, la mia funzione al curry non era così breve. Sei sicuro di non voler pubblicarlo come risposta personale?
FlipTack

No, lo farei se usassimo una formula diversa, ma ora le nostre soluzioni sono quasi identiche. Preferirei aiutarti ad arrivare allo stesso livello di Arnauld. ;-)
Luca

3
i=>n<=iBello ;-)
ETHproductions

3

MATL , 12 11 byte

`G@H+IXn>}@

Provalo online!

Spiegazione

`       % Do...while
  G     %   Push input, n
  @     %   Push iteration index (1-based), say m
  H     %   Push 2
  +     %   Add
  I     %   Push 3
  Xn    %   Binomial coefficient with inputs m+2, 3
  >     %   Is n greater than the binomial coefficient? If so: next iteration
}       %   Finally (execute after last iteration, before exiting the loop)
  @     %   Push last iteration index. This is the desired result
        % End (implicit)
        % Display (implicit)

2

05AB1E , 10 byte

XµNÌ3c¹‹_½

Provalo online!

Spiegazione

Xµ          # loop until counter equals 1
  NÌ3c      # binomial_coefficient(iteration_index+2,3)
      ¹     # push input
       ‹_   # not less than
         ½  # if true, increment counter
            # output last iteration index

1
Caspita, Binom è molto più intelligente di quello [N2Ý+P6÷¹Q#N>bello.
Magic Octopus Urn

2

Pyke, 11 byte

#3RL+B6f)lt

Provalo qui!

#3RL+B6f)   -  while rtn <= input as i:
 3RL+       -     i+j for j in range(3)
     B      -    product(^)
      6f    -   ^/6
         lt - len(^)-1

2

Mathematica, 26 byte

(0//.i_/;i+6#>i^3:>i+1)-1&

Funzione senza nome che accetta un argomento intero non negativo e restituisce un numero intero non negativo (sì, funziona anche per il giorno 0). Vogliamo trovare il numero intero più piccolo iper cui l'input #è al massimo i(i+1)(i+2)/6, che è la formula per il numero di regali offerti nei primi igiorni. Attraverso un leggero inganno algebrico, la disuguaglianza # ≤ i(i+1)(i+2)/6è equivalente (i+1) + 6# ≤ (i+1)^3. Quindi la struttura 0//.i_/;i+6#>i^3:>i+1inizia con una 0e continua ad aggiungere 1fino a quando il test i+6#>i^3è soddisfatto; quindi (...)-1&sottrae 1alla fine (anziché spendere byte con parentesi all'interno della disuguaglianza).

Se lasciamo che i 12 giorni di Natale continuino, possiamo gestire circa 65536 giorni prima del limite di ricorsione incorporato per //.interrompere il processo ... sono circa 4,7 * 10 ^ 13 giorni, o circa dieci volte l'età dell'universo finora ....


2

J , 9 byte

I.~3!2+i.

Provalo online!

Questo è più inefficiente rispetto all'uso dell'inverso del fattoriale, ma sembra essere più breve.

Ad esempio, se il numero intero di input è n = 5, crea l'intervallo [2, n+1].

2 3 4 5 6 choose 3
0 1 4 10 20

Questi sono i primi 5 numeri tetraedrici. Il prossimo passo è determinare a quale intervallo (giorno) n appartiene. Ci sono n +1 = 6 intervalli.

0 (-∞, 0]
1 (0, 1]
2 (1, 4]
3 (4, 10]
4 (10, 20]
5 (20, ∞)

Quindi n = 5 appartiene all'intervallo 3 che è (4, 10]e il risultato è 3.

Spiegazione

I.~3!2+i.  Input: integer n
       i.  Range [0, n)
     2+    Add 2 to each
   3!      Combinations nCr with r = 3
I.~        Interval index of n

2

Python, 43 byte

f=lambda n,i=0:n*6>-~i*i*(i+2)and-~f(n,i+1)

5 byte salvati grazie a @FlipTack e altri 3 grazie a @xnor !


Questo dà f(220)=11, che dovrebbe essere f(220)=10.
xnor

Oh, stavo usando Python 2. Questo ha bisogno di Python 3 per evitare la divisione dei piani, anche se forse puoi moltiplicare dall'altra parte invece di renderlo indipendente dalla versione.
xnor

Penso che tu possa fare and-~f(n,i+1)per and f(n,i+1)or i. Stranamente, di solito è più breve quando si conteggia ricorsivamente una variabile non per restituirla, ma per incrementare l'output in modo ricorsivo.
xnor

2

Japt , 12 byte

1n@*6§X³-X}a

Provalo online! oppure Verifica tutti i casi di test contemporaneamente

Come funziona

1n@*6§X³-X}a  // Implicit: U = input integer
  @       }a  // Find the smallest non-negative integer X which satisfies this condition:
      X³-X    //   (X ^ 3) - X
     §        //   is greater than or equal to
   *6         //   U * 6.
1n            // Subtract 1 from the result.
              // Implicit: output result of last expression

Questa è una semplificazione della formula tetraedrica che molte altre risposte stanno usando:

f(x) = (x)(x + 1)(x + 2)/6

Sostituendo x - 1per x, siamo in grado di semplificare questo considerevole:

f(x) = (x - 1)(x)(x + 1) / 6
f(x) = (x - 1)(x + 1)(x) / 6
f(x) = (x^2 - 1)(x) / 6
f(x) = (x^3 - x) / 6

Pertanto, il risultato corretto è uno in meno dell'intero più piccolo in xmodo che (x^3 - x) / 6sia maggiore o uguale all'input.

Soluzione a 13 byte, ispirata alla risposta di @ xnor :

p.3335 /.55 f

Qualche altra soluzione @ETHproductions e con cui ho giocato

J+@*6§X³-X}a 
@*6§X³-X}a -1
@§X/6*°X*°X}a 
_³-V /6¨U}a -1
§(°V nV³ /6?´V:ß
§(°VV³-V /6?´V:ß

Provalo qui .


1

SmileBASIC, 43 byte

INPUT X
WHILE X>P
I=I+1
R=R+I
P=P+R
WEND?I

Iè il giorno, Rè il inumero triangolare ed Pè il inumero tetraedrico (numero di regali).

Penso che una risposta simile in un'altra lingua, forse: x=>{while(x>p)p+=r+=++i;return i}potrebbe essere abbastanza buona.


Vuoi ?Ialla fine, vero?
Nick Matteo,

1

Python 3, 48 46 byte

f=lambda x,i=1:f(x,i+1)if(i+3)*i+2<x/i*6else i

@FlipTack Argh! Lo aggiusterò tra un secondo ... nessuno ha un voto negativo, per favore.
0WJYxL9FMN,

6
Puoi evitare qualsiasi downvoting eliminando la tua risposta. Sarai comunque in grado di modificare la risposta e di annullarla una volta che è stata risolta.
Laikoni,

Inoltre, questo non fa ancora ciò che la sfida richiede. Un input di 221lo arresterà in modo anomalo.
FlipTack

Ho provato questo su TIO e si blocca su tutti gli input. È questo il mio problema o sta succedendo a qualcun altro?

Ha funzionato per me. Lo proverò di nuovo.
0WJYxL9FMN,


1

Haskell, 21 23 byte

floor.(**(1/3)).(*6.03)

Modifica: Come ha sottolineato xnor, la soluzione originale ( floor.(/0.82).(**0.4)) non ha funzionato tra i giorni di Natale


Questo dà la risposta sbagliata su molti input, ad esempio 221.
xnor

0

Lotto, 69 byte

@set/an=d=t=0
:l
@set/at+=d+=n+=1
@if %t% lss %1 goto l
@echo %n%

Calcola manualmente i numeri tetraedronici.



0

R, 19 caratteri

floor((n*6)^.33359)

basato sulla risposta di xnor in Python.


0

QBIC , 19 byte

Questo ruba la formula di @xnor:

:?int((a*6)^.33359)

Ho provato a comporre la risoluzione a .3336 per salvare un byte, ma questo non riesce sul testcase finale.


0

Bash + bc, 44 byte

bc -l <<< "f=e(.33359*l($1*6));scale=0;f/1"
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.