1. kodused ülesanded

Üldinfo

Lahenduste esitamise tähtaeg on 10.10. Lahendused saata mailiga kas varmo@cs.ut.ee või nestra@cs.ut.ee (sõltuvalt sellest, millises praktikumi rühmas olete); subjektiks peab olema fpkodu1. Iga ülesande eest on võimalik saada kuni 2 punkti (seega kokku kuni 10 punkti). Hilinenud lahenduste korral väheneb punkti summa 20% iga hilinenud nädala kohta. Näiteks, kui lahendus on väärt 10 punkti, aga jõuab meieni 13.10 (so. kolm päeva hiljem), siis on tegelik punktisumma 10 * 0.8 = 8.

Vormistamisest

Kõigi ülesannete lahendused vormistada ühe Haskelli failina. Faili nimi peab olema FPKodu1.hs ning seal defineeritava mooduli nimi FPKodu1. Faili algusse lisada kommentaaridena kõigi rühmaliikmete nimed (rühmas võib olla max. 4 liiget, kusjuures kõigil peab olema sama praktikumi juhendaja) ja maili-aadressid. Kõigi ülesannete korral peavad funktsioonide nimed ja argumentide arv/järjekord vastama täpselt ülesandes esitatule. Lahendused peavad olema loetavad ja piisavalt kommenteeritud (sh. kui kasutate abiprotseduure, siis see mida nad teevad peab olema selgelt välja toodud). Näiteks (FPKodu1.hs):

module FPKodu1 where

---------------------------------------------------------------------
-- FPKodu1.hs
-- Funktsionaalprogrammeerimise meetod - 1. koduülesannete lahendused
--
-- Autorid:
--          Jaan    Tatikas   (tatikas@ut.ee)
--          Salomon Vesipruul (salomon@ut.ee)
---------------------------------------------------------------------

-- 1. ülesanne - Funktsioon atMost kontrollib ...

atMost :: Int -> [a] -> Bool
atMost n xs = ...

Ülesanded

  1. Funktsioon atMost kontrollib, kas list on mitte pikem kui etteantud täisarv:

    > atMost :: Int -> [a] -> Bool
    

    Üks võimalik, kuid ebaefektiivne (vaatab läbi kogu listi) selle funktsiooni definitsioon on esitatud järgnevalt:

    atMost n xs = length xs <= n
    

    Kirjutada funktsiooni atMost efektiivsem definitsioon, mille korral vaadatakse läbi ülimalt n esimest elementi.

  2. Kirjutada funktsioon toDOS, mis teisendab stringis olevad reavahetussümbolid DOS-i tekstiformaadile vastavaks; so. asendab stringis kõik reavahetussümboli '\n' esinemised kahe sümboliga "\r\n":

    > toDOS :: String -> String
    

    Näiteks:
    toDOS "abc\nef"     ==>  "abc\r\nef"
    toDOS "abcnef"      ==>  "abcnef"
    toDOS "abc\nef\n\n" ==>  "abc\r\nef\r\n\r\n"
    toDOS ""            ==>  ""
    
  3. Kirjutada funktsioon filterNext, mis saab ette predikaadi p ja listi xs ning annab väärtuseks listi, mille saame listist xs, kui jätame alles (omavahelist järjekorda muutmata) parajasti need elemendid, mis vahetult järgnevad mõnele tingimust p rahuldavale elemendile:

    > filterNext :: (a -> Bool) -> [a] -> [a]
    

    Näiteks:

    filterNext (> 0) []                  ==>  []
    filterNext (> 0) [-1]                ==>  []
    filterNext (> 0) [1]                 ==>  []
    filterNext (> 0) [1,2]               ==>  [2]
    filterNext (> 0) [1,-2]              ==>  [-2]
    filterNext (> 0) [1,-2,-3,4,5,-6,7]  ==>  [-2,5,-6]
    filterNext (> 0) [0,1,2,3,-4,-5,-6]  ==>  [2,3,-4]
    

  4. Kirjutada funktsioon flatZip :: [a] -> [a] -> [a], mis argumentlistidel k ja l annab väärtuseks listi, mille elemendid pärinevad vaheldumisi listidest k ja l, nende järjekorda muutmata. Pikema argumentlisti järelejääv sabaosa jääb vastuse lõppu.

    > flatZip :: [a] -> [a] -> [a]
    

    Näiteks:

    flatZip [1,2,3] [4,5,6]  ==>  [1,4,2,5,3,6]
    flatZip [1] [4,5,6]      ==>  [1,4,5,6]
    flatZip [1,2,3] [4,5]    ==>  [1,4,2,5,3]
    

  5. Kirjutada funktsioon rotations, mis leiab argumentlisti kõik tsüklilised nihked:

    > rotations :: [a] -> [[a]]
    

    Näiteks:

    rotations []       ==>  []
    rotations [1]      ==>  [[1]]
    rotations [1,2]    ==>  [[2,1], [1,2]]
    rotations [1,2,3]  ==>  [[2,3,1], [3,1,2], [1,2,3]]
    


Varmo Vene