elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Introducción a la Factorización De Semiprimos (RSA)


  Mostrar Temas
Páginas: [1]
1  Programación / Programación C/C++ / [C] Determinante de orden N en: 29 Marzo 2013, 20:57 pm
A partir del título de este post ( http://foro.elhacker.net/programacion_cc/determinante_matriz_de_orden_n-t352910.0.html )  me entró la curiosidad de resolverlo de manera dinámica. Y la manera que se me ocurría para un algoritmo sencillo pues es la regla de Laplace o el desarrollo por menores complementarios de manera recursiva:

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4.  
  5. #define N 4
  6.  
  7. /* DETERMINANTE DE UNA MATRIZ de orden N - por MAFH */
  8.  
  9. typedef int ** matriz;
  10.  
  11. void visualizar_matriz (matriz matrix, int m, int n) {
  12.    int i,j;
  13.    for (i=0; i<m; i++) {
  14.        for(j=0; j<n; j++) {
  15.            printf("%d ", matrix[i][j]);
  16.        }
  17.        printf("\n");
  18.    }
  19. }
  20.  
  21. matriz generar_matriz (int m, int n) {
  22.    int i;
  23.    matriz temp;
  24.    if ((temp = (matriz) malloc(m*sizeof(int*))) == NULL)
  25.        return NULL;
  26.    for (i=0; i<m; i++)
  27.        if ((temp[i] = (int *)malloc(n*sizeof(int))) == NULL)
  28.            return NULL;
  29.    return temp;
  30. }
  31.  
  32. matriz copiar_matriz (matriz matrix, int m, int n) {
  33.    int i,j;
  34.    matriz temp = (matriz) generar_matriz(m,n);
  35.    if (temp != NULL) {
  36. for (i=0; i<m; i++)
  37. for (j=0; j<n; j++)
  38. temp[i][j] = matrix[i][j];
  39.    }
  40.    return temp;
  41. }
  42.  
  43. void liberar_matriz (matriz matrix, int m) {
  44.    int i;
  45.    for (i=0; i<m; i++)
  46.        free(matrix[i]);
  47.    free(matrix);
  48. }
  49.  
  50. void rellenar_matriz (matriz matrix, int m, int n) {
  51.    int i,j;
  52.    for (i=0; i<m; i++)
  53.        for(j=0; j<n; j++) {
  54.            printf("Valor de matrix[%d,%d] = ", i, j);
  55.            scanf("%d", &(matrix[i][j]));
  56.        }
  57. }
  58.  
  59. matriz adjunto_matriz (matriz matrix, int fila, int columna, int n) {
  60.    matriz adjunto = (matriz) generar_matriz(n-1,n-1);
  61.    if (adjunto != NULL) {
  62. int i, j, k=0, l=0;
  63. for (i=0; i<n; i++)
  64. for (j=0; j<n; j++) {
  65. if ((i != fila) && (j != columna)) {
  66. adjunto[k][l] = matrix[i][j];
  67. if (++l == n-1) {
  68. l=0;
  69. k++;
  70. }
  71. }
  72. }
  73.    }
  74.    return adjunto;
  75. }
  76.  
  77. int determinante (matriz matrix, int n) {
  78.    if (n == 1) {
  79.        return matrix[0][0];
  80.    } else {
  81.        int j;
  82.        int res = 0;
  83.        for (j=0; j<n; j++){
  84.            matriz adjunto = (matriz) adjunto_matriz(matrix, 0, j, n);
  85.            if (adjunto == NULL) exit(1);
  86.            res += pow(-1, (j%2))*matrix[0][j]*determinante(adjunto, n-1);
  87.            liberar_matriz(adjunto,n-1);
  88.        }
  89.        return res;
  90.    }
  91. }
  92.  
  93.  
  94. int main (int argc, char ** argv) {
  95.    matriz m = (matriz) generar_matriz(N,N);
  96.    rellenar_matriz(m,N,N);
  97.    visualizar_matriz(m,N,N);
  98.    printf("|M| = %d\n", determinante(m,N));
  99.    liberar_matriz(m,N);
  100.    return 0;
  101. }
  102.  

Aunque tenemos la constante N para el orden de la matriz, podemos utilizar una variable para que el usuario introduzca el orden, evidentemente.

Una ejecución del código con Valgrind:
Citar
pyxolo@ubuntu:~/Escritorio$ gcc -o det determinanteN.c -lm
pyxolo@ubuntu:~/Escritorio$ valgrind ./det -all
==4938== Memcheck, a memory error detector
==4938== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==4938== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==4938== Command: ./det -all
==4938==
Valor de matrix[0,0] = 2
Valor de matrix[0,1] = 3
Valor de matrix[0,2] = -4
Valor de matrix[0,3] = 2
Valor de matrix[1,0] = 9
Valor de matrix[1,1] = 11
Valor de matrix[1,2] = 0
Valor de matrix[1,3] = 3
Valor de matrix[2,0] = 2
Valor de matrix[2,1] = -4
Valor de matrix[2,2] = -5
Valor de matrix[2,3] = -6
Valor de matrix[3,0] = 21
Valor de matrix[3,1] = 100
Valor de matrix[3,2] = 2
Valor de matrix[3,3] = 3
2 3 -4 2
9 11 0 3
2 -4 -5 -6
21 100 2 3
|M| = -23240
==4938==
==4938== HEAP SUMMARY:
==4938==     in use at exit: 0 bytes in 0 blocks
==4938==   total heap usage: 105 allocs, 105 frees, 752 bytes allocated
==4938==
==4938== All heap blocks were freed -- no leaks are possible
==4938==
==4938== For counts of detected and suppressed errors, rerun with: -v
==4938== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Conclusión del desarrollo por menores:

Orden 1:
1 de orden 1
no llamadas recursivas

Orden 2:
2 de orden 1
2 = 2 llamadas recursivas

Orden 3:
3 de orden 2
2 de orden 1
3*2 = 6 llamadas recursivas

Orden 4:
4 de orden 3
3 de orden 2
2 de orden 1
4*3*2 = 24 llamadas recursivas

Orden 5:
5 de orden 4
4 de orden 3
3 de orden 2
2 de orden 1
5*4*3*2 = 120 llamadas recursivas

Orden n:
n de orden n-1
n-1 de orden n-2
.... de orden ...
3 de orden 2
2 de orden 1
n*(n-1)*(n-2)*(n-3)*...*(n-n+1) = (productorio desde i=n hasta 2 de i) = n! llamadas recursivas

Como conclusión a los resultados expuestos obtenemos que el número de llamadas recursivas que se realizan viene dado por:

Nº llamadas recursivas = Permutaciones(Orden) = Orden!


Como bien había dicho ghastlyX en respuesta al tema arriba enlazado.



Edit:

He tratado de lanzar el código con un determinante de orden 13 y evidentemente "no terminaba"...
Nº llamadas recursivas = P(13) = 13! = 6227020800

T(n) es exponencial y encima con los alojos y desalojos de memoria... Para morirse xD

Por otra parte, convendría generar los adjuntos con la misma matriz que se usa o de alguna manera sin generar otra matriz de tamaño n-1 para cada adjunto ._.
2  Programación / Java / Servidor y Cliente UDP - echo test en: 6 Febrero 2013, 16:30 pm
Bueno, he codificado un cliente-servidor UDP pero mi servidor no logra recibir el paquete datagrama enviado por el cliente ._.

¿Alguna ayudita?

ClienteUDP,java
Código
  1. package proyecto.socketudp;
  2. import java.net.*;
  3. /** Ejemplo que implementa un cliente de eco usando UDP. */
  4. public class ClienteUDP {
  5. public static void main(String argv[]) {
  6. if (argv.length != 3) {
  7. System.err.println("Formato: ClienteUDP <maquina> <puerto> <mensaje>");
  8. System.exit(-1);
  9. }
  10. DatagramSocket sDatagram = null;
  11. try {
  12. // Creamos el socket no orientado a conexión
  13. // (en cualquier puerto libre)
  14. sDatagram = new DatagramSocket();
  15. // Establecemos un timeout de 30 segs
  16. sDatagram.setSoTimeout(30000);
  17. // Obtenemos la dirección IP del servidor
  18. // (recibida en el primer argumento por linea de comandos)
  19. InetAddress dirServidor = InetAddress.getByName(argv[0]);
  20. // Obtenemos el puerto del servidor
  21. // (recibido en el segundo argumento por linea de comandos)
  22. int puertoServidor = Integer.parseInt(argv[1]);
  23. // Obtenemos el mensaje
  24. // (tercer argumento de la linea de comandos)
  25. String mensaje = argv[2];
  26.  
  27. byte[] envInfo = new byte[1024];
  28.       envInfo = mensaje.getBytes();
  29. // Preparamos el datagrama que vamos a enviar y lo enviamos
  30. DatagramPacket envPaquete = new DatagramPacket(
  31. envInfo, envInfo.length,
  32. dirServidor, puertoServidor
  33. );
  34. // Enviamos el datagrama
  35. sDatagram.send(envPaquete);
  36. System.out.println(
  37. "CLIENTE: Enviando "
  38. + new String(envPaquete.getData()) + " a "
  39. + envPaquete.getAddress().toString() + ":"
  40. + envPaquete.getPort()
  41. );
  42.  
  43. // Preparamos el datagrama de recepción
  44. byte[] recInfo = new byte[1024];
  45. DatagramPacket recPaquete = new DatagramPacket(recInfo, recInfo.length);
  46. // Recibimos el mensaje
  47. sDatagram.receive(recPaquete);
  48. System.out.println(
  49. "CLIENTE: Recibido "
  50. + new String(recPaquete.getData(), 0, recPaquete.getLength())
  51. + " de " + recPaquete.getAddress().toString() + ":"
  52. + recPaquete.getPort()
  53. );
  54. } catch (SocketTimeoutException e) {
  55. System.err.println("30 segs sin recibir nada");
  56. } catch (Exception e) {
  57. System.err.println("Error: " + e.getMessage());
  58. } finally {
  59. // Cerramos el socket para liberar la conexión
  60. sDatagram.close();
  61. }
  62. }
  63. }

ServidorUDP.java
Código
  1. package proyecto.socketudp;
  2.  
  3. import java.net.*;
  4. /** Ejemplo que implementa un servidor de eco usando UDP. */
  5. public class ServidorUDP {
  6.    public static void main(String argv[]) throws SocketException {
  7.        if (argv.length != 1) {
  8.            System.err.println("Formato: ServidorUDP <puerto>");
  9.            System.exit(-1);
  10.        }
  11.        try {
  12.            // Creamos el socket datagrama
  13.            DatagramSocket sDatagram = new DatagramSocket(Integer.parseInt(arv[0]));
  14.            // Establecemos un timeout de 30 segs
  15.            sDatagram.setSoTimeout(30000);
  16.            byte array[] = new byte[1024];
  17.            DatagramPacket dgramRec, dgramEnv = null;
  18.            while (true) {
  19.                // Preparamos un datagrama para recepción
  20.                dgramRec = new DatagramPacket(array, array.length);
  21.  
  22.                // Recibimos el mensaje
  23.                sDatagram.receive(dgramRec);
  24.  
  25.                // Recabamos informacion
  26.                String mensaje = new String(dgramRec.getData());
  27.                InetAddress dirCliente = dgramRec.getAddress();
  28.                int puertoCliente = dgramRec.getPort();
  29.  
  30.                System.out.println(
  31.                    "SERVIDOR: Recibido "
  32.                    + new String(dgramRec.getData(), 0, dgramRec.getLength())
  33.                    + " de " + dirCliente.toString() + ":"
  34.                    + puertoCliente
  35.                );
  36.  
  37.                // Preparamos el datagrama que vamos a enviar
  38.                dgramEnv = new DatagramPacket(
  39.                    mensaje.getBytes(), mensaje.getBytes().length,
  40.                    dirCliente, puertoCliente
  41.                );
  42.  
  43.                // Enviamos el mensaje
  44.                sDatagram.send(dgramEnv);
  45.                System.out.println(
  46.                    "SERVIDOR: Enviando"
  47.                    + new String(dgramEnv.getData(), 0, dgramEnv.getLength())
  48.                    + " de " + dgramEnv.getAddress().toString() + ":"
  49.                    + dgramEnv.getPort()
  50.                );
  51.            }
  52.        } catch (SocketTimeoutException e) {
  53.            System.err.println("30 segs sin recibir nada");
  54.        } catch (Exception e) {
  55.            System.err.println("Error: " + e.getMessage());
  56.        }
  57.    }
  58. }
3  Programación / Programación C/C++ / Queja sobre este subforo. en: 31 Octubre 2012, 22:21 pm
He estado entrando últimamente al foro y, concretamente, a este subforo y veo muchísimos códigos que están fuera de la etiqueda [ code ] y lo más irónico es que ni siquiera están identandos (con tabuladores).

Yo, claramente me niego a leer códigos de esas características. Os pido a todos aquellos que no sigáis esa norma o que no estéis acostumbrados a hacerlo, que la tratéis de cumplir. No tan solo porque debéis, sino porque de esa manera atraeréis a más usuarios para que os ayuden.

Es un quid pro cuo, si pides ayuda, trata de facilitar el trabajo :)

Ahora podéis criticarme, banearme, lapidarme... lo que deseéis. Pero solo deseaba dejar constancia de ese hecho.

Gracias por su atención.
4  Programación / Programación C/C++ / [C] Búsqueda binaria recursiva en: 29 Octubre 2012, 18:54 pm
Este pequeñito aporte va dedicado especialmente a aquellos que comienzan recién en la programación :D

Prerrequisitos (?)

→ Vectores
→ Saber qué es y cómo se lleva a cabo la búsqueda binaria

Adjunto el código del algoritmo no recursivo (Por: Rodrigo Burgos Domínguez.):
http://algorithmmx.blogspot.com.es/2011/11/algoritmo-de-busqueda-binaria.html

Código
  1. int busqueda_binaria(vector <int> list, int val){
  2.   int der = list.size() - 1, izq = 0, m;
  3.   while(izq <= der){
  4.      m = (izq + der) / 2;
  5.      if(m == list[val]) return m; //la posicion del valor
  6.      if(m > list[val]) der = m – 1;
  7.      else izq = m + 1;
  8.   }
  9.   return -1; // no se encontro el dato :P
  10. }

Teniendo en cuenta que ya sabemos la lógica que sigue este algoritmo y su implementación arriba expuesta, vamos a pensar en hacerlo de forma recursiva, es decir, que la misma función vaya reduciendo el tamaño (N) del problema a un caso base, de tal manera, al conocer la solución del caso base, va a poder dar solución a cualquier problema de tamaño N.

Entonces el código sería el siguiente:

(utilizo int casting para no usar la librería math.h)

Código
  1. int BinarySearch(int x, int v[], int tam) {
  2.  
  3.    int RecursiveBinarySearch(int x, int v[], int i, int m, int d) {
  4.        if (i>d) return -1;
  5.        else if ( x == v[m] ) return m;
  6.        else if ( x < v[m] ) return RecursiveBinarySearch(x, v, i, (int)((i+m-1)/2), (m-1));
  7.        else return RecursiveBinarySearch(x, v, (m+1), (int)((d+m+1)/2), d);
  8.    }
  9.  
  10.    int i = 0;
  11.    int m = tam/2;
  12.    int d = tam;
  13.  
  14.    return RecursiveBinarySearch(x, v, i, m, d);
  15.  
  16. }

Explicación general:

La premisa que tenemos es que nosotros tenemos que buscar un elemento x en un vector v de tamaño N que está previamente ordenado. Teniendo eso en cuenta podemos afirmar que cualquier subvector w de v de tamaño [0..N] también está ordenado.

Pues teniendo eso en cuenta vamos reduciendo el tamaño del problema (N) a la mitad en cada llamada recursiva. ¿Por qué? Porque si x no es el elemento medio del vector v de tamaño N, entonces verificamos si es menor o mayor que él. Si es menor, buscamos en el subvector de tamaño N/2 izquierdo, sino en el derecho.

Como véis, en este caso, el algoritmo se pasa de forma cíclica a forma recursiva casi sin pensar. ¿Por qué? Estamos ante una Tail Recursive Function (la autollamada es lo último que se hace) y podemos pensar en definitiva que estamos ejecutando un ciclo simplemente.

Podría aquí estar escribiendo horas y horas sobre algoritmos de búsqueda y ordenación pero no es plan xD

Decir simplemente que hay tener en cuenta que el vector en el que vayamos a buscar un elemento, debe estar previamente ordenado.

En este momento os preguntaréis: ¿Qué me conviene más, buscar directamente en un vector con la búsqueda lineal o es mejor ordenarlo previamente (quicksort) y luego aplicar búsqueda binaria? Bueno eso ya son temas de complejidad algorítmica y haciendo un pequeño estudio se puede sacar conclusiones.

Decir también que hay estructuras de datos eficientes para la búsqueda como lo son por ejemplo las Tablas Hash o los Árboles Binarios de Búsqueda, ABB (variante AVL), por ejemplo.

Bueno con esto y un bizcocho me despido.

¡Saludos!

Todos los comentarios serán bien recibidos :)
5  Programación / Programación C/C++ / sys/stat, stat() problema (?) [Lenguaje C] en: 25 Octubre 2012, 22:58 pm
Bueno, estoy creando una shell básica en C y trato de crear el comando deltree. Lo que quiero hacer es poder diferenciar entre archivos y directorios para que cuando sea un directorio, hacer una llamada recursiva a la propia función. La idea, como todos sabréis, es yo le paso una ruta, y la función me borra todo el árbol de archivos y directorios cuya raíz es la ruta que le paso. (En el código no verifiqué todavía el argc, pero ahí no está el problema, sino en la struct stat que creo que no se actualiza correctamente.

El código:

Código
  1. // Includes de la shell
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <stdlib.h>
  6. #include <unistd.h>
  7. #include <dirent.h>
  8. #include <sys/dir.h>
  9. #include <sys/stat.h>
  10. #include <sys/types.h>
  11. #include <errno.h>
  12. #define MAXENTRADA 2048
  13.  
  14. void deltree (char ** argv, int argc) {
  15.    struct dirent *ent;
  16.    struct stat fStat;
  17.    DIR *dir = opendir(argv[1]);
  18.    if(dir == NULL) {
  19.        perror("Hubo un error");
  20.    } else {
  21.        while ( (ent=readdir(dir)) != NULL ) {
  22.  
  23.            if(strcmp(".",ent->d_name) == 0 ||
  24.               strcmp("..",ent->d_name) == 0) continue;
  25.  
  26.            stat(ent->d_name, &fStat);
  27.  
  28.            if ( S_ISDIR(fStat.st_mode) )
  29.                puts(ent->d_name);
  30.  
  31.        }
  32.  
  33.        closedir(dir);
  34.        free(ent);
  35.        ent = NULL;
  36.  
  37.    }
  38. }
  39.  

el stat(ent->d_name, &fStat); devuelve -1 pero cuando hago un stat("dir/archivo_válido", &fStat); funciona correctamente. Es decir, que cuando le paso un "string" a stat, funciona correctamente pero cuando le paso el d_name del struct dirent, su salida es -1...

¿Alguna ayudita para poder solucionar el código?

¡Gracias de antemano!
6  Programación / Scripting / [BATCH] Tipo de dato ARRAY en Batch en: 24 Julio 2012, 14:08 pm
Lo primero que debo decir es que, como ya sabéis, la estructura ARRAY no existe primitivamente en Batch, pero es simulado su tipo de dato (array unidimensional) a través de un conjunto de scripts que nos va a permitir manejar dicha estructura.

Si no conoces la estructura array visita:

Array data type: http://en.wikipedia.org/wiki/Array_data_type
Array data structure: http://en.wikipedia.org/wiki/Array_data_structure

Como dije antes, trabajaremos con arrays unidimensionales.

Para generar dicha estructura usaremos adicionalmente una función para crear strings.

create_string.bat
Código:
:: Standard Array Datatype Library V-0.5
:: [@FUNCTION NAME]: Create String
:: [@FUNCTION DESCRIPTION]: This script allows us to create strings and establishes some methods for them.
:: [@AUTHOR]: Manoel A. Folgueira
:: [@WEBSITE]: http://batchispano.com
:: [@Twitter]: @ant0nlg
:: create_string string_name:(bunch of chars, string) "text":(bunch of chars)

@echo off

set "text=%2"
for /f "usebackq tokens=*" %%i in ('!text!') do (
set "%1=%%~i"
)

:: String length method
set /a %1_len=0
if "!%1!" NEQ "" (
set /a i=0
set /a %1_len=0
:length_counter
if "!%1:~%i%,1!" NEQ "" (
set /a %1_len+=1
set /a i+=1
goto :length_counter
)
)

set /a %1_limit=%1_len-1

goto :eof

A continuación, mostraré los scripts que nos permiten manejar la estructura. Los códigos se pueden mejorar (sort_array.bat optimizarlo a quicksort) y todavía se deben hacer algunos cambios a la estructura y quizás realizar una especificación para que no haya problemas a la hora de utilizarla. Finalmente veremos un ejemplo de como se comporta la estructura.

create_array.bat
Código:
:: Standard Array Datatype Library V-0.5
:: [@FUNCTION NAME]: Create Array
:: [@FUNCTION DESCRIPTION]: This peace of code will let you create an array from 0.
:: [@AUTHOR]: Manoel A. Folgueira
:: [@WEBSITE]: http://batchispano.com
:: [@Twitter]: @ant0nlg
:: create_array array_name:(bunch of chars, string) "delimiter":(char) "array_content":(string w/delimiter)

@echo off

if "%~3" NEQ "" (
call create_string del %2
call create_string content %3
call create_string %1 "[!content!]"
set /a content_l=!content_len! - 1
set /a offset=0
set /a index=0

for /l %%i in (0,1,!content_l!) do (
if "!content:~%%i,1!" EQU "!del!" (
set /a len=%%i-!offset!
call :set_value_index %1 !index! "content:~!offset!,!len!"
set /a offset=%%i+1
set /a index+=1
)
)
call :set_value_index %1 !index! "content:~!offset!,!content_len!"
set /a %1_limit=!index!
set /a %1_len=!index!+1

:: delete values
set del=
set content=
set content_l=
set offset=
set index=
set len=
)

goto :eof

:set_value_index
call create_string %1[%2] "!%~3!"
goto :eof

show_array.bat
Código:
:: Standard Array Datatype Library V-0.5
:: [@FUNCTION NAME]: Show Array
:: [@FUNCTION DESCRIPTION]: The array structure of the array passed is shown.
:: [@AUTHOR]: Manoel A. Folgueira
:: [@WEBSITE]: http://batchispano.com
:: [@Twitter]: @ant0nlg
:: show_array array_name:(bunch of chars, string)

@echo off

echo Vector: !%1!
for /l %%U in (0, 1, !%1_limit!) do (
echo %1[%%U] =^> !%1[%%U]!
)

goto :eof

insert_array.bat
Código:
:: Standard Array Datatype Library V-0.5
:: [@FUNCTION NAME]: Insert Array
:: [@FUNCTION DESCRIPTION]: You can add any value you want to the specified array.
:: [@AUTHOR]: Manoel A. Folgueira
:: [@WEBSITE]: http://batchispano.com
:: [@Twitter]: @ant0nlg
:: insert_array array_name:(bunch of chars, string) "delimiter":(char) "value":(any) position:(int)

@echo off

if %4 EQU !%1_len! (
set "%1[%4]=%~3"
set "%1="
set /a %1_len+=1
set /a %1_limit+=1
for /l %%i in (0, 1, !%1_limit!) do (
set "%1=!%1!%~2!%1[%%i]!"
)
set %1=[!%1:~1!]
) else if %4 LSS !%1_len! (
if %4 GEQ 0 (
set /a %1_len+=1
set /a %1_limit+=1
set /a limit=%4+1
for /l %%j in (!%1_limit!, -1, !limit!) do (
set /a bPos=%%j-1
call :set_value %1[%%j] "%1[!bPos!]"
)
call create_string %1[%4] "%~3"
set "%1="
for /l %%k in (0, 1, !%1_limit!) do (
set "%1=!%1!%~2!%1[%%k]!"
)
set %1=[!%1:~1!]
)
)

goto :eof

:set_value

call create_string %1 "!%~2!"

goto :eof

delete_array.bat
Código:
:: Standard Array Datatype Library V-0.5
:: [@FUNCTION NAME]: Delete Array
:: [@FUNCTION DESCRIPTION]: With this function, you are able to delete any index of the array.
:: [@AUTHOR]: Manoel A. Folgueira
:: [@WEBSITE]: http://batchispano.com
:: [@Twitter]: @ant0nlg
:: delete_array array_name:(bunch of chars, string) "delimiter":(char) position:(int)

@echo off

if !%1_len! EQU 1 (
set /a %1_len-=1
set /a %1_limit-=1
call create_string %1[0] ""
set "%1=[]"
) else (
if %3 EQU !%1_limit! (
set "%1[%3]="
set "%1="
set /a %1_len-=1
set /a %1_limit-=1
for /l %%i in (0, 1, !%1_limit!) do (
set "%1=!%1!%~2!%1[%%i]!"
)
set %1=[!%1:~1!]
) else if %3 LSS !%1_len! (
if %3 GEQ 0 (
set /a %1_len-=1
set /a %1_limit-=1
for /l %%j in (%3, 1, !%1_limit!) do (
set /a bPos=%%j+1
call :set_value %1[%%j] "%1[!bPos!]"
)
call create_string %1[!%1_len!] ""
set "%1="
for /l %%k in (0, 1, !%1_limit!) do (
set "%1=!%1!%~2!%1[%%k]!"
)
set %1=[!%1:~1!]
)
)
)

goto :eof

:set_value

call create_string %1 "!%~2!"

goto :eof

modify_array.bat
Código:
:: Standard Array Datatype Library V-0.5
:: [@FUNCTION NAME]: Modify Array
:: [@FUNCTION DESCRIPTION]: It allows you to modify the content of any index within the array limits.
:: [@AUTHOR]: Manoel A. Folgueira
:: [@WEBSITE]: http://batchispano.com
:: [@Twitter]: @ant0nlg
:: modify_array array_name:(bunch of chars, string) "delimiter":(char) "value":(any) position:(int)

@echo off

if %4 geq 0 (
if %4 leq !%1_limit! (
call create_string %1[%4] "%~3"
set "%1="
for /l %%i in (0, 1, !%1_limit!) do (
set "%1=!%1!%~2!%1[%%i]!"
)
set "%1=[!%1:~1!]"
)
)

goto :eof

sort_array.bat
Código:
:: Standard Array Datatype Library V-0.5
:: [@AUTHOR]: Manoel A. Folgueira
:: [@WEBSITE]: http://batchispano.com
:: [@Twitter]: @ant0nlg
:: sort_array array_name:(bunch of chars, string) "delimiter":(char)

@echo off

call create_string array "%~1"
if !%array%_len! gtr 0 (
for /l %%i in (0, 1, !%array%_limit!) do (
for /l %%j in (%%i, 1, !%array%_limit!) do (
if !%array%[%%j]! lss !%array%[%%i]! (
call create_string t "!%array%[%%i]!"
call create_string  %array%[%%i] "!%array%[%%j]!"
call create_string  %array%[%%j] "!t!"
)
)
)
set "%array%="
for /l %%k in (0, 1, !%array%_limit!) do (
set "%array%=!%array%!%~2!%array%[%%k]!"
)
if !%array%_len! EQU 1 (
set %array%=[!%array%!]
) else (
set "%array%=[!%array%:~1!]"
)
)

goto :eof

l_search_array.bat
Código:
:: Standard Array Datatype Library V-0.5
:: [@FUNCTION NAME]: Linear Search
:: [@FUNCTION DESCRIPTION]: It allows you to find elements within an array without any restriction.
:: [@AUTHOR]: Manoel A. Folgueira
:: [@WEBSITE]: http://batchispano.com
:: [@Twitter]: @ant0nlg
:: l_search_array array_name:(bunch of chars, string) "value":(any) "position-to-return":(bunch of chars, string)

@echo off

set /a %~3=-1
set /a index=0

:search_loop
if %~2 EQU !%1[%index%]! (
set /a %~3=!index!
goto :eof
)

if !index! gtr !%1_limit! (goto :eof)
set /a index+=1
goto :search_loop

goto :eof

b_search_array.bat
Código:
:: Standard Array Datatype Library V-0.5
:: [@FUNCTION NAME]: Binary Search
:: [@FUNCTION DESCRIPTION]: It allows you to find elements within an array efectively. Array must be sorted.
:: [@AUTHOR]: Manoel A. Folgueira
:: [@WEBSITE]: http://batchispano.com
:: [@Twitter]: @ant0nlg
:: b_search_array array_name:(bunch of chars, string) "value":(any) "position-to-return":(bunch of chars, string)

@echo off

set /a %~3=-1
set /a LowerLimit=0
set /a HigherLimit=!%1_limit!
:search_loop
set /a CentralLimit=(LowerLimit+HigherLimit)/2
if %~2 EQU !%1[%CentralLimit%]! (
set /a %~3=!CentralLimit!
) else if %~2 gtr !%1[%CentralLimit%]! (
set /a LowerLimit=CentralLimit+1
) else (
set /a HigherLimit=CentralLimit-1
)

if !LowerLimit! gtr !HigherLimit! (
set "LowerLimit="
set "HigherLimit="
set "CentralLimit="
goto :eof
) else if !%~3! NEQ -1 (
set "LowerLimit="
set "HigherLimit="
set "CentralLimit="
goto :eof
) else (
goto :search_loop
)

goto :eof

Como se puede apreciar, en ningún script se habilita la expansión de variables, por lo que deberemos habilitarla en nuestros scripts.

Aquí un ejemplo de cómo funciona la estructura array hasta el momento.

script.bat
Código:
@echo off
setlocal enabledelayedexpansion

call create_array vector " " "50 -1 9"
call show_array vector
echo.
call insert_array vector " " "0" 1
call show_array vector
echo.
call delete_array vector " " 2
call show_array vector
echo.
call modify_array vector " " "-1" 1
call show_array vector
echo.
call l_search_array vector "50" LPos
echo Posicion de 50 con busqueda linear: !LPos!
echo.
call sort_array vector " "
echo Vector Ordenado
call show_array vector
echo.
call b_search_array vector "50" BPos
echo Posicion de 50 con busqueda binaria: !BPos!
echo.

pause

goto :eof



Y con esto me despido... Comentarios, críticas, insultos, y demás locuras que se les ocurran serán excelentemente bienvenidas...

Recuerden que todavía está por perfeccionar para el uso "común" de todos nosotros ;)

A mí, de momento, ya me ayudó a implementar el tipo SET o CONJUNTO :)


¡Saludos!
7  Programación / Scripting / Ejemplo Pascal Unit - Iniciados en la programación en: 2 Junio 2012, 22:42 pm
Un ejemplo de Unit - TAD Números Racionales - con implementación dinámica de punteros.

Código
  1. ////////////////////////////////////////////////////////////
  2. /////////////Nombre de Unidad: TAD Racionales///////////////
  3. ///////////////////Autor: Batchiano/////////////////////////
  4. //////////////////////////////////////////////////////////
  5. unit Racional;
  6.  
  7. interface
  8.  
  9. type
  10. tPRacional = ^tRacional; // Tipo puntero a racional
  11. tRacional = record // Tipo racional con un registro
  12. numerador,denominador:integer;
  13. end;
  14.  
  15. function CrearRacional(a,b:integer):tPRacional; { Crea un número racional }
  16. function MostrarRacional(r:tPRacional):string; { Muestra un número racional }
  17. function Numerador(r:tPRacional):integer; { Obtiene el numerador de un número racional }
  18. function Denominador(r:tPRacional):integer; { Obtiene el denominador de un número racional }
  19. function SumarRacional(r,s:tPRacional):tPRacional; { Suma dos números racionales }
  20. function RestarRacional(r,s:tPRacional):tPRacional; { Resta el segundo número racional al primero }
  21. function MultiplicarRacional(r,s:tPRacional):tPRacional; { Multiplica dos números racionales }
  22. function DividirRacional(r,s:tPRacional):tPRacional; { Divide el primer número racional pasado por el segundo }
  23. function SimplificarRacional(var r:tPRacional):tPRacional; { Simplifica un número racional }
  24. function mcd(a,b:integer):integer; { Obtiene el m.c.d de dos enteros (en términos positivos) }
  25.  
  26.  
  27. implementation
  28.  
  29. function min(a,b:integer):integer;
  30. begin
  31. min:=a;
  32. if b<a then
  33. min:=b;
  34. end;
  35.  
  36. function CrearRacional(a,b:integer):tPRacional;
  37. begin
  38. new(CrearRacional);
  39. CrearRacional^.numerador := a;
  40. CrearRacional^.denominador := b;
  41. end;
  42.  
  43. function MostrarRacional(r:tPRacional):string;
  44. var num,den:string;
  45. begin
  46. if ((numerador(r)>0) and (denominador(r)>0)) or ((numerador(r)<0) and (denominador(r)<0)) then begin
  47. str(abs(numerador(r)),num);
  48. str(abs(denominador(r)),den);
  49. MostrarRacional := num + '/' + den;
  50. end
  51. else begin
  52. str(abs(numerador(r)),num);
  53. str(abs(denominador(r)),den);
  54. MostrarRacional := '-' + num + '/' + den;
  55. end;
  56.  
  57. end;
  58.  
  59. function Numerador(r:tPRacional):integer;
  60. begin
  61. numerador := r^.numerador;
  62. end;
  63.  
  64. function Denominador(r:tPRacional):integer;
  65. begin
  66. denominador := r^.denominador;
  67. end;
  68.  
  69. function SimplificarRacional(var r:tPRacional):tPRacional;
  70. var a,b:integer;
  71. begin
  72. a:=abs(numerador(r));
  73. b:=abs(denominador(r));
  74. r^.numerador := numerador(r) div mcd(a,b);
  75. r^.denominador := denominador(r) div mcd(a,b);
  76. SimplificarRacional := r;
  77. end;
  78.  
  79. function SumarRacional(r,s:tPRacional):tPRacional;
  80. begin
  81. new(SumarRacional);
  82. SumarRacional^.denominador := denominador(r) * denominador(s);
  83. SumarRacional^.numerador := denominador(SumarRacional) div denominador(r) * numerador(r) + denominador(SumarRacional) div denominador(s) * numerador(s);
  84. SumarRacional := SimplificarRacional(SumarRacional);
  85. end;
  86.  
  87. function RestarRacional(r,s:tPRacional):tPRacional;
  88. begin
  89. new(RestarRacional);
  90. RestarRacional^.denominador := denominador(r) * denominador(s);
  91. RestarRacional^.numerador := denominador(RestarRacional) div denominador(r) * numerador(r) - denominador(RestarRacional) div denominador(s) * numerador(s);
  92. RestarRacional := SimplificarRacional(RestarRacional);
  93. end;
  94.  
  95. function MultiplicarRacional(r,s:tPRacional):tPRacional;
  96. begin
  97. new(MultiplicarRacional);
  98. MultiplicarRacional^.numerador := numerador(r) * numerador(s);
  99. MultiplicarRacional^.denominador := denominador(r) * denominador(s);
  100. MultiplicarRacional := SimplificarRacional(MultiplicarRacional);
  101. end;
  102.  
  103. function DividirRacional(r,s:tPRacional):tPRacional;
  104. begin
  105. new(DividirRacional);
  106. DividirRacional^.numerador := numerador(r) * denominador(s);
  107. DividirRacional^.denominador := denominador(r) * numerador(s);
  108. DividirRacional := SimplificarRacional(DividirRacional);
  109. end;
  110.  
  111. function mcd(a,b:integer):integer;
  112. var t:integer;
  113. begin
  114. a:=abs(a);
  115. b:=abs(b);
  116. t:=min(a,b);
  117. while (t>1) and (((b mod t) <> 0) or ((a mod t) <> 0)) do begin
  118. t:=t-1;
  119. end;
  120. mcd := t;
  121. end;
  122.  
  123. begin
  124.  
  125. end.
  126.  
8  Programación / Scripting / [Reto Batch] Get IP from DNS en: 7 Mayo 2012, 09:25 am
Otro más de comandos... (y último :P)

Reto iniciado por Batchiano

Reto Nº 12

Nombre:          Get IP from DNS
Dificultad:       4/10
Objetivo:         Crear un comando que, al enviar un DNS, devuelva la IP adjunta a dicho DNS
Indicaciones:  Es obligatorio utilizar FOR.
Pista:               PING.
Ejemplo:



Solución: MP
9  Programación / Scripting / [Reto Batch] Hex2Dec Batch Command en: 6 Mayo 2012, 16:35 pm
Aquí pueden comentar todo lo que quieran, sus dudas, avances o soluciones acerca del siguiente reto:

Reto iniciado por Batchiano

Reto Nº 11

Nombre:          Hex2Dec Batch Command
Dificultad:        3/10
Objetivo:         Crear un comando que convierta un número en hexadecimal a decimal.
Pista: El código es muy corto. Se aconseja pipear.
Ejemplo:



Solución:

Código
  1. @echo off
  2. if "%1"=="" (goto syn) else (
  3. echo | set /a %1
  4. exit /b
  5. )
  6.  
  7. :syn
  8. echo Error de sintaxis. %0 [NUMERO EN HEXADECIMAL]
10  Programación / Scripting / Contador (cuenta atrás) en: 7 Abril 2012, 09:40 am
Pues he implementado una cuenta atrás en Batch... segurísimamente ya esté hecho... pero me apetecía pensar como hacerlo... opiniones... mejoras... aplicaciones para la cuenta atrás... ideas... críticas constructivas... todo bienvenido :P

Operadores lógicos...

Código
  1. ::Cuenta atrás
  2. ::Batchiano
  3. @echo off
  4. setlocal enabledelayedexpansion
  5. :menu
  6. set /p h="Horas: "
  7. set /p m="Minutos: "
  8. set /p s="Segundos: "
  9. for %%z in (h,m,s) do if not defined %%z (
  10. call :formato
  11. )
  12. if %h% GEQ 0 (
  13. if %m% GEQ 0 (
  14. if %m% LEQ 59 (
  15. if %s% GEQ 0 (
  16. if %s% LEQ 59 (
  17. call :contador
  18. ) else (
  19. call :formato
  20. )
  21. ) else (
  22. call :fomato
  23. )
  24. ) else (
  25. call :formato
  26. )
  27. ) else (
  28. call :formato
  29. )
  30. ) else (
  31. call :formato
  32. )
  33. goto :eof
  34.  
  35. :contador
  36. cls
  37. if %h% GEQ 0 (
  38. if %m% GEQ 0 (
  39. if %s% GEQ 0 (
  40. for /l %%a in (!h!,-1,0) do (
  41. for /l %%b in (!m!,-1,0) do (
  42. for /l %%c in (!s!,-1,0) do (
  43. echo Contador: %%a:%%b:%%c
  44. ping localhost -n 2 > nul
  45. cls
  46. )
  47. set s=59
  48. )
  49. set m=59
  50. )
  51. )
  52. )
  53. )
  54. goto :eof
  55.  
  56. :formato
  57. echo Formato incorrecto. Vuelva a intentarlo
  58. pause>nul & cls & call :menu
  59.  
Páginas: [1]
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines