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.