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

 

 


Tema destacado:


  Mostrar Mensajes
Páginas: 1 2 3 4 [5] 6 7 8 9 10 11
41  Programación / Programación C/C++ / Re: Elegir ultimo fichero metido dentro de una carpeta en C++ Linux en: 19 Julio 2019, 11:26 am
Buenos días!
Estoy implementando un programa que se dedica a leer los datos de un fichero que se encuentra en una determinada carpeta. La cosa es que cada mes, se genera un nuevo fichero al que acceder, lo que me obliga a cambiar el código para acceder al ultimo fichero que se ha generado.

Mi pregunta es; existe alguna forma de que mi programa sea capaz de estar a la espera de encontrar un nuevo fichero dentro de la misma ruta con idea de que automáticamente, los datos que necesito sacar de dichos ficheros se actualicen sin necesidad de que cada mes tenga que cambiar el código.

Muchas gracias de antemano! Un saludo
A lo mejor no estás planteando el problema con la tecnología adecuada. Me explico: por qué programar un complejo programa C con llamadas complejas a API cuando todo esto se puede hacer con los comandos de la shell, ya que la pregunta original se refiere a Linux


A ver que te parece este pequeño scrpipt.

Código:
#!/bin/sh
TARGET_DIR=$HOME  # Change to your choice, i.e. "/tmp/log"
LAST_MODIFIED=$(stat -c "%Y %n" $TARGET_DIR/* | sort | cut -d ' ' -f 2 | tail -1)
echo $LAST_MODIFIED

Esto detecta el ultimo fichero modificado en un directorio. Si lo quieres hacer periódicamente cada mes, lo mejor es integrarlo el servicio cron .  No puedo desbribir aquí como va, (dale a man cron)

Finalmente, llega tu programa original, el que tiene que procesar el fichero detectado. En lugar de hacer echo, invocas tu programa pasando el fichero por parámetro, sin cambiarlo.
Código:
#!/bin/sh
TARGET_DIR=$HOME  # Change to your choice, i.e. "/tmp/log"
LAST_MODIFIED=$(stat -c "%Y %n" $TARGET_DIR/* | sort | cut -d ' ' -f 2 | tail -1)
myprogram $LAST_MODIFIED

Si puede valer....
42  Programación / Scripting / Re: Juego Python OhNO en: 3 Junio 2019, 16:56 pm
Citar
Tendré que diseñar un algoritmo de inteligencia artificial de expliración de estados (vamos, un backtraking de to la vida, que es cualquier cosa menos inteligente, es pura fuerza bruta) y exponer una combinación que tenga solución.
Citar
No lo veo necesario. Ni siquiera un backtracking...

Hola! Tus comentarios fueron muy útiles...! En otro correo cuando pueda respondo cómo me ayudó.
Como tu dices, no era necesario.

Vayan aquí unas fotos del juego que YA es practicable.  https://github.com/rafaelm53539600/OhnO

Os lo descargáis con el botón verde, que dice "Download zip".
 Después sólo que usar python 3, (no vale con python 2), y se invoca así.

Código:
python ohno.py








Recuerdo las reglas:

  • Una misma ficha azul puede ver a las otras azules contiguas en su misma fila y columna, excluyendo ella misma
  • Las fichas rojas rompen la contigüidad entre las azules
  • Haz click en las fichas para cambiar sus colores. Las fichas "clavadas" del principio no se pueden cambiar
  • Los numeros (A/B) describen cuantas fichas azules debe ver cada ficha azul (B) y cuantas ve relamente (A).
  • Como mínimo, cualquier ficha azul debe ver otra ficha azul
43  Programación / Scripting / Re: Juego Python OhNO en: 27 Mayo 2019, 10:31 am
Gracias NEBIRE, no veas lo que aprecio tu respuesta!
Veo que has comrpendido  a la perfección todo el sistema.


Me autorespondo...
Después de mirar el código, veo que la cuenta es de vecinas (contiguas) en la misma fila y columna, excluyéndose a sí misma de dicha cuenta. La aparición de una pieza roja, rompe la contigüidad.


Es así, y veo que tu redacción es mejor que la mía. Con tu permiso, lo cambiaré en el mensaje original.


Y el objetivo final es descubrir el color original de cada ficha en el mapa.


Bueno, esto no es exacto. El objetivo final es cumplir las restricciones de las fichas azules iniciales, llenado todo el tablero al 100% y esto no es siempre una solución única (más abajo te explico)

Personalmente creo que en la cuenta debiera contarse a sí misma y reflejarse así en el juego, es más fácil contar todas que saltarse una...

Yo también pensaba así, pero las reglas no dicen eso. Por eso puse la ayuda del par de números (A/B), (las que veo, las que debo ver). Esta claro que los maestros orientales del Japón valoraban la paciencia del conteo como forma de "concentración"  ;D ;D  (Vamos, eso creo yo...)

...

He hecho una simple aproximación (en pseudocódigo). Pero me doy cuenta que al hacerlo de forma sencilla, para elegir las piezas de dar pistas, al azar, puede dar lugar a múltiples soluciones válidas (de momento he optado por dejar como piezas fijas, tantas como un valor al azar entre 1/4 y 1/3 del total de las piezas del tablero), originado precisamente a causa de aquellas piezas que no son 'tocadas' por ninguna de las fijas que ofrecen las pistas... pero bueno es una primera aproximación... ya lo miraré más en profundidad cuando pase a la implementación.

Mirando tu ejemplo 'solved', se alcanza a ver esto mismo que acabo de decir, por ejemplo la última fila... al no tener pistas, no se ve forzado, luego da igual si se ponen rojas o azules... Más aún las dos ultimas filas, salvo las dos rojas, no importa de qué color sea el resto, ofrece pués múltiples soluciones válidas.

TOTALMENTE de acuerdo, tienes razón.
En definitiva, lo que trato de decir es que el juego sería más interesante (y también más difícil) si no tuviera múltiples soluciones, o al menos restringirlo lo más posible.


Pero el juego no descarta que haya multiples soluciones... Naturalmente, si restringes como dices las fichas, no es que es sea más difícil, al contrario, es más fácil, porque las posiciones se pueden "deducir" ("forzar", en tus propios términos) y no especular.

El problema entonces, es que, jugando con las restricciones de las fichas azules, su posición y la aritmética, puedes llegar a restringirlo tanto QUE NO TENGA solución.

Fijate en el siguiente ejemplo, surgido con fichas al azar, cambiando el código en la línea 180.

Código
  1.        blues,reds,r =  set(),set(), Random()
  2.        # An eye: there is no warrant to have unique solution for OhNO
  3.        # ever one in case!
  4.        # This is random... Hard to justify loop's termination (statistics)
  5.        while (len(blues)<(pow(self.N,2) / 4)):
  6.            blues.add((r.choice(range(self.N)),r.choice(range(self.N))))
  7.       while (len(reds)<(pow(self.N,2) / 8)):
  8.            reds.add((r.choice(range(self.N)),r.choice(range(self.N))))
  9.            reds.difference_update(blues)
  10.        #
  11.        #blues=[(0,1), (0,2), (1,1)]  <===============   Commented
  12.        #reds =[(0,0)]    <===============   Commented
  13.  
  14.  

Ahora el problema es irresoluble! La casilla 1,2 requiere ver tres fichas. Una por arriba, (hecho) , pero por abajo no puede (LOCK) y por la izquierda tampoco (poruqe  a lo podr'a llegar a ver una!)




Y es ahí donde  quiero llegar... No puedo poner unos valores de entrada para que el esforzado humano, después de jugar 4 horas, se de cuenta de que no tiene solución.

Tendré que diseñar un algoritmo de inteligencia artificial de expliración de estados (vamos, un backtraking de to la vida, que es cualquier cosa menos inteligente, es pura fuerza bruta) y exponer una combinación que tenga solución.

Se me está ocurriendo luego poner un boton de "Me rindo!!!" en el que pulsando salga UNA  de las posibles soluciones....


Un abrazo!
44  Programación / Scripting / Juego Python OhNO en: 24 Mayo 2019, 14:18 pm
Hola!
OhnO es un juego clásico de fichas sobre un tablero de origen japonés.  Sus reglas son:
EDITED: Credits NEBIRE
  • Una misma ficha azul puede ver a las otras azules contiguas en su misma fila y columna, excluyendo ella misma
  • Las fichas rojas rompen la contigüidad entre las azules
  • Haz click en las fichas para cambiar sus colores. Las fichas "clavadas" del principio no se pueden cambiar
  • Los numeros (A/B) describen cuantas fichas azules debe ver cada ficha azul (B) y cuantas ve relamente (A).
  • Como mínimo, cualquier ficha azul debe ver otra ficha azul

Es posible que haya miles de versiones por Internet.
Ofrezco la mía. Alguna valoración?
https://github.com/rafaelm53539600/OhnO






(Son 250 lineas, por eso no lo expongo en el Web)

45  Programación / Scripting / Re: Esteganografía NTFS ADS [BATCH] en: 24 Abril 2019, 20:41 pm
 ;-) :D :D
Bravo!
Auténtica exhibición!
46  Programación / Programación C/C++ / Re: Problema con buzones [con queues] en: 10 Abril 2019, 15:44 pm
Lo prometido es deuda. Aqui tienes una implementación de sincronización con colas System V.

Comentarios
  • Podemos emular una especie de semáforo distribuido con colas. Las operaciones P(s) y V(s) son las correspondeintes a rcv(q) y snd(q). Eso si, expresado en C, es un poco críptico, ya que tenemos que ver siempre el retorno de la llamada al sistema
  • Al ser utilizado como señalización, el mensaje no precisa de datos. no se precisa comunicar ningún dato, el mismo acto de envío y recepción es suficiente. De ahí que el msg.txt sea de tamñao 0, no es necesario poner "LUZ VERDE" o "LUZ ROJA"...



Código
  1. /*
  2.   Syncrhonized red-green semaphores
  3.  
  4.   using queues
  5.  
  6.   a queue can act as a distributed semaphore
  7. */
  8. #include <sys/types.h>
  9. #include <sys/ipc.h>
  10. #include <sys/msg.h>
  11.  
  12. #include <sys/stat.h>
  13. #include <fcntl.h>
  14.  
  15.  
  16.  
  17. #include <stdlib.h>  // exit
  18. #include <stdio.h>  // print
  19. #include <unistd.h> // sleep
  20.  
  21. int msq1;
  22. int msq2; // queue descriptors...
  23.  
  24.  
  25. typedef struct msgbuf {
  26.  long mtype;       /* message type, must be > 0 */
  27.  char mtext[0];    /* message data */
  28. } msg;
  29.  
  30.  
  31. void one_process()
  32. {
  33.  struct msgbuf msg = {  1 };
  34.  for( ; 1 ; )
  35.    {
  36.      if (msgrcv(msq1,(void *)&msg,sizeof(msg.mtext),0,0)==-1)
  37. {
  38.  perror("msgrcv");
  39.  exit(EXIT_FAILURE);
  40. }
  41.      printf("one: \t\tRED\n");
  42.      sleep(2);
  43.      if (msgsnd(msq2,(void *)&msg,sizeof(msg.mtext),0))
  44. {
  45.  perror("msgsnd");
  46.  exit(1);
  47. }
  48.      printf("one: \t\tGREEN\n");
  49.    }
  50. }
  51.  
  52.  
  53. void two_process()
  54. {
  55.  struct msgbuf msg = { 1 };
  56.  for( ; 1 ; )
  57.    {
  58.      if (msgrcv(msq2,(void *)&msg,sizeof(msg.mtext),0,0)==-1)
  59. {
  60.  perror("msgrcv");
  61.  exit(EXIT_FAILURE);
  62. }      printf("\t\t\t\ttwo: \t\tRED\n");
  63.      sleep(2);
  64.      if (msgsnd(msq1,(void *)&msg,sizeof(msg.mtext),0))
  65. {
  66.  perror("msgsnd");
  67.  exit(1);
  68. }
  69.      printf("\t\t\t\ttwo: \t\tGREEN\n");
  70.    }
  71. }
  72.  
  73.  
  74. int main(int argc, char **args)
  75. {
  76.  int pid;
  77.  int msgkey =IPC_PRIVATE;
  78.  struct msgbuf msg = { 1 };
  79.  
  80.  if ((msq1 = msgget(msgkey, IPC_CREAT | 0666 ))==-1)
  81.    {
  82.      perror("msgget");
  83.      exit(EXIT_FAILURE);
  84.    }
  85.  
  86.  if ((msq2 = msgget(msgkey, IPC_CREAT | 0666 ))==-1)
  87.    {
  88.      perror("msgget");
  89.      exit(EXIT_FAILURE);
  90.    }
  91.  
  92.  if (msgsnd(msq1,(void *)&msg,sizeof(msg.mtext),0))
  93.    {
  94.      perror("msgsnd");
  95.      exit(1);
  96.    }  
  97.  pid = fork();
  98.  switch (pid)
  99.    {
  100.    case 0 : // child
  101.      one_process();
  102.      break;
  103.    default: // parent
  104.      two_process();
  105.    }
  106.  
  107. }
  108.  








Código:
 gcc redgreen.que.c -o main && ./main
one: RED
one: GREEN
two: RED
two: GREEN
one: RED
one: GREEN
two: RED
two: GREEN
one: RED
one: GREEN
two: RED
two: GREEN
one: RED
one: GREEN
two: RED
two: GREEN
one: RED
one: GREEN
two: RED
two: GREEN
one: RED
one: GREEN
two: RED
47  Programación / Programación C/C++ / Re: Problema con buzones en: 8 Abril 2019, 15:14 pm
Hola!
Estaba haciendo un ejercicio en el cual hay que sincronizar varios procesos y que estos procesos sigan sincronizandose (en este caso los procesos son unos semaforos que tienen que ir cambiando de color de forma logica osea cuando uno este en verde el otro no puede estar en verde y viceversa) hasta que se pulse ctrl-c.
El caso es que  mi idea era realizar esta sincronizacion con un buzon IPC [...]

Muchas gracias!

A ver, la forma "natural" de hacerlo es con semáforos, no con lo que tu llamas "buzones"... (Creo que con lo que te refieres a eso es a colas, pero bueno...) En cuanto pueda, hago una solución de ese modo ;D

Aquí  hay una propuesta de simulación. Creo que deberías empezar por threads, en vez de , como creo, haces con IPC y fork(), al estar incompleto el código, no puedo interpretar....

Código
  1. /*
  2.   Syncrhonized red-green semaphores
  3.  
  4.   using semaphores...
  5.  
  6.   Safety Invariant:
  7.      0 <= one_sem + two_sem <= 1
  8.  
  9. */
  10.  
  11. #include <pthread.h>
  12. #include <semaphore.h>
  13.  
  14.  
  15. #include <stdlib.h>  // exit
  16. #include <stdio.h>  // print
  17. #include <unistd.h> // sleep
  18. sem_t one_sem;
  19. sem_t two_sem;
  20.  
  21.  
  22. void* one_thread(void *arg)
  23. {
  24.  for( ; 1 ; )
  25.    {
  26.      if (sem_wait(&one_sem))
  27. {
  28.  perror("sem_wait");
  29.  exit(1);
  30. }
  31.      printf("one: \t\tRED\n");
  32.      sleep(2);
  33.      if (sem_post(&two_sem))
  34. {
  35.  perror("sem_post");
  36.  exit(1);
  37. }
  38.      printf("one: \t\tGREEN\n");
  39.    }
  40. }
  41.  
  42.  
  43. void* two_thread(void *arg)
  44. {
  45.  for( ; 1 ; )
  46.    {
  47.      if (sem_wait(&two_sem))
  48. {
  49.  perror("sem_wait");
  50.  exit(1);
  51. }
  52.      printf("\t\t\t\ttwo: \t\tRED\n");
  53.      sleep(2);
  54.      if (sem_post(&one_sem))
  55. {
  56.  perror("sem_post");
  57.  exit(1);
  58. }
  59.      printf("\t\t\t\ttwo: \t\tGREEN\n");
  60.    }
  61. }
  62.  
  63.  
  64. int main(int argc, char **args)
  65. {
  66.  pthread_t one,two;
  67.  
  68.  sem_init(&one_sem,0,1);
  69.  sem_init(&two_sem,0,0);
  70.  if (pthread_create(&one, NULL, one_thread, NULL))
  71.    {
  72.      perror("pthread_create");
  73.      exit(1);
  74.    }
  75.  if (pthread_create(&two, NULL, two_thread, NULL))
  76.    {
  77.      perror("pthread_create");
  78.      exit(1);
  79.    }
  80.  
  81.  if (!pthread_join(one,NULL))
  82.    {
  83.      perror("pthread_join");
  84.      exit(1);
  85.    }
  86.  
  87.    if (!pthread_join(two,NULL))
  88.    {
  89.      perror("pthread_join");
  90.      exit(1);
  91.    }
  92.  
  93. }
  94.  


Y la salida, (el efecto temporal no sale en esta página estática Web, claro. Deberias ver que se sincronizan al mismo tiempo. Correlo en tu terminal.)
Código:
gcc redgreen.c -lpthread -o main && ./main
one: RED
one: GREEN
two: RED
two: GREEN
one: RED
one: GREEN
two: RED
two: GREEN
one: RED
one: GREEN
two: RED
two: GREEN
one: RED
one: GREEN
two: RED
two: GREEN
one: RED
one: GREEN
two: RED
two: GREEN
one: RED
one: GREEN
two: RED
two: GREEN
one: RED
one: GREEN
two: RED
two: GREEN
one: RED
48  Programación / Programación C/C++ / Re: condicion de carrera c++ threads en: 4 Abril 2019, 15:01 pm
Que bueno que la gente se meta con problemas de concurrente!

He solucionado el problema de la condición de carrera, helgrind ya no se queja, la culpa la tenía el método size en la línea while(num_producers_working != 0 || products.size() > 0)...

Cuidado! Yo no tengo ni idea de helgrind, no lo había oido en mi vida, pero la depuración en concurrente es algo impracticable! Necesitas un cálculo para razonar sobre la corrección de un programa, con invariantes, etc...
Conviene tener princpios sólidos sobre los que montar tus soluciones concurrentes.
Un buen libro: "Concurrent Programming. Gregory R. Andrews".
No vas a aprender nada de C++, pero si mucho de programaci'on concurrente!

Algunas observaciones a tu programa:

  • Productores consumidores se ejecutan indefinidamente. De otro modo, puedes llegar a bloqueos, (imagina 1 productor y 1000 consumidores, a 1 items cada uno... Es obvio que los consumidores se quedarán esperando indefinidamente
  • El buffer, o es un escalar, o un buffer limitado. Nada se gana con los stacks... Interesa FIFO, no LIFO
  • Nada se gana leyendo los manuales de la libreria <thread> o <condition variable> si no se conoce en que consisten los monitores



Código
  1. #include <cassert>
  2. #include <iostream>
  3. #include <vector> // as bounded buffer.
  4. #include <thread>
  5. #include <mutex>
  6. #include <condition_variable>
  7. #include <chrono>
  8. #include <atomic>
  9. #include <cassert>
  10.  
  11. #define MAX_THREADS 1000
  12. #define SIZE_BUFFER 5
  13. #define TIMEOUT  200
  14.  
  15. using namespace std;
  16.  
  17. // Patemeters overwritten on input.
  18. static int P = 5; // Producers
  19. static int C = 10; // Consumers
  20. static int P_DELAY=1000 ; // Prod-Delay
  21. static int C_DELAY=500;
  22.  
  23.  
  24. // MONITOR VARIABLES
  25. static mutex xmutex;                    // Our mutex, monitor methods in exclusion
  26. static condition_variable if_full;             // to indicate that our stack is
  27. // not full  between the thread operations
  28. static condition_variable if_empty;            // to indicate that our stack is
  29. // not empty between the thread operations
  30.  
  31. static int front = 0;
  32. static int rear = 0;
  33. static vector<int>  buf(SIZE_BUFFER);
  34. static int holes = SIZE_BUFFER;
  35. static int items = 0;
  36. // Monitor invariants:
  37. // inv. items =  (front "-" rear)
  38. // inv. holes = SIZE_BUFFER - (front "-" rear)
  39. // inv. 0 <= front < SIZE_BUFFER, 0 <= rear < SIZE_BUFFER
  40.  
  41. static atomic<int> m(0); // simulating a fresh message;
  42.  
  43. // MONITOR METHODS
  44. void init()
  45. {
  46.  front=rear=items=0;
  47.  holes = SIZE_BUFFER;
  48. }
  49.  
  50. void deposit(const int id,const int msg)
  51. {
  52. unique_lock<mutex> lock(xmutex);
  53.  
  54. // await holes > 0
  55. if_full.wait(lock, [] { return holes > 0; });
  56. buf[rear] = msg; rear = ((rear+1) % SIZE_BUFFER);
  57. cout << "p[" << id << "]\tdeposit\t:\t" << msg << endl;
  58. holes--; items++;
  59. if_empty.notify_all();
  60. }
  61.  
  62. //      Consume function, consumer_id will consume a product
  63. int fetch(const int id)
  64. {
  65. unique_lock<mutex> lock(xmutex);
  66. int mess;
  67. // await items > 0
  68. if_empty.wait(lock, [] { return items > 0; });
  69. mess = buf[front]; front = ((front+1) % SIZE_BUFFER);
  70. cout << "c[" << id << "]\t\t\t\t\tfetch\t:\t" << mess << endl;
  71. holes++;items--;
  72. if_full.notify_all();
  73. return mess;
  74. }
  75.  
  76.  
  77. // Real code for threads.
  78. void producer(int id)
  79. {
  80. for (; 1; )
  81. {
  82. deposit(id, ++m);
  83. this_thread::sleep_for(chrono::milliseconds(P_DELAY));
  84. }
  85. return;
  86. }
  87.  
  88. void consumer(int id)
  89. {
  90. int msg;
  91. for (; 1; )
  92. {
  93. msg = fetch(id);
  94. this_thread::sleep_for(chrono::milliseconds(C_DELAY));
  95. }
  96. return ;
  97. }
  98.  
  99.  
  100. void simulation()
  101. {
  102. vector<thread> threads;
  103.  
  104. init();
  105. // Create producers
  106. for (int p = 0; p < P; ++p)
  107.  threads.push_back(thread(producer, p));
  108.  
  109. // Create consumers
  110. for (int c = 0; c < C; ++c)
  111.  threads.push_back(thread(consumer, c));
  112.  
  113. // Wait for consumers and producers to finish
  114. for (auto& t : threads)
  115. t.join();
  116. }
  117.  
  118.  
  119. // IO staff.
  120. int main(int argc, char *args[])
  121. {
  122.  cout << "C P P_DELAY C_DELAY " << endl;
  123.  for( ; cin >> C >> P >> P_DELAY >> C_DELAY; )
  124.    {
  125.      assert((C<MAX_THREADS) && (P<MAX_THREADS) );
  126.      assert((P_DELAY > 0) && (C_DELAY > 0) );
  127.      simulation();
  128.    }
  129.  return 0;
  130. }
  131.  
  132.  

Aqui un ejemplo de salida. Tu puedes experimientar variando , el numero de p/c, la velocidad relativa...

Con independencia de la velocidad relativa, dentro de un mismo grupo no está determinado el orden de acceso al monitor. Así,  es posible que el productor del mensaje 9 tenga acceso al monitor antes que el productor del mensaje 8.  Eso sí, entre dos consumidores el primero en acceder extraerá el mnesaje 9, y el segundo el 8, por ser FIFO.



Código:
g++ conc.cpp -o main -lpthread && ./main
C P P_DELAY C_DELAY
5 5 500 500
p[1] deposit : 1
p[2] deposit : 2
p[0] deposit : 3
p[3] deposit : 4
c[0] fetch : 1
p[4] deposit : 5
c[1] fetch : 2
c[3] fetch : 3
c[2] fetch : 4
c[4] fetch : 5
p[1] deposit : 6
p[3] deposit : 7
p[0] deposit : 9
p[2] deposit : 8
c[0] fetch : 6
p[4] deposit : 10
c[1] fetch : 7
c[3] fetch : 9
c[2] fetch : 8
c[4] fetch : 10
p[1] deposit : 11
p[3] deposit : 12
p[0] deposit : 13
p[2] deposit : 14
c[0] fetch : 11
p[4] deposit : 15
c[1] fetch : 12
c[3] fetch : 13
c[2] fetch : 14
c[4] fetch : 15
p[1] deposit : 16
p[0] deposit : 18
p[3] deposit : 17
p[2] deposit : 19
c[0] fetch : 16
p[4] deposit : 20
c[1] fetch : 18
c[3] fetch : 17
c[2] fetch : 19
c[4] fetch : 20
p[0] deposit : 21
p[1] deposit : 22
p[3] deposit : 23
p[2] deposit : 24
p[4] deposit : 25
c[0] fetch : 21
c[1] fetch : 22
c[3] fetch : 23
c[2] fetch : 24
c[4] fetch : 25
p[0] deposit : 26
c[0] fetch : 26
p[3] deposit : 29
c[4] fetch : 29
p[4] deposit : 30
c[2] fetch : 30
p[1] deposit : 27
c[1] fetch : 27
p[2] deposit : 28
c[3] fetch : 28
p[0] deposit : 31
p[3] deposit : 32
c[4] fetch : 31
c[0] fetch : 32
p[4] deposit : 33
c[2] fetch : 33
p[1] deposit : 34
c[1] fetch : 34
p[2] deposit : 35
c[3] fetch : 35
p[4] deposit : 37
c[0] fetch : 37
p[3] deposit : 38
c[2] fetch : 38
p[2] deposit : 40
p[0] deposit : 36
p[1] deposit : 39
c[4] fetch : 40
c[1] fetch : 36
c[3] fetch : 39
p[4] deposit : 41
c[0] fetch : 41
p[3] deposit : 42
c[2] fetch : 42
p[2] deposit : 43
p[0] deposit : 44
p[1] deposit : 45
c[4] fetch : 43
c[1] fetch : 44
c[3] fetch : 45
...
C-c C-c



49  Programación / Programación C/C++ / Re: [PARTIR EN PARRAFOS UN TEXTO ] Detectar linea en blanco en C en: 7 Marzo 2019, 12:08 pm
Como lo solucionaste, tengo un problema parecido...

Todavia no lo ha resuelto.

Lo que dice MAFUS respecto a la redireccion de la entrada estandar en shell/UNIX (tambien en COMMAND/Microsoft) es cierto, pero va a ser dificil si no elevas la abstracción, de "caracter \n" a "linea vacia". Para eso te ayuda la función

Código:
#include <stdio.h>

ssize_t getline(char **lineptr, size_t *n, FILE *stream);

Aquí va una propuesta, con una "durisima" formalización, de la que no estoy seguro al 100%.
IMPORTANTE: Segun mi criterio, el ultimo parrafo acaba en EOF, no en EOL.

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <assert.h>
  4. #include <string.h> // strlen
  5.  
  6.  
  7. #define LINES_PER_FILE 1000
  8. #define LINES_PER_PARAGRAPH 100
  9. #define PARAGRAPH 100
  10. #define LENGTH_LINE 250
  11.  
  12. /*
  13.   Formal spec hard. Use line (not char) as main abstraction
  14.  
  15.   P : text[0..txtLns) of char[LENGTH_LINE];
  16.   Q : \forall i,j : 0 <= i <= j <= N and paragraph(V,i,j,N) :
  17.            let
  18.              M = emptyLines(V,0,i)
  19.            in
  20.              isCopy(Pgrphs,M,i,j) and PgrphLns[M]=(j-i)
  21.       txtPgrphs = min(1,N) + emptyLines(text,0,txtLns)
  22.  
  23.   where
  24.  
  25.      emptyLines(text,0,txtLns) = #i : 0 <=i <txtLns :empty(text[i])
  26.      paragraph(V,i,j,N) =
  27.                   i = max k : 0 <= k <=j and (k > 0 -> empty(text[k-1]) : k
  28.                   j = min k : i <= k <= N and (k < N -> empty(text[k]) : k
  29.      isCopy(Pgrphs,M,n,m) = \forall i : 0 <= i < m-n : Pgrphs[M][i]=text[n+i]
  30.  
  31. */
  32. void  text2paragraphs(const char text[][LENGTH_LINE],
  33.      const int txtLns,
  34.                      char pgrphs[PARAGRAPH][LINES_PER_PARAGRAPH][LENGTH_LINE],
  35.      int *txtPgrphs,
  36.      int pgrphLns[])
  37. {
  38.  int n;
  39.  for(*txtPgrphs=(txtLns>0), n=pgrphLns[0]=0;  n<txtLns;n++)  
  40.    if (strlen(text[n])>1)
  41.      strncpy(pgrphs[*txtPgrphs-1][pgrphLns[(*txtPgrphs-1)]++],text[n],LENGTH_LINE);
  42.    else
  43.      (*txtPgrphs)++;
  44.  return;
  45. }
  46.  
  47. int main(int argc, char *args[])
  48. {
  49.  char text[LINES_PER_FILE][LENGTH_LINE];
  50.  int txtLns,txtPgrphs;
  51.  char paragraphs[PARAGRAPH][LINES_PER_PARAGRAPH][LENGTH_LINE];
  52.  int pgrphLns[PARAGRAPH];
  53.  
  54.  char *line=NULL;
  55.  ssize_t read;
  56.  size_t len;
  57.  
  58.  // Input
  59.  txtLns = 0 ;
  60.  while ((read=getline(&line,&len,stdin))!=-1)
  61.      strncpy(text[txtLns++],line,LENGTH_LINE);
  62.  free(line);
  63.  
  64.  // Process
  65.  text2paragraphs(text,txtLns,paragraphs,&txtPgrphs,pgrphLns);
  66.  
  67.  // Output
  68.  printf("%d\n",txtPgrphs);
  69.  for (int i=0; i< txtPgrphs ; i++)
  70.    {
  71.      printf("(%d,%d)\n",i,pgrphLns[i]);
  72.      for (int j=0; j< pgrphLns[i] ; j++)
  73. printf("%d.%d\t%s",i,j,paragraphs[i][j]);
  74.    }
  75. }
  76.  
Ahora comprobamos con el siguiente soneto en castellano del insigne Garcilaso de la Vega (quitando acentos y usando algunas formas del siglo XVI). Fichero poema.txt

Código:
bash-2.04$ cat poema.txt
A Dafne ya los brazos le crecian
y en luengos ramos vueltos se mostraban;
en verdes hojas vi que se tornaban
los cabellos qu'el oro escurecian;

de aspera corteza se cubrian
los tiernos miembros que aun bullendo 'staban;
los blancos pies en tierra se hincaban
y en torcidas raices se volvian.

Aquel que fue la causa de tal danio,
a fuerza de llorar, crecer hacia
este arbol, que con lagrimas regaba.

Oh miserable estado, oh mal tamanio,
que con llorarla crezca cada dia
la causa y la razon por que lloraba!


Veamos la salida en shell/UNIX. La primera linea marca el  número de parrafos. Despues, por cada párrafo se da el número de orden , el total de líneas por parrafo, y cada línea enumerada dentro de su párrafo.

Código:
bash-2.04$ ./main < poema.txt
4
(1,4)
1.1 A Dafne ya los brazos le crecian
1.2 y en luengos ramos vueltos se mostraban;
1.3 en verdes hojas vi que se tornaban
1.4 los cabellos qu'el oro escurecian;
(2,4)
2.1 de aspera corteza se cubrian
2.2 los tiernos miembros que aun bullendo 'staban;
2.3 los blancos pies en tierra se hincaban
2.4 y en torcidas raices se volvian.
(3,3)
3.1 Aquel que fue la causa de tal danio,
3.2 a fuerza de llorar, crecer hacia
3.3 este arbol, que con lagrimas regaba.
(4,3)
4.1 Oh miserable estado, oh mal tamanio,
4.2 que con llorarla crezca cada dia
4.3 la causa y la razon por que lloraba!


Hmm...  :-\ Demasiada formalidad para un poema tan humano. ;) ;)
50  Programación / Programación C/C++ / Re: ENIGMA SOBRE C . Terminación de programas en: 4 Marzo 2019, 20:34 pm
Una proposición falsa implica a todas las proposiciones, verdaderas o falsas. Que uno se encuentre con una aparente consistencia puede favorecer el entusiasmo pero no aporta prueba de nada; lamentablemente la pura lógica no se conmueve con expresiones emocionales :)

Pero bueno, este es tu acertijo y tus reglas. Por mí está bien, como digas.


Ejem, ejem.... Veo que has entendido parcialmente el razonamiento: de premisas falsas se llega conclusiones falsas. Es decir, el enigma podría decir que después de acabar el bucle infinito se podía llegar a cualquier cosa: que 2=2, 23=11+25, que la raíz de dos es un número racional.... Tanto verdaderas como falsas... En latín

Citar

EX IMPOSSIBILE QUOD LIBET SEQUITUR
(DE LO IMPOSIBLE SE SIGUE CUALQUIER COSA)

Pero no es de recibo desacreditar mi razonamiento por la "sorpresa", o "entusiasmo" en aras a la rigurosidad implacable de la lógica... El razonamiento es absolutamente válido y correcto. Lo que no sería es decir que se concluye que 1==0.

En ningún caso se ha probado que 1=0. Fíjate bien: En el enunciado el autor marcó on terminating the program, realzando al terminar el programa.... Cosa que no ocurre nunca, y por tanto, solo ocurre "en el infinito", lo que puede dar lugar a una contradicción, según el estándar C: 1=0. A partir de ahí, como tú dices, se puede sacar lo que quieras, en particular que assert(1) fallara.

Creo que es compatible con mostrar una reacción de asombro ante  un razonamiento riguroso y objetivo. Sin "smileys" se encuentra la prueba entre etiquetas geshi...

De todas formas, gracias loretz por tu comentario. ;)
Páginas: 1 2 3 4 [5] 6 7 8 9 10 11
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines