Compare commits

..
4 Commits
Author SHA1 Message Date
JosephFerano f4496a8648 Haskell: Exercise #9 2023-11-21 15:21:21 +07:00
JosephFerano ceed59bf21 Haskell n.8 2023-11-17 15:21:13 +07:00
JosephFerano c54a056489 Adding more info to the README 2023-11-16 14:13:16 +07:00
JosephFerano a226b35406 Some more Haskell exercises. Adding LICENSE 2023-11-16 14:10:26 +07:00
2 changed files with 159 additions and 8 deletions

No files matched your search

+156 -5
View File
@@ -80,11 +80,162 @@ myLength xs = foldl (\acc _ -> acc + 1) 0 xs
myLength' [] = 0 myLength' [] = 0
myLength' [x] = 1 myLength' [x] = 1
myLength' (_:xs) = 1 + myLength xs myLength' (_:xs) = 1 + myLength xs
myLength [1..5]
myLength' [1..5]
#+end_src #+end_src
#+RESULTS: *** #5 Reverse a list.
: 5
#+begin_src haskell
λ> myReverse "A man, a plan, a canal, panama!"
"!amanap ,lanac a ,nalp a ,nam A"
λ> myReverse [1,2,3,4]
[4,3,2,1]
#+end_src
**** Solution
#+begin_src haskell
myReverse = go []
where go acc [] = acc
go acc (x:xs) = go (x:acc) xs
#+end_src
*** #6 Find out whether a list is a palindrome
#+begin_src haskell
λ> isPalindrome [1,2,3]
False
λ> isPalindrome "madamimadam"
True
λ> isPalindrome [1,2,4,8,16,8,4,2,1]
True
#+end_src
**** Solution
#+begin_src haskell
isPalindrome xs = xs == reverse xs
#+end_src
*** #7 Flatten a nested list structure.
Transform a list, possibly holding lists as elements into a `flat' list by replacing each list with its elements (recursively).
Example:
#+begin_src haskell
,* (my-flatten '(a (b (c d) e)))
(A B C D E)
#+end_src
Example in Haskell:
We have to define a new data type, because lists in Haskell are homogeneous.
#+begin_src haskell
data NestedList a = Elem a | List [NestedList a]
#+end_src
#+begin_src haskell
λ> flatten (Elem 5)
[5]
λ> flatten (List [Elem 1, List [Elem 2, List [Elem 3, Elem 4], Elem 5]])
[1,2,3,4,5]
λ> flatten (List [])
[]
#+end_src
**** Solution
#+begin_src haskell
flatten = reverse . go []
where go acc (List []) = acc
go acc (Elem x) = x:acc
go acc (List (x:xs)) = go (go acc x) (List xs)
#+end_src
*** #8 Eliminate consecutive duplicates of list elements
If a list contains repeated elements they should be replaced with a single copy of the element. The order of the elements should not be changed.
Example:
#+begin_src haskell
,* (compress '(a a a a b c c a a d e e e e))
(A B C A D E)
#+end_src
Example in Haskell:
#+begin_src haskell
λ> compress "aaaabccaadeeee"
"abcade"
#+end_src
**** Solution
This is not great...
#+begin_src haskell
compress xs = reverse $ go [] xs
where go acc [] = acc
go [] (x:xs) = go [x] xs
go [a] [x]
| a == x = [a]
| otherwise = [x,a]
go (a:as) [x]
| a == x = a:as
| otherwise = x:a:as
go [a] (x:xs)
| a == x = go [a] xs
| otherwise = go [x,a] xs
go (a:as) (x:xs)
| a == x = go (a:as) xs
| otherwise = go (x:a:as) xs
#+end_src
Especially when one of the solutions is the following;
#+begin_src haskell
import Data.List
compress :: Eq a => [a] -> [a]
compress = map head . group
#+end_src
*** #9 Pack consecutive duplicates of list elements into sublists
If a list contains repeated elements they should be placed in separate sublists.
Example:
#+begin_src haskell
,* (pack '(a a a a b c c a a d e e e e))
((A A A A) (B) (C C) (A A) (D) (E E E E))
#+end_src
Example in Haskell:
#+begin_src haskell
λ> pack ['a', 'a', 'a', 'a', 'b', 'c', 'c', 'a', 'a', 'd', 'e', 'e', 'e', 'e']
["aaaa","b","cc","aa","d","eeee"]
#+end_src
**** Solution
In python you can use ~Counter~
#+begin_src python
from collections import Counter
def pack(arr):
return [[key] * val for key,val in Counter(arr).items()]
#+end_src
In Haskell, this is just ~group~
#+begin_src haskell
pack :: [a] -> [[a]]
pack = group
#+end_src
Here's my naive implementation
#+begin_src haskell
pack :: Eq a => [a] -> [[a]]
pack xs = reverse $ go [[]] xs
where
go acc [] = acc
go ([]:acc) (x:xs) = go ([x]:acc) xs
go ((a:as):acc) (x:xs)
| a == x = go ((x:a:as):acc) xs
| otherwise = go ([x]:(a:as):acc) xs
#+end_src
+3 -3
View File
@@ -7,12 +7,12 @@ challenge problems in the style of "99 Problems". See below for references. The
intention is to practice these languages in the hopes of someday using them in intention is to practice these languages in the hopes of someday using them in
anger. The solutions use a style of programming known as [[https://en.wikipedia.org/wiki/Literate_programming][Literate Programming]] anger. The solutions use a style of programming known as [[https://en.wikipedia.org/wiki/Literate_programming][Literate Programming]]
with the help of Emacs, org-mode, and [[https://orgmode.org/worg/org-contrib/babel/intro.html][org-babel]]. All code is executable from with the help of Emacs, org-mode, and [[https://orgmode.org/worg/org-contrib/babel/intro.html][org-babel]]. All code is executable from
within Emacs by just running ~C-c C-c~ while the cursor is in the source code within Emacs by invoking the ~C-c C-c~ keybinding while the cursor is in the
block. source code block.
* Progress * Progress
- [16/99] OCaml - [16/99] OCaml
- [4/99] Haskell - [7/99] Haskell
- [0/99] Lisp (Soon) - [0/99] Lisp (Soon)
* References * References