DEV Community

Discussion on: Javascript Sock Merchant Challenge - Solution 2

Collapse
 
johnboy5358 profile image
John • Edited

Hello Ady, thanks for the reply.

I recognize that my solution must look a bit strange on first sight. I was reading on MDN recently about the draft proposal for the pipeline operator aka |> to be added to JavaScript(as yet unsupported).

I also had passed sometime on the egghead.io site
re: egghead.io/courses/professor-frisb... and was intrigued how .map is used here to produce a topdown workflow composing(or piping) one function's result to the next function. What a shame that, as you have discovered, JS is not performant in this way, because, I for one, think this is an elegant and clean workflow that I hope, one day, will be worth using.

Of course speed of execution is always an important issue and so for the moment, atleast, we fall back to the roots of JavaScript and use it's for, for of, while, etc loops. Shame, because I really do like a more declarative style of coding and here I was merely experimenting.

Perhaps you will forgive a quick hack to make my solution a tad more readable(see code below) by placing a pipe method on the Array prototype. Sorry, I can't do anything about JS performance, but I think somewhat less than 10,000 socks to sort would be favourable; that sock merchant needs to keep his house in closer order I think!

Incidentally, please excuse me if I decline the webinar participation; it really is not my thing and you may take this reply as my input to that.

Have a great day.


if(!Array.prototype.pipe) Array.prototype.pipe = Array.prototype.map
const reduce = (fn, init) => xs => Array.prototype.reduce.call(xs, fn, init)

const a = [10, 20, 20, 10, 10, 30, 50, 10, 20]
// [[10, 10, 10, 10], [20, 20, 20], [30], [50]]
// => 3 complete pairs (& 3 odd socks)

const group = (p,c) =>
  (c in p)
    ? {...p, [c]: p[c] + 1}
    : {...p, [c]: 1}

// Note: ~~ is Math.floor in js.
const sumPairs = (acc, x) => acc + ~~(x/2)

// Note: .pipe is function composition. Pipes the result of a function to the next.
// Visit https://egghead.io/lessons/javascript-linear-data-flow-with-container-style-types-box
const completePairs = (n, ary) =>
  [ary]
    .pipe(reduce(group, {}))
    .pipe(Object.values)
    .pipe(reduce(sumPairs,0))
    .pop()

console.log(completePairs(9, a))
// => 3

As a final request, I would be interested in what benchmark timings (in milliseconds) you achieved for my soloution vs your solution for a test array of 10,000 integers.