1 ( 7) Uppgifter till tenta i 729G04 Programmering och diskret matematik. 17 december 2015, kl 14:00-18:00 Tillåtna hjälpmedel: Dator, penna, papper, linjal, suddgummi, godkänd(a) bok/böcker/kompendier (ej anteckningar, föreläsningsbilder, gamla tentor, gamla labbar eller labbinstruktioner) Uppgifter: Tentan består av 8 uppgifter för TEN3 och 9 uppgifter för TEN4. TEN3 = de som läste kursen i höstas. TEN4 = de som läste kursen mellan HT2009-HT20013. Poäng TEN3: 29 Poäng TEN4: 33 Betyg TEN3: Godkänd: minst 14 poäng, varav minst 11 poäng från uppgift 1-6. Väl godkänd: minst 22 poäng och Godkänd. Betyg TEN4: Godkänd: behövs minst 16 poäng, varav minst 10 poäng från uppgift 1-6 och 2 poäng från uppg 9. Väl godkänd: minst 23 poäng och Godkänd. Frågor på tentamen: Examinator är närvarande i lokalen i början av tentan och besöker sedan tentalokalen kl. 16. Du kan dock ställa frågor via meddelandesystemet (se instruktionsbladet). Om du har funderingar som du inte kan få svar på, skriv ner dessa och hur du tolkat eventuella oklarheter som kommentarer i koden. Om det är systemet som krånglar, kan en av tentavakterna kontakta examinatorn. OBS! Uppgift 9 görs bara av de som läste kursen första gången mellan HT 2009 och HT 2013. Felhantering av funktioners indata behöver ej göras om det inte explicit anges i uppgiften. Koden behöver ej följa PEP8 eller PEP257.
2 ( 7) Uppgift 1 (1p) Implementera funktionen half_string_length(string_value) som får in en sträng och returnerar längden på halva strängen. Kontrollera också så att det värde som kommer in är en sträng. Om värdet inte är en sträng, skriv ut ett felmeddelande och returnera None. >>> half_string_length("hej") 1.5 >>> half_string_length(3) Error: Input type should be a string. >>> Uppgift 2 (3p) Funktionerna i nedanstående deluppgifter får in en lista (string_length) med strängar (anta att alla värden i listan är strängar) och ett heltalsargument length. Funktionerna ska returnera en lista med de strängar som är längre än lika med argumentet length. (Tryckfel. Skulle stå lika med) >>> get_strings_with_length_for(["hej", "hopp", "hoppsan"], 4) ['hopp'] >>> get_strings_with_length_for(["hej", "hopp", "hoppsan"], 2) [] a) Implementera funktionen get_string_swith_length_for(string_list, length) som fungerar enligt ovan. Använd en for-loop. b) Implementera funktionen get_string_swith_length_while(string_list, length) som fungerar enligt ovan. Använd en while-loop. c) Implementera funktionen get_string_swith_length_rec(string_list, length) som fungerar enligt ovan. Använd rekursion.
3 ( 7) Uppgift 3 (4p) För nedanstående uppgifter ska funktionen find_self_references(articles) ta in ett dictionary vars nycklar är strängar och deras värden är listor. Nycklarna är namn på en artikel och deras värden är listor med namn på artiklar som refereras till). Funktionen ska returnera en lista av tupler med två element: nyckel och värde. De nyckel-värdepar som är med i den returnerade listan är de nyckel-värdepar där artikeln innehåller en referens till sig själv. Om inga självreferenser finns så returneras en tom lista. I körexemplet är dictionaryt article_library definierat enligt nedan. article_library = { "abc": ["cde", "def", "efg"], "cde": ["abc", "cde", "efg", "fgh"], "def": ["fgh", "ghi"], "efg": ["efg", "fgh", "ghi"] } >>> find_self_references_for(article_library) [("cde", ["abc", "cde", "efg", "fgh"]), ("efg", ["efg", "fgh", "ghi"])] >>> find_self_references_for({}) [] a) Implementera funktionen find_self_references_for(articles) som fungerar enligt ovan. Använd en for-loop. b) Implementera funktionen find_self_references_while(articles) som fungerar enligt ovan. Använd en while-loop. c) Implementera funktionen find_self_references_rec(articles) som fungerar enligt ovan. Använd en rekursion. Uppgift 4 (5p) Implementera funktionen, kontrollera_personnummer(personnummer) som tar in ett personnummer. Personnummret fås in som en sträng på 10 siffror och ett bindestreck. Funktionen ska kontrollera om det är ett giltigt personnummer. Om personnummret är giltigt, returneras True. Om personnummret är ogiltigt returneras. Algoritmen för att kontrollera ett personnummer beskrivs nedan: 1. Multiplicera den sista siffran i personnummret med 1. Multiplicera den näst sista med 2, den tredje sista med 1, den fjärde sista med 2 osv. 2. Om produkten av en multiplikation blir större än 9, subtrahera 9 från detta tal. 3. Summera alla korrigerade produkter. 4. Om summan av de korrigerade produkterna är jämt delbar med 10 är personnummret giltigt.
4 ( 7) Exempel på uträkning Personnummer: 811218-9876 Personnummer 8 1 1 2 1 8 9 8 7 6 Multiplicera med 2 1 2 1 2 1 2 1 2 1 Produkt 16 1 2 2 2 8 18 8 14 6 Korrigerad produkt (subtrahera 9 om > 9) 7 1 2 2 2 8 9 8 5 6 Summa av korrigerade produkter: 7+1+2+2+2+8+9+8+5+6=50 50 är delbart med 10, alltså är personnummret giltigt. >>> kontrollera_personnummer("811218-9876") True >>> kontrollera_personnummer("811218-9875") Uppgift 5 (5p) Vi lagrar namn på personer och namnen på deras barn i ett dictionary. Nyckeln i dictionaryt är förälderns namn och värdet som är associerat till detta namn är en lista med namn. Alla namn är strängar. a) Implementera funktionen add_child(child, parent, people) som lägger till namnet på barnet child till rätt förälder, parent, i dictionaryt people. Om föräldern inte finns med i vårt dictionary, så lägger vi till den föräldern och dess barn. b) I funktionskommentaren till denna funktion, beskriv eventuella nackdelar med denna datastruktur för lagring av föräldrar och deras barn. Vilka är nackdelarna och varför är de en nackdel vad blir svårare eller omöjligt med denna representation av föräldrar och barn? >>> people_db = {"homer": ["bart"]} >>> add_child("lisa", "homer", people_db) >>> people_db {'homer': ['bart', 'lisa']} >>> add_child("maggie", "marge", people_db) >>> people_db {'homer': ['bart', 'lisa'], 'marge': ['maggie']}
5 ( 7) Uppgift 6 (2p) Skriv funktionen child_exists(child, people) som använder samma datastruktur som föregående uppgift för att representera föräldrar och deras barn. Funktionen ska returnera True om det finns ett barn med namnet child i datastrukturen, annars returneras. >>> some_people_with_children = {"a": ["b", "c"], "d":["e", "f"], "g":["h"]} >>> child_exists("a", some_people_with_children) >>> child_exists("b", some_people_with_children) True >>> child_exists("t", some_people_with_children) Uppgift 7 (4p) I sudoku har man ett fyrkantigt bräde som är uppdelad i nio lådor (de med tjockare markering). Varje låda är i sin tur uppdelad i nio rutor. Vi har alltså ett bräde med 9x9 rutor. Vi representerar detta bräde som en lista med listor. Varje rad är en lista med 9 element. Tomma rutor har värdet None. Ett tomt bräde ser alltså ut enligt nedan: sudoku_board = [ [None, None, None, None, None, None, None, None, None]] Tips: I Python kan man skapa listan [None, None, None] genom att skriva [None]*3
6 ( 7) a) Implementera funktionen create_empty_board() som returnerar ett tomt sudokubräde enligt ovanstående specifikation. b) Implementera funktionen fill_board(board) som fyller alla rutor i sudokubrädet med en slumpmässig en siffra mellan 1-9. Dubbletter får förekomma. c) Implementera funktionen check_row(board, row) som kontrollerar om en rad i ett sudokubräde är godkänt. En rad är godkänd om det inte finns några dubbletter och alla rutor är fyllda. Funktionen tar emot ett bräde (board) och ett radnummer (row). Radnummret är ett heltal mellan 1-9. Funktionen ska returnera True om det inte finns dubbletter i raden. Om det finns dubbletter returneras. Försök att hitta ett sätt för detta som på ett smidigt sätt skulle kunna anpassas till andra radlängder och andra sifferintervall. Uppgift 8 (5p) a) Skriv pseudokod för funktionen get_box(board, box_number) som givet ett sudokubräde (board) enligt ovan, returnerar lådan med det specificerade nummret (box_number). låda. En låda representeras av en lista som innehåller tre listor. Varje lista innehåller i sin tur 3 element. T.ex. [[1,2,3][4,5,6][7,8,9]]. Lådorna numreras från vänster till höger, uppifrån och ner. 1 2 3 4 5 6 7 8 9 Godkänd pseudokod ska ej innehålla tvetydigheter som har betydelse för algoritmen och ligga på en för uppgiften bra abstraktionsnivå (dvs pseudokod som bara säger "returnera rätt låda" är inte godkänd).
7 ( 7) b) Implementera funktionen check_box(box) som kontrollerar om en sudoku-låda är godkänt. En låda är godkänd om det inte finns några dubbletter och alla rutor är fyllda. Funktionen tar emot en låda (box) som har samma datastruktur som returneras av funktionen i uppgift 8a. Funktionen ska returnera True om det inte finns dubbletter i raden lådan. Om det finns dubbletter returneras. Försök att hitta ett sätt för detta som på ett smidigt sätt skulle kunna anpassas till andra radlängder och andra sifferintervall. Uppgift 9 - TEN4 (4p) OBS! Uppgift 9 görs bara av de som läste kursen första gången mellan HT 2009 och HT 2013. Vi använder en lista som datastruktur för att representera en abstrakt datatyp för en spelare i ett datorspel. Nedan är ett exempel: ['unic0rn', 2368, ['sword of love', 'broken helmet']] Listan består alltså av tre element. Det första är spelarens namn, det andra är spelarens poäng och det tredje elementet är en lista med namn på de saker som spelaren har. a) Implementera funktionen is_player(player) som tar in ett värde och kontrollerar så gott det går att det värdet har rätt struktur för ADT:n spelare. Om player har rätt struktur returneras True, annars returneras. b) Implementera funktionen add_item(player, item_name) som lägger till värdet i item_name till listan över saker i spelaren player. Kontrollera att argumentet player som fås är av rätt struktur och att item_name är en sträng. Skriv ut ett felmeddelande om något inte är som det ska. : >>> player1 = ['unic0rn', 2368, ['sword of love', 'broken helmet']] >>> not_a_player = ['unic0rn', 2368, 'sword of love', 'broken helmet'] >>> is_player(player1) True >>> is_player(not_a_player) >>> add_item(player1, "python") >>> player1 ['unic0rn', 2368, ['sword of love', 'broken helmet', 'python']] >>> add_item(not_a_player, "python") ERROR: wrong input. >>>