Ayuda programacion en C

SnAk0

Buenas, el problema es el siguiente:
Necesito hacer una practica para la universidad y me e quedado atascado, y me gustaria a ver si alguno se tira el royo y me ayuda a hacer el codigo.
a continuacion pongo el enunciado.

EJERCICIO 5. El bingo.

Construid el programa bingo.c que, usando una permutación aleatoria, genere un cartón de bingo de 3x5 casillas con números entre 0 y 99 (no puede haber números repetidos en el cartón). El programa utilizará otra permutación de los números 0 a 99 para simular la salida de bolas del bombo, e imprimirá por pantalla:

* El cartón.
* La secuencia de números extraídos del bombo hasta el momento en que se completa el cartón. Si el número está en el cartón imprimirá un asterisco al lado.
* Los momentos en los que se canta la primera columna y la primera línea.

A continuación se muestra una posible salida del programa:


Este es mi carton:

5 4 43 67 66
69 19 40 20 58

52 16 24 14 49

Estas son las bolas que salen del bombo:

64
80
36
69*
6
93
85
62
39
53
51
24*
25
17
30
21
96
52*
48
45
38
47
56
86
91
70
33
67*
54
5* COLUMNA
22
76
43*
0
98
28
94
26
18
34
2
95
78
84
61
49*
14*
20*
55
59
83
12
89
19*
68
72
79
73
90
81
3
1
65
40*
4*
29
99
16* FILA
82
35
13
10
9
92
71
77
46
63
58*
23
57
75
27
7
44
42
15
60
88
66* BINGO

Gracias de antemano.

javithelong

¿Cual es el problema? ¿hacer una permutación aleatoria? saca números ordenados del 1 al 99 en una tabla, y luego los desordenas a base de números aleatorios.

haces algo en plan:
de i=1 a 99: tabla = i

y luego vas haciendo swap (intercambiando valores):
de i=1 a 99: swap(tabla, tabla[aleatorio])

elkaoD

Una opción facililla para no hacer un array bidimensional y no tener que tirar de bucles (Hacky que te cagas) es hacer cuatro arrays, uno int carton[100], int bola[100], int fila[3], int total, inicializados a 0.

carton = x; donde i = numero en el cartón y x = fila en la que está

bola = 1; donde i = la bola que sale (Para no repetir bolas ni cartones)

Cuando salga la bola, if carton != 0 comprueba el valor de carton y la fila en la que está, sumando uno a fila[x], y sumando uno tambien a total.

Si total = 15 o fila[x] = 5, tenemos bingo o linea respectivamente.

Espero haberme explicado. Tambien podría estar guay cuando incializas tener un array carton para no repetir posiciones en este, aunque puede obviarse si vas dando a x (en carton) del 1 al 15

La otra opción, más "elegante" pero que tira demasiado de bucles para mi gusto, es chequear fila y columna en un array bidimensional carton [5][3]

SnAk0

si podeis postear codigos lo agradeceria es que estoy bastante pez xD.pero aun asi gracias por contestar pero no e entendido muy bien lo de los array

cabron

¿Estas atascado en algún lugar en particular, o pretendes que te lo haga alguien entero?

Eres tú el que debería postear código, y decir que dudas tienes o que es lo que no te sale, y entonces te podría ayudar, pero vamos, yo por lo menos no te voy a hacer los deberes.

Josepanaero

Como dice #5, aquí no te va a faltar gente q te ayude con algún problema en concreto. Pero nadie te va a hacer los deberes. Es más, yo mismo tengo amigos q han tenido q hacer una práctica muy parecida, pero naturalmetne q no me voy a molestar en pedírsela para dársela a alguien q no se molesta en hacerla.

Ponte a hacerla y postea dudas concretas, q en eso sí vas a tener a mucha gente q te ayude.

WaYnE10

tiene razon #6 , para que te vamos a dar un codigo si no sabes lo que es un array, luego sino lo pasaras mal a lo largo de la carrera. Piensa que C se usará quizas muxo en la carrera, lo que deberias es aprnder a programar y las dudas concrtas que te salgan pueds postearlas por aki

elkaoD

¿Es que nadie va a comentar lo cutre de mi idea? xD

Soltrac

Me parece más "elegante" la idea de la matriz bidimensional, pero bueno, tu idea sirve kaod :D

elkaoD

Sí, si yo mismo reconozco que mi idea es hacky y cutre que te cagas, pero es que yo tiendo a ser hacky y cutre que te cagas, ahorrar ciclos en cuanto puedo, etc. Es la costumbre de programar en ASM :P

Con la matriz bidimensional tiene que ir chequeando uno a uno con bucles en cada bola y me parece un malgasto de CPU increíble. Algunos dirán que para las CPUs que tenemos, sobra, y están en lo cierto, pero soy un puto manías xD

Para #1, me aburría así que te he hecho el código, lo tienes en http://pastebin.com/f1f6d582b , pero le he añadido algún que otro bug y cosa mal hecha, para que te molestes en intentar entender el código, ver cómo funciona y arreglarlo tú mismo. De hecho le he añadido alguna que otra feature como posibilidad de definir numero de bolas y ancho y alto del carton, y porque no estoy tan aburrido como para ponerme a parsear argumentos xD

JuAn4k4

#10 Ahorras ciclos y malgastas memoria no ?

AdemŽças de que te faltaría la columna, para lo que necesitarías, otro vector mas ? carton[100] ; carton = y; donde i es el número del carton e "y" la columna donde está.


Por cierto, te has dado cuenta que dices de "ahorrar ciclos de reloj" y me cascas esto:


for (i=0; i<ANCHO*ALTO; i++)
{
...
random = rand() % BOLAS;
if (carton[random] != VACIO) i--;
...
}

Imaginate para rellenar el ultimo hueco, hasta que salga el ultimo puto numero que queda. Y no te digo nada con todo el resto, los primeros aun, pero cuando llegas a la mitad...


PD: No entiendo
printf ("%d-* ",ncifras(BOLAS - 1),carton_ordenado[j]);

Esto pintara solo el numero de cifras no ?
Seria en plan:

if ((numeroApintar / 10) >= 0 )
{ pintar "%d" }
else
{ pintar "0%d" }

elkaoD

Lo de la memoria, ¿Qué son, 230sizeof(INT) bytes por array? Vamos a ver, hasta el ordenador más viejo tiene 230sizeof(INT) bytes de memoria que se pueden usar xD Además, la memoria no es un problema hoy en dia, pero ajustar en ciclos de CPU aunque sea en programas cortos ayuda a ajustar cuando haces cosas más largas (Especialmente en ASM, prográmate tu un motor gráfico viejo para DOS acostumbrado a tirar de arrays y bucles anidados xD), si te hace sentir mejor cámbialos de int a char, y gastas sólo 230bytes de memoria en variables. Al ahorrar en código, más de 230 bytes me he ahorrado también, y esos 230 bytes también van a parar a la memoria, así que creo que compensa :) Especialmente sabiendo que los bucles son casi lo que peor lleva el compilador para optimizar, especialmente anidados.

Lo de la columna no lo he captado, si quieres te paso el código sin bugs y ves que funciona sin la matriz esa que dices. Aún así, si he entendido bien lo que quieres decir y sigues leyendo el código verás que la solución es muy fácil. posicion_lineal%ancho_carton = número de columna en el que está.

Y lo de rellenar ese array. Date cuenta de que va de i=0 hasta i=ANCHO*ALTO, no pone TODAS LAS BOLAS eligiéndolas una por una de forma aleatoria. Elije 15 bolas de forma aleatoria y las setea. El "if (carton[random] != VACIO) i--;" es para cuando la bola ya está seteada, cosa rara de 15 entre 100 bolas :)

Y respecto a lo del printf, ten en cuenta que he metido bugs en el código, uno de ellos es ese. De hecho el código tal y como está ahí compila, pero no funciona bien, nunca canta bingo.

Si pones "%-*d", es decir, los modificadores antes del d, te printea lo correcto, con el * haces que se autoajuste el ancho (Es decir, con 77 printea "77" , pero con un 4 printea " 4", especificado por una variable int, precediendo en los argumentos del printf al int que queremos printear), y el guion es para decir que se alinea a la derecha el número. Yo tampoco sabía que se podía hacer eso, y lo hice con un bucle for (Recuerda que las bolas pueden ser 100 o 10000, con tu código de ejemplo sólo vale para 100), pero curioseando por el man de printf lo vi y dije, joder, sería de tontos no aprovecharlo.

cabron

#12:

"Lo de la memoria, ¿Qué son, 230sizeof(INT) bytes por array? Vamos a ver, hasta el ordenador más viejo tiene 230sizeof(INT) bytes de memoria que se pueden usar xD"

Lo mismo se puede aplicar a la cpu... hoy día el que menos tiene, usa una CPU a más de 1ghz, es absurdo "ahorrar ciclos" de CPU en cualquier programa que hagas, eso solo tiene sentido en programas específicos corriendo en hardware específico, donde no te queda más remedio que optimizar al máximo, pero en general, no hay ninguna necesidad de buscar soluciones rebuscadas para que un bucle de 7 vueltas menos, es mucho mejor buscar una solución fácil de entender.

elkaoD

#13, no estamos hablando de programas, si no, por ejemplo de un juego, que es por donde pretendo moverme. Incluso tú mismo dices que hay programas que sí son CPU intensive.

Prefiero una IA rápida a una IA que consuma poca memoria.

Prefiero FPS capados por la GPU que capados por la CPU.

"hoy día el que menos tiene, usa una CPU a más de 1ghz"
Excepto el que posee, por ejemplo una NDS. Tiene dos CPUs ARM7 y 9 de 33 y 66MHz respectivamente (Hablo de memoria, no tengo ni idea de si me he equivocado en las cifras), es decir, bastante limitadillos. También tiene sólo 4MB de RAM, lo cuál es una putada dado que tienes que almacenar gráficos y tal. Sin embargo, 230 bytes frente a 4MB no es mucho, incluso aunque tiene la irrisoria cantidad de 4MB. Ahorrar ciclos de CPU en un juego es crucial, y creo que compensa.

Vale, tú mismo dices que es para hardware específico, pero es que es ESE hardware específico el que me interesa. ¿Además, no será mejor saber hacerlo de las dos formas? Si me preocupo de saber en programas pequeños qué hacer para ahorrar ciclos, y me preocupo de saber cómo ahorrar memoria, tengo mucho ganado. Gracias a preocuparme por optimizar, aprendí cosas como que no es lo mismo "mov eax, 0" que "xor eax, eax" :)

Por otra parte, os entráis mucho en el tema optimización cuando es lo que menos me importa. Prefiero la solución alternativa e ingeniosa, programo por diversión :) Lo que me gusta no es la solución, sino como llegar a ella. Pensar las ideas es lo que me gusta, programarlas es sólo la forma (Inevitable) de plasmarlas, como el que dibuja un cuadro.

cabron

#14:

No sé si te das cuenta que en tu respuesta no me cuentas nada que no haya dicho yo ya xD

He reconocido que existen casos en los que sí tiene sentido la optimización del código a esos extremos, lo que he dicho, es que en general no tiene sentido, vamos, que es una práctica que solo se hace cuando hay un motivo, no siempre y por que sí.

Que luego tú lo quieras hacer por que te van las soluciones rebuscadas, es algo ya personal tuyo y ahí no me meto, pero como práctica común de desarollo, no es algo ni bueno ni práctico oscurecer el código con implementaciones rebuscadas para ahorrar tiempo de CPU, salvo que los requisistos del programa impongan unas exigencias de ejecución que solo se pueden satisfacer con este tipo de optimizaciones.

Poisonous

"printear" .... pq no usar palabras que salgan en el diccionario o al menos que sean de un uso mas extendido? xd

solo te falto poner displayear o cualquier burrada asi

elkaoD

#15, ya, ya, si básicamente lo que te decía era eso, que tenías razón, pero que bajo mi punto de vista conviene saber tanto hacerlo de una forma como otra, limitarse a hacerlo de una forma, pues eso, limita xD

#16, probablemente porque hablo más en inglés que en españo. Justo en el momento de redactar el post (Digo, la respuesta) estaba hablando con un par de amigos estadounidenses por MSN. También puede ser porque C usa una sintaxis y nombres de funciones en inglés, y por eso hablamos de bucles "for", y por eso printf no imprime sino que "printea" xD Si te viene mejor "imprime", yo edito el post, pero dado que estamos hablando de la función printf, lo primero que se me viene a la cabeza es printear xD

Me has entendido, que es lo importante, ¿No? ;)

cabron

En eso estoy de acuerdo, siempre está bien saber como optimizar código para cuando te toca hacerlo.

sh0ty

Este es mi codigo. He intentado ser lo mas breve posible pero no se como generar numeros aleatorios, si alguien puede tomarse la molestia de editar mi codigo se lo agradeceria.

http://pastebin.com/m547bd0c1

LOc0

EDITADO para que no salgan repetidos.

http://pastebin.com/m78080af4

Salu2 ;)

PD: sí, variables globales y "halgoritmo" "heficiente" "hamericano", pero la cosa era corregir por encima su código, que lo entendiera y funcionase.

ExTiNcT_

Porque ayer acabe mi practica de programacion.. pero otro dia tamb posteare a ver si alguien me la hace xDD

JuAn4k4

#19 Alaaa variables globales
En RecorrerCarton tendrias que meter:
"char Carton[3][5], Filas[3], Columnas[3]", como estaticas. Y "Total" en el main pasandoselo a RecorrerCarton como parametro por referencia para que lo modifique.

Hay varias librerias para generar nºs pseudorandoms de esos cutres.

PD: Has programado a lo "americano" (creo) haciendo una funcion con 2 usos y dentro el if que te diferencia uno de otro dependiendo de si hay o no parametro.

elkaoD

Estoy deseando llegar a casa, compilar ambos y comprobar que despues de defender a capa y espada mi método, es más eficiente su código que el mío xD En momentos como este echo de menos mi frontend online de GCC :)

(Jodido Steam, por tu culpa he reiniciado a Windows)

JuAn4k4

#23 No lo es, de hecho no funciona, ya que los numeros aleatorios del carton se pueden repetir.

Editado: Ostias ahora ha editado el codigo xD no me habia fijado.

Si no te interesa ahorrar memoria y quieres hacer ese bucle mas eficiente yo haria:

Tener otro vector de usados[100] , y poner a 1 los que usas para despues hacer while ( usado ) { i = rand()%100; } usado=1;

Ahora no estoy seguro de que usado cuando no esta inicializado da false, eso ya dependera del compilador, con gcc creo que da false pero no estoy seguro ahora mismo. Seria mirarlo y hacerlo al reves, con cuidado y te ahorras el inicializarlo xD

PD Edit : Pero si es lo que haces solo que cuando esta usado vuelves al bucle otra iteracion mas, ¿para eso es mas logico buscar otro random no ? que en definitiva hace lo mismo solo que comparando despues mas cosas y tal.

LOc0

#24 Habla solo xDDDDDDDDDDDD

A ver, el algoritmo "requete-güeno" es el de #3 pero el de #1 no está tan mal leñe (vale, el código que he pegado es bastante chapucerillo, y la parte de evitar el repetido con el C--, pues eso xD, pero insisto que tenía que ser lo más parecido a lo que puso #19)

Salu2 ;)

elkaoD

:$

sh0ty

Se me resiste la practica de mierda. Ahora que he vuelto a escribir el codigo y editado parte de la modificacion de Loc0 (por cierto gracias) el programa se para despues de poner unos cuantos numeros en la pantalla. Pero me da la impresion que debe ser culpa de la funcion rand() porque sino no me lo explico.
Agradeceria que alguien me ayudara.

http://pastebin.com/m8609d71

LOc0

http://pastebin.com/m35d7d930

Por cierto, usar char para almacenar números es totalmente válido, pero para programitas de este tipo y sobre todo si estás empezando puede ser un poco lioso. Utiliza int, que por gastar un par más de bytes no pasa nada.

Salu2 ;)

Gn0m4

Si no lo ves a ojo pon un ruptura de control en el bucle que saca numeros y visualiza al mismo tiempo los valores que van saliendo y donde se guardan (si es que se guardan en algun lado, que no me he leido tu ejercicio).
De esta forma iras siguiendo el proceso y veras donde peta.
Otra opcion es que alguien te lo arregle, pero te recomiendo que vayas viendo tu como funciona esto, porque algun dia te tocara a ti sacarte los problemas.

Edito: Parece que ya te lo han arreglado.

JuAn4k4

Se me olvido comentar que no está contemplada la opcion de que al completar fila completes tambien columna, justo a la vez, pero vamos que hay que ser tiquis-miquis.