-
-
Notifications
You must be signed in to change notification settings - Fork 518
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add parallel_letter_frequency_test.rb
Co-authored-by: KOTP <[email protected]>
- Loading branch information
Showing
5 changed files
with
225 additions
and
0 deletions.
There are no files selected for viewing
9 changes: 9 additions & 0 deletions
9
exercises/practice/parallel-letter-frequency/data/moby_dick_ch37.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
The cabin; by the stern windows; Ahab sitting alone, and gazing out. | ||
|
||
I leave a white and turbid wake; pale waters, paler cheeks, where’er I sail. The envious billows sidelong swell to whelm my track; let them; but first I pass. | ||
|
||
Yonder, by ever-brimming goblet’s rim, the warm waves blush like wine. The gold brow plumbs the blue. The diver sun—slow dived from noon—goes down; my soul mounts up! she wearies with her endless hill. Is, then, the crown too heavy that I wear? this Iron Crown of Lombardy. Yet is it bright with many a gem; I the wearer, see not its far flashings; but darkly feel that I wear that, that dazzlingly confounds. ’Tis iron—that I know—not gold. ’Tis split, too—that I feel; the jagged edge galls me so, my brain seems to beat against the solid metal; aye, steel skull, mine; the sort that needs no helmet in the most brain-battering fight! | ||
|
||
Dry heat upon my brow? Oh! time was, when as the sunrise nobly spurred me, so the sunset soothed. No more. This lovely light, it lights not me; all loveliness is anguish to me, since I can ne’er enjoy. Gifted with the high perception, I lack the low, enjoying power; damned, most subtly and most malignantly! damned in the midst of Paradise! Good night—good night! (waving his hand, he moves from the window.) | ||
|
||
’Twas not so hard a task. I thought to find one stubborn, at the least; but my one cogged circle fits into all their various wheels, and they revolve. Or, if you will, like so many ant-hills of powder, they all stand before me; and I their match. Oh, hard! that to fire others, the match itself must needs be wasting! What I’ve dared, I’ve willed; and what I’ve willed, I’ll do! They think me mad—Starbuck does; but I’m demoniac, I am madness maddened! That wild madness that’s only calm to comprehend itself! The prophecy was that I should be dismembered; and—Aye! I lost this leg. I now prophesy that I will dismember my dismemberer. Now, then, be the prophet and the fulfiller one. That’s more than ye, ye great gods, ever were. I laugh and hoot at ye, ye cricket-players, ye pugilists, ye deaf Burkes and blinded Bendigoes! I will not say as schoolboys do to bullies—Take some one of your own size; don’t pommel me! No, ye’ve knocked me down, and I am up again; but ye have run and hidden. Come forth from behind your cotton bags! I have no long gun to reach ye. Come, Ahab’s compliments to ye; come and see if ye can swerve me. Swerve me? ye cannot swerve me, else ye swerve yourselves! man has ye there. Swerve me? The path to my fixed purpose is laid with iron rails, whereon my soul is grooved to run. Over unsounded gorges, through the rifled hearts of mountains, under torrents’ beds, unerringly I rush! Naught’s an obstacle, naught’s an angle to the iron way! |
7 changes: 7 additions & 0 deletions
7
exercises/practice/parallel-letter-frequency/data/moby_dick_ch38.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
By the Mainmast; Starbuck leaning against it. | ||
|
||
My soul is more than matched; she’s overmanned; and by a madman! Insufferable sting, that sanity should ground arms on such a field! But he drilled deep down, and blasted all my reason out of me! I think I see his impious end; but feel that I must help him to it. Will I, nill I, the ineffable thing has tied me to him; tows me with a cable I have no knife to cut. Horrible old man! Who’s over him, he cries;—aye, he would be a democrat to all above; look, how he lords it over all below! Oh! I plainly see my miserable office,—to obey, rebelling; and worse yet, to hate with touch of pity! For in his eyes I read some lurid woe would shrivel me up, had I it. Yet is there hope. Time and tide flow wide. The hated whale has the round watery world to swim in, as the small gold-fish has its glassy globe. His heaven-insulting purpose, God may wedge aside. I would up heart, were it not like lead. But my whole clock’s run down; my heart the all-controlling weight, I have no key to lift again. | ||
|
||
[A burst of revelry from the forecastle.] | ||
|
||
Oh, God! to sail with such a heathen crew that have small touch of human mothers in them! Whelped somewhere by the sharkish sea. The white whale is their demigorgon. Hark! the infernal orgies! that revelry is forward! mark the unfaltering silence aft! Methinks it pictures life. Foremost through the sparkling sea shoots on the gay, embattled, bantering bow, but only to drag dark Ahab after it, where he broods within his sternward cabin, builded over the dead water of the wake, and further on, hunted by its wolfish gurglings. The long howl thrills me through! Peace! ye revellers, and set the watch! Oh, life! ’tis in an hour like this, with soul beat down and held to knowledge,—as wild, untutored things are forced to feed—Oh, life! ’tis now that I do feel the latent horror in thee! but ’tis not me! that horror’s out of me! and with the soft feeling of the human in me, yet will I try to fight ye, ye grim, phantom futures! Stand by me, hold me, bind me, O ye blessed influences! |
12 changes: 12 additions & 0 deletions
12
exercises/practice/parallel-letter-frequency/data/moby_dick_ch39.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
Fore-Top. | ||
|
||
(Stubb solus, and mending a brace.) | ||
|
||
Ha! ha! ha! ha! hem! clear my throat!—I’ve been thinking over it ever since, and that ha, ha’s the final consequence. Why so? Because a laugh’s the wisest, easiest answer to all that’s queer; and come what will, one comfort’s always left—that unfailing comfort is, it’s all predestinated. I heard not all his talk with Starbuck; but to my poor eye Starbuck then looked something as I the other evening felt. Be sure the old Mogul has fixed him, too. I twigged it, knew it; had had the gift, might readily have prophesied it—for when I clapped my eye upon his skull I saw it. Well, Stubb, wise Stubb—that’s my title—well, Stubb, what of it, Stubb? Here’s a carcase. I know not all that may be coming, but be it what it will, I’ll go to it laughing. Such a waggish leering as lurks in all your horribles! I feel funny. Fa, la! lirra, skirra! What’s my juicy little pear at home doing now? Crying its eyes out?—Giving a party to the last arrived harpooneers, I dare say, gay as a frigate’s pennant, and so am I—fa, la! lirra, skirra! Oh— | ||
|
||
We’ll drink to-night with hearts as light, | ||
To love, as gay and fleeting | ||
As bubbles that swim, on the beaker’s brim, | ||
And break on the lips while meeting. | ||
|
||
A brave stave that—who calls? Mr. Starbuck? Aye, aye, sir—(Aside) he’s my superior, he has his too, if I’m not mistaken.—Aye, aye, sir, just through with this job—coming. |
3 changes: 3 additions & 0 deletions
3
exercises/practice/parallel-letter-frequency/data/ruby_wiki.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
Ruby is an interpreted, high-level, general-purpose programming language which supports multiple programming paradigms. It was designed with an emphasis on programming productivity and simplicity. In Ruby, everything is an object, including primitive data types. It was developed in the mid-1990s by Yukihiro "Matz" Matsumoto in Japan. | ||
|
||
Ruby is dynamically typed and uses garbage collection and just-in-time compilation. It supports multiple programming paradigms, including procedural, object-oriented, and functional programming. According to the creator, Ruby was influenced by Perl, Smalltalk, Eiffel, Ada, BASIC, Java, and Lisp. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,194 @@ | ||
require 'minitest/autorun' | ||
require_relative 'parallel_letter_frequency' | ||
|
||
# rubocop:disable Layout/SpaceInsideHashLiteralBraces | ||
class ParallelLetterFrequencyTest < Minitest::Test | ||
def test_no_texts | ||
# skip | ||
texts = %w[] | ||
expected = {} | ||
actual = ParallelLetterFrequency.count(texts) | ||
assert_equal expected, actual | ||
end | ||
|
||
def test_one_text_one_letter | ||
skip | ||
texts = %w[a] | ||
expected = {'a' => 1} | ||
actual = ParallelLetterFrequency.count(texts) | ||
assert_equal expected, actual | ||
end | ||
|
||
def test_one_text_multiple_letters | ||
skip | ||
texts = %w[abbca] | ||
expected = {'a' => 2, 'b' => 2, 'c' => 1} | ||
actual = ParallelLetterFrequency.count(texts) | ||
assert_equal expected, actual | ||
end | ||
|
||
def test_two_texts_one_letter | ||
skip | ||
texts = %w[a a] | ||
expected = {'a' => 2} | ||
actual = ParallelLetterFrequency.count(texts) | ||
assert_equal expected, actual | ||
end | ||
|
||
def test_two_texts_multiple_letters | ||
skip | ||
texts = %w[abcd ac] | ||
expected = {'a' => 2, 'b' => 1, 'c' => 2, 'd' => 1} | ||
actual = ParallelLetterFrequency.count(texts) | ||
assert_equal expected, actual | ||
end | ||
|
||
def test_ignore_letter_case | ||
skip | ||
texts = %w[Aa aA] | ||
expected = {'a' => 4} | ||
actual = ParallelLetterFrequency.count(texts) | ||
assert_equal expected, actual | ||
end | ||
|
||
def test_ignore_whitespace | ||
skip | ||
texts = [' ', "\t", "\n", "\r\n"] | ||
expected = {} | ||
actual = ParallelLetterFrequency.count(texts) | ||
assert_equal expected, actual | ||
end | ||
|
||
def test_ignore_punctuation | ||
skip | ||
texts = ['!', '?', ';', ',', '.', '-', "'", '"', '/', ':', '{}', '[]', '()'] | ||
expected = {} | ||
actual = ParallelLetterFrequency.count(texts) | ||
assert_equal expected, actual | ||
end | ||
|
||
def test_ignore_numbers | ||
skip | ||
texts = %w[1 2 3 4 5 6 7 8 9 0] | ||
expected = {} | ||
actual = ParallelLetterFrequency.count(texts) | ||
assert_equal expected, actual | ||
end | ||
|
||
def test_unicode_letters | ||
skip | ||
texts = %w[本 φ ほ ø] | ||
expected = {'本' => 1, 'φ' => 1, 'ほ' => 1, 'ø' => 1} | ||
actual = ParallelLetterFrequency.count(texts) | ||
assert_equal expected, actual | ||
end | ||
|
||
def test_combo_lower_upper_punctuation_whitespace | ||
skip | ||
ruby_wiki = File.read(File.expand_path('data/ruby_wiki.txt', __dir__)) | ||
texts = ruby_wiki | ||
expected = { | ||
"r" => 34, | ||
"u" => 20, | ||
"b" => 10, | ||
"y" => 14, | ||
"i" => 53, | ||
"s" => 26, | ||
"a" => 46, | ||
"n" => 37, | ||
"t" => 34, | ||
"e" => 39, | ||
"p" => 28, | ||
"d" => 24, | ||
"h" => 10, | ||
"g" => 23, | ||
"l" => 26, | ||
"v" => 6, | ||
"o" => 26, | ||
"m" => 25, | ||
"w" => 5, | ||
"c" => 18, | ||
"j" => 5, | ||
"k" => 2, | ||
"z" => 1, | ||
"f" => 4 | ||
} | ||
actual = ParallelLetterFrequency.count(texts) | ||
assert_equal expected, actual | ||
end | ||
|
||
def test_large_texts | ||
skip | ||
ch37 = File.read(File.expand_path('data/moby_dick_ch37.txt', __dir__)) | ||
ch38 = File.read(File.expand_path('data/moby_dick_ch38.txt', __dir__)) | ||
ch39 = File.read(File.expand_path('data/moby_dick_ch39.txt', __dir__)) | ||
texts = [ch37, ch38, ch39] | ||
expected = { | ||
"f" => 89, | ||
"o" => 333, | ||
"r" => 250, | ||
"e" => 570, | ||
"t" => 429, | ||
"p" => 57, | ||
"s" => 311, | ||
"u" => 131, | ||
"b" => 110, | ||
"l" => 260, | ||
"a" => 356, | ||
"n" => 278, | ||
"d" => 184, | ||
"m" => 156, | ||
"i" => 352, | ||
"g" => 120, | ||
"c" => 77, | ||
"h" => 308, | ||
"y" => 113, | ||
"v" => 52, | ||
"k" => 49, | ||
"q" => 2, | ||
"w" => 133, | ||
"x" => 2, | ||
"j" => 6, | ||
"z" => 4 | ||
} | ||
actual = ParallelLetterFrequency.count(texts) | ||
assert_equal expected, actual | ||
end | ||
|
||
def test_many_small_texts | ||
skip | ||
texts = Array.new(100, 'abc') | ||
actual = ParallelLetterFrequency.count(texts) | ||
expected = {'a' => 100, 'b' => 100, 'c' => 100} | ||
assert_equal expected, actual | ||
end | ||
|
||
def test_faster_than_serialized_answer | ||
skip | ||
texts = Array.new(20, 'a' * 100_000) | ||
|
||
GC.start | ||
t0_parallel = Minitest.clock_time | ||
ParallelLetterFrequency.count(texts) | ||
parallel_time = Minitest.clock_time - t0_parallel | ||
|
||
t0_sequential = Minitest.clock_time | ||
sequential_letter_frequency(texts) | ||
sequential_time = Minitest.clock_time - t0_sequential | ||
|
||
assert parallel_time < sequential_time, | ||
'Parallel execution should be faster than sequential for batches of large texts' | ||
end | ||
|
||
def sequential_letter_frequency(texts) | ||
tally = Hash.new(0) | ||
texts.each do |text| | ||
text.each_grapheme_cluster do |cluster| | ||
tally[cluster] += 1 | ||
end | ||
end | ||
|
||
tally | ||
end | ||
end | ||
# rubocop:enable Layout/SpaceInsideHashLiteralBraces |