Sara Hedbrandh Strömberg Programkonstruktion VT 10 Inlämninsguppgift 1.Inledning 1.2 Sammanfattning 1.3 Programmet Användarbeskrivning 2.1 Lösa korsordet 2.2 Körexempel Programdokumentation 3.1 Abstrakta datatypen 3.2 Algoritmer 3.3 Delfunktioner 3.4 Inläsning av korsordet 3.4.1 Algoritm 3.4.2 Funktionsspecifikation 3.4.3 Programflödet 3.5 Inläsning av ordlista 3.5.1 Algoritm 3.5.2 Funktionsspecifikation 3.5.3 Programflödet 3.6 Lösning av kryptokorsord 3.6.1 Algoritm 3.6.2 Funktionsspecifikation 3.6.3 Programflödet 3.7 Presentation av lösningarna 3.7.1 Algoritm 3.7.2 Funktionsspecifikation 3.7.3 Programflödet 4. Brister
1. Inledning 1.2 Programmet Programmets uppgift är att med hjälp av en ordlista och ett kryptokorsord få ut alla möjliga kombinationer av tal-bokstavspar så att alla kryptoord i kryptokorsordet bildar befintliga ord i ordlistan. Alla möjliga matchningar binds i den abstrakta datatypen match som tal-bokstavspar. 2. Användarbeskrivning 2.1 Lösa korsordet För att kryptokorsordslösaren ska fungera korrekt måste kryptokorsordet upfylla typen int list list och ordlistan typen string list list. En dellista i ordlistan består av ord med samma storlek och tillsammans med fler dellistor med ord av samma storlek i respektive lista bildar en ordlista. Kryptolistan består av en lista med ord som i sig representeras av tal i olika kombinationer. Ett tal kan bara bindas till en bokstav och omvänt. 2.1.1 I Moscow ML: Genom solve(kryptolista,ordlistor); körs programmet och kryptokorsodet löses. Det som returneras är den abstrakta datatypen match som ligger i listan. För att få fram alla matchningar skrivs frommatch(hd(it)); in i terminalen och första matchningen skrivs ut i läslig form. 2.1.2 På hemsidan Krypto-korsordslösaren Skriv talen från korsordet du vill lösa i rätt rutor i tabellen. De svarta rutorna lämnas tomma i tabellen, klicka därefter på Lös och de tio första matchningarna visas på en ny sida. För att lösa ännu ett nytt korsord klickar du på Lös ett nytt korsord. För att rensa det påbörjade korsordet och börja om klicka på Rensa. 2.2 Körexempel Ett körexempel i Moscow ML är : solve([[1,2],[2,1,3]],[["i"],["is","ni"],["nix","sil","sav"],["tomt"]]); Vilket ger : [<match>] Eftersom innehållet inte kan visas i match måste match skrivas om i läslig form. Det görs genom att anropa: frommatch(hd(it));
Matchningen skrivs ut: [(3, #"L"), (1, #"I"), (2, #"S")] 3. Programdokumentation 3.1 Abstrakta datatypen Matchningarna har jag representerat med en abstype match = M of (int*char) list. Funktionerna i gränssnittet som används är: - taurb: (int* match -> string) taurb returnerar bokstaven, som är bunden till det inmatade talet, skrivet som en sträng. - taurt: (char * match -> string) taurt returnerar talet, som är bundet till den inmatade bokstaven, skrivet som en sträng. - finns: ((int*char) * match -> bool) finns undersöker om tal-bokstavsparet finns i match - ettkrypto: (int list * string * match -> match) alla tal i kryptot binds till bokstäverna med hänsyn till match - frommatch: (match -> (int * char) list ) frommatch skriver ut en matchning i läslig form - tom: (match -> bool) tom undersöker om match är tom. Sant om listan är tom. 3.2 Algoritmer 3.2.1 Funktioner hittaolist: (int list * string list list -> string list) Den anropar sig själv rekursivt för att hitta ordlista som har element med samma längd som kryptoordet. Returnerar en ordlista. helaolist: (int list * string list list * match -> match list) helaolist returnerar alla möjliga matchningar av hela ordlistan på ett kryptoord med hänsyn till match match2: (int list * string list list * match list -> match list) alla möjliga utvecklingar på matchningarna med hänsyn till kryptoordet match1: (int list list * string list list * match list -> match list) alla möjliga matchningar med hänsyn till mat
3.3 Delfunktioner 3.4 Inläsning av korsordet 3.4.1 Algoritm 1. Alla fält läggs i en lista (l) där en rad i tabellen blir en dellista, och en kolumn också blir en dellista. 2. Fösta dellistan i listan (l) tas ur. Nya listor bildas där talet 0 bildar en tom lista och bryter av till nya listor. Om listan är tom så tom lista. 3. De tomma listorna och listor som har längden mindre än 2 tas bort. Detta sätts ihop med 3) med resten av listan (l). 3.4.2 Funktionsspecifikation (* tolist2(l) TYPE : int list list-> int list list POST : alla element i listan l omgjorda till dellistor där 0:orna bryter av till en dellista. EXAMPLES: tolist2([[1,2,3,4,2,4],[1,2,0,7,4]]) -> [[1,2,3,4,2,4],[1,2],[7,4]] (* variant: lenth l 3.4.3 Programflödet (1) a är bundet till all rutorna från hemsidan som ligger i en lista. En rad ger en dellista och en kolumn ger också en dellista i listan. (2) words binds till funktionsanropet tolist2(a). (3) Denne anropar tokrypto3 på första elementet i listan, där dellistan görs om till kryptoord med hänsyn på talet 0, som sätts ihop med anropet av tolist2 med resten av listan. 3.5 Inläsning av ordlista 3.5.1 Algoritm 1. Strömmen öppnas. 2. Alla rader läggs som element i en lista. 3. Listan sorteras med hänsyn till elementens storlek. 4. Fösta elementet läggs i en dellista. 5) med resten av listan 5. Är listan tom så tom lista och avsluta funktionen. Är första elementet lika långt som dellistan som precis bildats läggs elementet i samma lista annars läggs den i en ny dellista. 5) med resten av listan. 3.5.2 Funktionsspecifikation (* wordlist(l) TYPE : string list -> string list list PRE : (l är en sorterad lista i stigande ordning) POST : alla i element i listan l som är lika långa läggs i en och samma lista EXAMPLES: wordlist(["hej","haj","hopp","hejsan"]) -> [["hej","haj"],["hopp"],["hejsan"]] (* Variant:!y
3.5.3 Programflödet sorteradordlista: (1) fgrep( long.txt ) hämtar alla ord och lägger dem i en lista. (2) Med mergesort av det listan sorteras alla orden med kortaste först. (3) alla element som är mindre än 2 tas bort. (4) words: wordlist(sorteradordlista) som lägger alla ord i dellistor. Ord som är lika långa ligger i samma dellista. 3.6 Lösning av kryptokorsord 3.6.1 Algoritm 1. Ta ur ett kryptoord i taget. 2. Ta rätt dellista ur ordlistan där orden har samma längd som det tagna kryptoordet. Hitta alla matchningar som finns av talen och bokstäverna för alla ord och kryptoordet. 3. Upprepa steg 2 på nästa kryptoord i listan, dessutom med hänsyn till dem nya matchningarna. Uppstår det en tom matchning tas den bort. 4. Upprepa steg 2 och 3 med nästa kryptoord och alla nya matchningar. 5. Returnera alla fungerande matchningar och skriv ut i läslig form. 3.6.2 Funktionsspecifikationer De viktigaste specifikationerna till funktionerna: (* hittaolist ( a,b) TYPE : int list * string list list -> string list PRE : ordlistan i b måste innehålla element som alla har samma längd POST : ordlistan i b som innehåller element med samma längd som kryptot a. EXAMPLES : hittaolist([1,2],[["h"],["ho","hi"]]) -> ["ho","hi"] (* variant: length b (* helaolist(krypto,ordlista,match) TYPE : int list * string list list * match -> match list POST : alla möjliga matchningar av hela ordlistan på kryptoordet med hänsyn till match EXAMPLES: helaolist([1,2,3,1,1],[["aj"],["?nska","sluss","kloss"]],empty) = [[(3, #"U"), (2, #"L"), (1, #"S")]] helaolist([1,2,3,1,1],[["aj"],["?nska","sluss","kloss"]],m[(1,#"b")]) = [] helaolist([1,2,3],[["aj"],["hej","haj","apa"]],[]) = [M[(3, #"J"), (2, #"E"), (1, #"H")], M[(3, #"J"), (2, #"A"), (1, #"H")]] (* solve(crypto,words) TYPE : int list list * string list list -> match list PRE : words uppfyller kraven på en ordlista POST : En lista med alla lösningar till kryptokorsordet crypto med ord tagna från ordlistan words EXAMPLE : solve([[1,2],[2,1,3]],[["i"],["is","ni"],["nix","sil","sav"],["tomt"]]) = [matchningen 1-I 2-S 3-L]
3.6.3 Programflödet (1) solve anropar match1 med en tom matchning som i sin tur anropar (2) match2 på alla kryptoord, (3) hittaolist (av respektive kryptoord och hela ordlistan) och nya matchningar som bildas. (3) match2 tar bort alla tomma matchningar på anropet av (4) helaolist, som anropas med ett kryptoord, hela ordlistan på alla matchningarna. (5) helaolist tar bort alla tomma matchningar av anropet av ettkrypto med kryptoordet på alla ord i ordlistan och en matchning. (6) ettkrypto undersöker om alla tal i kryptoordet finns i matchningen med hjälp av funktionen (7) taurb och alla bokstäver i ordet med hjälp av funktionen (8) taurt. Den undersöker också om bindningen redan finns mellan alla tal och bokstäver som finns i matchingen med hjälp av (9) finns. 3.7 Presentation av lösningarna 3.7.1 Algoritm 1. Första elementet ur det första elementet i matchlistan skrivs ut med ett likhetstecken mellan. Därefter skrivs nästa element ut på nästa rad. 2. När matchlistan är tom returneras en rad med bindestreck under. 3.7.2 Funktionsspecifikation (* frommatch(l) TYPE : match -> (int * char) list POST : en lista med matchningarna i läslig form EXAMPLES: frommatch(empty) = [] För hemsidan används funktionen write som skriver ut matchningar som en sträng. (* write'(l) TYPE : (int * char) list POST : l som en sträng EXAMPLES: write'([(1,#"h"),(2,#"a")]) -> "1 = h, 2 = a, <br>----------<br>" (*variant: length l 3.7.3 Programflödet På hemsidan: (1) write anropar ((2) frommatch på dem 10 första matchningarna från anropet av solve) och dem matchningarna skrivs ut som en sträng. I terminalen: (1) frommatch(hd(it)) tar första matchningen och skriver ut den i läslig form.
4. Brister Med lösningar med flera ord tar det för lång tid. Där skulle jag vilja förbättra koden så det går snabbare att lösa. Just nu har jag löst det genom att förkorta ordlistan. Detta är inte optimalt utan jag skulle vilja använda hela ordlistan för att lösa korsordet men eftersom tio lösningar max ska visas, ansåg jag detta var ett alternativ.