Skip to content

Commit

Permalink
Upload permutations
Browse files Browse the repository at this point in the history
  • Loading branch information
IvoTod committed Nov 29, 2016
2 parents da63f1d + c48c6b3 commit d7707ad
Show file tree
Hide file tree
Showing 26 changed files with 1,770 additions and 511 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ cabal.sandbox.config
*.eventlog
.stack-work/
cabal.project.local
staging/
25 changes: 24 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,24 @@
# fp-haskell
- **Седмица 1 (19.10.2016)**
[Относно курса](lectures/00-setup/setup.md)
[Що е то функционално програмиране? История на Haskell](lectures/01-intro/intro.md)
[Въведение в Haskell. Основени типове и синтаксис.](lectures/02-syntax-and-types/syntax-and-types.md)

- **Седмица 2 (26.10.2016)**
[Въведение част 2 Lists, Guards and Pattern matching](lectures/03-lists-guards-patterns/lists-guards-patterns.md)
Домашно: [Езика на разбойниците](exercises/secret-lang/Secret-lang.md) ([secret-lang](exercises/secret-lang))

- **Седмица 3 (02.11.2016)**
[Работа със списъци](exercises/lists/Lists.md)
Задачи от часа: [Lists.hs](exercises/lists/Lists.hs), [Colorize](exercises/colorize/Colorize.md) ([colorize](exercises/colorize))
Домашно: [Домашно Lists](exercises/lists/ListsHW.md) ([lists](exercises/lists))

- **Седмица 4 (09.11.2016)**
[List comprehension ](lectures/04-list-comprehension/lcomprehension.md)
Задачи от часа: [listcomp.md](exercises/list-comp/listcomp.md) ([list-comp](exercises/list-comp))
Домашно: [Пермутации](exercises/permutations/perm.md) ([permutations](exercises/permutations))

---

**Допълнителни материали**
[Литература, среда и др.](lectures/00-setup/extra.md)

23 changes: 0 additions & 23 deletions check_lecture.sh

This file was deleted.

41 changes: 31 additions & 10 deletions exercises/colorize/Colorize.hs
Original file line number Diff line number Diff line change
Expand Up @@ -26,33 +26,44 @@ clear = 0
-- Exercise 1

getLastDigit :: Int -> Int
getLastDigit = undefined
getLastDigit x = mod x 10


dropLastDigit :: Int -> Int
dropLastDigit = undefined
dropLastDigit x = quot x 10


-- Exercise 2

getReverseDigits :: Int -> [Int]
getReverseDigits = undefined
getReverseDigits x | x < 10 = [x]
| otherwise = getLastDigit x : getReverseDigits (dropLastDigit x)


-- Exercise 3

toChar :: Int -> Char
toChar = undefined
toChar 0 = '0'
toChar 1 = '1'
toChar 2 = '2'
toChar 3 = '3'
toChar 4 = '4'
toChar 5 = '5'
toChar 6 = '6'
toChar 7 = '7'
toChar 8 = '8'
toChar 9 = '9'
toChar _ = error "Not a digit"


-- Exercise 4

itoaLoop :: String -> [Int] -> String
itoaLoop = undefined

itoaLoop acc [] = acc
itoaLoop acc (x:xs) = itoaLoop (toChar x : acc) xs

itoa :: Int -> String
itoa = undefined
itoa num = itoaLoop [] (getReverseDigits num)


-- Exercise 5
Expand All @@ -66,8 +77,16 @@ mkTextStyle color = mkStyle (color + textStyle)


getStyle :: String -> String
getStyle = undefined

getStyle "blk" = mkTextStyle black
getStyle "red" = mkTextStyle red
getStyle "grn" = mkTextStyle green
getStyle "ylw" = mkTextStyle yellow
getStyle "blu" = mkTextStyle blue
getStyle "mgt" = mkTextStyle magenta
getStyle "cyn" = mkTextStyle cyan
getStyle "wht" = mkTextStyle white
getStyle "clr" = mkStyle clear
getStyle xs = "<" ++ xs ++ ">"

-- Exercise 6

Expand All @@ -82,7 +101,9 @@ bleach [] = []


colorize :: String -> String
colorize = undefined
colorize ('<':x:y:z:'>':rest) = getStyle [x, y, z] ++ colorize rest
colorize (x:xs) = x : colorize xs
colorize [] = []


-- Extra
Expand Down
129 changes: 71 additions & 58 deletions exercises/colorize/Colorize.md
Original file line number Diff line number Diff line change
@@ -1,41 +1,52 @@
<!--
```hs
import Colorize hiding (mkStyle, mkTextStyle)
```
-->

Colorize
====

Хаки МакХакер, син на най-уважаваните програмисти в Ламбда Ленд, тамън започва да се учи да програмира. Амбициозните му родители са му дали за задача да принтира цветен текст по терминала на Линукската му машина. Хаки, незнаейки как да се справи, е решил да потърси решение в интернет форумите. След любезно запитаване в БезкрайнаРекурсия, Ти си видял въпроса му. Вече преминал обичайните чудения дали да го downvote-неш, че пита нещо очевидно, или че е поредният ученик търсещ бързо решение на домашното си, виждаш че той е положил усиля, като е прочел в WikiLambdia и се е опитал да достигне до решение, но без успех. От прочита на WikiLambdia, Хаки е дефинирал няколко цветови константи и е написал заготовки ([stubs](https://en.wikipedia.org/wiki/Stub)) на функциите `colorize` и `bleach`.


### Упражнение #1

От описанието на Хаки и приложения [линк към статията](https://en.wikipedia.org/wiki/ANSI_escape_code), ставя ясно, че оформянето на текст работи по прост начин, с инструктиране на терминала посредством запазен символ (`Escape`) и последваща кодова комбинация (число). Още начинаещ в Haskell, нашият младеж не знае функцията за обърщане на число към `String` (низ от символи), затова е дефинирал следните две функции:

```hs
```hs
getLastDigit :: Int -> Int
dropLastDigit :: Int -> Int
```

`getLastDigit` връща последната цифра на подадено дадено число. Или погледнато математически, остатъкът след деление на 10. Пр:

```hs
getLastDigit 12345
> 5
> getLastDigit 12345
5

getLastDigit 7
> 7
> getLastDigit 7
7

getLastDigit 0
> 0
> getLastDigit 0
0
```

Hint: В Haskell няма оператор, както в C-образните езици, за операцията `modulo`. За целта се ползва функцията `mod`.

`dropLastDigit` има точно противоположна функция на `getLastDigit` - тя връща число с премахната последна цифра. Т.е. цялата част при деление на 10. Обичайният оператор за деление `\` няма да свърши работа, понеже за разлика от в C, в Haskell той работи само върху рационални числа.

```hs
dropLastDigit 12345
> 1234
> dropLastDigit 12345
1234

dropLastDigit 7
> 0
> dropLastDigit 7
0

dropLastDigit 0
> 0
> dropLastDigit 0
0
```


Expand All @@ -48,17 +59,17 @@ dropLastDigit 0

Очакваното поведение е:
```hs
getReverseDigits 12345
> [5, 4, 3, 2, 1]
> getReverseDigits 12345
[5, 4, 3, 2, 1]

getReverseDigits (-12345)
> [5, 4, 3, 2, 1]
> getReverseDigits (-12345)
[5, 4, 3, 2, 1]

getReverseDigits 7
> [7]
> getReverseDigits 7
[7]

getReverseDigits 0
> [0]
> getReverseDigits 0
[0]
```


Expand All @@ -67,34 +78,34 @@ getReverseDigits 0
Трябва ни функция, която от обръща дадена цифра към символа й. Решението не е много елегантно, но Haskell не позволява събирането на число и буква. Затова се спираме на по-простия вариант с pattern-matching по цифрите и връщане на съответния символ. Така дефинирана функцията няма да е валидана за всеки произволен вход, което не е хубаво свойство. В литературата такива функции се наричат _"непълни"_ (_partial_) и Haskell ни предупреждава с warning. Решението е да наравим функцията _"пълна"_ (_total_), като добавим pattern, който приема всички останали стойности и хвърля грешка. Струва си да отбележим, че функцията продължава да не е добре дефинирана за произволен вход (т.е. нецифри), но от гледна точка на компилатора всички възможности са обработени.

Използвайте следния pattern, като крайно условие:
```hs
```hs
toChar _ = error "Not a digit"
```

Резултат от изпълнението:
```hs
toChar 1
> '1'
> toChar 1
'1'

toChar 9
> '9'
> toChar 9
'9'

toChar 10
> *** Exception: Not a digit
> toChar 10
*** Exception: Not a digit
```


### Упражнение #4

Вече имаме всички нужни подфункции, за да напишем

```hs
```hs
itoa :: Int -> String
```

Тук е времето и мястото да се справим с обратния ред на цифрите. За целта ще ползваме спомагателна функция:

```hs
```hs
itoaLoop :: String -> [Int] -> String
```

Expand All @@ -104,23 +115,23 @@ itoaLoop :: String -> [Int] -> String

Функцията `itoa` се дефинира тривиално посредством `itoaLoop`. Този прийом е много често използван във функционалното програмиране. Не е задължително спомагателната функция да използва акумулатор - понякога целта и е само емулиране на цикъл, а понякога акумулатори се ползват и извън рекурсивни функции :).

```hs
itoaLoop "" [3, 2, 1]
```hs
> itoaLoop "" [3, 2, 1]
-> itoaLoop "3" [2, 1]
-> itoaLoop "23" [1]
-> itoaLoop "123" []
> "123"
"123"
```

```hs
itoa 12345
> "12345"
> itoa 12345
"12345"

itoa 7
> "7"
> itoa 7
"7"

itoa 0
> "0"
> itoa 0
"0"
```


Expand All @@ -140,7 +151,7 @@ mkTextStyle color = mkStyle (color + textStyle)
```

Вашата задача е да дефинирате функцията
```hs
```hs
getStyle :: String -> String
```

Expand All @@ -164,17 +175,17 @@ getStyle :: String -> String

Пример:
```hs
getStyle "bkl"
> "\x1B[30m"
> getStyle "blk"
"\x1B[30m"

getStyle "blu"
> "\x1B[34m"
> getStyle "blu"
"\x1B[34m"

getStyle "clr"
> "\x1B[0m"
> getStyle "clr"
"\x1B[0m"

getStyle "other"
> "<other>"
> getStyle "other"
"<other>"
```


Expand All @@ -183,19 +194,19 @@ getStyle "other"
Всички нужни части от пъзела са вече налице. Един от ветераните съфорумец е написал функцията за премахване на стиловете - `bleach`, но не и на `colorize`. Всички са на мнение, че Хаки трябва да извърви последната миля сам. Дадена е подсказка, че `colorize` прилича много на `bleach`, но има някои съществени разлики. `colorize` приема `String` като входен аргумент и заменя всички обръщения към кодови думи с тяхната стойност. Кодовите думи са обградени с `<>`. Така например, ако входът е `"<red>hello"`, то изходът трябва да бъде `"\x1B[30mhello"`. Ако ли пък е непозната комбинация, то тя трябва да остане непроменена. Обърнете внимание, че всички ключови думи са с точно три букви и са обградени със знаци. `colorize` не се нуждае от спомагателни функции, всичко нужно е вече налично.

```hs
colorize "<red>hello<clr>"
> "\x1B[30mhello"
> colorize "<red>hello<clr>"
"\x1B[31mhello\x1B[0m"


colorize "<red>hello <blue>world<clr>"
> "\x1B[30mhello \x1B[34mworld\x1B[0m"
> colorize "<red>hello <blu>world<clr>"
"\x1B[31mhello \x1B[34mworld\x1B[0m"

colorize "<haskell><hsk>"
> "<haskell><hsk>"
> colorize "<haskell><hsk>"
"<haskell><hsk>"
```

Принтирането на escape комбинациите не е много забавно. За да видите цветовете иползвайте функцията `putStrLn`, например:
```hs
```hs
putStrLn (colorize "<red>hello<clr>")
```

Expand All @@ -207,7 +218,7 @@ putStrLn (colorize "<red>hello<clr>")

Дадени са заготовки на функциите:

```hs
```hs
mkBackgroundStyle :: Int -> String
dropMarkup :: String -> String
getMarkup :: String -> String
Expand All @@ -224,9 +235,11 @@ colorize2 :: String -> String

Пр:
```hs
getStyle "bgr-red"
> "\x1B[41m"
> getStyle "bgr-red"
"\x1B[41m"
```

```hs
putStrLn (colorize2 "<bgr-wht><blk>black <bgr-blk><wht> white<clr>")
```

Expand Down
Loading

0 comments on commit d7707ad

Please sign in to comment.