Showing posts with label haskell. Show all posts
Showing posts with label haskell. Show all posts

Saturday, April 10, 2010

Merge and Sort

So, as an exercise in Haskell and recursive algorithms I implemented an exhaustive search called `search`, a faster and correct binary search called `bSearch` which requires a sorted list to start with to work correctly.


module Main where
import Data.List

search t [] = False --t is an item we want to check is an a list. if the list is empty, then obviously it can't contain t
search t (x:xs) | t == x = True -- if the first item in the list is the same as t, then the search returns the result of True
| otherwise = search t xs --if t is not the head of the list, search the rest of the list

bSearch t xs = bSearch' t (mergeSort xs) -- Binary search requires a sorted list, so we search through the sorted list, using t as the item we want to find
bSearch' t [] = False -- same as before
bSearch' t (x:xs) | t == x = True -- same as before
| t < x = pt fst -- since the list is ordered, we can check the first half of the list if t is less than x
| t > x = pt snd --otherwise we can check the second half of the list
where
pt f = bSearch' t $ f $ splitAt ((length xs)`div`2) (x:xs) -- to save time, here is another function that will perform a binary search on the half of the list you want (f)



On the sorting side I implemented the merge sort algorithm; wherein you keep break the list in half until you have pairs or a single and then sort the pairs and then rejoin everything together in the correct order (`merge`) after they've been sorted. This is implemented as `mergeSort`:


mergeSort :: (Ord a) => [a] -> [a] -- this says the sort function takes a list and returns a list. Each element in the list must be an ordered type, like numbers or letters which come in order
mergeSort [] = [] --obviously an empty list is already sorted
mergeSort [a] = [a] -- as well as list with one element
mergeSort [a,b] = order a b -- for a list with 2 elements, order them according to the definition below
mergeSort xs = merge (pt fst) (pt snd) --merge the 2 halves of the sorted lists, this will continue until the original list has been broken up into smaller lists of 1 or 2 elements
where
pt f = mergeSort $ f $ splitAt ((length xs)`div`2) xs

order :: (Ord a) => a -> a -> [a]
order a b | a < b = [a,b] --order a pair of things
| a > b = [b,a] --and return a list in the correct order, that is biggest at the right, and smallest at the left
| a == b = [a,b] --if the 2 items are the same, leave them that way

merge ::(Ord a) => [a] -> [a] -> [a]
merge [] ys = ys --merging the broken up lists back together, an empty list merging with a non-empty list, you just get the nonempty list
merge xs [] = xs -- they need to be in the correct order; same as above
merge xX@(x:xs) yY@(y:ys) | x <= y = x:(merge xs yY) --if x is less than or equal to y,(x and y being the first element in each list) the merged list will have the head of x merged with the rest of the first list and all of the second list
| otherwise = y:(merge xX ys) --same as above but reversed

Thursday, January 21, 2010

And then I was all

NYAAUUUUUUU
And made this for project euler number 17 in a magical 15 lines. Screw you if you want numbers more than 1000 in word form.

module Main where
nones = ["","one","two","three","four","five","six","seven","eight","nine","ten","eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen","nineteen"]
tens = ["","","twenty","thirty","forty","fifty","sixty","seventy","eighty","ninety"]
num2word :: Int -> String
num2word n | x <= 2 && n < 20 = nones !! x
| x == 2 && n >= 20 = tens !! fst y ++ nones !! snd y
| x == 3 = nones !! fst z++"hundred" ++ a
| n == 1000 = "onethousand"
where
x = length $ show n
y = divMod n 10
z = divMod n 100
a | snd z == 0 = ""
| otherwise = "and"++num2word (snd z)
main = print $ length $ concatMap num2word [1..1000]

Wednesday, October 14, 2009

Yet another post

In current news, according to the Myers-Briggs Type Indicator, I am an INTJ. Apparently they are the mastermind and comprise 1% of the population. What about you?.

Anyway, in the interest of always learning new things, I have begun learning Haskell (upon suggestion from a friend), and to learn that, I started doing the questions over at http://projecteuler.net. I have answered 33 so far, using Haskell for all but 1 of them, when it seemed my trusty TI-83 Plus would suffice. In doing these questions I have learned a lot more number theory.

Also, I recently found that many text editting things like word or even firefox allow you to navigate around the text by going CTRL+ left or right to skip through words!

Also Jazz is pretty good and I would suggest you listen to the "Times" series by Dave Brubeck. Either that or Herbie Hancock.

Also here's a giant ascii fractal made with haskell, extract and view, zoomed out in firefox for best effect, then zoom in and see that it is actually text.

I final note, I rarely watch TV these days, it's usually crap. That and Nong Shim noodles are way better than Mi Goreng.



*brace for shitstorm*