Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow synchronous and concurrent and parallel solutions to Parallel Letter Frequency #2418

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion .prettierignore
@@ -1,5 +1,6 @@
/.github/labels.yml
/.github/workflows/sync-labels.yml
/.github/workflows/no-important-files-changed.yml
exercises/**/README.md
!/README.md

Expand All @@ -14,4 +15,4 @@ config.json

# Originates from https://github.com/exercism/problem-specifications
exercises/practice/**/.docs/instructions.md
exercises/practice/**/.docs/introduction.md
exercises/practice/**/.docs/introduction.md
@@ -1,8 +1,23 @@
# Instructions append

Due to the single-threaded nature of Javascript, code that appears to execute in parallel,
such as `async functions` or `Promises`, actually execute concurrently.
Such solutions will pass all the tests, even though they do not meet the requrement for parallel execution.
such as `async functions` or `Promise`, actually execute concurrently at most.
In fact, all code is executed synchronously even in `Promise` constructors, until control is passed back to the Event-Loop (the outermost function call ends).
Such solutions will pass all the tests, even though they do not meet the requirement for parallel or concurrent execution.

## Achieving concurrent execution for the exercise

To use concurrent execution to solve the exercise, you need to return from the function before executing the algorithm to solve the problem.
This can be acheived by using `setTimeout()` to "delay" execution of a `Promise` constructor:

```javascript
return new Promise((resolve) => {
setTimeout(() => {
// The code to run concurrently
// Use `resolve()` to report the result
}, 1);
});
```

## Concurency vs. Parallelism

Expand Down Expand Up @@ -47,6 +62,8 @@ onmessage = function (event) {
```

As a stretch goal, consider if your implementation can be adapted to make use of `Web workers`.
But beware, the Web worker API differs largely between browsers and other JavaScript environments.
Make sure you use the target environments documentation, which is Node.js LTS for this exercise.

---

Expand Down
Expand Up @@ -2,6 +2,9 @@
"authors": [
"Cool-Katt"
],
"contributors": [
"mk-mxp"
],
"files": {
"solution": [
"parallel-letter-frequency.js"
Expand Down
Expand Up @@ -3,6 +3,6 @@
// convenience to get you started writing code faster.
//

export const parallelLetterFrequency = (texts) => {
export const parallelLetterFrequency = async (texts) => {
throw new Error('Remove this statement and implement this function');
};
@@ -1,96 +1,96 @@
import { parallelLetterFrequency } from './parallel-letter-frequency';

describe('ParallelLetterFrequency', () => {
test('no texts', () => {
test('no texts', async () => {
const expected = {};
const actual = parallelLetterFrequency([]);
const actual = await parallelLetterFrequency([]);
expect(actual).toEqual(expected);
});

xtest('one text with one letter', () => {
xtest('one text with one letter', async () => {
const texts = ['a'];
const expected = {
a: 1,
};
const actual = parallelLetterFrequency(texts);
const actual = await parallelLetterFrequency(texts);
expect(actual).toEqual(expected);
});

xtest('one text with multiple letters', () => {
xtest('one text with multiple letters', async () => {
const texts = ['bbcccd'];
const expected = {
b: 2,
c: 3,
d: 1,
};
const actual = parallelLetterFrequency(texts);
const actual = await parallelLetterFrequency(texts);
expect(actual).toEqual(expected);
});

xtest('two texts with one letter', () => {
xtest('two texts with one letter', async () => {
const texts = ['e', 'f'];
const expected = {
e: 1,
f: 1,
};
const actual = parallelLetterFrequency(texts);
const actual = await parallelLetterFrequency(texts);
expect(actual).toEqual(expected);
});

xtest('two texts with multiple letters', () => {
xtest('two texts with multiple letters', async () => {
const texts = ['ggh', 'hhi'];
const expected = {
g: 2,
h: 3,
i: 1,
};
const actual = parallelLetterFrequency(texts);
const actual = await parallelLetterFrequency(texts);
expect(actual).toEqual(expected);
});

xtest('ignore letter casing', () => {
xtest('ignore letter casing', async () => {
const texts = ['m', 'M'];
const expected = {
m: 2,
};
const actual = parallelLetterFrequency(texts);
const actual = await parallelLetterFrequency(texts);
expect(actual).toEqual(expected);
});

xtest('ignore whitespace', () => {
xtest('ignore whitespace', async () => {
const texts = [' ', '\t', '\r\n'];
const expected = {};
const actual = parallelLetterFrequency(texts);
const actual = await parallelLetterFrequency(texts);
expect(actual).toEqual(expected);
});

xtest('ignore punctuation', () => {
xtest('ignore punctuation', async () => {
const texts = ['!', '?', ';', ',', '.'];
const expected = {};
const actual = parallelLetterFrequency(texts);
const actual = await parallelLetterFrequency(texts);
expect(actual).toEqual(expected);
});

xtest('ignore numbers', () => {
xtest('ignore numbers', async () => {
const texts = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'];
const expected = {};
const actual = parallelLetterFrequency(texts);
const actual = await parallelLetterFrequency(texts);
expect(actual).toEqual(expected);
});

xtest('Unicode letters', () => {
xtest('Unicode letters', async () => {
const texts = ['本', 'φ', 'ほ', 'ø'];
const expected = {
本: 1,
φ: 1,
ほ: 1,
ø: 1,
};
const actual = parallelLetterFrequency(texts);
const actual = await parallelLetterFrequency(texts);
expect(actual).toEqual(expected);
});

xtest('combination of lower- and uppercase letters, punctuation and white space', () => {
xtest('combination of lower- and uppercase letters, punctuation and white space', async () => {
const texts = [
'There, peeping among the cloud-wrack above a dark tower high up in the mountains, Sam saw a white star twinkle for a while. The beauty of it smote his heart, as he looked up out of the forsaken land, and hope returned to him. For like a shaft, clear and cold, the thought pierced him that in the end, the shadow was only a small and passing thing: there was light and high beauty forever beyond its reach.',
];
Expand Down Expand Up @@ -118,11 +118,11 @@ describe('ParallelLetterFrequency', () => {
w: 9,
y: 4,
};
const actual = parallelLetterFrequency(texts);
const actual = await parallelLetterFrequency(texts);
expect(actual).toEqual(expected);
});

xtest('large texts', () => {
xtest('large texts', async () => {
const texts = [
"I am a sick man.... I am a spiteful man. I am an unattractive man.\nI believe my liver is diseased. However, I know nothing at all about my disease, and do not\nknow for certain what ails me. I don't consult a doctor for it,\nand never have, though I have a respect for medicine and doctors.\nBesides, I am extremely superstitious, sufficiently so to respect medicine,\nanyway (I am well-educated enough not to be superstitious, but I am superstitious).\nNo, I refuse to consult a doctor from spite.\nThat you probably will not understand. Well, I understand it, though.\nOf course, I can't explain who it is precisely that I am mortifying in this case by my spite:\nI am perfectly well aware that I cannot \"pay out\" the doctors by not consulting them;\nI know better than anyone that by all this I am only injuring myself and no one else.\nBut still, if I don't consult a doctor it is from spite.\nMy liver is bad, well - let it get worse!\nI have been going on like that for a long time - twenty years. Now I am forty.\nI used to be in the government service, but am no longer.\nI was a spiteful official. I was rude and took pleasure in being so.\nI did not take bribes, you see, so I was bound to find a recompense in that, at least.\n(A poor jest, but I will not scratch it out. I wrote it thinking it would sound very witty;\nbut now that I have seen myself that I only wanted to show off in a despicable way -\nI will not scratch it out on purpose!) When petitioners used to come for\ninformation to the table at which I sat, I used to grind my teeth at them,\nand felt intense enjoyment when I succeeded in making anybody unhappy.\nI almost did succeed. For the most part they were all timid people - of course,\nthey were petitioners. But of the uppish ones there was one officer in particular\nI could not endure. He simply would not be humble, and clanked his sword in a disgusting way.\nI carried on a feud with him for eighteen months over that sword. At last I got the better of him.\nHe left off clanking it. That happened in my youth, though. But do you know,\ngentlemen, what was the chief point about my spite? Why, the whole point,\nthe real sting of it lay in the fact that continually, even in the moment of the acutest spleen,\nI was inwardly conscious with shame that I was not only not a spiteful but not even an embittered man,\nthat I was simply scaring sparrows at random and amusing myself by it.\nI might foam at the mouth, but bring me a doll to play with, give me a cup of tea with sugar in it,\nand maybe I should be appeased. I might even be genuinely touched,\nthough probably I should grind my teeth at myself afterwards and lie awake at night with shame for\nmonths after. That was my way. I was lying when I said just now that I was a spiteful official.\nI was lying from spite. I was simply amusing myself with the petitioners and with the officer,\nand in reality I never could become spiteful. I was conscious every moment in myself of many,\nvery many elements absolutely opposite to that. I felt them positively swarming in me,\nthese opposite elements. I knew that they had been swarming in me all my life and craving some outlet from me,\nbut I would not let them, would not let them, purposely would not let them come out.\nThey tormented me till I was ashamed: they drove me to convulsions and - sickened me, at last,\nhow they sickened me!",
'Gentlemen, I am joking, and I know myself that my jokes are not brilliant\n,but you know one can take everything as a joke. I am, perhaps, jesting against the grain.\nGentlemen, I am tormented by questions; answer them for me. You, for instance, want to cure men of their\nold habits and reform their will in accordance with science and good sense.\nBut how do you know, not only that it is possible, but also that it is\ndesirable to reform man in that way? And what leads you to the conclusion that man\'s\ninclinations need reforming? In short, how do you know that such a reformation will be a benefit to man?\nAnd to go to the root of the matter, why are you so positively convinced that not to act against\nhis real normal interests guaranteed by the conclusions of reason and arithmetic is certainly always\nadvantageous for man and must always be a law for mankind? So far, you know,\nthis is only your supposition. It may be the law of logic, but not the law of humanity.\nYou think, gentlemen, perhaps that I am mad? Allow me to defend myself. I agree that man\nis pre-eminently a creative animal, predestined to strive consciously for an object and to engage in engineering -\nthat is, incessantly and eternally to make new roads, wherever\nthey may lead. But the reason why he wants sometimes to go off at a tangent may just be that he is\npredestined to make the road, and perhaps, too, that however stupid the "direct"\npractical man may be, the thought sometimes will occur to him that the road almost always does lead\nsomewhere, and that the destination it leads to is less important than the process\nof making it, and that the chief thing is to save the well-conducted child from despising engineering,\nand so giving way to the fatal idleness, which, as we all know,\nis the mother of all the vices. Man likes to make roads and to create, that is a fact beyond dispute.\nBut why has he such a passionate love for destruction and chaos also?\nTell me that! But on that point I want to say a couple of words myself. May it not be that he loves\nchaos and destruction (there can be no disputing that he does sometimes love it)\nbecause he is instinctively afraid of attaining his object and completing the edifice he is constructing?\nWho knows, perhaps he only loves that edifice from a distance, and is by no means\nin love with it at close quarters; perhaps he only loves building it and does not want to live in it,\nbut will leave it, when completed, for the use of les animaux domestiques -\nsuch as the ants, the sheep, and so on. Now the ants have quite a different taste.\nThey have a marvellous edifice of that pattern which endures for ever - the ant-heap.\nWith the ant-heap the respectable race of ants began and with the ant-heap they will probably end,\nwhich does the greatest credit to their perseverance and good sense. But man is a frivolous and\nincongruous creature, and perhaps, like a chess player, loves the process of the game, not the end of it.\nAnd who knows (there is no saying with certainty), perhaps the only goal on earth\nto which mankind is striving lies in this incessant process of attaining, in other words,\nin life itself, and not in the thing to be attained, which must always be expressed as a formula,\nas positive as twice two makes four, and such positiveness is not life, gentlemen,\nbut is the beginning of death.',
Expand Down Expand Up @@ -156,18 +156,18 @@ describe('ParallelLetterFrequency', () => {
x: 7,
y: 251,
};
const actual = parallelLetterFrequency(texts);
const actual = await parallelLetterFrequency(texts);
expect(actual).toEqual(expected);
});

xtest('many small texts', () => {
xtest('many small texts', async () => {
const texts = Array(50).fill('abbccc');
const expected = {
a: 50,
b: 100,
c: 150,
};
const actual = parallelLetterFrequency(texts);
const actual = await parallelLetterFrequency(texts);
expect(actual).toEqual(expected);
});
});