Skip to content

Instantly share code, notes, and snippets.

@spasiu
Created May 29, 2015 15:10
Show Gist options
  • Save spasiu/9e51785bcfc4999785bf to your computer and use it in GitHub Desktop.
Save spasiu/9e51785bcfc4999785bf to your computer and use it in GitHub Desktop.

Four chapters into Learn you a Haskell for Great Good I decided to tackle a codewars problem in Haskell

The problem was to take an array and a number, and return the array ommitting occurences of any integer in excess of the given number. So like func ([1, 1, 2, 3], 1) -> [1, 2, 3]. Great, so at first I was like, let's do this!

...

... and drew a complete blank. So I did it in JavaScript.

function deleteNth(arr,x){
  return arr.reduce(function(p, c) {
    if (!p.occur[c] || p.occur[c] < x) {
      p.arr.push(c);
      p.occur[c] = p.occur[c] + 1 || 1;
    }
    return p;
  }, {
    occur: {},
    arr: []
  }).arr;
}

Then, I went to implement it in Haskell.

...

So I rewrote it in JS in a way where I wouldn't have to store any state. It ended up as a filter with a nested reduce for big n.

function deleteNth(arr,x) {
  return arr.filter(function(e, i, a) {
     if (a.slice(0, i).reduce(function(p, c) {
       return c === e ? p + 1 : p; 
     }, 0) < x) {
       return true;
     } else {
       return false;
     }
  });
}

And then implemented it in Hasekll as a reduce with a nested list comp that acts like a filter. My hope is that Haskell somehow magically optimizes away that big n, but I don't think so in this case...

deleteNth :: [Int] -> Int -> [Int]
deleteNth lst n = foldl (\acc element -> if n > length [x | x <- acc, x == element] then acc ++[element] else acc) [] lst

I guess it could be formatted like this... I'm not sure about the standards.

deleteNth :: [Int] -> Int -> [Int]
deleteNth lst n = foldl 
    (\acc element -> 
    if n > length [x | x <- acc, x == element] 
    then acc ++[element] 
    else acc) 
    [] lst
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment