¿Qué día de Navidad es?

27

Prefacio

En el conocido villancico, Los doce días de Navidad , el narrador recibe varios regalos cada día. La canción es acumulativa : en cada verso, se agrega un nuevo regalo, con una cantidad mayor que el regalo anterior. Una perdiz, dos tórtolas, tres gallinas francesas, etc.

En cualquier verso dado, N , podemos calcular la suma acumulada de regalos hasta ahora en la canción al encontrar el número N - tetraédrico , que da los resultados:

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

Por ejemplo, después del versículo 4, hemos tenido 4 * (1 perdiz) , 3 * (2 tórtolas) , 2 * (3 gallinas francesas) y 1 * (4 pájaros voladores) . Al sumar estos, obtenemos 4(1) + 3(2) + 2(3) + 1(4) = 20.

El reto

Su tarea es escribir un programa o función que, dado un número entero positivo que representa el número de regalos 364 ≥ p ≥ 1 , determine qué día (verso) de Navidad es.

Por ejemplo, si p = 286 , estamos en el día 11 de Navidad. Sin embargo, si p = 287 , entonces la próxima carga de regalos ha comenzado, lo que significa que es el día 12.

Matemáticamente, esto es encontrar el siguiente número tetraédrico y devolver su posición en toda la secuencia de números tetraédricos.

Reglas:

  • Este es el , por lo que gana la solución más corta (en bytes).
  • Se aplican lagunas de golf estándar.
  • Cuando se trata de días, su programa debe estar indexado en 1.
  • Su envío debe ser un programa completo o una función, pero no un fragmento.

Casos de prueba

1   ->  1
5   ->  3
75  ->  7
100 ->  8
220 ->  10
221 ->  11
364 ->  12
FlipTack
fuente
55
En caso de que ayude a alguien, el enésimo número tetraédrico es también la suma de los primeros n números triangulares.
DJMcMayhem
Esto podría ayudar: x=>{while(x>p)p+=r+=++i;return i}estoy seguro de que se puede acortar en un lenguaje como JavaScript.
12Me21
1
Este es el primer desafío navideño, ¿verdad? :)
insertusernamehere

Respuestas:

7

Gelatina , 7 6 bytes

-1 byte gracias a Dennis (use mínimo vectorizado «, y primer índice, i)

R+\⁺«i

TryItOnline

¿Cómo?

No es tan eficiente: calcula los números tetraédricos del primero al noveno en orden en una lista y devuelve el índice basado en 1 del primero que es igual o mayor.

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)

Anterior 7 byters utilizando gama rebajado [0,1,2,3,...,n-1]y contando tetrahedrals menos de n:
Ḷ+\⁺<µS,
Ḷ+\⁺<ḅ1,
Ḷ+\⁺<ċ1, y
Ḷ+\⁺<¹S

Jonathan Allan
fuente
19

Python , 27 bytes

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

Pruébalo en línea!

Una fórmula directa con algunos ajustes de curva, igual que la original encontrada por Level River St.

La ecuación desplazada i**3-i==n*6es cercana a i**3==n*6grande i. Se resuelve a i=(n*6)**(1/3). Tomando el piso las rondas hacia abajo según sea necesario, compensando el off-by-one.

Pero, hay 6 entradas en los límites donde el error lo lleva debajo de un entero que debería estar arriba. Todo esto se puede solucionar aumentando ligeramente el exponente sin introducir más errores.


Python , 38 bytes

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

La fórmula n=i*(i+1)*(i+2)/6para los números tetraédricos se puede escribir mejor i+1como n*6=(i+1)**3-(i+1). Entonces, encontramos el más bajo ipara el cual i**3-i<n*6. Cada vez que incrementamos a ipartir de 1, las llamadas recursivas se suman 1a la salida. Comenzando desde i=1más que i=0compensa el cambio.

xnor
fuente
Agradable. Pensé en jugar al golf de esta manera, pero no lo hice. Sin embargo, intentaré cambiar; Nuestras respuestas seguirán siendo diferentes.
0WJYxW9FMN
1
Woah Tu nuevo es asombroso.
0WJYxW9FMN
1
La versión de 26 bytes falla para 364, que se excluye del rango de prueba. **.33359funciona para un byte extra.
Dennis
@ Dennis Gracias. ¡Las gamas exclusivas de Python atacan de nuevo!
xnor
1
lambda n:n**.3336//.5501Guarda algunos bytes.
Dennis
10

J , 12 bytes

2>.@-~3!inv]

Puede haber una forma más golfosa de hacer esto, pero esta es una hermosa oportunidad para usar la inversión de función incorporada de J.

Pruébalo en línea!

Cómo funciona

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.
Dennis
fuente
7

Jalea , 7 bytes

R‘c3<¹S

Pruébalo en línea!

Cómo funciona

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.
Dennis
fuente
2
A veces es de extrañar que, lo que puede Jelly no hacer?
Sombrero Chicken
1
Uno de estos días alguien será como "Code Golf, un MMO con todas las funciones" y Dennis publicará "Jelly, 29 bytes" o algo estúpido como ese.
corsiKa
6

JavaScript (ES6), 33 bytes

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

Basado en la fórmula recursiva:

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

La segunda expresión también se puede escribir como ...

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

... que es el que estamos usando aquí.

a(i - 1)en realidad se almacena en la kvariable y se pasa a la siguiente iteración hasta k >= n.

Casos de prueba

Arnauld
fuente
¡Esto es furtivamente corto! Buen trabajo.
FlipTack
@FlipTack Mi primer intento se basó en la fórmula que usaste. Tuve que cambiar mis planes. ;-)
Arnauld
6

Rubí, 26 bytes

Editar: versión alternativa, todavía 26 bytes

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

Versión original

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

Utiliza el hecho de que T(x) = x(x+1)(x+2)/6 = ((x+1)**3-(x+1))/6está muy cerca (x+1)**3/6.

La función simplemente se multiplica por 6, encuentra una versión ligeramente modificada de la raíz cúbica (sí, se requieren 5 decimales) y devuelve el resultado truncado a un entero.

Programa de prueba y salida

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]
Level River St
fuente
0.3336Parece funcionar para la versión original. (Editar: No importa, Dennis señala que me estaba olvidando de 364.)
xnor
5

JavaScript, 36 33 bytes

-3 bytes gracias a Luke (haciendo la función curry)

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

Esta es una función lambda sin nombre que se puede asignar funcy llamar con func(220)(), como se describe en esta meta publicación . Mi función original, no curry se ve así:

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

Esta respuesta utiliza el hecho de que el número x tetraédrico se puede encontrar con la siguiente función:

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

La presentación funciona aumentando iy encontrando recursivamente tetrahedral(i), hasta que sea mayor o igual que n(el número de regalos dados).

Cuando se llama con un argumento como se esperaba i = undefined, y, por lo tanto, no es mayor que n. Esto significa que f(n,-~i)se ejecuta y se -~undefinedevalúa como 1, lo que desencadena la recursividad.


Fragmento de prueba:

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)()));

FlipTack
fuente
Estaba a punto de publicar exactamente la misma respuesta. Me ganó por 2 minutos. ¡Buen trabajo!
Lucas
Puede guardar 3 bytes por currificación: n=>g=i=>n<=i/6*++i*++i?i-2:g(~-i). Lo llamarías así f(2)().
Lucas
@Luke buen lugar, mi función de curry no era tan corta. ¿Estás seguro de que no quieres publicar eso como tu propia respuesta?
FlipTack
No, lo haría si estuviéramos usando una fórmula diferente, pero ahora nuestras soluciones son casi idénticas. Prefiero ayudarte a estar al mismo nivel que Arnauld. ;-)
Lucas
3
i=>n<=iBeautiful ;-)
ETHproductions
3

MATL , 12 11 bytes

`G@H+IXn>}@

Pruébalo en línea!

Explicación

`       % 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)
Luis Mendo
fuente
2

05AB1E , 10 bytes

XµNÌ3c¹‹_½

Pruébalo en línea!

Explicación

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
Emigna
fuente
1
Wow, binom es mucho más inteligente que [N2Ý+P6÷¹Q#N>, agradable.
Magic Octopus Urn
2

Pyke, 11 bytes

#3RL+B6f)lt

Pruébalo aquí!

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

Mathematica, 26 bytes

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

Función sin nombre que toma un argumento entero no negativo y devuelve un entero no negativo (sí, también funciona durante el día 0). Queremos encontrar el número entero más pequeño ipara el cual la entrada #es como máximo i(i+1)(i+2)/6, que es la fórmula para la cantidad de obsequios entregados en los primeros idías. A través del engaño algebraico leve, la desigualdad # ≤ i(i+1)(i+2)/6es equivalente a (i+1) + 6# ≤ (i+1)^3. Por lo tanto, la estructura 0//.i_/;i+6#>i^3:>i+1comienza con a 0y sigue agregando 1mientras i+6#>i^3se satisfaga la prueba ; luego (...)-1&resta 1al final (en lugar de gastar bytes con paréntesis dentro de la desigualdad).

Si dejamos que continúen los 12 días de Navidad, podemos manejar unos 65536 días antes de que el límite de recursión incorporado //.detenga el proceso ... eso es aproximadamente 4.7 * 10 ^ 13 días, o aproximadamente diez veces la edad del universo hasta ahora ....

Greg Martin
fuente
2

J , 9 bytes

I.~3!2+i.

Pruébalo en línea!

Esto es más ineficiente que usar el inverso de factorial pero resulta ser más corto.

Por ejemplo, si el entero de entrada es n = 5, haga el rango [2, n+1].

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

Estos son los primeros 5 números tetraédricos. El siguiente paso es determinar a qué intervalo (día) n pertenece. Hay n +1 = 6 intervalos.

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

Entonces n = 5 pertenece al intervalo 3 que es (4, 10]y el resultado es 3.

Explicación

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
millas
fuente
2

Python, 43 bytes

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

¡ Ahorré 5 bytes gracias a @FlipTack y otros 3 gracias a @xnor !

Loovjo
fuente
Esto da f(220)=11, que debería ser f(220)=10.
xnor
Oh, estaba usando Python 2. Esto necesita Python 3 para evitar la división del piso, aunque tal vez puedas multiplicarlo en el otro lado para hacerlo independiente de la versión.
xnor
Creo que se puede hacer and-~f(n,i+1)para and f(n,i+1)or i. Curiosamente, generalmente es más corto cuando estás contando una variable recursivamente para no devolverla, sino para aumentar la salida recursivamente.
xnor
2

Japt , 12 bytes

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

¡Pruébalo en línea! o Verificar todos los casos de prueba a la vez

Cómo funciona

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

Esta es una simplificación de la fórmula tetraédrica que utilizan otras respuestas:

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

Mediante la sustitución x - 1de x, podemos simplificar esta forma considerable:

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

Por lo tanto, el resultado correcto es uno menos que el entero más pequeño, de xmodo que (x^3 - x) / 6sea ​​mayor o igual que la entrada.

Solución de 13 bytes, inspirada en la respuesta de @ xnor :

p.3335 /.55 f

Algunas soluciones más @ETHproductions y jugué con

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:ß

Pruébalo aquí .

Oliver
fuente
1

SmileBASIC, 43 bytes

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

Ies el día, Res el inúmero triangular th y Pes el inúmero tetraédrico th (número de regalos).

Creo que una respuesta similar en otro idioma, quizás: x=>{while(x>p)p+=r+=++i;return i}podría ser bastante buena.

12Me21
fuente
Quieres ?Ial final, ¿no?
Nick Matteo
1

Python 3, 48 46 bytes

f=lambda x,i=1:f(x,i+1)if(i+3)*i+2<x/i*6else i
0WJYxW9FMN
fuente
@FlipTack Argh! Lo arreglaré en un segundo ... nadie rechaza, por favor.
0WJYxW9FMN
66
Puede evitar cualquier downvoting eliminando su respuesta. Entonces aún podrá editar la respuesta y recuperarla una vez que se haya solucionado.
Laikoni
Además, esto todavía no hace lo que pide el desafío. Una entrada de 221lo bloqueará.
FlipTack
He probado esto en TIO y se bloquea en todas las entradas. ¿Es este mi problema o le está sucediendo esto a alguien más?
Funcionó para mi. Lo probaré de nuevo.
0WJYxW9FMN
1

Mathematica, 31 25 bytes

Floor@Root[x^3-x-6#+6,1]&
martín
fuente
1

Haskell, 21 23 bytes

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

Editar: como señaló xnor, la solución original ( floor.(/0.82).(**0.4)) no funcionó entre los días de navidad

Joshua David
fuente
Esto da la respuesta incorrecta en muchas entradas, por ejemplo 221.
xnor
0

Lote, 69 bytes

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

Calcula manualmente los números de tetraedro.

Neil
fuente
0

R, 19 caracteres

floor((n*6)^.33359)

basado en la respuesta de xnor en Python.

Mark Miller
fuente
0

QBIC , 19 bytes

Esto roba la fórmula de @xnor:

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

Traté de reducir la resolución a .3336 para guardar un byte, pero eso falla en el caso de prueba final.

Steenbergh
fuente
0

Bash + bc, 44 bytes

bc -l <<< "f=e(.33359*l($1*6));scale=0;f/1"
Dani_l
fuente