Cobol Foro

Cobol Foro (https://www.cobolforo.es/index.php)
-   COBOL - General (https://www.cobolforo.es/forumdisplay.php?f=44)
-   -   [Sintaxis] sumar numeros de una lista (https://www.cobolforo.es/showthread.php?t=1155)

Breew 31 de mayo de 2020 22:17

sumar numeros de una lista
 
Hola.

Como conseguiriais averiguar en un listado de numeros, que combinacion de numeros suman un valor determinado.

Por ejemplo, si tengo un listado con 30 numeros, que combinaciones de numeros suman un total de 986.

Gracias

Joseg 1 de junio de 2020 12:06

Cita:

Citación del post de Breew (Mensaje 5765)
Hola.

Como conseguiriais averiguar en un listado de numeros, que combinacion de numeros suman un valor determinado.

Por ejemplo, si tengo un listado con 30 numeros, que combinaciones de numeros suman un total de 986.

Gracias

Analise este código:
https://craftofcoding.wordpress.com/...-and-an-array/

Usar índices poderá ajudar:

Código COBOL:
  1. 01 myvar occurs 30 times INDEXED by myindex.
  2.     05 munumer  pic 999.

JCantero 1 de junio de 2020 15:28

Cita:

Citación del post de Breew (Mensaje 5765)
Hola.

Como conseguiriais averiguar en un listado de numeros, que combinacion de numeros suman un valor determinado.

Por ejemplo, si tengo un listado con 30 numeros, que combinaciones de numeros suman un total de 986.

Gracias

Bonito problema a resolver en cobol con un occurs (array o tabla en otros lenguajes). ( esto podría ser un buen algoritmo para seleccionar personas con conocimientos)

Esto se puede resolver de forma recursiva o interactiva.

De forma interactiva lo haría de la siguiente forma:

- Metería los números en un occurs o tabla.

- Buscar combinaciones de 1 elemento. Hasta recorrer la tabla o pasarse de la suma (condicion).
- Buscar 2 elementos alternando posiciones, hasta (condición).
*
*
*
- Buscar 29 elementos alternando posiciones, hasta condición.
- Buscar 30 elementos, hasta condición.

O quizas hacerlo justamente al revés.

Bonito reto.
A ver si tengo un rato y lo implemento.
:flipa:

Josber 1 de junio de 2020 17:58

@JCantero,

No existe ningún algoritmo que haga eso, (que yo sepa), el caso está en que si son la suma de 2 o 3 elementos en una combinación de, por ejemplo 30 elementos, el algoritmo es sencillo y rápido, el problema está en que sean la suma de cualquiera de los 30 elementos, (en el que necesites sólo 1 para que dé ese valor, o necesites los 30, para que lo dé), ahí el problema es que la cantidad de combinanciones, es exponencial al número de elemento, por lo que, en una tabla de 30 elementos, la cantidad de combinaciones sería de 2,6e+32, (30!), osea, 26 seguido 32 ceros, (2.600.000.000.000.000.000.000.000.000.000.000), lo cual, hace imposible el cálculo.

Un saludo.-

JCantero 2 de junio de 2020 01:01

Cita:

Citación del post de Josber (Mensaje 5768)
@JCantero,

No existe ningún algoritmo que haga eso, (que yo sepa), el caso está en que si son la suma de 2 o 3 elementos en una combinación de, por ejemplo 30 elementos, el algoritmo es sencillo y rápido, el problema está en que sean la suma de cualquiera de los 30 elementos, (en el que necesites sólo 1 para que dé ese valor, o necesites los 30, para que lo dé), ahí el problema es que la cantidad de combinanciones, es exponencial al número de elemento, por lo que, en una tabla de 30 elementos, la cantidad de combinaciones sería de 2,6e+32, (30!), osea, 26 seguido 32 ceros, (2.600.000.000.000.000.000.000.000.000.000.000), lo cual, hace imposible el cálculo.

Un saludo.-


Creo que no es tanto.

Son (2^30)-1 == 1.073.741.823

Bonito reto

Josber 2 de junio de 2020 09:15

Cita:

Citación del post de JCantero (Mensaje 5769)
Creo que no es tanto.

Serían combinaciones, (30!), no permutaciones, ¿no?, perdón si estoy equivocado, hace tantos años de las matemáticas ... a ver si alguiien más puesto que yo, nos lo aclara :silba: :piensa:

Joseg 2 de junio de 2020 10:57

1 Archivos Adjunto(s)
Cita:

Citación del post de Josber (Mensaje 5770)
Serían combinaciones, (30!), no permutaciones, ¿no?, perdón si estoy equivocado, hace tantos años de las matemáticas ... a ver si alguiien más puesto que yo, nos lo aclara :silba: :piensa:


Em anexo projecto em Powercobol para calculo de um factorial e uma solução para o problema:
Código COBOL:
  1. * IDENTIFICATION DIVISION.
  2. * PROGRAM-ID. ACCSUM.
  3.  ENVIRONMENT     DIVISION.
  4.  DATA            DIVISION.
  5.  WORKING-STORAGE SECTION.
  6.  01  ACCOUNTS.
  7.      05  ACC-X       PIC S9(4)v99 COMP-3
  8.                     OCCURS 12 TIMES.
  9.  01  B               PIC 9(06) comp.
  10.  01  bx              PIC 9(06) comp.
  11.  01  pos             pic 9(06) comp.
  12.  01  sum1            pic s9(8)v99 comp-3.
  13.  01  sum2            pic s9(8)v99 comp-3.
  14.  01  r               pic 9(06) comp.
  15.  01  res             pic 9(06) comp.
  16.  01  comb            pic x(15) value space.
  17.  PROCEDURE       DIVISION.
  18.  0000-MAIN SECTION.
  19.      PERFORM 0100-init
  20.      perform 0200-process
  21.      EXIT PROGRAM.
  22.      
  23.  0100-init section.
  24.      move  134  to ACC-X(1)
  25.      move  400  to ACC-X(2)
  26.      move  322  to ACC-X(3)
  27.      move  100  to ACC-X(4)
  28.      move  300  to ACC-X(5)
  29.      move  86   to ACC-X(6)
  30.      move  600  to ACC-X(7)
  31.      move  700  to ACC-X(8)
  32.      move  800  To ACC-X(9)
  33.      move  200  to ACC-X(10)
  34.      move  123  to ACC-X(11)
  35.      move  203  to ACC-X(12).
  36. *>   exit.      *> GnuCobol
  37.  0200-process section.
  38.  
  39.      perform varying b from 0 by 1
  40.        until b > 4095   *> 2^12  --> se for 30 numeros tem k ser 2^30 = 1.073.741.824
  41.         compute bx = b
  42.         compute pos = 0
  43.         move zero to sum1 sum2
  44.         perform until bx = zero
  45.              divide bx by 2 giving res remainder r
  46.  
  47.             if ( r NOT = zero )
  48.               compute sum1 = sum1 + acc-x ( pos + 1 )
  49.               move '1' to comb(pos + 1 : 1)
  50.             else
  51.               compute sum2 = sum2 + acc-x ( pos + 1 )
  52.               move '0' to comb(pos + 1 : 1)
  53.             end-if
  54.  
  55.             compute bx = bx / 2
  56.             add 1 to pos
  57.  
  58.         end-perform
  59.  
  60.         if (sum1 = 986 ) then
  61.           display "-->Combinação: " comb " -->Soma=" sum2
  62.         end-if
  63.      end-perform.
  64. *>   exit.      *> GnuCobol

JCantero 2 de junio de 2020 20:18

@Joseg, reto conseguido y muy curiosa la solución.

---------- Post añadido : 14:35 ---------- Post anterior : 14:17 ----------

Va analizando cada combinación en binario. Es decir:

0
1
01
11
001
101
011
111
*
*
*
1111111111111 (hasta las posiciones que se configuren, en este caso 12)

Y va sumando en cada combinacion con los elementos de la lista dada y comprobando si da el resultado buscado.

¡ Muy Curioso ! pero eficiciente.

Ya lo he modificado para 30 elementos y lo he puesto en un windows y en un linux, a ver lo que tarda ¡¡¡

:pared:

---------- Post añadido : 20:18 ---------- Post anterior : 14:35 ----------

Para vuestra información y curiosidad. (buscando con 30 elementos) ( 2^30-1 combinaciones)

Compilado en RM/cobol y ejecutado en windows y linux.

Después de 7 horas esperando:
1) el proceso de windows 10 (64 bits) lleva un 30%
2) el proceso en linux (virtual) con 8 CPUs lleva un 45%

He realizado lo mismo en C. Lo he ejecutado en el linux. Ha tardado 2,5 minutos. Ya lo esperaba pero me ha sorprendido tan poco tiempo.

Me gustaria que hicierais lo mismo en otros COBOL para ver como son de rápidos en estas cosas.

Hacedlo para 30 elementos, modificando el programa de @joseg o os lo envio.

Por este motivo yo muchas veces implemento rutinas en C para obtener mejores resultados aunque no sean valorados. :cojo:

Breew 2 de junio de 2020 22:59

Brutal !!!!!!!!!

Menudos fieras

Gracias

Kuk 3 de junio de 2020 09:52

@JCantero, el problema de rendimiento debe venir del hecho que la rutina de @Joseg (a diferencia de tu rutina en C) no usa campos nativos.

Los COMP y COMP-3 deben reemplazarse por unos COMP-5 (de 2-4-8 bytes) para corresponder con la plataforma. Esto acelerará mucho el asunto.


La franja horaria es GMT +2. Ahora son las 13:40.

Powered by: vBulletin, Versión 3.8.7
Derechos de Autor ©2000 - 2026, Jelsoft Enterprises Ltd.