# Advent Of Code 2017 Day 4 (part 2) in Functional Programming (FP)

I wanted to practice functional programming (FP) without using any library but using vanilla JavaScript only. So I took a problem from Advent of Code (the 2nd part of Day 4)

You can only access the 2nd part if you type in the solution for the 1st part: 466 or look at my solution for part 1

--- Part Two --- For added security, yet another system policy has been put in place. Now, a valid passphrase must contain no two words that are anagrams of each other - that is, a passphrase is invalid if any word's letters can be rearranged to form any other word in the passphrase.

For example:

• abcde fghij is a valid passphrase.
• abcde xyz ecdab is not valid - the letters from the third word can be rearranged to form the first word.
• a ab abc abd abf abj is a valid passphrase, because all letters need to be used when forming another word.
• iiii oiii ooii oooi oooo is valid.
• oiii ioii iioi iiio is not valid - any of these words can be rearranged to form any other word. Under this new system policy, how many passphrases are valid?

My solution in FP:

const INPUT =
pphsv ojtou brvhsj cer ntfhlra udeh ccgtyzc zoyzmh jum lugbnk
spjb xkkak anuvk ejoklh nyerw bsjp zxuq vcwitnd xxtjmjg zfgq xkpf
...
juo pmiyoh xxk myphio ogfyf dovlmwm moevao qqxidn;

const get = input => input.split('\n');
const countDuplicate = words => words.reduce((acc, word) => {
return Object.assign(acc, {[word]: (acc[word] || 0) + 1});
}, {});
const onlyUniqueWords = phrases => {
const words = phrases.split(' ');
const duplicateWords = countDuplicate(words);
return !Object.values(duplicateWords).some(w => w > 1);
};
const sortWords = words => words.map(word =>  word.split('').sort().join(''));
const noAnagrams = phrases => {
const words = phrases.split(' ');
const sortedWords = sortWords(words).sort().join(' ');
return onlyUniqueWords(sortedWords);
};
const phrasesWithNoAnagrams = get(INPUT)
.filter(noAnagrams);
console.log("solution ", phrasesWithNoAnagrams.length);


Is there a better way to write it in FP with pure JavaScript, i.e. no additional FP library? Any other improvement suggestions are welcomed.

• Just curious, is there a reason for using Object.assign when you're only adding a single property to it? Please tell me you're not doing that just because it's "functional?" Jan 11, 2018 at 21:13
• There's no purpose to a lot of the things you're doing here. This reminds me of some sarcastic code I wrote recently. No offense but you're trying way too hard. There's no reason this task requires 6 functions. The spirit of functions is about making code reusable - you're completely missing that point. You functions are only used once each. This is a one-liner, even in "functional" js. const hasAnagram = input=>input.split(' ').map(i=>i.split('').sort().join('')).sort().reduce((ac,cv,id,ar)=>ac || (id && ar[id-1] === cv), false); Jan 11, 2018 at 21:34
• techfindings.one/archives/2652 Jan 11, 2018 at 22:19
• Thanks for sharing your links. I really appreciate and will read them through and hopefully won't repeat my mistakes. Thanks for sharing. Jan 12, 2018 at 7:34
• @Iwrestledabearonce. your code is technically a one liner but not really declarative and easy to understand. I think it is better to break them down into smaller functions. Also, like I said in a previous question of mine, I don't agree on all the points. What I agree on in the article is that FP should be easy to read and understand. Jan 12, 2018 at 16:32

I don't see much that I would change about this code. I recently discovered that the spread syntax can be used to split a string into an array so that could be used to eliminate calling the split() function.

const sortWords = words => words.map(word =>  word.split('').sort().join(''));


const sortWords = words => words.map(word =>  [...word].sort().join(''));


In this reduction:

const countDuplicate = words => words.reduce((acc, word) => {
return Object.assign(acc, {[word]: (acc[word] || 0) + 1});
}, {});


I presume that the only reason you used brackets with a return statement is because it would be too long for a single line. You could avoid those by pulling out the arrow function to a separate line:

const countWord = (acc, word) => Object.assign(acc, {[word]: (acc[word] || 0) + 1});
const countDuplicate = words => words.reduce(countWord, {});


I know that is only one line shorter but at least there is no need for the brackets and return statement.