El equipo de futbol de Bolullos de Ayala ha llegado a la final

Anuncio
Informatikaren Oinarriak eman ta zabal zazu
Universidad
del país vasco
2008 / 2009 Ikasturtea
Euskal herriko
unibertsitatea
Bilbo, 2009ko ekainak 10
Denbora: 2:15
'Bollullos de Ayala' futbol taldea probintziaren txapelketan finalera heldu da. Biztanleak poz­pozik daudenez, finala ikustera denek joan nahi dute, baina ez dago behar adina sarrera. Hori dela eta, herriko alkateak, arazorik ez izateko, sarrerak biztanleen artean zozketatuko ditu. Gainera, familiak eta lagun taldeak ez banatzearren, zozketa taldeka egingo da.
Prozesua honako era honetan burutuko da:
1.
Taldeka parte hartu ahal da zozketan. Taldean 1, 2, 3, 4 edo 5 kide egon daitezke. Baina, pertsona bakoitzak talde bakar batean eman dezake izena.
2.
Zozketa egiteko, talde bakoitzari zenbaki batzuk emango zaizkio; zenbaki kopurua, kideen kopuruaren funtzioan dagoelarik. Eta taldeko zenbakiren bat sarituta suertatuz gero, taldeko partaide guztiek partidua ikusteko sarrera jasoko dute. Talde bakoitzari sari bakarra tokatu ahal zaio. Hau da, nahiz eta saritutako zenbaki bat baino gehiago eduki, partidua ikusteko sarrera bakarra emango zaio taldekide bakoitzari. Bestela esanda, sari bat lortuta, hurrengoak ez dira kontuan izango. Hori dela eta, programa informatikoa egiteko agindua eman digu alkateak zozketaren arazoak konpontzeko: taldekideen izena eman, ausazko zozketa egin, saridunen zerrenda atera, …
DATUEN EGITURA:
Analisia egin ondoren, gure programak erabiliko dituen datuen egiturak honako hauek izango direla erabaki dugu: •
“taldeak.dat” izeneko fitxategia. Zozketan izena eman duten taldeen informazioa gordeko du honek. Talde bakoitzaren erregistroak honako informazioa edukiko du:
Talde Zenbakia
Integer
Taldearen identifikatzailea
Zenbaki korrelatiboak (1, 2,…)
Taldekide kopurua
Integer
1eta 5 bitarteko zenbakia
Kateen arraya
Taldekideen NAk
Taldekideen NA* zerrenda
* Nortasun Agiria
Adibi
dez:
Taldea
Perts.
Kop.
1
1
11111111
2
2
22222222
12345678
3
2
12121212
12121213
4
1
22223333
5
4
33333333
Taldeko pertsonen NA
44444444
55555555
66666666
Bestalde, taldeen eta zozketaren zenbakien arteko erlazioak gordeko dituen “zozketa.dat” fitxategia dugu. Honek biltegiratzen duen informazioa oso garrantzitsua da; honen bidez, saritua izan den jakin dezake talde bakoitzak. (Saria izanez gero, informazio hau Zenbakia eremuan egongo da, non zozketaren zenbaki sariduna gordeko den):
Talde Zenbakia
Integer
Taldearen identifikatzailea
Taldekide Kopurua
Integer
1eta 5 bitarteko zenbakia
Tartearen beheko LongInt
muga
Zozketan parte hartzeko, taldeari eman zaizkion zenbakien beheko muga
Tartearen goiko muga
LongInt
Zozketan parte hartzeko, taldeari eman zaizkion zenbakien goiko muga
Zenbakia
Integer
Zozketan sarituak izanez gero, saritutako zenbakia, bestela 0
Adibide
z:
Zozketa egin aurretik:
Taldea
Perts
Kop
1
1
2
2
3
2
4
1
5
4
.
Zozketa egin ondoren:
Honako zenbakiak atera badira: 15, 29, 24, 3
Beheko Goiko
Zenbakia
Muga
Tartea Muga
Tartea
1
5
0
6
11
12
17
18
22
23
30
30
.
Taldea
Perts
.
Kop
Beheko Goiko
Zenbakia
Muga
Tartea Muga
Tartea
1
1
1
0
2
2
6
0
3
2
0
4
1
0
5
4
5
11
12
17
18
22
23
30
3
0
15
0
29
PROGRAMA:
Menu honen bidez antolaturik dagoen programa bakarra egingo da:
Menua
1. Zozketan parte hartzeko talde berria gehitu
2. Partiduko sarreren zozketa egin
3. Saridunen NAak zerrendatu
0. Amaitu
Exekuzioaren hasieran, taldeen fitxategiaren izena eta zozketaren fitxategiaren izena eskatuko ditu programak. Taldeen fitxategia existitzen den egiaztatu ondoren, ez badago sortu egingo du.
OHARRA:
Programak fitxategiaren izena eskatuko du eta '.DAT' luzapena gehituko dio.
Adibidea: fitxategiaren izena eskatuta, 'GRP-09' irakurtzen badu, 'GRP-09.DAT' izena sortuko du.
Gero, aurreko menua pantailaratuko du eta erabiltzaileak hautatutakoa exekutatuko du ( prozesu hau behin eta berriro egingo da Amaitu aukeratu arte) 1. Aukera: Zozketan
parte hartzeko talde berria gehitu Taldekideen kopurua galdetuko du. Honen ondoren, taldekide guztien Nortasun Agiria irakurriko ditu (Norbait beste talde batean badago errore­mezua emango du eta berriro NA eskatuko du). Informazio honekin eta taldeari identifikatzailea eman ondoren (1, 2, 3,…), taldeen fitxategian elementu berri bat gehituko du.
Adibidea
:
Taldekide kopurua sartu: (1..5): 2
NA : 22222222
NA : 11111111
HONEK IZENA EMAN DU BESTE TALDE BATEAN, SARTU BESTE PERTSONA BAT,MESEDEZ
NA : 12345678
2. Aukera: Partiduko sarreren zozketa egin Lehenengo eta behin zozketaren fitxategia sortuko da. Honetan, taldeak beste elementu izango dira. Eta taldeari dagokion zenbaki kopurua taldekide kopuruaren funtzioan dago, honako formula honen bidez: Zenbaki kopurua = 5 + ( Taldekide kopurua – 1 )
Adibidea: Taldekide bat = 5 Zenbaki; 2 Taldekide = 6 Zenbaki; … 5 Taldekide = 9 Zenbaki.
Zozketaren zenbakiak kontsekutiboak izango dira adibidean azaltzen den bezala:
1. Taldea: taldekide 1, 5 zenbaki ⇒ tartea 1 .. 5
2. Taldea: 2 taldekide, 6 zenbaki ⇒ tartea 6 .. 11
3. Taldea: 2 taldekide, 6 zenbaki ⇒ tartea 12 .. 17
4. Taldea: taldekide 1, 5 zenbaki ⇒ tartea 18 .. 22
5. Taldea: 4 taldekide, 8 zenbaki ⇒ tartea 23 .. 30
Taldea
Grupo
Zozketarako 30 Zenbaki eman dira adibidean
Beheko
Num
Perts
Inf
Comp
Kop
Muga
Rango
1
1
1
2
2
6
3
2
4
1
5
4
Goiko
Sup
Nú
mero
Zenbakia
Muga
Rango
5
0
0
11
0
12
17
18
22
23
30
0
0
Zenbakia izeneko eremua 0 balioz hasieratu behar da.
Jarraian, zozkatzen diren sarreren kopuru minimoa eskatuko da. Kopuru hau zozketan sartzen diren pertsonen kopurua baino txikiagoa edo berdina dela ematen da. Hau ez da egiaztatu behar (aurreko adibidean, sarrera kopurua 10 baino txikiagoa edo berdina dela suposatzen da) Amaitzeko, zozketan sartzen den azken zenbakia lortuko du programak (adibidean 30 izango da) eta saritutako zenbakiak ausazko zenbakien bidez sortuko dira, sarrera guztiak esleitu arte.
Saritutako zenbaki bakoitzeko ea zein taldek duen bilatuko da; eta talde honek aurreko saririk ez badu jaso, taldekideei sarrera bana esleituko zaie eta Zenbaki eremuari zozketan atera den zenbakia biltegiratuko da.
A
d
i
b
i
d
e
a
:
Zozketa eman ondoresn:
Sari hauek atera badira 15, 29, 24, 3
Zenbakia eremua aldatuko da 3, 5 eta 1. taldeetan (orden honetan)
.
Taldea
Perts
.
Kop
Beheko
Muga
Tartea
1
1
1
2
2
6
3
2
4
1
5
4
Goiko
Zenbakia
Muga
Tartea
5
11
12
17
18
22
23
30
3
0
15
0
29
OHARRAK: Logikoa denez, sari kopurua ez dator bat sarrera kopuruarekin. Izan ere, sari bakoitzeko taldekide beste sarrera ematen baita.
Era berean, sarrera kopuru minimoa eskatu da lehen. Honela, saritutako azken taldeak behar beste sarrera ziurta daiteke
Adibidea: Zozketan gutxienez 7 sarrera badago: 15, 29, 24, 3 zenbakiak (orden honetan ) ateratzen badira , 7 sarrera (2 + 4 + 0 + 1) banatuko dira
3, 6, 12, 29 zenbakiak (orden honetan ) ateratzen badira , 9 sarrera (1 + 2 + 1 + 4) banatuko dira.
3. Aukera: Saridunen
NAak zerrendatu Zozketaren fitxategia existitzen dela egiaztatu ondoren, honako era honetan pantailaratuko dira sarituen datuak:
Tald Behek .. Goiko Zenbakia NA­ak
1 1 .. 5 3 11111111
3 12 .. 17 15 12121212 12121213
5 23 .. 30 29 33333333 44444444 55555555 66666666
0. Aukera: Amaitu
Programaren exekuzioa amaituko da.
Gutxienez egin behar den programak honako azpiprograma hauek izan behar ditu:
•
PertsonaBaDago: azpiprogramak sartutako NA zenbakiak taldeko fitxategian aurretik badagoela ala ez jakinarazten du
•
ZozketaFitxategiSortu: azpiprogramak talde fitxategitik dauden datutik Zozketa fitxategia sortuko du
•
AzkenZenbakia: azpiprogramak zozketan emandako azken zenbakia itzuliko du. Zenbaki hau zozketa fitxategi azken erregistroren goiko mugaren balioa izango da
•
TaldeSariemaileBilatu: azpiprogramak pasatutako zenbakia (Taldearen identifikatzailea bezala hartuz) taldea aurretik sari­emaile bada zozketa fitxategian duen kokapena itzuliko du, Bestela, –1 itzuliko du •
TaldekideakEskuratu: azpiprogramak taldearen identifikatzailea hartuz taldekide guztien NA itzuliko du
•
Ariketa honen kalifikazioa nota osoaren % 75koa da
•
Gainditzeko, azterketa osatzen duten parte bakoitzaren notaren % 50a lortzea, gutxienez, behar­beharrezkoa da PROGRAM FI_Jun_2009 ;
USES
Crt ;
CONST
EXT_ARCHIVOS
= '.DAT' ;
TYPE
tsCadenas = STRING [15] ;
tsCadDNI = STRING [8] ;
tasListaDNIs = ARRAY [1..5] OF tsCadDNI ;
trgGruposPersonas = RECORD
iNumGrupo,
iNumComp
: Integer ;
asDNIs
: tasListaDNIs ;
END ;
trgParticipaciones = RECORD
iNumGrupo,
iNumComp,
iRangoInf, iRangoSup,
iNumSorteo : Integer ; { Si ha salido en el sorteo }
{ Si NO vale 0
}
END ;
tfbrgFicherosGrupos
= FILE OF trgGruposPersonas ;
tfbrgFicherosParticipaciones = FILE OF trgParticipaciones ;
VAR
cOpcion, cEspera : Char ;
sNomFichGrupos, sNomFichSorteo: tsCadenas ;
FUNCTION fncLeerOpcion : Char ;
VAR
cOpcion : Char ;
BEGIN
ClrScr ;
Writeln ('--------------Menú de opciones ---------------') ;
Writeln ('1 Añadir nuevo grupo para el sorteo') ;
Writeln ('2 Realizar el sorteo') ;
Writeln ('3 Listar los grupos
afortunados en el sorteo');
Writeln ('0 Terminar') ;
Write
('Pulsa el codigo de la opcion: ') ;
REPEAT
cOpcion := ReadKey ;
UNTIL ('0' <= cOpcion) AND (cOpcion <= '3') ;
WriteLn (cOpcion) ;
fncLeerOpcion := cOpcion ;
END ; { fncLeerOpcion }
PROCEDURE CrearSiNoExiste (sNomFichGrupos : tsCadenas) ;
VAR
fbrgFichGrupos : tfbrgFicherosGrupos ;
BEGIN
Assign (fbrgFichGrupos, sNomFichGrupos) ;
{$I-}
Reset (fbrgFichGrupos) ;
{$I+}
IF IOResult <> 0 THEN
Rewrite (fbrgFichGrupos) ;
Close (fbrgFichGrupos) ;
Fundamentos de Informática
Junio­2009
1
END ; { CrearSiNoExiste }
Fundamentos de Informática
Junio­2009
2
FUNCTION fnboExistePersona (sDNIBuscado : tsCadDNI ;
sNomFichGrupos : tsCadenas) : Boolean ;
VAR
rgGrupo
: trgGruposPersonas
;
fbrgFichGrupos : tfbrgFicherosGrupos ;
i
: Integer ;
boEncontrado
: Boolean ;
BEGIN
boEncontrado := FALSE ;
Assign (fbrgFichGrupos, sNomFichGrupos) ;
Reset (fbrgFichGrupos) ;
WHILE NOT EOF (fbrgFichGrupos) DO
BEGIN
Read (fbrgFichGrupos, rgGrupo) ;
WITH rgGrupo DO
FOR i := 1 TO iNumComp DO
IF asDNIs[i] = sDNIBuscado THEN
boEncontrado := TRUE ;
END ;
Close
(fbrgFichGrupos) ;
fnboExistePersona := boEncontrado
END ; { fnboExistePersona }
PROCEDURE AniadirGrupoAlFichero (CONST rgGrupo
: trgGruposPersonas ;
sNomFichGrupos: tsCadenas) ;
VAR
rgGrupoNuevo
: trgGruposPersonas ;
fbrgFichGrupos : tfbrgFicherosGrupos ;
BEGIN
Assign (fbrgFichGrupos, sNomFichGrupos) ;
Reset (fbrgFichGrupos) ;
Seek
(fbrgFichGrupos, FileSize (fbrgFichGrupos)) ;
rgGrupoNuevo := rgGrupo ;
{ Rellenar el campo iNumGrupo antes de escribir el GRUPO en el fichero}
rgGrupoNuevo.iNumGrupo := FileSize (fbrgFichGrupos) + 1 ;
Write (fbrgFichGrupos, rgGrupoNuevo) ;
Close (fbrgFichGrupos) ;
END ;
PROCEDURE AniadirGrupo (sNomFichGrupos: tsCadenas) ;
VAR
rgGrupo : trgGruposPersonas ;
i
: Integer;
BEGIN
WITH rgGrupo DO
BEGIN
Write ('Escribe número de personas del grupo (1..5): ') ;
ReadLn (iNumComp) ;
i := 1 ;
WHILE i <= iNumComp DO
BEGIN
Write ('
ReadLn (asDNIs[i]) ;
Fundamentos de Informática
DNI de la persona: ') ;
Junio­2009
3
IF fnboExistePersona (asDNIs[i], sNomFichGrupos) THEN
Writeln ('ESA PERSONA YA ESTA APUNTADA EN OTRO GRUPO')
ELSE
i := i + 1 ;
END ;
{ No se ha rellenado el campo iNumGrupo.
Se rellenará antes de escribir el GRUPO en el fichero }
END ;
END ;
AniadirGrupoAlFichero (rgGrupo, sNomFichGrupos) ;
PROCEDURE CrearFichSorteo (sNomFichGrupos, sNomFichSorteo: tsCadenas) ;
VAR
rgGrupo
: trgGruposPersonas ;
fbrgFichGrupos : tfbrgFicherosGrupos ;
rgParticipacion : trgParticipaciones ;
fbrgFichSorteo : tfbrgFicherosParticipaciones ;
iUltimoNumero
: Integer ;
BEGIN
Assign (fbrgFichGrupos, sNomFichGrupos) ;
Reset
(brgFichGrupos) ;
Assign (fbrgFichSorteo, sNomFichSorteo) ;
Rewrite (fbrgFichSorteo) ;
iUltimoNumero := 0 ;
WHILE NOT EOF (fbrgFichGrupos) DO
BEGIN
Read (fbrgFichGrupos, rgGrupo) ;
WITH rgParticipacion DO
BEGIN
iNumGrupo
:= rgGrupo.iNumGrupo ;
iNumComp
:= rgGrupo.iNumComp ;
iRangoInf
:= iUltimoNumero + 1 ;
iRangoSup
:= iUltimoNumero + 5 + (rgGrupo.iNumComp - 1 ) ;
iNumSorteo
:= 0 ;
iUltimoNumero := iRangoSup ; { para la siguiente vez }
END ;
Write (fbrgFichSorteo, rgParticipacion) ;
END ;
Close (fbrgFichGrupos) ;
CLose (fbrgFichSorteo) ;
END ;
FUNCTION fniUltimoNumero (sNomFichSorteo : tsCadenas) : Integer ;
VAR
rgParticipacion : trgParticipaciones ;
fbrgFichSorteo
: tfbrgFicherosParticipaciones ;
iUltNumSorteo : Integer ;
BEGIN
Assign (fbrgFichSorteo, sNomFichSorteo) ;
Reset (fbrgFichSorteo) ;
Seek (fbrgFichSorteo, FileSize (fbrgFichSorteo) - 1 ) ;
IF FilePos (fbrgFichSorteo) > 0 THEN
BEGIN
Read (fbrgFichSorteo, rgParticipacion) ;
iUltNumSorteo := rgParticipacion.iRangoSup
END
ELSE
iUltNumSorteo := 0 ;
Close (fbrgFichSorteo) ;
Fundamentos de Informática
Junio­2009
4
fniUltimoNumero :=
END ;
iUltNumSorteo ;
FUNCTION fniBuscarGrupoPremiado (iNumeroAleat: Integer ;
sNomFichSorteo: tsCadenas) : Integer ;
VAR
rgParticipacion : trgParticipaciones ;
fbrgFichSorteo : tfbrgFicherosParticipaciones ;
boEncontrado
: Boolean ;
BEGIN
Assign (fbrgFichSorteo, sNomFichSorteo) ;
Reset (fbrgFichSorteo) ;
boEncontrado := FALSE ;
WHILE NOT EOF (fbrgFichSorteo) AND NOT boEncontrado DO
BEGIN
Read (fbrgFichSorteo, rgParticipacion) ;
WITH rgParticipacion DO
IF (iRangoInf <= iNumeroAleat) AND
(iNumeroAleat <= iRangoSup) THEN
boEncontrado := TRUE
END ;
IF boEncontrado AND (rgParticipacion.iNumSorteo = 0) THEN
{ Encontrado el grupo con ese número. Al que no le ha tocado antes }
fniBuscarGrupoPremiado := FilePos (fbrgFichSorteo) - 1
ELSE
fniBuscarGrupoPremiado := -1 ;
Close (fbrgFichSorteo) ;
END ; { fniBuscarGrupoPremiado }
PROCEDURE SortearEntradas (sNomFichSorteo: tsCadenas) ;
VAR
iNumeroMayor, iEntradasDisponibles, iEntradasAsignadas : Integer ;
rgParticipacion
: trgParticipaciones ;
fbrgFichSorteo
: tfbrgFicherosParticipaciones ;
iNumeroAleat, iPosicPremiado : Integer ;
boEncontrado
: Boolean ;
BEGIN
Randomize ;
Write ('Escribe número mínimo de entradas a sortear : ') ;
ReadLn (iEntradasDisponibles) ;
iNumeroMayor := fniUltimoNumero (sNomFichSorteo) ;
iEntradasAsignadas := 0 ;
WHILE iEntradasAsignadas < iEntradasDisponibles DO
BEGIN
iNumeroAleat := Random (iNumeroMayor) + 1 ;
iPosicPremiado := fniBuscarGrupoPremiado (iNumeroAleat, sNomFichSorteo) ;
IF iPosicPremiado <> -1 THEN
BEGIN {------------------ Actualizar el fichero de Sorteo ----------}
Assign (fbrgFichSorteo, sNomFichSorteo) ;
Reset (fbrgFichSorteo) ;
Seek
(fbrgFichSorteo, iPosicPremiado) ;
Read (fbrgFichSorteo, rgParticipacion) ;
rgParticipacion.iNumSorteo := iNumeroAleat ;
Seek (fbrgFichSorteo, iPosicPremiado) ;
Write (fbrgFichSorteo, rgParticipacion) ;
Fundamentos de Informática
Junio­2009
5
Close (fbrgFichSorteo) ;
iEntradasAsignadas := iEntradasAsignadas + rgParticipacion.iNumComp ;
END { IF }
END ; { WHILE }
END ; { SortearEntradas2 }
PROCEDURE ObtenerPersonasGrupo (
iNumeroGrupo
sNomFichGrupos
VAR
asDNIsGrupo
VAR iNumCompGrupo
:
:
:
:
Integer ;
tsCadenas ;
tasListaDNIs ;
Integer ) ;
{ Dado el uso que se va a hacer de este subprograma:
No sería necesario retornar la información iNumCompGrupo,
pues desde donde se efectúa la llamada ya se conoce esa información }
VAR
rgGrupo
: trgGruposPersonas ;
fbrgFichGrupos : tfbrgFicherosGrupos ;
boEncontrado
: Boolean ;
BEGIN
Assign (fbrgFichGrupos, sNomFichGrupos) ;
Reset (fbrgFichGrupos) ;
boEncontrado := FALSE ;
WHILE NOT EOF (fbrgFichGrupos) AND NOT boEncontrado DO
BEGIN
Read (fbrgFichGrupos, rgGrupo) ;
IF rgGrupo.iNumGrupo = iNumeroGrupo THEN
BEGIN
asDNIsGrupo
:= rgGrupo.asDNIs
;
iNumCompGrupo := rgGrupo.iNumComp ;
boEncontrado := TRUE ;
END ;
END ;
Close (fbrgFichGrupos) ;
END ; { ObtenerPersonasGrupo }
PROCEDURE ListaGruposPremiados (sNomFichPremiados, sNomFichGrupos : tsCadenas);
VAR
rgParticipacion
: trgParticipaciones ;
fbrgFichPremiados : tfbrgFicherosParticipaciones ;
asDNIs
: tasListaDNIs ;
iNumCompGrupo, i : Integer ;
BEGIN
Assign (fbrgFichPremiados, sNomFichPremiados) ;
Reset (fbrgFichPremiados) ;
Writeln ('Listado de Grupos premiados') ;
Writeln ;
Writeln ('Grupo':5, 'Inf':7, ' .. ',
'Sup':3, 'Premiado':10, ' DNIs de las personas del grupo')
Writeln
('================================================================') ;
WHILE NOT EOF (fbrgFichPremiados) DO
BEGIN
Read (fbrgFichPremiados, rgParticipacion) ;
;
IF rgParticipacion.iNumSorteo <> 0 THEN
WITH rgParticipacion DO
Fundamentos de Informática
Junio­2009
6
BEGIN
ObtenerPersonasGrupo (iNumGrupo, sNomFichGrupos,
asDNIs, iNumCompGrupo) ;
Write (iNumGrupo:5, iRangoInf:7, iRangoSup:7, iNumSorteo:10) ;
{ Listar los DNIs de las personas del grupo }
{ Se puede utilizar tanto iNumGrupo como iNumCompGrupo }
FOR i:= 1 TO iNumComp DO
Write (asDNIs[i]:10) ;
Writeln ;
END ;
END ;
Writeln ('---------------------------- Fin de listado ------------------') ;
Close
END ;
(fbrgFichPremiados) ;
FUNCTION fnboExisteFichero (sNomFichSorteo : tsCadenas) : Boolean ;
VAR
fbrgFichSorteo : tfbrgFicherosParticipaciones ;
BEGIN
Assign (fbrgFichSorteo, sNomFichSorteo) ;
{$I-}
Reset (fbrgFichSorteo) ;
{$I+}
IF IOResult <> 0 THEN
fnboExisteFichero := FALSE
ELSE
BEGIN
Close (fbrgFichSorteo) ;
fnboExisteFichero := TRUE
END ;
END ;
BEGIN {--------------------- PROGRAMA PRINCIPAL ----------------------}
Write ('Nombre del fichero con los grupos de personas que participan: ') ;
ReadLn (sNomFichGrupos) ;
sNomFichGrupos := sNomFichGrupos + EXT_ARCHIVOS ;
CrearSiNoExiste (sNomFichGrupos) ;
Write ('Nombre del fichero del sorteo: ') ;
ReadLn (sNomFichSorteo) ;
sNomFichSorteo := sNomFichSorteo + EXT_ARCHIVOS ;
Writeln (sNomFichSorteo) ;
REPEAT
cOpcion := fncLeerOpcion ;
CASE cOpcion OF
'1' : AniadirGrupo (sNomFichGrupos) ;
'2' : BEGIN
CrearFichSorteo (sNomFichGrupos, sNomFichSorteo) ;
SortearEntradas (sNomFichSorteo) ;
Writeln ('---- Finalizado el sorteo de las entradas ----')
END ;
'3' : IF fnboExisteFichero (sNomFichSorteo) THEN
ListaGruposPremiados (sNomFichSorteo, sNomFichGrupos)
ELSE
Writeln ('ERROR: no se ha efectuado el sorteo') ;
END ;
IF cOpcion <> '0' THEN
Fundamentos de Informática
Junio­2009
7
cEspera := ReadKey ;
UNTIL cOpcion = '0' ;
END. {----------------------- Fin del programa de Junio de 2009
Fundamentos de Informática
Junio­2009
--------------}
8
Otra forma de realizar el proceso del sorteo de entradas:
PROCEDURE SortearEntradas (sNomFichSorteo: tsCadenas) ;
VAR
iNumeroMayor, iNumeroAleat, iPosicPremiado,
iEntradasDisponibles, iEntradasAsignadas : Integer ;
rgParticipacion
: trgParticipaciones ;
fbrgFichSorteo
: tfbrgFicherosParticipaciones ;
BEGIN
Randomize ;
Write ('Escribe número mínimo de entradas a sortear : ') ;
ReadLn (iEntradasDisponibles) ;
Writeln ;
iNumeroMayor := fniUltimoNumero (sNomFichSorteo) ;
Assign (fbrgFichSorteo, sNomFichSorteo) ;
Reset (fbrgFichSorteo) ;
iEntradasAsignadas := 0 ;
WHILE iEntradasAsignadas < iEntradasDisponibles DO
BEGIN
iNumeroAleat := Random (iNumeroMayor) + 1 ;
iPosicPremiado := fniBuscarGrupoPremiado (iNumeroAleat,
sNomFichSorteo) ;
IF iPosicPremiado <> -1 THEN
BEGIN
Seek (fbrgFichSorteo, iPosicPremiado) ;
Read (fbrgFichSorteo, rgParticipacion) ;
rgParticipacion.iNumSorteo
:= iNumeroAleat ;
{ Actualizar el fichero de Sorteo }
Seek (fbrgFichSorteo, iPosicPremiado) ;
Write (fbrgFichSorteo, rgParticipacion) ;
iEntradasAsignadas := iEntradasAsignadas +
rgParticipacion.iNumComp ;
END
END ;
Close (fbrgFichSorteo) ;
END ; { SortearEntradas }
Fundamentos de Informática
Junio­2009
9
PROGRAM Sortear3 ;
USES
Crt ;
CONST
EXT_ARCHIVOS
= '.DAT' ;
TYPE
tsCadenas = STRING [15] ;
tsCadDNI = STRING [8] ;
tasListaDNIs = ARRAY [1..5] OF tsCadDNI ;
trgGruposPersonas = RECORD
iNumGrupo,
iNumComp
: Integer ;
asDNIs
: tasListaDNIs ;
END ;
trgParticipaciones = RECORD
iNumGrupo,
iNumComp,
iRangoInf, iRangoSup,
iNumSorteo : Integer ; { Si ha salido en el sorteo }
{ Si NO vale 0
}
END ;
tfbrgFicherosGrupos = FILE OF trgGruposPersonas ;
tfbrgFicherosParticipaciones = FILE OF trgParticipaciones ;
VAR
cOpcion, cEspera : Char ;
sNomFichGrupos, sNomFichSorteo: tsCadenas ;
FUNCTION fncLeerOpcion : Char ;
VAR
cOpcion : Char ;
BEGIN
ClrScr ;
Writeln ('--------------Menú de opciones ---------------') ;
Writeln ('1 Añadir nuevo grupo para el sorteo') ;
Writeln ('2 Realizar el sorteo') ;
Writeln ('3 Listar los grupos
afortunados en el sorteo');
Writeln ('0 Terminar') ;
Write
('Pulsa el codigo de la opcion: ') ;
REPEAT
cOpcion := ReadKey ;
UNTIL ('0' <= cOpcion) AND (cOpcion <= '3') ;
WriteLn (cOpcion) ;
fncLeerOpcion := cOpcion ;
END ; { fncLeerOpcion }
PROCEDURE CrearSiNoExiste (sNomFichGrupos : tsCadenas) ;
VAR
fbrgFichGrupos : tfbrgFicherosGrupos ;
BEGIN
Assign (fbrgFichGrupos, sNomFichGrupos) ;
{$I-}
Reset (fbrgFichGrupos) ;
{$I+}
IF IOResult <> 0 THEN
Rewrite (fbrgFichGrupos) ;
Close (fbrgFichGrupos) ;
Fundamentos de Informática
No publicada_Junio­2009
1
END ; { CrearSiNoExiste }
FUNCTION fnboExistePersona (sDNIBuscado : tsCadDNI ;
sNomFichGrupos : tsCadenas) : Boolean ;
VAR
rgGrupo
: trgGruposPersonas
;
fbrgFichGrupos : tfbrgFicherosGrupos ;
i
: Integer ;
boEncontrado
: Boolean ;
BEGIN
boEncontrado := FALSE ;
Assign (fbrgFichGrupos, sNomFichGrupos) ;
Reset (fbrgFichGrupos) ;
WHILE NOT EOF (fbrgFichGrupos) DO
BEGIN
Read (fbrgFichGrupos, rgGrupo) ;
WITH rgGrupo DO
FOR i := 1 TO iNumComp DO
IF asDNIs[i] = sDNIBuscado THEN
boEncontrado := TRUE ;
END ;
Close
(fbrgFichGrupos) ;
fnboExistePersona := boEncontrado
END ; { fnboExistePersona }
PROCEDURE AniadirGrupoAlFichero (CONST rgGrupo
: trgGruposPersonas ;
sNomFichGrupos: tsCadenas) ;
VAR
rgGrupoNuevo
: trgGruposPersonas ;
fbrgFichGrupos : tfbrgFicherosGrupos ;
BEGIN
Assign (fbrgFichGrupos, sNomFichGrupos) ;
Reset (fbrgFichGrupos) ;
Seek
(fbrgFichGrupos, FileSize (fbrgFichGrupos)) ;
rgGrupoNuevo := rgGrupo ;
{ Rellenar el campo iNumGrupo antes de escribir el GRUPO en el fichero}
rgGrupoNuevo.iNumGrupo := FileSize (fbrgFichGrupos) + 1 ;
Write (fbrgFichGrupos, rgGrupoNuevo) ;
Close (fbrgFichGrupos) ;
END ; { AniadirGrupoAlFichero }
PROCEDURE AniadirGrupo (sNomFichGrupos: tsCadenas) ;
VAR
rgGrupo : trgGruposPersonas ;
i
: Integer;
BEGIN
WITH rgGrupo DO
BEGIN
REPEAT
Write ('Escribe número de personas del grupo (1..5): ') ;
ReadLn (iNumComp) ;
UNTIL (1 <= iNumComp) AND (iNumComp <= 5) ;
i := 1 ;
Fundamentos de Informática
No publicada_Junio­2009
2
WHILE i <= iNumComp DO
BEGIN
Write ('
DNI de la persona: ') ;
ReadLn (asDNIs[i]) ;
IF fnboExistePersona (asDNIs[i], sNomFichGrupos) THEN
Writeln ('ESA PERSONA YA ESTA APUNTADA EN OTRO GRUPO. ',
'INDICA OTRA, POR FAVOR')
ELSE
i := i + 1 ;
END ;
{ No se ha rellenado el campo iNumGrupo.
Se rellenará antes de escribir el GRUPO en el fichero }
END ;
AniadirGrupoAlFichero (rgGrupo, sNomFichGrupos) ;
END ; { AniadirGrupo }
PROCEDURE CrearFichSorteo (sNomFichGrupos, sNomFichSorteo: tsCadenas) ;
VAR
rgGrupo
: trgGruposPersonas ;
fbrgFichGrupos : tfbrgFicherosGrupos ;
rgParticipacion : trgParticipaciones ;
fbrgFichSorteo : tfbrgFicherosParticipaciones ;
iUltimoNumero
: Integer ;
BEGIN
Assign (fbrgFichGrupos, sNomFichGrupos) ;
Reset (fbrgFichGrupos) ;
Assign (fbrgFichSorteo, sNomFichSorteo) ;
Rewrite (fbrgFichSorteo) ;
iUltimoNumero := 0 ;
WHILE NOT EOF (fbrgFichGrupos) DO
BEGIN
Read (fbrgFichGrupos, rgGrupo) ;
WITH rgParticipacion DO
BEGIN
iNumGrupo
:= rgGrupo.iNumGrupo ;
iNumComp
:= rgGrupo.iNumComp ;
iRangoInf
:= iUltimoNumero + 1 ;
iRangoSup
:= iUltimoNumero + 5 + (rgGrupo.iNumComp - 1 ) ;
iNumSorteo
:= 0 ;
iUltimoNumero := iRangoSup ; { para la siguiente vez }
END ;
Write (fbrgFichSorteo, rgParticipacion) ;
END ;
Close (fbrgFichGrupos) ;
CLose (fbrgFichSorteo) ;
END ; { CrearFichSorteo }
FUNCTION fniUltimoNumero (sNomFichSorteo : tsCadenas) : Integer ;
VAR
rgParticipacion : trgParticipaciones ;
fbrgFichSorteo
: tfbrgFicherosParticipaciones ;
iUltNumSorteo : Integer ;
BEGIN
Assign (fbrgFichSorteo, sNomFichSorteo) ;
Reset (fbrgFichSorteo) ;
Seek (fbrgFichSorteo, FileSize (fbrgFichSorteo) - 1 ) ;
Fundamentos de Informática
No publicada_Junio­2009
3
IF FilePos (fbrgFichSorteo) > 0 THEN
BEGIN
Read (fbrgFichSorteo, rgParticipacion) ;
iUltNumSorteo := rgParticipacion.iRangoSup
END
ELSE
{ FilePos (fbrgFichSorteo) = 0 }
iUltNumSorteo := 0 ;
Close
(fbrgFichSorteo) ;
fniUltimoNumero := iUltNumSorteo ;
END ; { fniUltimoNumero }
PROCEDURE SortearEntradas (sNomFichSorteo: tsCadenas) ;
VAR
iNumeroMayor, iEntradasDisponibles, iEntradasAsignadas : Integer ;
rgParticipacion
: trgParticipaciones ;
fbrgFichSorteo
: tfbrgFicherosParticipaciones ;
iNumeroAleat, iPosicPremiado
: Integer ;
boEncontrado
: Boolean ;
BEGIN
Randomize ;
Write ('Escribe número mínimo de entradas a sortear : ') ;
ReadLn (iEntradasDisponibles) ;
Writeln ;
iNumeroMayor := fniUltimoNumero (sNomFichSorteo) ;
Assign (fbrgFichSorteo, sNomFichSorteo) ;
Reset (fbrgFichSorteo) ;
iEntradasAsignadas := 0 ;
WHILE iEntradasAsignadas < iEntradasDisponibles DO
BEGIN
iNumeroAleat := Random (iNumeroMayor) + 1 ;
{--- Buscar en le fichero para ver si ya existe ese DNI ----}
boEncontrado := FALSE ;
Seek (fbrgFichSorteo, 0) ;
WHILE NOT EOF (fbrgFichSorteo) AND NOT boEncontrado DO
BEGIN
Read (fbrgFichSorteo, rgParticipacion) ;
WITH rgParticipacion DO
IF (iRangoInf <= iNumeroAleat) AND
(iNumeroAleat <= iRangoSup) THEN
boEncontrado := TRUE
END ;
antes }
IF boEncontrado AND (rgParticipacion.iNumSorteo = 0) THEN
{ Encontrado grupo con ese número. Al grupo no le ha tocado
iPosicPremiado := FilePos (fbrgFichSorteo) - 1
ELSE
iPosicPremiado := -1 ;
{---------------------- Fin de la búsqueda ----------------------}
IF iPosicPremiado <> -1 THEN
BEGIN
Seek (fbrgFichSorteo, iPosicPremiado) ;
Fundamentos de Informática
No publicada_Junio­2009
4
Read (fbrgFichSorteo, rgParticipacion) ;
rgParticipacion.iNumSorteo := iNumeroAleat ;
{ Actualizar el fichero de Sorteo }
Seek (fbrgFichSorteo, iPosicPremiado) ;
Write (fbrgFichSorteo, rgParticipacion) ;
iEntradasAsignadas := iEntradasAsignadas +
rgParticipacion.iNumComp ;
END
END ;
Close (fbrgFichSorteo) ;
END ; { SortearEntradas2 }
PROCEDURE ObtenerPersonasGrupo (
iNumeroGrupo
sNomFichGrupos
VAR
asDNIsGrupo
VAR iNumCompGrupo
:
:
:
:
Integer ;
tsCadenas ;
tasListaDNIs ;
Integer ) ;
{
Dado el uso que se va a hacer de este subprograma:
No sería necesario retornar la información iNumCompGrupo,
pues desde donde se efectúa la llamada ya se conoce esa información
}
VAR
rgGrupo
: trgGruposPersonas ;
fbrgFichGrupos : tfbrgFicherosGrupos ;
boEncontrado
: Boolean ;
BEGIN
Assign (fbrgFichGrupos, sNomFichGrupos) ;
Reset (fbrgFichGrupos) ;
boEncontrado := FALSE ;
WHILE NOT EOF (fbrgFichGrupos) AND NOT boEncontrado DO
BEGIN
Read (fbrgFichGrupos, rgGrupo) ;
IF rgGrupo.iNumGrupo = iNumeroGrupo THEN
BEGIN
asDNIsGrupo
:= rgGrupo.asDNIs
;
iNumCompGrupo := rgGrupo.iNumComp ;
boEncontrado := TRUE ;
END ;
END ;
Close (fbrgFichGrupos) ;
END ; { ObtenerPersonasGrupo }
PROCEDURE ListaGruposPremiados (sNomFichPremiados, sNomFichGrupos : tsCadenas);
VAR
rgParticipacion
: trgParticipaciones ;
fbrgFichPremiados : tfbrgFicherosParticipaciones ;
asDNIs
: tasListaDNIs ;
iNumCompGrupo, i : Integer ;
BEGIN
Assign (fbrgFichPremiados, sNomFichPremiados) ;
Reset (fbrgFichPremiados) ;
Writeln ('Listado de Grupos premiados') ;
Writeln ;
Fundamentos de Informática
No publicada_Junio­2009
5
Writeln ('Grupo':5, 'Inf':7, ' .. ',
'Sup':3, 'Premiado':10, ' DNIs de las personas del grupo')
Writeln ('=================================================',
'==============================') ;
;
WHILE NOT EOF (fbrgFichPremiados) DO
BEGIN
Read (fbrgFichPremiados, rgParticipacion) ;
IF rgParticipacion.iNumSorteo <> 0 THEN
WITH rgParticipacion DO
BEGIN
ObtenerPersonasGrupo (iNumGrupo, sNomFichGrupos,
asDNIs, iNumCompGrupo) ;
Write (iNumGrupo:5, iRangoInf:7,
iRangoSup:7, iNumSorteo:10) ;
END ;
{ Listar los DNIs de las personas del grupo }
{ Se puede utilizar tanto iNumGrupo como iNumCompGrupo }
FOR i:= 1 TO iNumComp DO
Write (asDNIs[i]:10) ;
Writeln ;
END ;
Writeln ;
Writeln ('-------------------------------- Fin de listado ----',
'---------------------------') ;
Close (fbrgFichPremiados) ;
END ; { ListaGruposPremiados }
FUNCTION fnboExisteFichero (sNomFichSorteo : tsCadenas) : Boolean ;
VAR
fbrgFichSorteo : tfbrgFicherosParticipaciones ;
BEGIN
Assign (fbrgFichSorteo, sNomFichSorteo) ;
{$I-}
Reset (fbrgFichSorteo) ;
{$I+}
IF IOResult <> 0 THEN
fnboExisteFichero := FALSE
ELSE
BEGIN
Close (fbrgFichSorteo) ;
fnboExisteFichero := TRUE
END ;
END ;
BEGIN {--------------------- PROGRAMA PRINCIPAL ----------------------}
Write ('Nombre del fichero con los grupos de personas que participan: ') ;
ReadLn (sNomFichGrupos) ;
sNomFichGrupos := sNomFichGrupos + EXT_ARCHIVOS ;
CrearSiNoExiste (sNomFichGrupos) ;
Write ('Nombre del fichero del sorteo: ') ;
ReadLn (sNomFichSorteo) ;
sNomFichSorteo := sNomFichSorteo + EXT_ARCHIVOS ;
Writeln (sNomFichSorteo) ;
Fundamentos de Informática
No publicada_Junio­2009
6
REPEAT
cOpcion := fncLeerOpcion ;
CASE cOpcion OF
'1' : AniadirGrupo (sNomFichGrupos) ;
'2' : BEGIN
CrearFichSorteo (sNomFichGrupos, sNomFichSorteo) ;
SortearEntradas (sNomFichSorteo) ;
Writeln ;
Writeln ('---- Finalizado el sorteo de las entradas ----')
END ;
'3' : IF fnboExisteFichero (sNomFichSorteo) THEN
ListaGruposPremiados (sNomFichSorteo, sNomFichGrupos)
ELSE
Writeln ('ERROR: no se ha efectuado el sorteo') ;
END ;
IF cOpcion <> '0' THEN
cEspera := ReadKey ;
UNTIL cOpcion = '0' ;
END. {--------------- Fin del programa de Junio de 2009 ------------------}
Fundamentos de Informática
No publicada_Junio­2009
7
FUNCTION fniBuscarGrupoPremiado (iNumeroAleat: Integer ;
sNomFichSorteo: tsCadenas) : Integer ;
VAR
rgParticipacion : trgParticipaciones ;
fbrgFichSorteo : tfbrgFicherosParticipaciones ;
boEncontrado
: Boolean ;
BEGIN
Assign (fbrgFichSorteo, sNomFichSorteo) ;
Reset (fbrgFichSorteo) ;
boEncontrado := FALSE ;
WHILE NOT EOF (fbrgFichSorteo) AND NOT boEncontrado DO
BEGIN
Read (fbrgFichSorteo, rgParticipacion) ;
WITH rgParticipacion DO
IF (iRangoInf <= iNumeroAleat) AND
(iNumeroAleat <= iRangoSup) THEN
boEncontrado := TRUE
END ;
IF boEncontrado AND (rgParticipacion.iNumSorteo = 0) THEN
{ Encontrado el grupo con ese número.
Al grupo no le ha tocado antes }
fniBuscarGrupoPremiado := FilePos (fbrgFichSorteo) - 1
ELSE
fniBuscarGrupoPremiado := -1 ;
Close (fbrgFichSorteo) ;
END ; { fniBuscarGrupoPremiado }
PROCEDURE SortearEntradas (sNomFichSorteo: tsCadenas) ;
VAR
iNumeroMayor, iNumeroAleat, iPosicPremiado,
iEntradasDisponibles, iEntradasAsignadas : Integer ;
rgParticipacion
: trgParticipaciones ;
fbrgFichSorteo
: tfbrgFicherosParticipaciones ;
BEGIN
Randomize ;
Write ('Escribe número mínimo de entradas a sortear : ') ;
ReadLn (iEntradasDisponibles) ;
Writeln ;
iNumeroMayor := fniUltimoNumero (sNomFichSorteo) ;
Assign (fbrgFichSorteo, sNomFichSorteo) ;
Reset (fbrgFichSorteo) ;
iEntradasAsignadas := 0 ;
WHILE iEntradasAsignadas < iEntradasDisponibles DO
BEGIN
iNumeroAleat := Random (iNumeroMayor) + 1 ;
iPosicPremiado := fniBuscarGrupoPremiado (iNumeroAleat,
sNomFichSorteo) ;
IF iPosicPremiado <> -1 THEN
BEGIN
Seek (fbrgFichSorteo, iPosicPremiado) ;
Read (fbrgFichSorteo, rgParticipacion) ;
rgParticipacion.iNumSorteo
Fundamentos de Informática
:= iNumeroAleat ;
No publicada_Junio­2009
8
{ Actualizar el fichero de Sorteo }
Seek (fbrgFichSorteo, iPosicPremiado) ;
Write (fbrgFichSorteo, rgParticipacion) ;
iEntradasAsignadas := iEntradasAsignadas +
rgParticipacion.iNumComp ;
END
END ;
Close (fbrgFichSorteo) ;
END ; { SortearEntradas }
Otra manera: Pasar como parámetro la variable ficheo
FUNCTION fniBuscarGrupoPremiado (iNumeroAleat: Integer ;
fbrgFichSorteo : tfbrgFicherosParticipaciones)
: Integer ;
VAR
rgParticipacion : trgParticipaciones ;
;
boEncontrado
: Boolean ;
BEGIN
Seek (fbrgFichSorteo, 0) ;
boEncontrado := FALSE ;
WHILE NOT EOF (fbrgFichSorteo) AND NOT boEncontrado DO
BEGIN
Read (fbrgFichSorteo, rgParticipacion) ;
WITH rgParticipacion DO
IF (iRangoInf <= iNumeroAleat) AND
(iNumeroAleat <= iRangoSup) THEN
boEncontrado := TRUE
END ;
IF boEncontrado AND (rgParticipacion.iNumSorteo = 0) THEN
{ Encontrado el grupo con ese número.
Al grupo no le ha tocado antes }
fniBuscarGrupoPremiado := FilePos (fbrgFichSorteo) - 1
ELSE
fniBuscarGrupoPremiado := -1 ;
END ;
{ fniBuscarGrupoPremiado }
PROCEDURE SortearEntradas (sNomFichSorteo: tsCadenas) ;
VAR
iNumeroMayor, iNumeroAleat, iPosicPremiado,
iEntradasDisponibles, iEntradasAsignadas : Integer ;
rgParticipacion
: trgParticipaciones ;
fbrgFichSorteo
: tfbrgFicherosParticipaciones ;
BEGIN
Randomize ;
Write ('Escribe número mínimo de entradas a sortear : ') ;
ReadLn (iEntradasDisponibles) ;
Writeln ;
iNumeroMayor := fniUltimoNumero (sNomFichSorteo) ;
Fundamentos de Informática
No publicada_Junio­2009
9
Assign (fbrgFichSorteo, sNomFichSorteo) ;
Reset (fbrgFichSorteo) ;
iEntradasAsignadas := 0 ;
WHILE iEntradasAsignadas < iEntradasDisponibles DO
BEGIN
iNumeroAleat := Random (iNumeroMayor) + 1 ;
iPosicPremiado := fniBuscarGrupoPremiado (iNumeroAleat,
fbrgFichSorteo) ;
IF iPosicPremiado <> -1 THEN
BEGIN
Seek (fbrgFichSorteo, iPosicPremiado) ;
Read (fbrgFichSorteo, rgParticipacion) ;
rgParticipacion.iNumSorteo
:= iNumeroAleat ;
{ Actualizar el fichero de Sorteo }
Seek (fbrgFichSorteo, iPosicPremiado) ;
Write (fbrgFichSorteo, rgParticipacion) ;
iEntradasAsignadas := iEntradasAsignadas +
rgParticipacion.iNumComp ;
END
END ;
Close (fbrgFichSorteo) ;
END ; { SortearEntradas }
Fundamentos de Informática
No publicada_Junio­2009
10
Descargar