diff --git a/code/Angabe2.hs b/code/Angabe2.hs index 4c095ae..9fb2772 100644 --- a/code/Angabe2.hs +++ b/code/Angabe2.hs @@ -30,7 +30,11 @@ data Tag = I | II | III | IV | V | VI | VII | VIII | IX | X data Monat = Jan | Feb | Mar | Apr | Mai | Jun | Jul | Aug | Sep | Okt | Nov | Dez deriving (Eq,Ord,Show) type Jahr = Nat1 -data Datum = D Tag Monat Jahr deriving (Eq,Show,Ord) +data Datum = D { + tag :: Tag, + monat :: Monat, + jahr :: Jahr + } deriving (Eq,Show,Ord) data Testart = PCR | Antigen deriving (Eq,Show,Ord) data Impfstoff = AstraZeneca | BioNTec | JundJ | Moderna | Sputnik | Sinovac deriving (Eq,Show,Ord) @@ -60,6 +64,41 @@ type Abzuweisende = [VorUndNachname] type Kontrollzeitpunkt = (Datum,Uhrzeit) data Kontrollergebnis = Einlassen | Abweisen | Ungueltig deriving (Eq,Show) +-- General functions +was_sick :: Person -> Bool +was_sick p + | dreig_status p == Genesen = True + | otherwise = False + +is_vaccinated :: Person -> Bool +is_vaccinated p = + case dreig_status p of + Geimpft _ _ -> True + _ -> False + +is_tested :: Person -> Bool +is_tested p = + case dreig_status p of + Getestet _ _ _ -> True + _ -> False + +full_months::[Monat] +full_months = [Jan, Mar, Mai, Jul, Aug, Okt, Dez] + +is_date_valid :: (Datum, Uhrzeit) -> Bool +is_date_valid (d, u) + | monat d == Feb = + let y = jahr d in + let t = tag d in + if y `mod` 4 /= 0 && t > XXVIII then False + else + if y `mod` 100 == 0 && y `mod` 400 /= 0 then False + else + if t > XXIX then False + else True + | tag d > XXX && not(monat d `elem` full_months) = False + | tag d > XXXI = False + | otherwise = True -- Aufgabe A.2 {- Knapp, aber gut nachvollziehbar geht einzulassen folgendermassen vor: @@ -69,9 +108,25 @@ data Kontrollergebnis = Einlassen | Abweisen | Ungueltig deriving (Eq,Show) einzulassen :: (Person,Regel,Kontrollzeitpunkt) -> Kontrollergebnis einzulassen (p, r, k) | dreig_status p == Udrei = Abweisen - | r == ZweiG = + | otherwise = should_allow p r k + +should_allow :: Person -> Regel -> Kontrollzeitpunkt -> Kontrollergebnis +should_allow p ZweiG k + | (not (was_sick p)) || (not (is_vaccinated p)) = Abweisen + | otherwise = check_cert_validity p k + +should_allow p ZweieinhalbG k + | is_tested p = if testart (dreig_status p) == Antigen then Abweisen - else Einlassen + else check_cert_validity p k + | otherwise = check_cert_validity p k + +should_allow p DreiG k = check_cert_validity p k + +check_cert_validity :: Person -> Kontrollzeitpunkt -> Kontrollergebnis +check_cert_validity p k + | not(is_date_valid k) = Ungueltig + | is_tested p && not(is_date_valid ((datum (dreig_status p)), (uhrzeit (dreig_status p)))) = Ungueltig | otherwise = Einlassen -- Aufgabe A.3 @@ -110,9 +165,3 @@ einzulassen (p, r, k) folgendermassen vor: ... -} - - - - - -