Dada una secuencia de enteros, encuentre la suma más grande de una subsecuencia (enteros en posiciones consecutivas) de la secuencia. La subsecuencia puede estar vacía (en cuyo caso la suma es 0).
La entrada se lee desde la entrada estándar, un número entero por línea. La suma más grande debe escribirse en la salida estándar.
Escribí un pequeño generador para ti:
#include <stdio.h>
#include <assert.h>
/* From http://en.wikipedia.org/wiki/Random_number_generation */
unsigned m_w;
unsigned m_z;
unsigned get_random()
{
m_z = 36969 * (m_z & 65535) + (m_z >> 16);
m_w = 18000 * (m_w & 65535) + (m_w >> 16);
return (m_z << 16) + m_w; /* 32-bit result */
}
int main(int argc, char **argv)
{
int i;
assert(argc == 3);
m_w = atoi(argv[1]);
m_z = atoi(argv[2]);
i = 10;
while (i--);
get_random();
i = atoi(argv[2]);
while (i--)
printf("%d\n", (int) get_random() << 8 >> 22);
return 0;
}
Ejemplos:
$ printf "1\n2\n-1\n4\n" | ./sum
6
$ printf "0\n-2\n-3\n" | ./sum
0
$ ./a.out 1 1 | ./sum
387
$ ./a.out 1 10 | ./sum
571
$ ./a.out 1 100 | ./sum
5867
$ ./a.out 1 1000 | ./sum
7531
$ ./a.out 1 10000 | ./sum
27268
$ ./a.out 1 100000 | ./sum
101332
$ ./a.out 1 1000000 | ./sum
187480
$ ./a.out 1 10000000 | ./sum
666307
./sum
es mi solucion./a.out
es el generador
Su solución debe ejecutarse en un tiempo razonable para todas las pruebas anteriores (la mía se ejecuta en 1.2s en el último caso de prueba).
El código más corto gana.
Editar : proporcione un ejemplo ejecutado en una de las pruebas anteriores.
code-golf
subsequence
Alexandru
fuente
fuente
#include <stdlib.h>
paraatoi()
.while (i--);
no debería terminar en punto y coma, ¿verdad?Respuestas:
Ruby, 53 caracteres
Toma aproximadamente 28 segundos para el último caso de prueba aquí.
fuente
Python,
918464 caracteresToma alrededor de
141272 segundos en el último caso de prueba. Editar: utilizando el algoritmo Paul R encontrado. Editar: rechazó la importación, usandoinput()
.fuente
C, 100 caracteres
Tiempo de ejecución = 1.14 s para el caso de prueba final (10000000) en 2.67 GHz Core i7 con ICC 11.1 (anteriormente: 1.44 s con gcc 4.2.1).
Nota: El algoritmo utilizado para la solución anterior proviene de Programming Pearls de Jon Bentley. Aparentemente, este algoritmo se conoce como Algoritmo de Kadane .
fuente
Haskell (
8864)Implementando el algoritmo de Kadane.
fuente
Python - 114 caracteres
Seguramente no es tan rápido como se requiere, pero funciona bien.
fuente
Python, usando programación dinámica - 92 caracteres
fuente
J (
3433 caracteres)Esta solución implementa una variante del algoritmo de Kadane y es razonablemente rápida.
Aquí hay una explicación:
u/ y
- El verbou
insertado entre elementos dey
. Por ejemplo,+/ 1 2 3 4
es como1 + 2 + 3 + 4
. Observe que todos los verbos en J están asociados a la derecha, es decir,-/ 1 2 3 4
es como1 - (2 - (3 - 4))
y calcula la suma alterna de1 2 3 4
.x >. y
- el máximo dex
yy
.x ([ >. +) y
- El máximo dex
yx + y
.[ >. +
es un verbo en notación tácita y se evalúa igual quex >. x + y
.([ >. +)/ y
- el prefijo no vacío dey
con la suma más grande.u\. y
-u
aplicado a todos los sufijos dey
. Observe que el código especial maneja el caso común deu/\. y
tal manera que esto se ejecuta en tiempo lineal en lugar de cuadrático.([ >. +)/\. y
- Un vector que denota el subconjunto no vacío más grande que comienza en cada posición dey
.0 , ([ >. +)/\. y
-0
preprendado al resultado anterior como0
es la longitud de un subconjunto vacío dey
.>./ 0 , ([ >. +)/\. y
- El subconjunto más grande dey
.0 ". ];._2 (1!:1) 3
- Entrada estándar convertida en un vector de números.>./ 0 , ([ >. +)/\. 0 ". ];._2 (1!:1) 3
- El subconjunto más grande en entrada estándar.fuente
Ruby, 68 caracteres
También un poco lento, pero completa las pruebas 1-10000000 en poco más de medio minuto, la mayor parte del tiempo empleado en la última prueba ...
Versión sangrada:
fuente
C ++, 192 caracteres
Funciona razonablemente rápido en mi computadora portátil (4 segundos para la última prueba).
fuente
cstdlib
nostdlib.h
Código awk (66) , muy lento, más de 8 segundos para el último caso de prueba
fuente