Autor
|
Tema: [ALGEBRA DE MATRICES] Matriz triangular INFERIOR DESCENDIENTE en C. (Leído 5,187 veces)
|
dijsktra
Desconectado
Mensajes: 110
Mr Edsger Dijsktra (Tribute to)
|
dijsktra deberías de poner mas retos como este Va por el fary ! Nuestros hermanos de América puede que no sepan quien es el Fary... Es... el "más cantante de España",,, https://www.youtube.com/watch?v=XLZO3DGRrfY(Parodia de lo mal que hablan los "gallegos"!!) A vueltas con las matrices... Se trata ahora de comprobar si una matriz es triangular inferior descendiente... Yo lo he hecho de arriba a bajo. Es similar, pero es como si a un zurdo le mandaran escribir con la derecha, o a un diestro con la izquierda... Vale el mismo código base de https://foro.elhacker.net/programacion_cc/algebra_de_matrices_matriz_triangular_superior_desdendiente_en_c-t504451.0.html;msg2220794#msg2220794int lowerTriangleDesc(const int **A, const int N) { // Start code here. return 1; }
De nuevo, el que más simple/bonito lo hace, (no el que termine antes, como en los concursos) gana! Ojo , YreX-DwX, no se te olivde que tienen que valer para matrices N>=1 columnas.... Ejemplos de entrada de casos son... EN DOS DIAS PONGO LA SOLUCION3 1 0 0 0 1 0 0 0 1 lowerTriangleDesc: 1 3 1 2 3 0 4 5 0 0 6 lowerTriangleDesc: 0 3 1 2 3 2 4 5 0 0 6 lowerTriangleDesc: 0 5 1 0 0 0 0 1 2 0 0 0 1 2 3 0 0 1 2 3 4 0 1 2 3 4 5 lowerTriangleDesc: 1 5 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 lowerTriangleDesc: 1 1 1 lowerTriangleDesc: 1 1 0 lowerTriangleDesc: 1
|
|
|
En línea
|
Si la depuración es el proceso de eliminar fallos en el software, entonces programar debe ser el proceso de ponerlos dentro. (Edsger Dijsktra)
|
|
|
K-YreX
|
Hmm... Veo demasiada similitud con el otro tema. Esto me da que pensar si será tan simple o hay alguna otra forma escondida. Le he dado muchas vueltas a ver si encontraba una alternativa como ir reduciendo la matriz por recursividad, pero no es posible (o eso me ha parecido, tengo un poco olvidado el trabajo directo con memoria...) al no ser una matriz como tal contigua en memoria. Así que aprovecharé para sacarme la espinita que se me quedó con el otro tema... Ojo , YreX-DwX, no se te olivde que tienen que valer para matrices N>=1 columnas.... Y tranquilo, ya no me olvidaré de las matrices de orden 1 int lowerTriangleDesc(const int **A, const int N){ int i, j = N; for(i = 0; i < N-1 && j == N; ++i) for(j = i+1; j < N && !A[i][j]; ++j); return j == N; }
PD: Sigo pensando que hay alguna solución oculta sorprendente. No dormiré tranquilo hasta ver la solución.
|
|
|
En línea
|
cout << "Todos tenemos un defecto, un error en nuestro código" << endl;
|
|
|
dijsktra
Desconectado
Mensajes: 110
Mr Edsger Dijsktra (Tribute to)
|
Hmm... Veo demasiada similitud con el otro tema.
Tienes razon. YreX-DwX... No me ha quedado bien.... Era muy similar al otro.... Y la solucion que pones es implecable... int lowerTriangleDesc(const int **A, const int N){ int i, j = N; for(i = 0; i < N-1 && j == N; ++i) for(j = i+1; j < N && !A[i][j]; ++j); return j == N; }
yo habia propuesto int lowerTriangleDescBis(const int **A, const int N) { int i,j; for (i=N-1,j=N; i && (j==N); i-=(j==N)) for(j=i; j<N && !A[i-1][j];j++); return !i; }
PD: Sigo pensando que hay alguna solución oculta sorprendente. No dormiré tranquilo hasta ver la solución. VAMOS A HACERLO DIFICIL, PERO DIFICILISMO ! Todo el mundo ve que hay dos bucles y dos variables ESTE ES EL RETO: PROGRAMAR LA SOLUCION USANDO SOLO UN BUCLE Y UNA SOLA VARIABLE DE CONTROL, A PARTE DE LAS QUE SE DAN POR PARAMETRO (Por supuesto, el programa sera mas dificil de legible, pero sera igualmente correcto....) No me pidais la solucion en un dia que no se si tendre tiempo... Se que se puede, y tengo que hacerla... y tu, YreX-DwX, m'as vale que duermas un poco...que te puedes volver tarumba...
|
|
|
En línea
|
Si la depuración es el proceso de eliminar fallos en el software, entonces programar debe ser el proceso de ponerlos dentro. (Edsger Dijsktra)
|
|
|
K-YreX
|
VAMOS A HACERLO DIFICIL, PERO DIFICILISMO ! Todo el mundo ve que hay dos bucles y dos variables ESTE ES EL RETO: PROGRAMAR LA SOLUCION USANDO SOLO UN BUCLE Y UNA SOLA VARIABLE DE CONTROL, A PARTE DE LAS QUE SE DAN POR PARAMETRO (Por supuesto, el programa sera mas dificil de legible, pero sera igualmente correcto....) Esto sí que promete. Después de darle unas cuantas vueltas creo que está cerca pero no consigo sacarlo así que dejo mi razonamiento por si alguien se anima a seguir mientras yo duermo... (Espero no soñar con esto ) La idea es tratarlo algo así como un array unidimensional, es decir, un único índice que se incrementa desde 1 hasta n siendo n el número de casillas a recorrer. Resulta que n = (N*(N-1)/2). Iremos incrementando el contador en 1 a no ser que una casilla no sea nula en cuyo caso podemos concluir que esa matriz no es triangular inferior. i := 1 MIENTRAS i <= (N*(N-1)/2) and i != 0 ENTONCES i = (A[f(i)][g(i)] == 0) * (i+1) FIN MIENTRAS RETURN i Como se puede apreciar falta definir las funciones f() y g() que determinen la fila y columna del siguiente elemento en función de i. Parece sencillo usando los operadores de división entera y módulo pero no es tan simple. Probando con matrices de orden N >= 2 (ya que de orden 1 sería triangular sin entrar por el bucle) he encontrado lo siguiente: N = 2 -> M = (N*(N-1)/2) = 1 i -> 1 f(i) -> 0 g(i) -> 1
N = 3 -> M = 3 i -> 1 - 2 - 3 f(i) -> 0 - 0 - 1 g(i) -> 1 - 2 - 2
N = 4 -> M = 6 i -> 1 - 2 - 3 - 4 - 5 - 6 f(i) -> 0 - 0 - 0 - 1 - 1 - 2 g(i) -> 1 - 2 - 3 - 2 - 3 - 3
N = 5 -> M = 10 i -> 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 f(i) -> 0 - 0 - 0 - 0 - 1 - 1 - 1 - 2 - 2 - 3 g(i) -> 1 - 2 - 3 - 4 - 2 - 3 - 4 - 3 - 4 - 4
N = 6 -> M = 15 i -> 01 - 02 - 03 - 04 - 05 - 06 - 07 - 08 - 09 - 10 - 11 - 12 - 13 - 14 - 15 f(i) -> 00 - 00 - 00 - 00 - 00 - 01 - 01 - 01 - 01 - 02 - 02 - 02 - 03 - 03 - 04 g(i) -> 01 - 02 - 03 - 04 - 05 - 02 - 03 - 04 - 05 - 03 - 04 - 05 - 04 - 05 - 05 Y así sucesivamente. Yo creo que se ve perfectamente el patrón. El problema como ya he dicho es sacar la que sería la fórmula cerrada de f() y g(). Si alguien se quiere animar a intentar seguir o a exponer su razonamiento...
|
|
|
En línea
|
cout << "Todos tenemos un defecto, un error en nuestro código" << endl;
|
|
|
fary
|
Hola, no había visto esto... ¿No es mejor crear otro tema para no mezclar todo? saludos!
|
|
|
En línea
|
Un byte a la izquierda.
|
|
|
Serapis
|
No es más complicado hacerlo en un solo bucle, tan solo es cuestión de precisar más cálculos (tampoco muchos más), que la simpleza de dos bucles ofrece... (nota: Estoy tomando como ejemplo el triangulo de la otra ocasión ya que es trivial modificarlo a cualquiera de las esquinas. Igualmente la nomenclatura de: (derecha izquierda, superior, inferior) no tiene más punto que ponerse de acuerdo. Personalmente entiendo que acomoda más denominarla conforme a la esquina que ocupa al vértice del triángulo que conecta solo con ceros, y que para el ejemplo a continuación es: inferior-iizquierda). Para entender el mecanismo subyacente hay que estudiar un poquito la matriz. ...y atribuir algunos estados que nos permitan dar flujo al cálculo Matriz: 0-35 ceros saltos index ini 5 6 0 8 2 3 - 0 - 6 00 - estado de escape 0 4 3 9 0 0 - 1 - 5 06 0 0 1 5 3 4 - 2 - 4 12 0 0 0 5 2 0 - 3 - 3 18 0 0 0 0 7 0 - 4 - 2 24 0 0 0 0 0 6 - 5 - 1 30 - estado inicial x x x x x x xx - estados de cambio ancho + 1: estado de avance
Explicando la tabla... - Lo obvio es que los ceros aumentan en uno con cada fila... en la columna fila se ha puesto una columna que lleva dicha cuenta. Una funcion podría simplemente contar cuando son 0 y devolcerá TRUE cuando sea el sumatorio de dicha serie. Aunque claramente es más ineficiente que devolver false tan pronto un valor no cumple la restricción. - La columna saltos, indica cuantos hay que omitir tras recorrer los 0. Algo tangible es que 'ceros + saltos = ancho, pués por algo son los elementos en una fila. - He añadido una última columna que señala los índices (de un array unidimensional) que suponen el primer elemento de cada fila. En el algoritmo a continuación se empieza por el vértice que da nombre al triángulo (ver nota arriba), y recorre en diagonal (en el ejemplo) hacia abajo y a la derecha... Así he añadido algunos estados para terminar de entender... El estado inicial es pués 30 : index = (size- ancho) En cada ciclo aumentará: index += (ancho +1) Cuando se alcanza un valor de index en los 'estados de cambio', justamente el enésimo valor que ocupa en esa fila (fuera de la matriz), es lo mismo que señalar la fila siguiente a la que saltar (pués es simétrico, considerando justamente como vértice del triángulo la esquina antedicha en la nota superior). El bucle termina cuando alcanza el estado de escape, que para este triángulo será el índice 0. ...y ahora el pseudocódigo (que cualquiera puede traducir a cualquier lenguaje, ya que el problema no es un problema restrictivo a ningún lenguaje específico, es decir no es un problema de ningún lenguaje si no de algoritmia)... Buleano = Funcion EsMTID(array byte Valores(), entero Ancho, entero Size) entero index index = (Size - Ancho) Hacer Si (Valores(index) <> 0) Devolver False // * index = (index + Ancho + 1) Si (index > Size) // conocemos la fila a la que saltar por el sobrante: (Index Modulo Ancho) index = (Size - (Ancho * (1 + (index Modulo Ancho)))) fin si Repetir Mientras (index > 0) Devolver True Fin Funcion
* Sí, también reconoce correctamente el caso de una matriz de 1x1
|
|
|
En línea
|
|
|
|
dijsktra
Desconectado
Mensajes: 110
Mr Edsger Dijsktra (Tribute to)
|
...y ahora el pseudocódigo (que cualquiera puede traducir a cualquier lenguaje, ya que el problema no es un problema restrictivo a ningún lenguaje específico, es decir no es un problema de ningún lenguaje si no de algoritmia)...
Tengo que dejar claro que su idea es la que más me ha gustado. Comentarios... - Mete una variable mas, size, que no es m'as que ancho*ancho, luego se puede enmendar
- No es programacion estructurada (return 0) pero eso es facilmente enmendable.Ojo!, no digo que no sea válida en C, digo que no es C-estructurada
- La construccion "repeat until", no es la adecuada. De hecho para N=1, el algoritmo falla. Pero es facilmente enmendable
Con las ligeras enmiendas... El pseudocodigo de NEBIRE pasado a C, resulta int upperTriangleDesc(const int *A, const int N) { int i=N*N-N; while (i && !A[i]) { i += N + 1; if (i > N*N) i = N*N - (N*(1 + (i%N))); } return !i; }
Y algunos resultados (correctos, por supuesto) 1 1 upperTriangleDesc: 1 2 1 1 0 1 upperTriangleDesc: 1 3 1 2 3 0 1 2 0 0 1 upperTriangleDesc: 1 3 1 2 3 0 1 2 1 0 1 upperTriangleDesc: 0
Es encomiable el esfuerzo por hallar la ley que aplica al indice "i". Realmente es una función compleja... Sin embargo... Hay un detalle no menor que puede echarse al traste.... SE HA CAMBIADO EL TIPO DE LA MATRIZ DE BIDIMENSIONAL A UNIDIMENSIONAL const int **A; // Set by if ((A =(int**)malloc(N *sizeof(int *)))==NULL ) { } for(int n=0;n<N;n++) { if ((A [n ]=(int*)malloc(N *sizeof(int)))==NULL ) { } }
por const int *A; if ((A =(int*)malloc(N *N *sizeof(int)))==NULL ) { }
EDITEsto supone que se han cambiado las condiciones del problema original por otro que era equivalente, que lo emula ,pero con condiciones distintas (los datos de entrada se presuponen codificados de otro modo). As'i, con N=6, el resultado no es correcto cuando se le pasa un valor const int **A, malloc(N), ya que A[30] , esta fuera de memoria. (si lo esta const int *A, malloc(N*N)...) Todavia no tengo la mia... tengo algnuas cosas todavía sin madurar.
|
|
« Última modificación: 20 Mayo 2020, 08:57 am por dijsktra »
|
En línea
|
Si la depuración es el proceso de eliminar fallos en el software, entonces programar debe ser el proceso de ponerlos dentro. (Edsger Dijsktra)
|
|
|
dijsktra
Desconectado
Mensajes: 110
Mr Edsger Dijsktra (Tribute to)
|
Bueno, ya va siendo hora que vaya dando una respuesta a este tema... ME VA A QUEDAR UN MENSAJE LARGO, pero a lo mejor a la posteridad le sirve de ayuda. Recordemos que las condiciones para resolverlo eran - sin cambiar la codificacion de los parametros, esto es, entra const int **A, no const int *A
- una sola variable de control, n, (aparte de los parametros, A, N)
- Un solo bucle. No he podido, me he cansado!! (Se puede, no obstante)
i := 1 MIENTRAS i <= (N*(N-1)/2) and i != 0 ENTONCES i = (A[f(i)][g(i)] == 0) * (i+1) FIN MIENTRAS RETURN i Como se puede apreciar falta definir las funciones f() y g() que determinen la fila y columna del siguiente elemento en función de i.Si alguien se quiere animar a intentar seguir o a exponer su razonamiento... Ni mucho menos es tan simple. En https://en.wikipedia.org/wiki/Pairing_function y en http://szudzik.com/ElegantPairing.pdf se describen algunos esquemas de recorrido de una matriz, proyectando dos dimensiones en uno y viceversa. No viene la tuya, pero para otras mas sencillas quedan expresiones muy complejas que trascienden el uso basico de % y /.... Un horror, vamos porque nosotros queremos no pasar de % y /. Yo sabia que se podía, porque un resultado clásico de computabilidad dice: todo lo que se puede computar con programa estilo "while" y N variables se puede hacer con 1 variable. La contrapartida será, por supuesto, - la legibilidad, No tiene interes pr'actico, pero si t'eorico, pues se puede hacer lo mismo con una variable que con N, (tesis de turing-Church)
- la eficiencia.Los programas consumen más tiempo de ejecución, aunque sin dejar de ser tratable polinomialmente (Tesis de Cook)
Esta es la estretegia: En una variable se pueden codificar el estado de N variables, sin más que adoptar en esa variable el producto de los primeros N numeros primos elevados al valor de cada variable respectiva.
Eso quiere decir que para codificar Damos el valor a n de. Que por el teorema de la Aritmetica, denota univocamente unico numero o valor para n. La forma para recuperar x, (y) será el exponente de la mayor potencia de 2, (3) que todavia haga divisible a n entre ella. x = max { k | \exists z n=2^k*z } = 3, ya que 2^4=32 no divide a 24 y = max { k | \exists z n=3^k*z } = 1 ya que 3^2=9 no divide a 24
Pero recordemos que no podemos usar m'as que una variable, luego es ilegal llamar a funciones f(n) g(n), porque estas har'ian uso de pilas y variables, y eso es trampa... Da la casualidad de que esas funciones SI SE PUEDEN COMPUTAR SOLO CON % Y /.Este es el codigo que quier implementar de partida. int lowerTriangleDesc(const int **A, const int N) { int i, j ; for(i = 0, j=i+1; i < N-1 && !A[i][j]; ) if (j==N-1) { i++; j = i + 1 ;} else j++; return i==N-1; }
Fijemonos en como se realizan las instrucciones post decremento post incremento #define DEC(id) n/=id #define INC(id) n*=id
Esto es asi, ya que sumar 1 a la n'esima variable equivalea multiplicar el numero por el n-esimo factor primo. M'as dificil... Como poder evaluar i < N - 1, cuando en nuestra unica variable solo esta almacenado n=2^i*3^j ? La estrategia sera cargar en una variable auxiliar-virtual k,n=2^i*3^j*5^k el valor de N-1-i y ver si es mayor que cero - el exponente k(5) tiene que ser igual a N, lo que solo se puede llevar a cabo al multiplicar tantas veces por 5 como unidades tenga N
- Como esto solo se puede saber decrementando N una unidad hasta que queda 0...al punto que multiplicamos por 5, multiplicamos por 7 (otra variable virtual l) para no perder la referencia de N en posteriores computos (que rollo!)
- A continuacion, restauramos N, haciendo la operacion inversa, dividiendo por 7, hasta que no se pueda mas. esto es n%7==0, ycada vez se suma 1 a N
- Despues restamos a k (5), 1, dividiendo por 5.
- Despues restamos i(2) a k(5), con cuidado de guardar copia en l(7) de lo que vale i (Otra vez Un rollo!!!)
- Restauramos en i(2), previamente guardado en el exponente de l(7)
- Finalmente, vemos el resultado k(5) a ver si es mayor que cero. Esto ocurre si el numero n%5==0, en otro caso, k(5) es igual a 0. Convencete con n=(2^1)*(3^3)*5(^1). Ves que el resto entre 5(k) es 0, lo que no pasa con n=(2^1)*(3^3)*5(^0), cuyo resto entre 5(k) no es 0
// Expressions #define NON_ZERO(id) !(n % id) #define ZERO(id) (n%id)
Con un poco de paciencia, se puede entender el razonamiento. - Como es tan tedioso y proclve a errores me he creado una especie de "compilador" con las directivas de preprocesador C.
- El monstruo ha quedado notablemente m'as complejo que el programa anterior, pero era lo esperado... ya que, como se puede ver, solo se usa UNA variable, n)
int debug(const char *s, int n, const int i) { #ifdef DEBUG int c; for( c=0; !(n%i) ; n/=i) c++; printf("debug STATE %s : -> %d \n",s ,c ); return c; #endif } // N Constant #define ASSIGN_N(id1,N,id2) for( ;N;N--) n*=id1*id2 #define RESTORE_N(N,id) for( ; !(n%id);n/=id) N++ // Restoring #define RESTORE(id2,id3) for( ; !(n%id3);n/=id3) n*=id2 // Ordinary vars. #define DEC(id) n/=id #define INC(id) n*=id #define SUBS(id1,id2,id3) for( ; !(n%id2);n/=id2) { n/=id1; n*=id3 ;} #define RESET(id) for( ; !(n%id);n/=id) #define ASSIGN(id1,id2,id3) for( ; !(n%id2);n/=id2) n*=id1*id3 #define NEG(id) if (n%id) n*=id; else for( ; !(n%id);n/=id) // Expressions #define NON_ZERO(id) !(n % id) #define ZERO(id) (n%id) // Indirect pointers; #define INC_POINTER(A,id1,id2) for( ; !(n%id1); n/=id1 ) { A++; n*=id2 ; } #define INC_POINTER_POINTER(A,id1,id2) for( ; !(n%id1); n/=id1 ) { (*A)++; n*=id2; } #define DEC_POINTER_POINTER(A,id1,id2) for( ; !(n%id1); n/=id1 ) { (*A)--; n*=id2; } #define DEC_POINTER(A,id1,id2) for( ; !(n%id1); n/=id1 ) { A--; n*=id2 ; } int lowerTriangleDesc(const int **A, int N) { int n=1; // i,j,k : 2,3,5 l : 7 n=3; // i,j,k,l=0,1,0,0 ASSIGN_N(5,N,7); RESTORE_N(N,7); DEC(5); SUBS(5,2,7); RESTORE(2,7); if (NON_ZERO(5)) // if (N-1-i>0), i.e i<N-1 { INC_POINTER(A,2,7); // A[i] RESTORE(2,7) ; INC_POINTER_POINTER(A,3,7); // A[i][j] RESTORE(3,7) ; if (**A) RESET(5); DEC_POINTER_POINTER(A,3,7); // A[i][j] RESTORE(3,7) ; DEC_POINTER(A,2,7); RESTORE(2,7) ; } // k = k && !A[i][j] debug("init i",n,2); debug("init j",n,3); debug("B: loop i < N-1 && !A[i][j]",n,5); for(; NON_ZERO(5); ) { RESET(5); ASSIGN_N(5,N,7); RESTORE_N(N,7); DEC(5); SUBS(5,3,7); // N-1-j > 0 , j<N-1 RESTORE(3,7); if (ZERO(5)) { INC(2); //i++ RESET(3); ASSIGN(3,2,5); RESTORE(2,5); INC(3); //j++ } else INC(3); debug("step i",n,2); debug("step j",n,3); ASSIGN_N(5,N,7); RESTORE_N(N,7); DEC(5); SUBS(5,2,7); RESTORE(2,7); if (NON_ZERO(5)) // if (N-1-i>0), i.e i<N-1 { INC_POINTER(A,2,7); // A[i] RESTORE(2,7) ; INC_POINTER_POINTER(A,3,7); // A[i][j] RESTORE(3,7) ; if (**A) RESET(5); DEC_POINTER_POINTER(A,3,7); // A[i][j] RESTORE(3,7) ; DEC_POINTER(A,2,7); RESTORE(2,7) ; } // k = k && !A[i][j] debug("B: loop i < N-1 && !A[i][j]",n,5); } ASSIGN_N(5,N,7); RESTORE_N(N,7); DEC(5); SUBS(5,2,7); RESTORE(2,7); NEG(5); debug("epilogue: i==N-1",n,5); return NON_ZERO(5); }
Los mensajes debug, por supuesto, son opcionales y no forman parte del codigo. Es para poder seguir mejor la codificacion de las variables en una sola. Ah!, las pruebas de que va bien! El codigo de IO esta en https://foro.elhacker.net/programacion_cc/algebra_de_matrices_matriz_triangular_superior_desdendiente_en_c-t504451.0.html;msg2220794#msg2220794$ ./main 1 1 debug STATE init i : -> 0 debug STATE init j : -> 1 debug STATE B: loop i < N-1 && !A[i][j] : -> 0 debug STATE epilogue: i==N-1 : -> 1 lowerTriangleDesc: 1 2 1 0 1 1 debug STATE init i : -> 0 debug STATE init j : -> 1 debug STATE B: loop i < N-1 && !A[i][j] : -> 1 debug STATE step i : -> 1 debug STATE step j : -> 2 debug STATE B: loop i < N-1 && !A[i][j] : -> 0 debug STATE epilogue: i==N-1 : -> 1 lowerTriangleDesc: 1 2 1 1 1 1 debug STATE init i : -> 0 debug STATE init j : -> 1 debug STATE B: loop i < N-1 && !A[i][j] : -> 0 debug STATE epilogue: i==N-1 : -> 0 lowerTriangleDesc: 0 3 1 0 0 1 1 0 1 1 1 debug STATE init i : -> 0 debug STATE init j : -> 1 debug STATE B: loop i < N-1 && !A[i][j] : -> 2 debug STATE step i : -> 0 debug STATE step j : -> 2 debug STATE B: loop i < N-1 && !A[i][j] : -> 3 debug STATE step i : -> 1 debug STATE step j : -> 2 debug STATE B: loop i < N-1 && !A[i][j] : -> 1 debug STATE step i : -> 2 debug STATE step j : -> 3 debug STATE B: loop i < N-1 && !A[i][j] : -> 0 debug STATE epilogue: i==N-1 : -> 1 lowerTriangleDesc: 1 3 1 0 0 1 1 1 1 1 1
debug STATE init i : -> 0 debug STATE init j : -> 1 debug STATE B: loop i < N-1 && !A[i][j] : -> 2 debug STATE step i : -> 0 debug STATE step j : -> 2 debug STATE B: loop i < N-1 && !A[i][j] : -> 3 debug STATE step i : -> 1 debug STATE step j : -> 2 debug STATE B: loop i < N-1 && !A[i][j] : -> 0 debug STATE epilogue: i==N-1 : -> 0 lowerTriangleDesc: 0 P.DSi aun no te convence que es una variable... aplica la siguiente linea en el compilador para observar que solo existe la varaible "n" en la rutina... gcc -E source.c -o source.hcp
el resultado es. int lowerTriangleDesc(const int **A, int N) { int n=1; n=3; for( ;N;N--) n*=5*7; for( ; !(n%7);n/=7) N++; n/=5; for( ; !(n%2);n/=2) { n/=5; n*=7 ;}; for( ; !(n%7);n/=7) n*=2; if (!(n % 5)) { for( ; !(n%2); n/=2 ) { A++; n*=7 ; }; for( ; !(n%7);n/=7) n*=2 ; for( ; !(n%3); n/=3 ) { (*A)++; n*=7; }; for( ; !(n%7);n/=7) n*=3 ; if (**A) for( ; !(n%5);n/=5); for( ; !(n%3); n/=3 ) { (*A)--; n*=7; }; for( ; !(n%7);n/=7) n*=3 ; for( ; !(n%2); n/=2 ) { A--; n*=7 ; }; for( ; !(n%7);n/=7) n*=2 ; } debug("init i",n,2); debug("init j",n,3); debug("B: loop i < N-1 && !A[i][j]",n,5); for(; !(n % 5); ) { for( ; !(n%5);n/=5); for( ;N;N--) n*=5*7; for( ; !(n%7);n/=7) N++; n/=5; for( ; !(n%3);n/=3) { n/=5; n*=7 ;}; for( ; !(n%7);n/=7) n*=3; if ((n%5)) { n*=2; for( ; !(n%3);n/=3); for( ; !(n%2);n/=2) n*=3*5; for( ; !(n%5);n/=5) n*=2; n*=3; } else n*=3; debug("step i",n,2); debug("step j",n,3); for( ;N;N--) n*=5*7; for( ; !(n%7);n/=7) N++; n/=5; for( ; !(n%2);n/=2) { n/=5; n*=7 ;}; for( ; !(n%7);n/=7) n*=2; if (!(n % 5)) { for( ; !(n%2); n/=2 ) { A++; n*=7 ; }; for( ; !(n%7);n/=7) n*=2 ; for( ; !(n%3); n/=3 ) { (*A)++; n*=7; }; for( ; !(n%7);n/=7) n*=3 ; if (**A) for( ; !(n%5);n/=5); for( ; !(n%3); n/=3 ) { (*A)--; n*=7; }; for( ; !(n%7);n/=7) n*=3 ; for( ; !(n%2); n/=2 ) { A--; n*=7 ; }; for( ; !(n%7);n/=7) n*=2 ; } debug("B: loop i < N-1 && !A[i][j]",n,5); } for( ;N;N--) n*=5*7; for( ; !(n%7);n/=7) N++; n/=5; for( ; !(n%2);n/=2) { n/=5; n*=7 ;}; for( ; !(n%7);n/=7) n*=2; if (n%5) n*=5; else for( ; !(n%5);n/=5); debug("epilogue: i==N-1",n,5); return !(n % 5); }
SE PUEDE HACER CON UN SOLO BUCLE DE NUEVO, EL COSTE A PAGAR SERA UN CONTROL MAS COMPLEJO, AQUI LO DEJO.
|
|
« Última modificación: 19 Mayo 2020, 23:21 pm por dijsktra »
|
En línea
|
Si la depuración es el proceso de eliminar fallos en el software, entonces programar debe ser el proceso de ponerlos dentro. (Edsger Dijsktra)
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
Matriz Triangular Superior
Programación C/C++
|
m@o_614
|
9
|
25,926
|
30 Junio 2013, 19:28 pm
por m@o_614
|
|
|
[Consulta] Matriz triangular inferior y superior en C++
Programación C/C++
|
romybe
|
1
|
9,524
|
20 Julio 2015, 21:21 pm
por romybe
|
|
|
Matriz triangulada inferior
Programación C/C++
|
Snarky
|
3
|
2,818
|
10 Octubre 2017, 20:06 pm
por ivancea96
|
|
|
matriz triangular superior
Programación C/C++
|
openclasroom
|
1
|
2,953
|
24 Octubre 2017, 16:07 pm
por engel lex
|
|
|
[ALGEBRA DE MATRICES] Matriz triangular superior desdendiente en C.
« 1 2 »
Programación C/C++
|
dijsktra
|
13
|
6,861
|
3 Mayo 2020, 20:21 pm
por fary
|
|