Inspired by The Beauty and the Strings question, I tried to implement the "Maximum Beauty of String" in a stateless fashion using ES6. Unfortunately, I ran into two places where I had to assign variables.
The questions I have:
- How can I remove the state in the reducer for
mapLettersByCount
? - How can one use generators without assigning it to a variable? (see
points
variable in themaxBeauty
function) Is this even considered state in this situation?
Code:
const EMPTY_STRING = '';
const LETTERS_ONLY = /[a-z]/i;
function mapLettersByCount(sentence) {
return sentence.split(EMPTY_STRING)
.filter(letter => LETTERS_ONLY.test(letter))
.map(letter => [letter.toUpperCase(), 1])
.reduce((letterCount, [key, count]) => {
letterCount[key] = (letterCount[key] || 0) + count;
return letterCount;
}, {});
}
function * downCounter(maxValue) {
yield maxValue;
yield * downCounter(maxValue > 0 ? maxValue - 1 : 0);
}
export function maxBeauty(sentence = "") {
const points = downCounter(26);
return Object.values(mapLettersByCount(sentence))
.sort().reverse()
.reduce((score, count) => score + count * points.next().value, 0);
}
Test Cases:
import {maxBeauty} from './beauty';
describe('The maximum beauty', () => {
it('should calculate for a word', () => {
expect(maxBeauty('AbBCcC')).toBe(152);
});
it('should calculate ignoring spaces', () => {
expect(maxBeauty('This is from Facebook Hacker Cup 2013.'))
.toBe(551);
});
it('should calculate ignoring punctuation', () => {
expect(maxBeauty('Ignore punctuation, please :)'))
.toBe(491);
});
});