pondělí 30. ledna 2006

Haskell - male ulozky

Napsal: David

Sada malych uloh z haskellu i s resenim. Hodi se k priprave na zkousku z neproceduralniho programovani.


------------------------------ Male ulohy Haskell ------------------------------

-- 1. RIDKE MATICE -------------------------------------------------------------

{-
Ridka matice je reprezentovana jako trojice (m,n,s), kde m je pocet radek,
n je pocet sloupcu a s je seznam trojic (i,j,a_ij) (kde i je cislo radky,
j je cislo sloupce a a_ij je nenulova hodnota) usporadany vzestupne podle
i a uvnitr radek podle j.

Naprogramujte funkce, ktere v teto reprezentaci realizuji

(a) transpozici matic
(b) nasobeni matic
(c) umocnovani matic (dobrovolne)
-}

-- datova struktura

-- (i,j,a_ij)
type RMVals = (Int,Int,Int)

-- (m,n,s)
type RM = (Int,Int,[RMVals])

-- sortovani trojic

sort3 :: [RMVals] -> [RMVals]
sort3 [] = []
sort3 (x:xs) = sort3 [a | a <- xs, a<- xs, a>=x]

-- transpozice

-- transpozice hodnot
transV :: [RMVals] -> [RMVals]
transV [] = []
transV ((a,b,c):xs) = (b,a,c):(transV xs)

-- transpozice matice

trans :: RM -> RM
trans (m,n,s) = (n,m,sort3 (transV s))

-- nasobeni matic


del0 :: [RMVals] -> [RMVals] -- vynechani nulovych prvku
del0 [] = []
del0 ((a,b,c):xs) | c==0 = del0 xs
| otherwise = (a,b,c):(del0 xs)

-- z matice, ktera muze obsahovat vicekrat jeden prvek udela normalni
-- souctem hodnot techto duplicitnich prvku
-- tedy secte hodnoty stejnych prvku za sebou
simpM :: [RMVals] -> [RMVals]
simpM [] = []
simpM [x] = [x]
simpM ((xa,xb,xc):(ya,yb,yc):xys)
| xa==ya && xb==yb = simpM ((xa,xb,xc+yc):(xys))
| otherwise = (xa,xb,xc):(simpM ((ya,yb,yc):xys))


-- vynasobi matice s tim, ze format matice muze obsahovat nulove prvky
mulM :: [RMVals] -> [RMVals] -> [RMVals]
mulM xs ys = simpM (sort3 [(xa,yb,xc*yc)
| (xa,xb,xc) <- xs, (ya,yb,yc) <- ys, xb==ya]) -- samotne nasobeni mul :: RM -> RM -> RM
mul (m1,n1,s1) (m2,n2,s2) | n1==m2 = (m1,n2,s3)
where s3 = del0 (mulM s1 s2)

-- testovaci matice

t1 :: RM
t1 = (2,3,[(1,3,1),(2,1,2),(2,2,1)])

t2 :: RM
t2 = (3,4,[(1,1,6),(1,2,2),(2,1,1),(3,4,1)])

-- testy testovacich matic

r1 :: RM
r1 = trans t1

r2 :: RM
r2 = trans t2

r3 :: RM
r3 = t1 `mul` t2




-- 2. VYPOUSTENI Z BVS --------------------------------------------------------

{-
Definujte prirozenou reprezentaci binarniho stromu, v jehoz uzlech je ulozena
informace nejakeho typu (podtridy Ord).

Naprogramujte funkci, ktera z binarniho vyhledavaciho stromu vypusti uzly
patrici do zadaneho intervalu (nejsou-li tam zadne takove, bude to identita).
-}


-- datova struktura

data BVSTree a = Nil | BVS ((BVSTree a),a,(BVSTree a)) deriving (Show, Eq)

-- najde min/max v BVS
findMin :: (Ord a) => BVSTree a -> a
findMin (BVS (left,val,right))
| left==Nil = val
| otherwise = findMin left

findMax :: (Ord a) => BVSTree a -> a
findMax (BVS (left,val,right))
| right==Nil = val
| otherwise = findMax right

-- vypusti ze stromu vsechny uzly od m do n
remBVS :: (Ord a) => BVSTree a -> a -> a -> BVSTree a
remBVS Nil _ _ = Nil

remBVS (BVS (Nil,val,Nil)) m n
| m <= val && val <= n = Nil | otherwise = BVS (Nil,val,Nil) remBVS (BVS (left,val,right)) m n = if m>n then Nil
else if n a -> [a] -> Bool
notMember _ [] = True
notMember y (x:xs)
| y==x = False
| otherwise = notMember y xs

-- resi danou ulohu
solve3 :: [Int] -> Int -> [Int]
solve3 xs k = take k [x | x <- [1..], x `notMember` xs] -- testy solve3_test1 = solve3 [8,25,4,7,12,2,1,23] 16 solve3_test2 = solve3 [1,2,3,4,5,6,8,9,10] 1 solve3_test3 = solve3 [] 12 -- 4. 1-2 STROMY --------------------------------------------------------------- {- Haskell: mam datovy typ reprezentujici 1-2 strom: data T1 a = Nil | N1 a (T1 a) | N2 a (T1 a) (T1 a) Ukolem je napsat funkci fold typu: b -> (a -> b -> b) -> (a -> b -> b -> b) -> T1 a -> b

a funkci hodnota, ktera pomoci funkce fold projde zadany strom a vrati seznam
hodnot z konstruktoru N2 v poradi preorder - tj. vsechny hodnoty z vrcholu,
ktere maji dva potomky

Hint:
V tomto pripade byla fold definovana takto:

fold::b->(a->b->b)->(a->b->b->b)->T1 a->b

b nahradi vrcholy konstruovane Nil
na vrchol s konstruktorem N1 a (T1 a) zavola funkci (a->b->b)
a na N2 a (T1 a) (T1 a) zavola funkci (a->b->b->b)
-}


data T1 a = NilX | N1 a (T1 a) | N2 a (T1 a) (T1 a) deriving (Show, Eq)

-- funkce fold (=svinovani)
fold :: b -> (a -> b -> b) -> (a -> b -> b -> b) -> (T1 a) -> b
fold fNil fN1 fN2 NilX = fNil
fold fNil fN1 fN2 (N1 val next) = fN1 val (fold fNil fN1 fN2 next)
fold fNil fN1 fN2 (N2 val left right) = fN2 val (fold fNil fN1 fN2 left) (fold fNil fN1 fN2 right)

-- funkce hodnota pomoci fold
hodnota :: (T1 a) -> [a]
hodnota = fold [] (\ _ xs -> xs) (\ x xs ys -> (x:xs)++ys)


-- pro lepsi pochopeni jeste funkce pro seznam hodnot ve VSECH vrcholech
hodnota_all :: (T1 a) -> [a]
hodnota_all = fold [] (\ x xs -> (x:xs)) (\ x xs ys -> (x:xs)++ys)

-- testovaci strom

t12_t1 :: (T1 Int)
t12_t1 = N1 20
(
N2 13
(
N2 1
(
N2 21
(
N1 9 NilX
)
(
N1 11
(
N1 8 NilX
)
)
)
(
N1 2
(
N1 5 NilX
)
)
)
(
N1 4
(
N1 8
(
N1 7 NilX
)
)
)
)

{-
take se da zapsat jako

N1 20 (N2 13 (N2 1 (N2 21 (N1 9 NilX) (N1 11 (N1 8 NilX))) (N1 2 (N1 5 NilX)))
(N1 4 (N1 8 (N1 7 NilX))))
-}

-- testy
t12_test1 = hodnota t12_t1




-- 5. BATOH --------------------------------------------------------------------

{-
Je dan seznam A cislo N. Napiste funkci, ktera zjisti, zda je mozne poscitat
(nektere) prvky seznamu, aby soucet vysel N.
-}

-- implementujeme funkci, ktera tento seznam vrati, dana uloha pak by byla
-- pokud seznam neexistuje, vraci se []
batoh :: [Int] -> Int -> [Int]
batoh _ 0 = []
batoh [] _ = []
batoh (x:xs) n
| sum newBatoh1 == n = newBatoh1
| sum newBatoh2 == n = newBatoh2
| otherwise = []
where newBatoh1 = x:(batoh xs (n-x))
newBatoh2 = batoh xs n

-- testy
b1 = batoh [1,58,3,9,2,1,85,2,6,51,8,69,21] 34
b2 = batoh [1,58,3,9,2,1,85,2,6,51,8,69,21] 35
b3 = batoh [1,58,3,9,2,1,85,2,6,51,8,69,21] 60
b4 = batoh [2,4,8,16,32,64,128] 91
b5 = batoh [1,2,4,8,16,32,64,128] 91
b6 = batoh [1,5..] 91
b7 = batoh [1,1..] 654




-- 6. PERMUTACE USPORADANI -----------------------------------------------------

{-
Je dan seznam A - seznam dvojic prvku, urcujici castecne usporadani. Vyrobte
seznam vsech permutaci puvodniho seznamu, ktere vyhovuji castecnemu
usporadani.
-}

-- vrati seznam bez jendoho prvku
without :: (Eq a) => [a] -> a -> [a]
without [] _ = []
without (x:xs) a
| a==x = xs `without` a
| otherwise = x:(xs `without` a)


-- not member vraci, zda prvek neni v seznamu
notMember1 :: (Eq a) => a -> [a] -> Bool
notMember1 _ [] = True
notMember1 y (x:xs)
| y==x = False
| otherwise = notMember1 y xs

-- ze seznamu prvku vylouci opakujici se prvky
uniq :: (Eq a) => [a] -> [a]
uniq [] = []
uniq (x:xs)
| x `notMember1` xs = x:(uniq xs)
| otherwise = uniq xs

-- vrati seznam prvku ze seznamu dvojic
tuplList :: (Eq a) => [(a,a)] -> [a]
tuplList [] = []
tuplList ((one,two):xs) = uniq (one:two:(tuplList xs))

-- vytvori seznam vsech permutaci prvku
perm :: (Eq a) => [a] -> [[a]]
perm [] = [[]]
perm xs = [one:others | one <- xs, others <- (perm (xs `without` one)) ] -- vrati suffix seznamu od zadaneho prvku upto :: (Eq a) => [a] -> a -> [a]
upto [] _ = []
upto (x:xs) a
| x==a = [x]
| otherwise = x:(xs `upto` a)

-- overi, zda permutace splnuje podminky usporadani
validone :: (Eq a) => [a] -> (a,a) -> Bool
validone p (a,b) = b `notMember1` (p `upto` a)

valid :: (Eq a) => [a] -> [(a,a)] -> Bool
valid p [] = True
valid p (cond:conds) = validone p cond && valid p conds

-- vyresi ulohu tak, ze ze seznamu dvojic udela seznam prvku, z nej vytvori
-- vsechny permutace, ktere pak prefiltruje pres podminky usporadani
permus :: (Eq a) => [(a,a)] -> [[a]]
permus a = [p | p <- perm (tuplList a), valid p a] -- testy perm_test1 = permus [(1,2),(17,18),(16,17)] -- 7. PREVOD N-ARNI -> BINARNI -------------------------------------------------

{-
Sestavte funkci realizujici kanonickou reprezentaci obecneho stromu pomoci
binarniho ("levy syn" = prvorozeny syn, "pravy syn" = mladsi bratr).
-}

-- datova struktura

data TreeN a = NodeN a [TreeN a] deriving (Eq, Show)
data TreeB a = NilB | NodeB a (TreeB a) (TreeB a) deriving (Eq, Show)


--
convNBs :: (Eq a) => [TreeN a] -> (TreeB a)
convNBs [] = NilB
convNBs [NodeN a []] = NodeB a NilB NilB
convNBs [NodeN a [x]] = NodeB a NilB (convNB x)
convNBs [NodeN a xs] = NodeB a (convNBs xs) NilB
convNBs ((NodeN a xs):ts) = NodeB a (convNBs xs) (convNBs ts)

--
convNB :: (Eq a) => (TreeN a) -> (TreeB a)
convNB tree = convNBs [tree]

-- testovaci data

treeN1 :: TreeN Int
treeN1 = NodeN 10
[
NodeN 5
[
NodeN 2 [],
NodeN 7 []
],
NodeN 7
[
NodeN 10 []
],
NodeN 12 [],
NodeN 3
[
NodeN 18 [],
NodeN 1 [],
NodeN 40 []
]
]

{-
take se da zapsat jako

NodeN 10 [NodeN 5 [NodeN 2 [],NodeN 7 []],NodeN 7 [NodeN 10 []],NodeN 12 [],
NodeN 3 [NodeN 18 [],NodeN 1 [],NodeN 40 []]]
-}

treeN2 :: TreeN Int
treeN2 = NodeN 10
[
NodeN 5
[
NodeN 4 [],
NodeN 1 []
],
NodeN 7 [],
NodeN 2 []
]


-- testy

treeNB_t1 = convNB treeN1
treeNB_t2 = convNB treeN2




-- 8. PRUCHOD KANONICKOU REPREZENTACI ------------------------------------------

{-
Naprogramujte funkci, ktera na zaklade kanonicke reprezentace obecneho stromu
pomoci binarniho stromu vyda seznam vznikly pruchodem puvodniho obecneho
stromu do sirky.
-}

-- datova struktura - shodna s predchozi ulohou
{-
data TreeN a = NodeN a [TreeN a] deriving (Eq, Show)
data TreeB a = NilB | NodeB a (TreeB a) (TreeB a) deriving (Eq, Show)
-}

-- vraci value X (hodnotu v uzlu)
getVal :: (TreeB a) -> a
getVal (NodeB a _ _) = a

-- vraci leveho syna
getLeft :: (TreeB a) -> (TreeB a)
getLeft (NodeB _ left _) = left

-- vraci praveho syna
getRight :: (TreeB a) -> (TreeB a)
getRight (NodeB _ _ right) = right

-- reseni ulohy podle schematu:
-- 1) je-li fronta prazda -> konec, jinak odeber X prvek z fronty
-- 2) jestlize X==NilB jdi na 1) jinak na 3)
-- 3) dej value X na vystup (hodnota v uzlu)
-- 4) vloz left X do fronty a pro X:=right X proved 2)
-- rekurze pro right X je trikova pomoci zarazeni right X na zacatek fronty
-- a zavolani 1) tudiz se vlastne provede 2) pro right X

tKBFSq :: (Eq a) => [TreeB a] -> [a]
tKBFSq [] = []
tKBFSq (x:xs)
| x==NilB = tKBFSq xs
| otherwise = [getVal x]++(tKBFSq ([getRight x] ++ xs ++ [getLeft x]))

-- zavola funkci s frontou o jednom prvku
tKBFS :: (Eq a) => (TreeB a) -> [a]
tKBFS tree = tKBFSq [tree]

-- testovaci data
treeBK1 :: TreeB Int
treeBK1 = NodeB 10
(
NodeB 5
(
NodeB 2
NilB
(
NodeB 7 NilB NilB
)
)
(
NodeB 7
(
NodeB 10 NilB NilB
)
(
NodeB 12
NilB
(
NodeB 3
(
NodeB 18
NilB
(
NodeB 1
NilB
(
NodeB 40 NilB NilB
)
)
)
NilB
)
)
)
) NilB

{-
take se da napsat jako

NodeB 10 (NodeB 5 (NodeB 2 NilB (NodeB 7 NilB NilB)) (NodeB 7 (NodeB 10 NilB
NilB) (NodeB 12 NilB (NodeB 3 (NodeB 18 NilB (NodeB 1 NilB (NodeB 40 NilB
NilB))) NilB)))) NilB

nebo jako vysledek predchozi ulohy

treeNB_t1
-}

-- testy

tKBFS_t1 = tKBFS treeBK1
tKBFS_t2 = tKBFS treeNB_t1
tKBFS_t3 = tKBFS treeNB_t2




-- 9. OPERACE NAD FUNKCI APL ---------------------------------------------------

{-
Definujte funkci apl se ctyrmi parametry:
S ... seznam prvku nejakeho typu
f ... unarni funkce aplikovatelna na prvky tohoto typu
g ... binarni (vlevo asociativni) funkce aplikovatelna na prvky tohoto typu
p ... pocatecni hodnota

Funkce apl "provede funkci f na vsechny prvky seznamu S, za takto vznikly
seznam pripoji prvek p a spocita vysledek, ktery vznikne tim, ze do vsech
mezer noveho seznamu vlozime funkci g". (To neni navod k programovani,
ale popis funkce.)

Na zaklade funkce apl vytvorte nasledujici funkce:
a) minimum prvku z neprazdneho seznamu
b) aritmeticky prumer z prvku neprazdneho seznamu
c) geometricky prumer z prvku neprazdneho seznamu (n-ta odmocnina ze soucinu
jeho prvku - n je delka seznamu.)
d) harmonicky prumer z prvku neprazdneho seznamu (druha odmocnina ze souctu
druhych mocnin jeho prvku)

Navod: Maji funkce b) az d) neco spolecneho?
-}

{-
zrejme tedy

apl [1,2,3] (*3) (+) 100

udela seznam

[3,6,9]

potom nasklada funkce g:

(((3 + 6) + 9) + 100)

a vysledek tedy bude

118
-}

-- funkce apl je slozeni foldl a map
apl :: [a] -> (a -> a) -> (a -> a -> a) -> a -> a
apl s f g p = foldl g p (map f s)

-- minimum prvku z neprazdneho seznamu
aplMin :: (Ord a) => [a] -> a
aplMin (x:xs) = apl xs (\ x -> x) (min) x

-- aritmeticky prumer z prvku neprazdneho seznamu
aplAvA :: (Fractional a) => [a] -> a
aplAvA (x:xs) = apl xs (\ y -> y/lxs) (+) (x/lxs)
where lxs = fromInt (length (x:xs))

-- geometricky prumer z prvku neprazdneho seznamu
aplAvG :: [Double] -> Double
aplAvG (x:xs) = apl xs (\ y -> y**(1/lxs)) (*) (x**(1/lxs))
where lxs = fromInt (length (x:xs))

-- harmonicky prumer z prvku neprazdneho seznamu
aplAvH :: [Double] -> Double
aplAvH (x:xs) = sqrt (apl xs (\ y -> y**2) (+) (x**2))
where lxs = fromInt (length (x:xs))

-- testy

apl_t1 = apl [1,2,3] (*3) (+) 100
apl_t2 = aplMin [4,1,3,6,5,-3,2,6,0]
apl_t3 = aplAvA [5,9,1,0,4,5]
apl_t4 = aplAvG [16,9,12]
apl_t5 = aplAvH [3,5,4,10] -- = 12.24




-- 10. CETNOST SLOV ------------------------------------------------------------

{-
Typ string je definovan takto: type String = [Char]. Krome zapisu
['a','n','n','a'] muzeme ekvivalentne psat i "anna". Naprogramujte funkci,
ktera dostane jako vstup string Doc (ktery pro jednoduchost muze obsahovat
jen mala pismena anglicke abecedy, znak \n a znak mezera) a cislo N a vyrobi
z nej "abecedni index vyskytu slov delky alespon N na radcich" dokumentu Doc,
tj. provede s nim nasledujici operace (budeme je demonstrovat na priklade):

Doc=="jak kul husar\nluk\nstal jak\n\nkul v plote\nuz jsem zase v tom"

N==3

a) Rozdeli vstupni string doc na posloupnost radek (stringu) Lines
(radky jsou oddeleny znakem \n)

["jak kul husar", "luk", "stal jak", [], "kul v plote",
"uz jsem zase v tom"]


b) Radky v seznamu Lines ocisluje - vystupem bude tedy seznam dvojic
(cisloradky, radka)

[(1, "jak kul husar"), (2, "luk"), (3, "stal jak"), (4, ""),
(5, "kul v plote"), (6, "uz jsem zase v tom")]


c) Rozdeli kazdou radku na slova - vyda seznam dvojic (cisloradky, slovo)

[(1, "jak"), (1, "kul"), (1, "husar"), (2, "luk"), (3, "stal"),
(3, "jak"), (5, "kul"), (5, "v"), (5, "plote"), (6, "uz"),
(6, "jsem"), (6, "zase"), (6, "v"), (6, "tom")]


d) Usprada tento seznam podle druhe slozky - slova

[(1, "husar"), (1, "jak"), (3, "jak"), (6, "jsem"), (1, "kul"),
(5, "kul"), (2, "luk"), (5, "plote"), (3, "stal"), (6, "tom")
(6, "uz"), (5, "v"), (6, "v"), (6, "zase")]


e) Prepracuje vstupni seznam na seznam dvojic
(Slovo, SeznamCiselRadkuNaKterychSeTotoSlovoVyskytuje)

[("husar", [1]), ("jak", [1,3]), ("jsem", [6]), ("kul", [1,5]),
("luk", [2]), ("plote", [5]), ("stal", [3]), ("tom", [6]),
("uz", [6]), ("v", [5,6]), ("zase", [6])]


f) Vypusti slova kratsi nez vstupni parametr N (v priklade == 3)

[("husar", [1]), ("jak", [1,3]), ("jsem", [6]), ("kul", [1,5]),
("luk", [2]), ("plote", [5]), ("stal", [3]), ("tom", [6]),
("zase", [6])]

-}

-- porovnani zacatku retezce s patternem
match :: String -> String -> Bool
match str pat = (take (length pat) str) == pat

-- ze stringu vybere string az do prvniho vyskytu patternu
upToStr :: String -> String -> String
upToStr "" _ = []
upToStr str@(x:xs) pat
| str `match` pat = []
| otherwise = x:(xs `upToStr` pat)

-- ze stringu vybere string po prvnim vyskytu patternu
fromStr :: String -> String -> String
fromStr str "" = str
fromStr "" _ = []
fromStr str@(x:xs) pat@(y:ys)
| str `match` pat = xs `fromStr` ys
| otherwise = (xs `fromStr` pat)


-- cast a)
makeLines :: String -> String -> [String]
makeLines [] _ = []
makeLines doc delim = [(doc `upToStr` delim)] ++ (makeLines (doc `fromStr` delim) delim)

-- cast b)
numberLines :: [String] -> [(Int,String)]
numberLines lines = numLines 1 lines

-- reseni b) s akumulatorem cisel
numLines :: Int -> [String] -> [(Int,String)]
numLines _ [] = []
numLines n (x:xs) = [(n,x)] ++ numLines (n+1) xs

-- cast c)
splitLines :: [(Int,String)] -> [(Int,String)]
splitLines [] = []
splitLines ((n,str):xs) = map ((,) n) (makeLines str " ") ++ splitLines xs

-- cast d)
sortPairs :: [(Int,String)] -> [(Int,String)]
sortPairs [] = []
sortPairs ((j,s):xs) = (sortPairs [(i,r) | (i,r) <- xs, r<- xs, s<=t]) -- cast e) joinPairLists :: [(String,[Int])] -> [(String,[Int])]
joinPairLists [] = []
joinPairLists ((s,i):(t,j):xs)
| s==t = joinPairLists ([(s,i ++ j)] ++ xs)
| otherwise = [(s,i)] ++ joinPairLists ((t,j):xs)
joinPairLists xs = xs

joinPairs :: [(Int,String)] -> [(String,[Int])]
joinPairs xs = joinPairLists (map (\ (i,s) -> (s,[i])) xs)

-- cast f)
cutShorts :: [(String,[Int])] -> Int -> [(String,[Int])]
cutShorts [] _ = []
cutShorts ((s,i):xs) n
| length(s) < n =" cutShorts" otherwise =" [(s,i)]"> Int -> [(String,[Int])]
wordFreq doc n = cutShorts (joinPairs (sortPairs (splitLines (numberLines (makeLines doc "\n"))))) n

-- testovaci data
doc :: String
doc = "jak kul husar\nluk\nstal jak\n\nkul v plote\nuz jsem zase v tom"

-- testy
wF_t1 = makeLines doc "\n"
wF_t2 = numberLines wF_t1
wF_t3 = splitLines wF_t2
wF_t4 = sortPairs wF_t3
wF_t5 = joinPairs wF_t4
wF_t6 = cutShorts wF_t5 3
wF_t7 = wordFreq doc 3




-- 11. VYPOUSTENI BVS UZLU -----------------------------------------------------

{-
Definujeme prirozenou reprezentaci binarniho stromu, v jehoz uzlech je
ulozena informace nejakeho typu (podtridy Ord).
Naprogramujte funkci, ktera z BVS vypusti uzel se zadanou hodnotou.
-}

-- jedna se o lehci variantu ulohy 2.


-- THE END ---------------------------------------------------------------------

7 komentářů:

Anonymní řekl(a)...

hm, nemáte ty příklady někdo v klasické textové podobě?

jak to HTML parser různě mrší a schovává < a > tak se v tom místy nevyznám :(

Anonymní řekl(a)...

Bonjorno, s0cketka.blogspot.com!
cui la partner sia acquisto cialis Io avevo precedentemente pagato un [url=http://farmamed.fora.pl/ ] Comprare cialis in Italia[/url] Acquistare Online una farmacia europea Cialis generico, tadalafil, [url=http://farmitalia.fora.pl/ ]Come Comprare cialis generico[/url] icaxwshd, comprare cialis online, teuhyaun, viagra, ypcwjypm, uanlrjnu, [url=http://milanofarma.fora.pl/ ]Dove Comprare cialis online[/url] E' possibile comprare online il Cialis, per la cura della disfunzione erettile. [url=http://farmanova.fora.pl/ ]Come Comprare cialis generico[/url] cialis 20 mg. Cialis · Effetti del Cialis · Disfunzione Erettile [url=http://farmaroma.fora.pl/ ] Compra cialis [/url]

Donarus řekl(a)...

Zdravim - k uloze jedna dodavam svoje reseni, vychazejici ze zde uvedeneho - myslim, ze je trochu jednodussi.

{-
Ridka matice je reprezentovana jako trojice (m,n,s),
m = #radek,
n = #sloupcu,
s = [(i,j,a_ij)], usporadany vzestupne podle i a uvnitr radek podle j.
i = cislo radky,
j = cislo sloupce,
a_ij = hodnota

naprogramuj:
(a) transpozici matic
(b) nasobeni matic
-}


module RidkaMatice where
type RMVal = (Int, Int, Int)
type RM = (Int, Int, [RMVal])

sort_matice :: [RMVal] -> [RMVal]
sort_matice [] = []
sort_matice (x:xs) = sort_matice [p | p<-xs, p < x] ++ [x] ++ sort_matice [p | p<-xs, p >= x]


transponuj :: RM -> RM
transponuj (a,b,s) = let zamen (x,y,z) = (y,x,z) in (b,a,map zamen s)



secti_shodne :: [RMVal]->[RMVal]
secti_shodne [] = []
secti_shodne [x] = [x]
secti_shodne ((x1,x2,xv):(y1,y2,yv):zb)
| x1 == y1 && x2 == y2 = secti_shodne((x1,x2,xv+yv):zb)
| otherwise = (x1,x2,xv):(secti_shodne((y1,y2,yv):zb))

vynasob_vals :: [RMVal]->[RMVal]->[RMVal]
vynasob_vals m1 m2 = secti_shodne(sort_matice([(x1,y2,x*y) | (x1,x2,x) <- m1, (y1,y2,y) <- m2, x2==y1]))

vynasob :: RM -> RM -> RM
vynasob (m1,m2,m) (n1,n2,n) | m1 == n2 = (m1,n2,s)
where s = vynasob_vals m n

Donarus řekl(a)...

jeste pridavam svoje poupravene reseni pro 6 - tj permutace a castecne usporadani



{-
vstup:
[(a,a)] = seznam dvojic prvku, urcujici castecne usporadani.

zadani:
vygeneruj seznam vsech permutaci puvodniho seznamu, ktere vyhovuji castecnemu zadanemu usporadani.
-}

module CUPerm where
-- linearizuje dvojice dos seznamu prvku (zachovava duplicity - nutno osetrit zvlast)
linearize :: [(a,a)]->[a]
linearize [] = []
linearize ((a,b):zb) = [a,b] ++ linearize zb

-- odstrani vsechny duplicity
rmdups :: (Eq a) => [a] -> [a]
rmdups [] = []
rmdups (x:xs) = [x] ++ rmdups [p|p<-xs, p /= x ]

-- vytvori permutace ze seznamu prvku (zachovava duplicity - nutno osetrit zvlast)
perm :: (Eq a) => [a] -> [[a]]
perm [] = [[]]
perm xs = [one:others | one <- xs, others <- perm (rm one xs) ]

-- odstrani prvni vyskyt prvku ze seznamu
rm :: (Eq a)=>a->[a]->[a]
rm _ [] = []
rm a (x:xs)
| a == x = xs
| otherwise = x:(rm a xs)

-- profiltruje vsechny permutace vuci vsem podminkam cast. usporadani
filter_perms_all :: (Eq a)=>[(a,a)]->[[a]]->[[a]]
filter_perms_all [] s = s
filter_perms_all (p:podminky) s =
let prefiltrovane = filter_perms_all podminky s
in filter_perms_single p prefiltrovane

-- profiltruje vsechy zadane permutace vuci jedne podmince cast. usporadani
filter_perms_single :: (Eq a)=>(a,a)->[[a]]->[[a]]
filter_perms_single podm perms = filter (vyhovuje podm) perms

-- kontrola, zda jedna permutace vyhovuje jedne podmince cast. usporadani
vyhovuje :: (Eq a)=>(a,a)->[a]->Bool
vyhovuje _ [] = True
vyhovuje (a,b) (x:perm)
| a == x = obsahuje b perm
| otherwise = vyhovuje (a,b) perm

-- zjisti, jestli seznam obsahuje prvek
obsahuje :: (Eq a) => a -> [a] -> Bool
obsahuje _ [] = False
obsahuje p (x:xs)
| p == x = True
| otherwise = obsahuje p xs

-- hlavni procedura (1. linearizuje, 2. odstrani duplicity, 3. vytvori permutace, 4. profiltruje)
permus :: (Eq a) => [(a,a)] -> [[a]]
permus p = filter_perms_all p l
where l = perm(rmdups(linearize p))

Donarus řekl(a)...

kdyby nekoho zajimalo, jak jsem resil 8, tak jsem resil pomoci 2 front a taky to funguje :)


{-
zadani:
funkci, ktera na zaklade kanonicke reprezentace obecneho stromu
pomoci binarniho stromu vyda seznam vznikly pruchodem puvodniho obecneho
stromu do sirky.
-}


module KanDoSirky where
data BT a = Nil | BN (BT a) a (BT a) deriving (Show)

instance Eq (BT a) where
Nil == Nil = True
_ == _ = False


seznamq :: [BT a] -> [BT a] -> [a]
seznamq [] [] = []
seznamq pq (Nil:xs) = seznamq pq xs
seznamq (Nil:xs) lq = seznamq xs lq
seznamq pq ((BN pravy val levy):xs) = [val] ++ (seznamq (pq ++ [pravy]) (xs++[levy]))
seznamq ((BN pravy val levy):xs) [] = [val] ++ (seznamq (xs++[pravy]) [levy])

seznam :: BT a -> [a]
seznam t = seznamq [t] []



test_data :: (Num a) => BT a
test_data = BN (BN (BN Nil 2 (BN Nil 7 Nil)) 5 (BN (BN Nil 10 Nil) 7 (BN Nil 12 (BN (BN Nil 18 (BN Nil 1 (BN Nil 40 Nil))) 3 Nil)))) 10 Nil

test = seznam test_data

Donarus řekl(a)...

jeste trochu zaspamuju:

reseni 10 jsem u delal sice na podobnem principu ale prece dost odlisne. Myslim, ze je zbytecne psat si funkce pro rozdeleni na seznam radek a slov, kdyz na to mame v Prelude funkce lines, words, ale pro trenink to neni spatne, nicmene pak bych namisto nejakeho akumulatoru pouzil klasicke zip a [...|...] pattern



module Cetnosti where

-- vezmu doc
-- splitnu na radky a pamatuji si cisla radku
-- radky splitnu po mezerach (a ke slovum si pridavam cisla radku)
-- sesortim podle slova
-- profiltruju na delku slova
-- vratim seznam

sortBW :: [([Int], String)] -> [([Int], String)]
sortBW [] = []
sortBW (([n],w):xs) = (sortBW male) ++ [([n],w)] ++ (sortBW velke)
where male = [([x],y) | ([x],y)<-xs, y <= w]
velke = [([x],y) | ([x],y)<-xs, y > w]

filt :: [([Int], String)] -> Int -> [([Int], String)]
filt s n = filter (\(_,w) -> length w >= n) s

splitByRows :: String->[(Int, String)]
splitByRows s = zip [1..] (lines s)

splitByCols :: [(Int, String)]->[([Int], String)]
splitByCols [] = []
splitByCols ((i,s):xs) = [([i], sw) | sw<-words s] ++ splitByCols xs

join :: [([Int], String)] -> [([Int], String)]
join [] = []
join [p] = [p]
join (w1@(i1, s1):w2@(i2, s2):xs)
| s1 == s2 = join ((i1++i2, s1):xs)
| otherwise = w1 : join (w2:xs)

sort :: [Int] -> [Int]
sort [] = []
sort (x:xs) = sort male ++ [x] ++ sort velke
where male = [p | p<-xs, p <= x]
velke = [p | p<-xs, p > x]

rmdups :: [Int] -> [Int]
rmdups [] = []
rmdups [x] = [x]
rmdups (x1:x2:xs)
| x1 == x2 = rmdups (x2:xs)
| otherwise = x1:(rmdups (x2:xs))

cetnosti :: String -> Int -> [([Int], String)]
cetnosti doc n = [ (rmdups (sort pos), w) | (pos, w) <- (join(sortBW(filt (splitByCols (splitByRows doc)) n)))]

Anonymní řekl(a)...

TAUTOLOGIE: staci jen pri ohodnoceni dane promenne p(X) vybrat true i false, a pak na vsechny vysledky dat and.
Upravil sem to podle eval checker kde byl seznam a promena se ohodnocovala ze seznamu, proto tam je ten jeden parametr navic, ktery tam byt nemusi:


:-op(200, fy, not).
:-op(210, yfx, and).
:-op(220, yfx, or).

eval(true, _, true).
eval(false, _, false).
eval(p(_), _, true).
eval(p(_), _, false).
eval(not X, S, H):- eval(X, S, H1), eval_not(H1,H).
eval(X and Y, S, H):- eval(X, S, H1), eval(Y, S, H2), eval_and(H1, H2, H).
eval(X or Y, S, H):- eval(X, S, H1), eval(Y, S, H2), eval_or(H1, H2, H).

eval_not(true, false).
eval_not(false, true).

eval_and(true, true, true):-!.
eval_and(_, _, false).


eval_or(false, false, false):-!.
eval_or(_, _, true).


tautologie(F):-bagof(H, eval(F, [], H), H),andNaSeznamu(H).
andNaSeznamu([]).
andNaSeznamu([false|_]):- fail.
andNaSeznamu([true|T]):-andNaSeznamu(T).