Zadanie 2

Získať môžete max. 5 bodov za každú z úloh (spolu max. 10 bodov).

Odovzdávajte úlohy do Moodle vo forme zdrojového kódu v jazyku Haskell so stručnými komentármi.

Generovanie rodných čísel

Vytvorte funkciu, ktorá bude generovať všetky platné rodné čísla pre zadaný dátum narodenia a pohlavie. Na reprezentáciu dátumu a pohlavia použite dátové typy:

data Date = Date Int Int Int -- Year, Month, Day
data Sex = Male | Female deriving Eq

Vygenerované rodné čísla preveďte na reťazce v tvare "xxxxxx/xxxx", pričom platí, že rodné číslo je platné vtedy, ak je deliteľné číslom 11.

validBirthNumbers :: Date -> Sex -> [String]

Spracovanie výsledkov volieb

Vytvorte program pre spracovanie výsledkov volieb. Výsledky volieb nech sú zadané ako zoznam dvojíc (strany, počet hlasov). Program má vypočítať, ktoré strany prekonajú hranicu prechodu do parlamentu a koľko získajú poslaneckých mandátov.

Nech sú definované dve funkcie:

electionResults :: [(Subjekt, Int)] -> [(Subjekt, Int)]

formatElectionResults :: [(Subjekt, Int)] -> String

Prvá vypočíta výsledky volieb, teda počty poslaneckých mandátov získaných jednotlivými stranami.

Druhá naformatuje už vypočítaný výsledok v tvare:

Smer-SD ............................. 62
SDKU-DS ............................. 28
SaS ................................. 22
KDH ................................. 15
Most-Hid ............................ 14
SNS .................................. 9

Keďže okrem jednotlivých strán môžu kandidovať aj koalície, použijeme dátový typ:

data Subjekt = Strana String | Koalicia [String]

Postup výpočtu počtu poslancov nech je nasledovný (ide o mierne zjednodušenú verziu skutočného postupu):

  1. Najprv sa vyberú strany, ktoré prekonali stanovenú hranicu (podiel z celkového počtu hlasov), a teda sa dostanú do parlamentu. Hranica je 5% pre strany, 7% pre dvoj a trojkoalície, a 10% pre väčšie koalície.
  2. Následne sa vypočíta súčet hlasov za tieto strany a vydelí sa celkovým počtom poslancov. Takto získané číslo nazvime volebným číslom.
  3. Počet hlasov za každú postupujúcu stranu sa vydelí volebným číslom a výsledok celočíselného delenia je predbežným počtom mandátov, ktoré strana dostane.
  4. Ak takýmto spôsobom nebudú pridelené všetky mandáty, zvyšné mandáty je potrebné prideliť (po jednom) stranám s najväčším zostatkom pri delení volebným číslom.

Na testovanie programu môžete použiť výsledky volieb 2010:

elections2010 :: [(Subjekt, Int)]
elections2010 = [
    (Strana "Smer-SD", 880111), (Strana "SDKU-DS", 390042),
    (Strana "SaS", 307287), (Strana  "KDH", 215755),
    (Strana "Most-Hid", 205538), (Strana "SNS", 128490),
    (Strana "SMK", 109638), (Strana "LS-HZDS", 109480),
    (Strana "SDL", 61137), (Strana "LSNS", 33724),
    (Strana "KSS", 21104), (Strana "Unia", 17741),
    (Strana "Paliho Kapurkova", 14576), (Strana "EDS", 10332),
    (Strana "ND", 7962), (Strana "SRK", 6947),
    (Strana "ZRS", 6196), (Strana "AZEN", 3325)]

elections2020 :: [(Subjekt, Int)]
elections2020 = [
    (Strana "OLANO", 721166), (Strana "SMER-SD", 527172),
    (Strana "Sme rodina", 237531), (Strana  "LSNS", 229660),
    (Koalicia ["PS", "Spolu"], 200780), (Strana "SaS", 179246),
    (Strana "Za ludi", 166325), (Strana "KDH", 134099),
    (Strana "MKS", 112662), (Strana "SNS", 91171),
    (Strana "Dobra volba", 88220), (Strana "Vlast", 84507),
    (Strana "Most-HID", 59174), (Strana "Socialisti.sk", 15925),
    (Strana "Mame toho dost!", 9260), (Strana "SLS", 8191),
    (Strana "DS", 4194), (Strana "SOLIDARITA", 3296),
    (Strana "SNK", 2018), (Strana "SHO", 1966),
    (Strana "Hlas ludu", 1887), (Strana "PSN", 1261),
    (Strana "99%", 991), (Strana "Slovenska liga", 809)]

elections2023 :: [(Subjekt, Int)]
elections2023 = [
    (Strana "SMER-SD", 681017), (Strana "PS", 533136),
    (Strana "HLAS-SD", 436415), (Koalicia ["OLANO", "KU", "Za ludi"], 264137),
    (Strana "KDH", 202515), (Strana "SaS", 187645), (Strana "SNS", 166995),
    (Strana "Republika", 141099), (Strana "Aliancia", 130183),
    (Strana "Demokrti", 87006), (Strana "Sme rodina", 65673),
    (Strana  "LSNS", 25003), (Strana "KSS", 9867), (Strana "Pirati", 9358),
    (Strana "MM", 7935), (Strana "MF", 3468), (Strana "MySlovensko", 2786),
    (Strana "KARMA", 2407), (Strana "SOS", 2401), (Strana "SRDCE", 2315),
    (Strana "Princip", 1817), (Strana "Spravodlivost", 1335),
    (Strana "SHO", 1332), (Strana "VB", 1262), (Strana "SDKS-DS", 771)]

main = putStrLn (formatElectionResults (electionResults elections2020))