Compare commits
4
Commits
83408ddc5d
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f4496a8648 | ||
|
|
ceed59bf21 | ||
|
|
c54a056489 | ||
|
|
a226b35406 |
No files matched your search
+156
-5
@@ -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
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
Copyright (c) 2023 Joseph Ferano - joseph@ferano.io
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
+20
-2
@@ -1,3 +1,21 @@
|
|||||||
** 99 Problems
|
#+OPTIONS: toc:nil
|
||||||
|
|
||||||
Literate documents for OCaml and Haskell 99 problems
|
* About
|
||||||
|
|
||||||
|
This repository contains my ongoing solutions for both OCaml and Haskell coding
|
||||||
|
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
|
||||||
|
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
|
||||||
|
within Emacs by invoking the ~C-c C-c~ keybinding while the cursor is in the
|
||||||
|
source code block.
|
||||||
|
|
||||||
|
* Progress
|
||||||
|
- [16/99] OCaml
|
||||||
|
- [7/99] Haskell
|
||||||
|
- [0/99] Lisp (Soon)
|
||||||
|
|
||||||
|
* References
|
||||||
|
|
||||||
|
- OCaml Exercises: https://ocaml.org/problems
|
||||||
|
- 99 Haskell Problems: https://wiki.haskell.org/H-99:_Ninety-Nine_Haskell_Problems
|
||||||
Reference in new issue
Block a user