Sumas de enteros consecutivos


27

Antes de que nadie diga nada, similar y similar . Pero esto no es un engaño.


Algunos enteros positivos se pueden escribir como la suma de al menos dos enteros positivos consecutivos. Por ejemplo, 9=2+3+4=4+5. Escriba una función que tome un entero positivo como entrada e imprima como salida la secuencia más larga de enteros positivos consecutivos crecientes que suman (cualquier formato es aceptable, aunque -5 bytes si la salida es la secuencia creciente separada por +como se muestra arriba Si no existe tal secuencia, se debe imprimir el número mismo.

Este es el código de golf. Aplican reglas estándar. El código más corto en bytes gana.


Muestras (tenga en cuenta que el formato varía)

Input:   9
Output:  2,3,4

Input:   8
Output:  8

Input:   25
Output:  [3,4,5,6,7]

2
¿Los números generados tienen que estar en un orden específico (como aumentar)?
xnor

2
¿Los números tienen que ser> 0: 6 = 0 + 1 + 2 + 3 o 6 = 1 + 2 + 3
Damien

55
Como nota al margen, si hay desafíos estrechamente relacionados, decir "esto no es un engaño" hará poco para convencer a la gente de eso si creen que es un engaño. Sería más útil si explicara por qué cree que no lo es.
Martin Ender

1
@Damien "positivo" normalmente significa> 0. Si se incluyera 0, se llamaría "no negativo".
Martin Ender

3
cc @Vixen ^ (también si se permitieran números negativos, la solución óptima siempre sería el rango de -n+1a n)
Martin Ender

Respuestas:


11

Python, 67 bytes

f=lambda n,R=[1]:n-sum(R)and f(n,[R+[R[-1]+1],R[1:]][sum(R)>n])or R

Una estrategia extrañamente sencilla: busca el intervalo R con la suma correcta.

  • Si la suma es demasiado pequeña, cambie el punto final derecho del intervalo hacia arriba agregando el siguiente número más alto.
  • Si la suma es demasiado grande, desplace hacia arriba el punto final izquierdo eliminando el elemento más pequeño
  • Si la suma es correcta, salida R.

Como el extremo inferior del intervalo solo aumenta, se encuentran intervalos más largos antes que los más cortos.


Curiosamente eficiente también. La pila de recursión finalmente se desborda, por ejemplo n = 8192.
primo

7

Pyth, 12 10 bytes

j\+hfqsTQ}M^SQ2

El código tiene 15 bytes de longitud y califica para la bonificación de -5 bytes . Pruébelo en línea en el compilador Pyth .

¡Gracias a @Jakube por jugar golf en 2 bytes!

Cómo funciona

j\+hfqsTQ}M^SQ2    (implicit) Store evaluated input in Q.

            S      Compute [1, ..., Q].
           ^  2    Get all pairs of elements of [1, ..., Q].
         }M        Reduce each pair by inclusive range. Maps [a, b] to [a, ..., b].
    f              Filter; for each pair T:
      sT             Add the integers in T.
     q  Q            Check if the sum equals Q.
                   Keep the pair if it does.
   h               Retrieve the first match.
                   Since the ranges [a, ..., b] are sorted by the value of a,
                   the first will be the longest, in ascending order.
j\+                Join, using '+' as separator.

1
Para aquellos de nosotros que no estamos iluminados en el área de Pyth, ¿podrían agregar una explicación por favor? :)
ETHproductions

He editado mi respuesta.
Dennis

¡Genial gracias! Me gusta tu tecnica
ETHproductions

1
Entrada 1000: 30 minutos y contando ...
primo

3

Mathematica, 73 68 65 56 43 bytes

Cases[Range~Array~{#,#},i_/;Tr@i==#,{2},1]&

1
+1 Anoche terminé con una solución similar, pero mi internet se cayó. También puedes hacer Tuplesuna expresión infija.
LegionMammal978

3

Haskell, 49 48 bytes

f n=[[a..b]|a<-[1..n],b<-[a..n],sum[a..b]==n]!!0

1
1 byte para guardar: use en [...]!!0lugar de head[...].
nimi

2

MATLAB, 87 79 bytes

Sé que ya hay una respuesta MATLAB, pero esta es significativamente diferente en el enfoque.

x=input('');m=1:x;n=.5-m/2+x./m;l=max(find(~mod(n(n>0),1)));disp(m(1:l)+n(l)-1)

Esto también funciona en Octave . Puedes probar en línea aquí . Ya he agregado el código consecutiveSum.men el espacio de trabajo vinculado, así que solo ingrese consecutiveSumen el símbolo del sistema, luego ingrese el valor (por ejemplo, 25).

Todavía estoy trabajando para reducirlo (quizás ajustando un poco la ecuación utilizada), pero básicamente encuentra el valor más grande npara el cual mes un número entero, luego muestra los primeros mnúmeros que comienzan con n.

Entonces, ¿por qué funciona esto? Bueno, básicamente hay una ecuación matemática que rige todos esos números. Si considera que todos son consecutivos y comienzan desde algún punto, básicamente puede decir:

n+(n+1)+(n+2)+(n+3)+...+(n+p)=x

Ahora, a partir de esto, se hace evidente que la secuencia es básicamente solo los primeros pnúmeros de triángulo (incluido el 0 '), sumados a p+1muchos n. Ahora si dejamos m=p+1, podemos decir:

m*(n+(m-1)/2)==x

Esto es realmente bastante solucionable. Todavía estoy buscando la forma más breve de hacerlo, tengo algunas ideas para tratar de reducir el código anterior.


Para una entrada de 25, la salida sería:

3     4     5     6     7

2
Con respecto a su punto sobre los números de triángulo, este desafío es esencialmente tratar de encontrar números triangulares con una diferencia positiva de la entrada de modo que 1,3,6,10,...se maximicen los índices de los números triangulares en la secuencia .
Arcturus

1

Python 2, 94 bytes

n=input()
r=int((2*n)**.5)
while r:
 if~r%2*r/2==n%r:print range(n/r-~-r/2,n/r-~r/2);r=1
 r-=1

La entrada se toma de stdin. Esta solución es adecuada para entradas muy grandes.

Esto itera sobre las posibles longitudes de solución, r , que tiene r ≤ √ (2n) , y busca una solución explícitamente. Para que exista una solución, si r es impar, n mod r debe ser cero, y si r es par, n mod r debe ser r / 2 .


Uso de muestra

$ echo 8192 | python sum-con-int.py
[8192]

$ echo 1000002 | python sum-con-int.py
[83328, 83329, 83330, 83331, 83332, 83333, 83334, 83335, 83336, 83337, 83338, 83339]

$ echo 1000000006 | python sum-con-int.py
[250000000, 250000001, 250000002, 250000003]

He elegido deliberadamente ejemplos con resultados relativamente pequeños.


1

Octava, 89 bytes

Esto es lo mejor que pude hacer en Octave. El algoritmo es el mismo que el de xnor.

x=input('');k=i=1;while x;s=sum(k:i);if s<x;i++;elseif s>x;k++;else;x=0;end;end;disp(k:1)

En MATLAB esto sería 95 bytes:

x=input('');k=1;i=1;while x;s=sum(k:i);if s<x;i=i+1;elseif s>x;k=k+1;else x=0;end;end;disp(k:i)

En MATLAB esto se ejecuta en aproximadamente 0.1 segundos para la entrada 2000000y 1 segundo para la entrada 1000002.


1

awk, 51 bytes

{while($0!=s+=s<$0?++j:-++i);while(++i-j)r=r i"+"}$0=r j

El código es de 56 bytes, menos 5 bytes para el formato de salida. Tuve que usar 4 bytes adicionales para producir ese formato, así que en realidad guardé 1 byte. ¡Hurra! ;)

En realidad, está haciendo el trabajo duro de resumir comenzando desde 1 hasta que la suma sea mayor que la entrada. Luego comienza a restar números a partir de 1 hasta que el número sea más pequeño que la entrada. Sigue cambiando el número inicial y final de esta manera hasta que encuentra un resultado, que luego imprime.

Ejemplo de uso

echo 303 | awk '{while($0!=s+=s<$0?++j:-++i);while(++i-j)r=r i"+"}$0=r j'

Salida de ejemplo

48 + 49 + 50 + 51 + 52 + 53

He intentado esto para una entrada de 1e12y dio el resultado correcto ( 464562+...+1488562) casi de inmediato. Aunque tomó un tiempo imprimirlo, por supuesto ...


Me encanta el enfoque Awk. Tengo problemas para determinar el orden de precedencia en los enlaces. ¿Le importaría incluir una versión con más paréntesis para que sea un poco más obvio? :)
Comodín

1
Espero que esto ayude: {while($0!=s)s+=(s<$0) ? (++j) : -(++i); while(++i<j)r=r i"+"}$0=r j i siempre es el último entero que se resta del comienzo de la cadena, j es siempre el último entero agregado al final de la cadena
Cabbie407

0

Japt , 33 bytes

Utiliza la técnica Pyth de Dennis , aunque es considerablemente más larga ...

1oU à2 £W=Xg o1+Xg1¹x ¥U©W} rª ªU

Pruébalo en línea! Advertencia: para entradas más grandes (<= 20), toma un tiempo terminar y congela su navegador hasta que lo haga.

Sin golfos y explicación

1oU à2 £    W=Xg o1+Xg1¹ x ¥ U© W} rª  ª U
1oU à2 mXYZ{W=Xg o1+Xg1) x ==U&&W} r|| ||U

          // Implicit: U = input integer
1oU à2    // Generate a range from 1 to U, and take all combinations of length 2.
mXYZ{     // Map each item X in this range to:
W=Xg o    //  Set variable W to the range of integers starting at the first item in X,
1+Xg1)    //  and ending at 1 + the second item in X.
x ==U&&W  //  If the sum of this range equals U, return W; otherwise, return false.
r||       // Reduce the result with the || operator, returning the first non-false value.
||U       // If this is still false, there are no consecutive ranges that sum to U,
          // so resort to U itself.
          // Implicit: output last expression

Versión de bonificación: (38 bytes - 5 = 33)

1oU à2 £W=Xg o1+Xg1¹x ¥U©W} rª ªU² q'+

0

Julia, 92 bytes

x->(t=filter(i->all(j->j==1,diff(sort(i))),partitions(x));collect(t)[indmax(map(length,t))])

Esta es una función anónima que acepta un número entero y devuelve una matriz. Para llamarlo, dale un nombre, por ejemplo f=x->....

Sin golf:

function f(x::Integer)
    # Get all arrays of integers that sum to x
    p = partitions(x)

    # Filter these down to only consecutive runs by checking whether
    # all differences are 1
    t = filter(i -> all(j -> j == 1, diff(sort(i))), p)

    # Find the index of the longest element of t
    i = indmax(map(length, t))

    return collect(t)[i]
end

0

Ruby, 94 bytes

->n{([*1..n].permutation(2).map{|i,j|[*i..j]if(i..j).reduce(:+)==n}-[p]).max_by{|k|k.size}||n}

Sin golf:

-> n {
  ([*1..n].permutation(2).map { |i,j|   # Finds all the possible sets of size 2
     [*i..j] if(i..j).reduce(:+) == n   # Adds a set to an array if sum of the set is n.
   }-[p]                                # Removes nil from the array
  ).max_by { |k|                        # Finds the longest sequence
    k.size
  } || n                                # Returns n if no sequence found.
}

Uso:

->n{([*1..n].permutation(2).map{|i,j|[*i..j]if(i..j).reduce(:+)==n}-[p]).max_by{|k|k.size}||n}[25]
=> [3, 4, 5, 6, 7]

0

En serio, 53 - 5 = 48 bytes

,;;;╝`;u@n╟(D;)`n(XXk`iu@u@x;Σ╛=[])Ii`╗`ñ╜M`M;░p@X'+j

Hex Dump

2c3b3b3bbc603b75406ec728443b29606e2858586b60697540754
0783be4be3d5b5d29496960bb60a4bd4d604d3bb0704058272b6a

¡Pruébelo en línea!

Es el enfoque de la fuerza bruta, similar al Pyth de Dennis.

Todo hasta el ksolo lee la entrada nen el registro 1 y luego crea la lista [[1],[2,2],[3,3,3],[4,4,4,4],...]hasta n n's.

El siguiente bit hasta es una función almacenada en el registro 0 que toma un par, incrementa ambos elementos, los convierte en un rango, encuentra la suma del rango y verifica si esa suma es el valor en el registro 1. Si es así, devuelve el rango correspondiente y, si no lo es, devuelve una lista vacía.

La parte hasta la última aparición de Masigna una función sobre la lista elegante de listas descritas anteriormente, haciendo enumerateen cada lista, luego asignando la función almacenada sobre ella. Cuando está hecho, tenemos una lista de listas, cada una de las cuales está vacía o un rango que suma n.

;░elimina las listas vacías. p@Xtoma la primera lista que queda ( 0@Etambién funcionaría). '+jpone +entre cada número mientras convierte la lista en una cadena para el bono.


0

ES6, 72 bytes

n=>{for(l=u=1;n;)n>0?n-=u++:n+=l++;return[...Array(u).keys()].slice(l);}

Puerto directo de la solución awk de @ Cabbie407, pero sin el bono de formato, ya que es una penalización aquí.


0

Pitón 3, 239 236 215 203 bytes

Esto es un poco engorroso. Tendré que jugar golf más tarde.

def x(n):
 r=[n]
 for i in range(2,n):
  t=[]
  if i%2*(n%i<1):t=[j+n//i-i//2for j in range(i)]
  elif i%2<1and n%i==i//2:t=[j+n//i-i//2+1for j in range(i)]
  if t[:1]>[0]*(sum(t)==n):r+=t,
 return r[-1]

La krazón es que si revisas t[0]un vacío t, Python te hace ruidos groseros. Nuevamente, esto necesita golf. Gracias a t[:1], no más ruidos groseros! Solo necesita verificar con otra matriz.


0

Gelatina , 8 bytes (no competitiva)

ẆS⁼¥Ðf⁸Ṫ

Pruébalo en línea!

Si entiendo correctamente, esta podría ser una versión (11-5 = 6) bytes:

ẆS⁼¥Ðf⁸Ṫj”+

En aras del interés, hay 12 soluciones similares (incluida esta) intercambiando los iguales que no se vectorizan por los iguales de vectorización, cambiando el argumento izquierdo por el primer argumento o la identidad, e intercambiando iguales por no iguales y filtro por filtrado para vectorización y no vectorización. : O
HyperNeutrino

Digamos que publiqué el que tiene más sentido, pero con optimización de velocidad.
Erik the Outgolfer

0

05AB1E , 11 - 5 = 6 bytes (no competitivos)

Tomando esa bonificación, por supuesto :)

LŒʒOQ}é¤'+ý

Pruébalo en línea!

LŒʒOQ}é¤'+ý  Argument: n
LŒ           Sublists of range 1 to n
  ʒOQ}       Filter by total sum equals n
      é¤     Get longest element
        '+ý  Join on '+'

0

PHP, 70 bytes

while(fmod($q=sqrt(2*$argn+(++$p-.5)**2)-.5,1));print_r(range($p,$q));

Ejecutar como tubería con -nRo probarlo en línea .

incrementa phasta encontrar una solución entera para argument==(p+q)*(q-p+1)/2,
luego imprime el rango de pa q.


0

Excel VBA, 119-5 = 114 bytes

Subrutina que toma la entrada ndel tipo entero esperado y genera la secuencia más larga de números consecutivos que se suman a la celda[A1]

Sub a(n)
For i=1To n
s=0
For j=i To n
s=s+j
If s=n Then:For k=i To j-1:r=r &k &"+":Next:[A1]=r &j:End
Next
Next
End Sub
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.