2003-01-14.kl.14-18 Uppgift 1 Din uppgift är att skriva en liten mikroräknare (en pytteliten version av en miniräknare). Inmatningen till mikroräknaren skall vara en rad innehållande en matematisk beräkning. De enda operatorer som skall existera är + och *. Ett exempel på inmatning skulle kunna vara: 0 * 1 + 2 * 3 + 4 * 5 + 6 * 7 + 8 * 9 Det är givet att det före och efter varje operator skall finnas exakt ett blanktecken och att det efter sista talet på raden endast finns ett radslutstecken (RETURN). Det är också givet att de tal som skall matas in är av flyttalstyp (det går då också att mata in heltal). Ditt program skall avslutas då det skrivit ut resultatet (avrundat till 2 decimaler) på skärmen. Ett par körexempel: Mata in ett matematiskt uttryck: 0 * 1 + 2 * 3 + 4 * 5 + 6 * 7 + 8 * 9 Resultatet blir: 140.00 Mata in ett matematiskt uttryck: 0.5 * 2 * 0.5 * 2 * 0.5 * 2 * 0.5 * 2 * 0.5 * 2 * 0.5 * 2 Resultatet blir: 1.00 Observera att inmatningen kan vara godtyckligt lång. Du får inte sätta några begränsingar på radlängd. Det är givet att uttrycket går att beräkna. Prioriteringsreglerna för addition och multiplikation antar vi att ni kan.
2003-01-14.kl.14-18 Uppgift 2 På en fil ligger ett krypterat meddelande. I detta meddelande finns ett lösenord. Detta lösenord skall du skriva in som kommentar i ditt program (som första rad i programmet) innan du skickar in din lösning. Den kryptering som använts i filen är ett så kallat monoalfabetiskt krypto vilket innebär att man har substituerat tecken i originaltexten med en given uppsättning andra tecken. Varje tecken i alfabetet har alltså endast ett motsvarande tecken i krypteringsalfabetet. Ett exempel: Ordinarie alfabet: ABCDEFGHIJKLMNOPQRSTUVWXYZÅÄÖ Krypterat alfabet: BCDEFGHIJKLMNOPQRSTUVWXYZÅÄÖA Det ordinarie alfabetet är alltid givet. Detta råkade vara endast en förskjutning av tecknen, ett hack, men det kan vara slumpmässig ordning av tecknen i det krypterade alfabetet. I ditt program skall man mata in krypteringsalfabetet. Det första tecknet ersätter A o.s.v. Vi kallar detta för krypteringsnyckeln (eller nyckeln) för krypteringen. Din uppgift är alltså att skriva ett program som frågar användaren efter en krypteringsnyckel (29 tecken), det filnamn där det krypterade meddelandet finns samt det filnamn där man vill få resultatet (originaltexten, eller klartexten som det egentligen heter). Därefter skall programmet dekryptera meddelandet i den krypterade filen och lagra resultatet i klartextfilen. Exempel på programkörning: Mata in kryptoalfabetet: QWERTYUIOPÅÄÖLKJHGFDSAZXCVBNM Mata in filnamn för det krypterade meddelandet: KRYPTFIL.TXT Mata in filnamn där resultatet skall hamna: KLARTEXT.TXT Resultatet finns nu på filen KLARTEXT.TXT Det är givet att filnamnen alltid skall vara 12 tecken långa. Körexemplet ovan anger också både kryptoalfabetet och filnamnet där det kryterade meddelandet finns. Filen är given och finns tillgänglig. När du dekrypterar filen är det inte säkert att hela filens innehåll blir läsbart. Det är dock givet att det som blir läsbart går att förstå (hela meningar).
2003-01-14.kl.14-18 Uppgift 3 I Florida behövs ett program där man räknar röster. På röstsedlarna står ett namn på en person (maximalt 20 tecken). Personen deltar i valet för ett givet parti där partinamnet är maximalt 20 tecken. Din uppgift är att skriva ett program där man först matar in vilka personer som tillhör vilket parti (det är maximalt 10 personer som deltar i valet och det är maximalt 4 olika partier) och efter detta skall programmet räkna röster. Räkningen av röster går till så att man får mata in namnet på den person som står på röstsedeln till progammet. Resultatet skall ange vilket parti som vunnit. Körexempel: Mata in antal partier: 2 Mata in antal kandidat: 4 Mata in namn för kandidat nummer 1: Al Mata in parti för kandidat nummer 1: Yes Party Mata in namn för kandidat nummer 2: Smith Mata in parti för kandidat nummer 2: No Party Mata in namn för kandidat nummer 3: George Mata in parti för kandidat nummer 3: Yes Party Mata in namn för kandidat nummer 4: Jones Mata in parti för kandidat nummer 4: No Party Mata in antal valsedlar: 10 Mata in namn på valsedel nummer 1: Al Mata in namn på valsedel nummer 2: George Mata in namn på valsedel nummer 3: Smith Mata in namn på valsedel nummer 4: Al Mata in namn på valsedel nummer 5: Al Mata in namn på valsedel nummer 6: Smith Mata in namn på valsedel nummer 7: George Mata in namn på valsedel nummer 8: George Mata in namn på valsedel nummer 9: Al Mata in namn på valsedel nummer 10: Jones Efter röstsammanräkningen ser vi att Yes Party har vunnit. Tips: I denna uppgift är det bra att tänka till om datastrukturerna först.
2003-03-12.kl.08-12 Uppgift 1 Du skall skriva ett program som kontrollerar om ett tal P är ett så kallat pseudoprimtal till basen B. För att P skall vara pseudoprimtal till basen B måste följande villkor vara uppfyllda: Villkor 1: B (P-1) mod P = 1 Villkor 2: Största gemensamma delare för B och P är 1 För att beräkna största gemensamma delare krävs att man gör en liten funktion. I denna uppgift ger vi denna helt gratis. Vi kallar den för S_G_D. function S_G_D(A, B : in Integer) return integer is begin if (B mod A) = 0 then return A; end if; return S_G_D((B mod A), A); end S_G_D; Det finns dock ett litet problem till att lösa. Vi ser direkt att B (P-1) kommer att bli mycket stora tal även för ganska små värden på B och P. För att lösa detta problem, d.v.s. villkor 1, kan vi använda oss av en liten finess som kallas modulär exponentiering som finns i matematiken. Följande gäller för modulär exponentiering: För N = 0: A N mod B = 1 För N > 0: A N mod B = (A * (A N-1 mod B)) mod B Din uppgift blir alltså att skriva ett program som frågar användaren efter ett tal och en bas och sen skriver ut om talet är ett pseudoprimtal till basen. Exempel på programkörningar: Mata in P och B: 45 19 Talet 45 är ett pseudoprimtal till basen 19 Mata in P och B: 1729 11 Talet 1729 är ett pseudoprimtal till basen 11 Mata in P och B: 1729 13 Talet 1729 är inte ett pseudoprimtal till basen 13 Mata in P och B: 561 11 Talet 561 är inte ett pseudoprimtal till basen 11 Mata in P och B: 561 13 Talet 561 är ett pseudoprimtal till basen 13
2003-03-12.kl.08-12 Uppgift 2 En matematiker som hette Erathostenes funderade en hel del på hur man snabbt skulle kunna få fram alla primtal från 2 upp till ett visst tal. Han kom fram till att man skulle kunna skriva upp alla tal upp till det tal man önskade på ett papper och sen utföra en sekvens av strykningar av ickeprimtal. Detta kallas för Erathostenes såll och du skall nu utföra detta i ett program för att slippa sitta och skriva en massa tal på papper. Själva strykningarna går till på följande sätt: 1. Använd det lägsta tal som inte är struket (detta är ett primtal) och inte tidigare använt. 2. Stryk alla övriga tal som är jämnt delbara med detta tal. 3. Börja om från punkt 1 tills det att inga tal är oanvända. Exempel på strykningar om vi antar att det maximala talet är 10: Ursprungliga tal: 2 3 4 5 6 7 8 9 10 Första strykningsomgången: 2 3 4 5 6 7 8 9 10 (stryker alla multiplar av 2) Andra strykningsomgången: 2 3 4 5 6 7 8 9 10 (stryker alla multiplar av 3) Tredje strykningsomgången: 2 3 4 5 6 7 8 9 10 (stryker alla multiplar av 5) Fjärde strykningsomgången: 2 3 4 5 6 7 8 9 10 (stryker alla multiplar av 7) De tal som fortfarande är ostrukna är de primtal som finns mellan 2 och det tal som efterfrågades. I exemplet ovan är alltså 2, 3, 5, 7 primtal. I ditt program skall först det sökta maxtalet efterfrågas och sen skall alla tal mellan 2 och det sökta talet lagras i ett fält (en array ). Fältet skall dimensioneras så att det får plats precis så många tal som efterfrågas. Efter insättningen av alla tal i fältet skall strykningarna utföras. Till sist skall programmet skriva ut de tal som ej är strukna, d.v.s. de primtal som finns upp till maxtalet. Körexempel: Mata in det maximala talet: 75 Primtalen är: 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 Tips: Det är tillåtet att definiera datatyper i underprogram.
2003-03-12.kl.08-12 Uppgift 3 Som du såg i uppgiften om Erathostenes gäller att ett primtal endast är jämnt delbart med sig självt och 1 (självklart). Att lagra alla talen först och sen stryka dem är väldigt krävande ur minnessynpunkt. Detta kan man undvika genom att lagra primtalen allt eftersom man hittar dem. I denna uppgift skall du låta användaren mata in ett maxtal. Efter detta skall du gå igenom alla tal från 2 upp till maxtalet. Varje tal du testar och finner att det är ett primtal skall lagras sist i en fil som skall heta PRIMES.TXT. För att testa om ett tal är ett primtal krävs att du kontrollerar att det inte är jämnt delbart med något av de tidigare primtalen. Detta innebär (tyvärr) att du måste gå igenom filen för varje nytt tal som skall testas, men det är den uppgift du nu har framför dig. När alla tal upp till och med maxtalet är testade (och alla av dessa som är primtal är lagrade på filen) skall programmet skriva ut de funna primtalen. Körexempel: Mata in det maximala talet: 76 Primtalen är: 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 Krav: Programmet får inte anta att filen existerar innan programmet körs.
2003-03-12.kl.14-18 Uppgift 1 En matematiker som hette Erathostenes funderade en hel del på hur man snabbt skulle kunna få fram alla primtal från 2 upp till ett visst tal. Han kom fram till att man skulle kunna skriva upp alla tal upp till det tal man önskade på ett papper och sen utföra en sekvens av strykningar av ickeprimtal. Detta kallas för Erathostenes såll och du skall nu utföra detta i ett program för att slippa sitta och skriva en massa tal på papper. Själva strykningarna går till på följande sätt: 1. Använd det lägsta tal som inte är struket (detta är ett primtal) och inte tidigare använt. 2. Stryk alla övriga tal som är jämnt delbara med detta tal. 3. Börja om från punkt 1 tills det att inga tal är oanvända. Exempel på strykningar om vi antar att det maximala talet är 10: Ursprungliga tal: 2 3 4 5 6 7 8 9 10 Första strykningsomgången: 2 3 4 5 6 7 8 9 10 (stryker alla multiplar av 2) Andra strykningsomgången: 2 3 4 5 6 7 8 9 10 (stryker alla multiplar av 3) Tredje strykningsomgången: 2 3 4 5 6 7 8 9 10 (stryker alla multiplar av 5) Fjärde strykningsomgången: 2 3 4 5 6 7 8 9 10 (stryker alla multiplar av 7) De tal som fortfarande är ostrukna är de primtal som finns mellan 2 och det tal som efterfrågades. I exemplet ovan är alltså 2, 3, 5, 7 primtal. I ditt program skall först det sökta maxtalet efterfrågas och sen skall alla tal mellan 2 och det sökta talet lagras i en enkellänkad lista (skapad m.h.a. pekare). Efter insättningen av alla tal i listan skall strykningarna utföras. Till sist skall programmet skriva ut de tal som ej är strukna, d.v.s. de primtal som finns upp till maxtalet. Körexempel: Mata in det maximala talet: 77 Primtalen är: 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73
2003-03-12.kl.14-18 Uppgift 2 I matematiken används lite då och då primtal. Om två på varandra följande primtal endast har differensen 2 kallas de tvillingprimtal. Ett par exempel på sådana är 5 och 7 respektive 11 och 13. I en textfil som heter GIVEN_PRIMES.TXT finns de första N stycken primtalen (där N är ett heltal som är minst noll). Bland dessa finns det eventuellt ett antal tvillingprimtalspar. Du skall skriva ett program som frågar användaren vilket tvillingprimtalspar som önskas och sen skall programmet skriva ut detta par. Om användaren matar in att den söker par nummer 5 skall alltså det femte tvillingprimtalsparet skrivas ut. Om det är så att användaren matar in ett tal som är för stort, d.v.s. det finns inte så många tvillingprimtalspar i filen, skall meddelandet Det fanns inte så många tvillingprimtal i filen. skrivas ut. Körexempel: Mata in vilket tvillingprimtal som sökes: 1 Du sökte tvillingparet: 3, 5 Mata in vilket tvillingprimtal som sökes: 4 Du sökte tvillingparet: 17, 19 Mata in vilket tvillingprimtal som sökes: 12 Du sökte tvillingparet: 149, 151 Mata in vilket tvillingprimtal som sökes: 20 Du sökte tvillingparet: 311, 313 Mata in vilket tvillingprimtal som sökes: 25 Du sökte tvillingparet: 521, 523 Mata in vilket tvillingprimtal som sökes: 101 Det fanns inte så många tvillingprimtal i filen. I sista exemplet antar vi att filen som användes inte innehöll så många tvillingprimtalspar. Tips: Titta i filen för att se vilket format som används. Krav: Programmet måste fungera även om vi provkör med en datafil som innehåller fler eller färre primtal än den ni har fått som exempel. Det är alltså meningen att du skall upptäcka att det inte fanns så många par i filen. Ingen felhantering på inmatningar av negativa tal behöver göras. Användaren matar alltid in positiva tal.
2003-03-12.kl.14-18 Uppgift 3 Du skall skriva ett program som kontrollerar om ett tal B är en så kallad primitiv rot modulo talet P. För att B skall vara en primitiv rot modulo talet P måste ett antal saker vara uppfyllda: Ekvation 1: B N mod P = 1 Ekvation 2: Phi(P) = N I ekvation 1 skall man finna det minimala talet N som är större än noll. I ekvation 2 skall Phi(P) räkna antalet tal, T, i intervallet [1, P] som uppfyller villkoret: Villkor: Största gemensamma delaren för T och P är 1 För att ni skall slippa skriva funktionen Phi(P) har vi givit denna. I filen phi.adb ligger denna funktion. Speciellt gäller att Phi(P) = (P - 1) om P är ett primtal. Du får använda den på det sätt du anser lämpligt. För att beräkna största gemensamma delare krävs att man gör en liten funktion. I denna uppgift ger vi denna helt gratis (också). Vi kallar den för S_G_D. function S_G_D(A, B : in Integer) return integer is begin if (B mod A) = 0 then return A; end if; return S_G_D((B mod A), A); end S_G_D; Det finns dock ett litet problem. Vi ser direkt att B N kommer att bli mycket stora tal även för ganska små värden på B och N. Vi skall inte lösa detta problem, men vi skall se till att programmet inte hamnar i ett felläge. Detta gör vi genom att bestämma att N inte får bli större eller lika med P. Om N blir större eller lika med P skall felmeddelandet Ett fel har inträffat! skrivas ut. Din uppgift blir alltså att skriva ett program som frågar användaren efter talet B och talet P och sen letar reda på N (om det går) och skriver ut om B är en primitiv rot modulo P enligt nedan. Exempel på programkörningar: Mata in B och P: 2 11 Talet 2 är en primitiv rot modulo 11 Mata in B och P: 2 13 Talet 2 är en primitiv rot modulo 13 Mata in B och P: 5 13 Talet 5 är inte en primitiv rot modulo 13
2003-03-13.kl.08-12 Uppgift 1 Ibland vill man kunna primtalsfaktorisera stora tal. Detta kan göras på många olika sätt och man kan dra nytta av primtalsfaktorerna på olika sätt. Ibland är man dock inte intresserad av alla faktorerna eller hur många gånger de förekommer. I denna uppgift skall du ta fram alla unika primtalsfaktorer ur en sekvens av primtalsfaktorer som användaren matar in. Detta kallas för att vi plockar fram den kvadratfria delen i primtalsfaktorsekvensen. På en textfil som heter GIVEN_PRIMES.TXT finns de första 100 primtalen. Dessa kan du läsa in till en vektor och använda vid lösningen av problemet. Användaren skall anmodas skriva in ett antal primfaktorer samt att avsluta inmatningen med en nolla. Programmet skall läsa in de primfaktorer som matats in och på något sätt lagra information om dessa. När alla primfaktorer är inlästa skall programmet skriva ut alla primfaktorerna, men varje faktor får endast skrivas ut exakt en gång. För att göra uppgiften lite mer spännande skall primfaktorerna skrivas ut i sorterad ordning där det minsta skrivs ut först. Det är givet i uppgiften att användaren inte matar in primfaktorer som är större än det största primtalet på filen. Exempel på programkörningar: Mata in ett antal primfaktorer (avsluta med en nolla): 3 5 7 11 13 17 19 5 13 191 193 197 199 17 7 0 31 37 41 43 0 Kvadratfria delen (sorterad) är: 3 5 7 11 13 17 19 191 193 197 199 Mata in ett antal primfaktorer (avsluta med en nolla): 2 3 2 3 2 3 2 3 2 3 2 3 2 3 2 3 2 3 23 2 3 0 Kvadratfria delen (sorterad) är: 2 3 23 Krav: Du får INTE lagra information om de inlästa primtalsfaktorerna i en länkad lista!
2003-03-13.kl.08-12 Uppgift 2 Som du säkert redan vet gäller att ett primtal endast är jämnt delbart med sig självt och 1. En matematiker som hette Erathostenes funderade en hel del på hur man snabbt skulle kunna få fram alla primtal från 2 upp till ett visst tal. Han kom fram till att man skulle kunna skriva upp alla tal upp till det tal man önskade på ett papper och sen utföra en sekvens av strykningar av ickeprimtal. Detta kallas för Erathostenes såll och du skall nu utföra detta i ett program för att slippa sitta och skriva en massa tal på papper. Själva strykningarna går till på följande sätt: 1. Använd det lägsta tal som inte är struket (detta är ett primtal) och inte tidigare använt. 2. Stryk alla övriga tal som är jämnt delbara med detta tal. 3. Börja om från punkt 1 tills det att inga tal är oanvända. Exempel på strykningar om vi antar att det maximala talet är 10: Ursprungliga tal: 2 3 4 5 6 7 8 9 10 Första strykningsomgången: 2 3 4 5 6 7 8 9 10 (stryker alla multiplar av 2) Andra strykningsomgången: 2 3 4 5 6 7 8 9 10 (stryker alla multiplar av 3) Tredje strykningsomgången: 2 3 4 5 6 7 8 9 10 (stryker alla multiplar av 5) Fjärde strykningsomgången: 2 3 4 5 6 7 8 9 10 (stryker alla multiplar av 7) De tal som fortfarande är ostrukna är de primtal som finns mellan 2 och det tal som efterfrågades. I exemplet ovan är alltså 2, 3, 5, 7 primtal. Som du inser är det väldigt krävande ur minnessynpunkt att först lagra alla talen och sen stryka dem. Detta kan man undvika genom att lagra primtalen allt eftersom man hittar dem. I denna uppgift skall du låta användaren mata in ett maxtal. Efter detta skall du gå igenom alla tal från 2 upp till maxtalet. Varje tal du testar och finner att det är ett primtal skall lagras sist i en länkad lista (med pekare alltså). För att testa om ett tal är ett primtal krävs att du kontrollerar att det inte är jämnt delbart med något av de tidigare primtalen. Detta innebär att du måste gå igenom listan för varje nytt tal som skall testas, men det är den uppgift du nu har framför dig. När alla tal upp till och med maxtalet är testade (och alla av dessa som är primtal är lagrade i listan) skall programmet skriva ut de funna primtalen. Körexempel: Mata in det maximala talet: 78 Primtalen är: 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73
2003-03-13.kl.08-12 Uppgift 3 I krypteringssammanhang pratas det ofta om RSA-krypton. Detta krypto lanserades av tre forskare i USA som hette Ron Rivest, Adi Shamir och Leonard Adleman. Själva algoritmen är enligt källor i England använd redan tidigare i militära sammanhang. Att denna algoritm inte publicerades av militären var väl ganska naturligt. Vi beskriver här RSA-kryptot kortfattat. Hela principen bygger på att man vill skapa en publik nyckel samt en privat nyckel som gör att meddelandet blir i princip oknäckbart. Nyckelgenereringen går till på följande sätt: 1. Vi väljer två väldigt stora primtal (åtminstone 200-siffriga tal), vi kallar dessa P och Q. Dessa multipliceras till ett nytt tal, N = P * Q. Dessutom beräknar vi Phi = (P-1) * (Q-1). 2. Välj den minimala krypteringsnyckel, K, som är relativt prim med Phi. Ett tal är relativt primt med ett annat om talens största gemensamma delare är ett. Vi har nu den publika nyckeln till RSA-kryptot som består av talen K och N. 3. Förutom detta krävs att man skapar en privat avkrypteringsnyckel, A. Detta går till på så sätt att man söker det minimala talet A som uppfyller ekvationen ((A * K) mod Phi) = 1. Vi söker alltså ett tal som multiplicerat med K ger en rest på 1 när produkten delas med Phi. Vi har nu den privata avkrypteringsnyckeln A. Krypteringen går till på följande sätt: Vi använder följande formel: C = (T K mod N), där C är den krypterade texten (kryptotexten) och T är den ursprungliga texten (klartexten) samt K och N den publika nyckeln. Dekrypteringen går till på följande sätt: Vi använder vi följande formel: T = (C A mod N). Där C är kryptotexten, T klartexten, A den privata avkrypteringsnyckeln och N en del av den publika nyckeln. Din uppgift är att låta en användare mata in två primtal (P och Q) utan felhantering och sedan ta fram värdena på A och K. Vi begränsar oss till små primtal för att inte få så stora problem. Givet i uppgiften är också att du får funktionen som tar fram största gemensamma delare (vi kallar den S_G_D). Denna finns på filen "s_g_d.adb". Ett par exempel på programkörningar (observera att vi använder ganska små primtal :-): Mata in P och Q: 5 11 De sökta talen är: A = 27 K = 3 Mata in P och Q: 13 7 De sökta talen är: A = 29 K = 5 Ett exempel som tar lite tid i värsta fall (dock inte längre än 1-2 minuter): Mata in P och Q: 10007 10009 De sökta talen är: A = 60084029 K = 5
2003-04-30.kl.08-12 Uppgift 1 Nu i valborg är det ju tyvärr en massa problem för polisen vad det gäller alltför berusade personer som desutom håller på med smällare och raketer. Detta har polisen nu kommit fram till att de skall kunna göra något åt genom att låta varje misstänkt skriva ett litet program som utför ett enkelt alkoholtest. Det program som den misstänkte (Se det inte som att det är du som är den misstänkte utan att du får vara försöksperson.) skall skriva är ett program som läser in en alkohol och sen skriver ut den igen. Då polisen antar att de som är berusade inte kan hantera kemiska formler på rätt sätt, medan de som inte är berusade kan detta, anser de att det räcker att mata in alkoholen med dess kemiska formel (t.ex. C 2 H 5 OH). Hur detta ser ut syns i exemplen nedan. Vi antar att man inte skall kunna mata in alkoholer med fler än nio kolatomer (C), men programmet får förstås klara fler. Programmet skall vara konstruerat så att det inte kan anses vara s.k. fullständig uppräkning av fall, d.v.s. alla varianter skall hanteras likvärdigt och inte med en uppräkning av alla fall som finns. Ingen felhantering av indata behöver göras. Den som provar programmet anses vara nykter och veta vad den gör. Krav på programmet: 1. Alkoholen skall lagras i en post. Datatypen skall vara privat och ligga i ett paket. 2. Ingen felhantering. 3. I paketet skall det finnas en Get_Line som ser till att hela den inmatade raden är bortläst (inklusive radslut) och en Put_Line som ser till att utskriften avslutas med ett radslut. Get_Line och Put_Line får endast ha en parameter och den skall vara av den privata datatypen ovan. Inmatningen skall ske på formen CaHbOH, där a och b är de tal som anger antal atomer av respektive slag (b=a*2+1). a skall alltid matas in (även om a=1). Utskriften skall se ut enligt exemplen nedan. Exempel på programkörningar: Mata in en alkohol: C1H3OH Alkoholen ser ut enligt följande: H H - C - OH H Mata in en alkohol: C9H19OH Alkoholen ser ut enligt följande: H H H H H H H H H H - C - C - C - C - C - C - C - C - C - OH H H H H H H H H H
2003-04-30.kl.08-12 Uppgift 2 Alla vi människor tycker väl att det är lite kul att veta sitt ursprung. Det kan vara mormors farmors mor Valborg eller farmors morfar Valle Borg som vi har något minne av eller tycker hade ett intressant yrke. Det du skall göra är att skriva ett program som läser in en rad bestående av maximalt 80 tecken (utan felhantering) och sen kontrollerar om den inmatade raden innehåller en beskrivning av typen ovan (d.v.s. farmors mormors farfars morfars mor eller liknande). Vi antar för enkelhetens skull att det alltid är gemener (a-ö) som användaren matar in. Det som skall kontrolleras är alltså att raden som matas in innehåller orden mor eller far så att det blir en korrekt beskrivning. Kombinationerna farmor m.fl. måste avslutas med ett s om de följs av ytterligare ord. Det är alltså inte korrekt att mata in mormor mormor mor medan det är korrekt att mata in mormors mormor. Krav på programmet: 1) Det är inte ok att räkna upp andra ord än mor och far i programmet. Ni får alltså inte jämföra med t.ex. mormor. 2) Själva testet av korrekthet skall utföras i en funktion som heter Legal_Value. Körexempel: Mata in en släktrelation: mormors farmors morfars farfars mormors morfars farmors far Det är ok! Mata in en släktrelation: mormors morfars farmors fars mormors farmors morfars farfar Det är fel! Tips: Det är tillåtet att använda rekursion för att lösa problemet med kontrollen.
2003-04-30.kl.08-12 Uppgift 3 Skriv ett program som går igenom filen VINTERN_RASAT.TXT (som ni förstår är detta kopplingen till valborg) och sen skriver ut vilket tecken som förekommer flest gånger. OBS! Det är programmet som skall räkna ut vilket tecknet är (eller tecknen om det är flera). Rader som börjar med blanktecken skall ignoreras. Endast de tecken som finns med i svenska alfabetet (a-ö) räknas, d.v.s. alla specialtecken som bindestreck, siffror, punkter m.m. skall ignoreras. Om det är så att två eller flera tecken förekommer lika många gånger (och det är maxantalet förstås) skall alla dessa skrivas ut. I texten på filen finns både gemener och versaler vilket kan ställa till det lite. Vi räknar alla tecken som versaler och ni får konvertera de som är gemener. Därför har vi här en hjälpfunktion som gör om alla svenska bokstäver till versaler: function To_Upper(Item : in Character) return Character is begin if (Item in a.. z ) or else (Item = å ) or else (Item = ä ) or else (Item = ö ) then return Character Val(Character Pos(Item) - Character Pos( a ) + Character Pos( A )); end if; return Item; end To_Upper; Körexempel (om det är flera tecken skrivs de ut med och enligt andra exemplet): I filen VINTERN_RASAT.TXT finns X flest gånger. I filen VINTERN_RASAT.TXT finns X och Y flest gånger.
2003-04-30.kl.14-18 Uppgift 1 Nu i valborg är det ju tyvärr en massa problem för polisen vad det gäller alltför berusade personer som desutom håller på med smällare och raketer. Detta har polisen nu kommit fram till att de skall kunna göra något åt genom att låta varje misstänkt skriva ett litet program som utför ett enkelt alkoholtest. Det program som den misstänkte (Se det inte som att det är du som är den misstänkte utan att du får vara försöksperson.) skall skriva är ett program som läser in en alkohol och sen skriver ut den igen. Då polisen antar att de som är berusade inte kan hantera kemiska formler på rätt sätt, medan de som inte är berusade kan detta, anser de att det räcker att mata in alkoholen med dess kemiska formel (t.ex. C 2 H 5 OH). Hur detta ser ut syns i exemplen nedan. Vi antar att man inte skall kunna mata in alkoholer med fler än tio kolatomer (C), men programmet får förstås klara fler. Programmet skall vara konstruerat så att det inte kan anses vara s.k. fullständig uppräkning av fall, d.v.s. alla varianter av inmatningar skall hanteras likvärdigt och inte med en uppräkning av alla fall som finns. Användaren av programmet är en annan misstänkt individ så det måste finnas full felkontroll av inmatningen. D.v.s. indata kan vara precis vad som helst. Vid felaktiga inmatningar skall programmet skriva ut att det är fel och sen skall programmet fråga efter en ny inmatning. Så fort det är en korrekt inmatning skall programmet skriva ut det inmatade igen och sen avsluta. Krav på programmet: 1. Alkoholen skall lagras i en post. Datatypen skall vara privat och ligga i ett paket. 2. Full felhantering (inklusive undantag, d.v.s. exceptions ) av indata och felutskrifterna skall göras i huvudprogrammet. 3. I paketet skall det finnas en Get_Line som ser till att hela den inmatade raden är bortläst (inklusive radslut) och en Put_Line som ser till att utskriften avslutas med ett radslut. Get_Line och Put_Line får endast ha en parameter och den skall vara av den privata datatypen ovan. Inmatning och utskrift skall ske på formen CaHbOH, där a och b är de tal som anger antal atomer av respektive slag (b=a*2+1). a kan uteslutas (om a=1). Exempel på programkörningar (programmet avslutas när en korrekt formel matas in): Mata in en alkohol: CH3O Felaktig inmatning! Mata in en alkohol: CH3OH Du matade in CH3OH. Mata in en alkohol: C10H20OH Felaktig inmatning! Mata in en alkohol: Jag är inte berusad! Felaktig inmatning! Mata in en alkohol: CH2OH Felaktig inmatning! Mata in en alkohol: C10H21OH Du matade in C10H21OH.
2003-04-30.kl.14-18 Uppgift 2 Skriv ett program som går igenom filen VARSANG.TXT (se i filen för att se kopplingen till valborg :-) och sen skriver ut hur många specialtecken det finns i texten. OBS! Det är programmet som skall räkna ut antalet. Rader som börjar med blanktecken skall ignoreras. Dessutom skall blanktecken, radslutstecken (RETURN) och de vanliga bokstäverna i det svenska alfabetet inte räknas som specialtecken. I texten på filen finns både gemener och versaler vilket skulle kunna ställa till det lite. Därför har vi här en hjälpfunktion som gör om alla gemener till versaler: function To_Upper(Item : in Character) return Character is begin if (Item in a.. z ) or else (Item = å ) or else (Item = ä ) or else (Item = ö ) then return Character Val(Character Pos(Item) - Character Pos( a ) + Character Pos( A )); end if; return Item; end To_Upper; Körexempel (XXX nedan ersätts med det antal programmet hittar i filen): I filen VARSANG.TXT finns det XXX stycken specialtecken.
2003-04-30.kl.14-18 Uppgift 3 I Ada finns datatypen String som ni väl känner till. När man deklarerar en variabel av denna typ måste man alltid ange start- och slutindex vilket gör att man direkt vet hur många tecken som kommer att lagras. När man sen läser in en sträng från tangentbordet med Get resp. Put måste användaren alltid mata in exakt så många tecken som strängen är dimensionerad för och utskriften sker med alla tecken som skickas till Put. I många fall vore det trevligt om man hade en strängdatatyp som inte var så hårt begränsad (vad det gäller längd). Man kanske vill kunna skriva Get och sen låta användaren mata in godtyckligt många tecken. För att lösa detta skulle man kunna tänka sig att använda en länkad lista med tecken. I denna uppgift skall vi göra det lite enklare genom att bestämma oss för att användaren aldrig matar in mer än 80 tecken. Din uppgift är att skapa en datatyp som du skall kalla Unbounded_String som skall innehålla representationen av det som motsvarar strängen beskriven ovan. Dessutom skall det finnas en Get (med en parameter) som läser så många tecken som det finns på den inmatade raden och lagrar detta i parametern. En Put måste ju också finnas med. Denna skall ha en parameter (av din strängtyp) och se till att skriva ut exakt så många tecken som matades in. Krav på din Get : Skall se till att hela raden (inklusive radslut) är inläst. Krav på din Put : Skall se till att hela strängen skrivs ut (lagom många tecken alltså). Radslut skall inte skrivas ut. Givetvis skall ditt program visa att dina underprogram och datatypen fungerar som de skall. Detta innebär att du måste kunna påvisa på något sätt att det inte är något kvar i inmatningsbufferten efter det att Get gjort sitt. Vi antar att inmatningen inte går så fort att det kan komma in någon extra inmatning efter det att användaren tryckt på RETURN. Tips: Din datatyp bör vara en post med en sträng (String) och ett heltal som anger antal inmatade tecken. Det är ok att göra motsvarande med en lista av tecken om du vill, men det blir lite mer kodskrivande. Krav: Det är inte tillåtet att använda sig av andra specialdatatyper som kan finnas i Ada. Inte använda redan befintliga datatyper mer än de grundläggande (Integer, Float, Boolean, Character och String) eller strukturer uppbyggda av dessa (array, access och record). Exempel på programkörning (användarens indata är markerad med fetstil): Mata in en sträng med maximalt 80 tecken: Nu i valborg är det ju trevligt att gå på lite firande! Du skall behöva trycka RETURN för att komma vidare om det är så att inmatningsbufferten är tom. Tryck RETURN nu! Du matade in (denna text skall komma efter ditt RETURN): Nu i valborg är det ju trevligt att gå på lite firande!
2003-08-21.kl.14-18 Uppgift 1 Ett företag har beställt ett program som letar efter förekomster av en teckensekvens i en annan teckensekvens. Din uppgift är alltså att skriva detta program. Programmet skall till att börja med be användaren att mata in två teckensekvenser. Den första sekvensen kallar vi texten och den andra kallar vi söksträngen. Sekvenserna avslutas med varsitt radslut (RETURN). Söksträngen skall alltså försöka återfinnas i texten. Det speciella med detta program är att det inte behöver vara en exakt matchning av söksträngen i texten. Det är helt ok att det finns fler likadana tecken i rad i texten än det finns i söksträngen. Ett exempel som är en matchning är texten= KKAAALLEEE och söksträngen= KALLE. Detta beroende på att det är helt ok att ha flera K, A och E i rad trots att det bara finns ett i söksträngen på motsvarande position. Det är dock viktigt att påpeka att det måste finns minst två L i rad i texten då det finns två i söksträngen (det hade förstås varit ok med tre stycken L i rad också). Ditt program skall upprepa inmatningarna tills det att en matchning funnits. Efter det att en matchning funnits skall programmet avslutas. Exempel på programkörningar (programmet avslutas när en matchning hittats): Mata in texten : KKAAARLLLEEE Mata in söksträngen: KALLE ** Ingen matchning! Mata in texten : Man kan blanda gemener och VERSALER. Mata in söksträngen: versaler ** Ingen matchning! Mata in texten : Sångaren sjöng lallaaalllaaallaaala. Mata in söksträngen: lalalalala ** Matchning! Mata in texten : Morfar: Har ekorren hjul? Mata in söksträngen: Pojken: Nej den har ben... och SVANS! ** Ingen matchning! Mata in texten : Morfar: Var sitter den? Mata in söksträngen: Pojken: I granen! ** Ingen matchning! Mata in texten : Skämt åsido. GRANEN Mata in söksträngen: GRANNEN ** Ingen matchning! Mata in texten : GRANNEN Mata in söksträngen: GRANNNEN ** Ingen matchning! Mata in texten : GRANNEN Mata in söksträngen: GRANNEN ** Matchning! Tips: Det är ok att anta att användaren inte matar in mer än 80 tecken i någon av sekvenserna, men det är inte givet att användaren matar in färre tecken i söksträngen än i texten.
2003-08-21.kl.14-18 Uppgift 2 En pojke fick en klocka i födelsedagspresent och den hade inte bara tidsvisning utan var försedd med datumvisning också (endast vilken dag i månaden alltså). Det pojken upptäckte var dock att klockan hade en intern kontroll av vilken månad det var för tillfället och vid första månadsskiftet kom klockan att stå fel. Detta justerade pojken på det enkla sättet att han drog tillbaka datumet tills det att det stämde igen. Nu kan det tänkas att pojken kommer att få göra detta ett antal gånger innan klockan internt tror sig vara i samma månad som pojken befinner sig i. Din uppgift är att skriva ett program som läser in två datum (månad och dag exakt på formen MM-DD) som motsvarar dels klockans interna datum och dels det aktuella datumet som pojken fyller år (observera att dagnumret skall vara lika i de två inmatningarna) och sen gör samma justeringar som pojken skulle göra. Som resultat av en programkörning skall programmet skriva ut hur lång tid det tagit (i dagar räknat) efter det att pojken fyllde år tills dess att klockan går rätt samt hur många ändringar av klockan som är gjorda (vi antar att pojekn ställer klockan på rätt dagnummer på sin födelsedag.. Det är givet att användaren matar in korrekta data och att inga skottår skall hanteras. Körexempel: Mata in födelsedag : 03-04 Mata in internt datum: 04-04 Antal dagar efter födelsedagen : 27 Antal tillrättningar av klockan: 1 Mata in födelsedag : 04-04 Mata in internt datum: 03-04 Antal dagar efter födelsedagen : 665 Antal tillrättningar av klockan: 11 Mata in födelsedag : 08-01 Mata in internt datum: 03-01 Antal dagar efter födelsedagen : 546 Antal tillrättningar av klockan: 7 Mata in födelsedag : 01-11 Mata in internt datum: 09-11 Antal dagar efter födelsedagen : 383 Antal tillrättningar av klockan: 8 Mata in födelsedag : 01-01 Mata in internt datum: 01-01 Antal dagar efter födelsedagen : 0 Antal tillrättningar av klockan: 0
2003-08-21.kl.14-18 Uppgift 3 På ett hundpensionat i staden var det en gång två hunder som kom in samtidigt och skulle dela rum. Den ena av hundarna hade inga loppor i sin päls medan den andre hade exakt etthundra stycken. Nu bar det sig inte bättre än att dessa loppor hade en tendens att vilja hoppa från den hund de satt på till den andre. En fråga som direkt uppstår är: Hur lång tid tar det innan båda hundarna har lika många loppor i sina respektive pälsar (d.v.s. femtio stycken var)? Du skall skriva ett program som simulerar detta förlopp 1000 gånger och sen skriva ut hur lång tid det tagit i medeltid tills hundarna har lika många loppor. Simuleringen har följande begränsning: Det är alltid exakt en loppa som byter päls (hoppar till den andra hunden) per tidsenhet. Du kan redogöra för tiden i tidsenheter (inte timmar, minuter och sekunder). Tips: Det kan eventuellt vara av intresse att lagra information i ett fält (en array ). Exempel på programkörning (observera att det kan vara andra snittider du får...): Det tog i snitt 148.95 tidsenheter innan det var jämvikt.