fizzbuzzer 0.1.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Manifest.txt +3 -0
- data/README.md +351 -4
- data/Rakefile +2 -0
- data/lib/fizzbuzzer.rb +328 -1
- data/lib/fizzbuzzer/version.rb +2 -2
- data/test/helper.rb +10 -0
- data/test/test_fizzbuzz.rb +55 -0
- data/test/test_version.rb +21 -0
- metadata +33 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: da58d7c29be8ab792904f6568b0accce17d2cf3c
|
4
|
+
data.tar.gz: 414323b0ae95450d79aa2d0da5be1c065470e57e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4c75335ebca864f1d72568312fb813b53b16ef46fc79c01f3331bea11ce8b4fed9cc06ee17d10630986f135a919d1e84868c32de8845b5115ba63369b2a9aaf3
|
7
|
+
data.tar.gz: 86134a7767428e28906ce3539714265b8f7910c3a0ead9928dfa39e16288117e78993e67c499f4b56ee1379b50737561c0f4e1c72f70e1277737bab9e48aaac4
|
data/Manifest.txt
CHANGED
data/README.md
CHANGED
@@ -1,9 +1,16 @@
|
|
1
1
|
# FizzBuzzer
|
2
2
|
|
3
|
-
fizzbuzzer - 1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz, 11, Fizz, 13, 14, Fizz Buzz, ... -
|
4
|
-
|
5
|
-
|
6
|
-
the
|
3
|
+
fizzbuzzer - 1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz, 11, Fizz, 13, 14, Fizz Buzz, ... -
|
4
|
+
a collection of algorithms for playing the word game for children that teaches division
|
5
|
+
(one of the four basic arithmetic operations in mathematics)
|
6
|
+
or helps you find the world's best coders in programming job interviews -
|
7
|
+
are you (re)using the fizzbuzzer library? ;-) - don't reinvent the wheel or the feedbuzzer!
|
8
|
+
|
9
|
+
|
10
|
+
* home :: [github.com/rubylibs/fizzbuzzer](https://github.com/rubylibs/fizzbuzzer)
|
11
|
+
* bugs :: [github.com/rubylibs/fizzbuzzer/issues](https://github.com/rubylibs/fizzbuzzer/issues)
|
12
|
+
* gem :: [rubygems.org/gems/fizzbuzzer](https://rubygems.org/gems/fizzbuzzer)
|
13
|
+
* rdoc :: [rubydoc.info/gems/fizzbuzzer](http://rubydoc.info/gems/fizzbuzzer)
|
7
14
|
|
8
15
|
|
9
16
|
|
@@ -88,7 +95,347 @@ def fizzbuzz
|
|
88
95
|
end
|
89
96
|
```
|
90
97
|
|
98
|
+
### Classic
|
99
|
+
|
100
|
+
``` ruby
|
101
|
+
def fizzbuzz
|
102
|
+
(1..100).map do |n|
|
103
|
+
if n % 3 == 0 && n % 5 == 0
|
104
|
+
"FizzBuzz"
|
105
|
+
elsif n % 3 == 0
|
106
|
+
"Fizz"
|
107
|
+
elsif n % 5 == 0
|
108
|
+
"Buzz"
|
109
|
+
else
|
110
|
+
n
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
```
|
115
|
+
|
116
|
+
Or use `zero?` and `n % 15` (3x5) for `n % 5 && n % 3`:
|
117
|
+
|
118
|
+
``` ruby
|
119
|
+
def fizzbuzz
|
120
|
+
(1..100).map do |n|
|
121
|
+
if (n % 15).zero? then "FizzBuzz"
|
122
|
+
elsif (n % 3).zero? then "Fizz"
|
123
|
+
elsif (n % 5).zero? then "Buzz"
|
124
|
+
else n
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
```
|
129
|
+
|
130
|
+
Or use `case/when/else`:
|
131
|
+
|
132
|
+
``` ruby
|
133
|
+
def fizzbuzz
|
134
|
+
(1..100).map do |n|
|
135
|
+
case
|
136
|
+
when n % 3 == 0 && n % 5 == 0 then "FizzBuzz"
|
137
|
+
when n % 3 == 0 then "Fizz"
|
138
|
+
when n % 5 == 0 then "Buzz"
|
139
|
+
else n
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
```
|
144
|
+
|
145
|
+
Or use `next` with `if`-clause:
|
146
|
+
|
147
|
+
``` ruby
|
148
|
+
def fizzbuzz
|
149
|
+
(1..100).map do |n|
|
150
|
+
next "FizzBuzz" if n % 3 == 0 && n % 5 == 0
|
151
|
+
next "Fizz" if n % 3 == 0
|
152
|
+
next "Buzz" if n % 5 == 0
|
153
|
+
n
|
154
|
+
end
|
155
|
+
end
|
156
|
+
```
|
157
|
+
|
158
|
+
|
159
|
+
### Monkey Patch (Extend) Fixnum Class
|
160
|
+
|
161
|
+
``` ruby
|
162
|
+
class Fixnum
|
163
|
+
def to_fizzbuzz
|
164
|
+
if self % 3 == 0 && self % 5 == 0
|
165
|
+
"FizzBuzz"
|
166
|
+
elsif self % 3 == 0
|
167
|
+
"Fizz"
|
168
|
+
elsif self % 5 == 0
|
169
|
+
"Buzz"
|
170
|
+
else
|
171
|
+
self
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
def fizzbuzz
|
177
|
+
(1..100).map { |n| n.to_fizzbuzz }
|
178
|
+
end
|
179
|
+
```
|
180
|
+
|
181
|
+
## Object-Oriented with New Fizznum Class
|
182
|
+
|
183
|
+
``` ruby
|
184
|
+
class Fizznum
|
185
|
+
attr_accessor :num
|
186
|
+
|
187
|
+
def initialize(num)
|
188
|
+
self.num = num
|
189
|
+
end
|
190
|
+
|
191
|
+
def fizzbuzz?() num % 3 == 0 && num % 5 == 0; end
|
192
|
+
def fizz?() num % 3 == 0; end
|
193
|
+
def buzz?() num % 5 == 0; end
|
194
|
+
|
195
|
+
def to_s
|
196
|
+
if fizzbuzz? then "FizzBuzz"
|
197
|
+
elsif fizz? then "Fizz"
|
198
|
+
elsif buzz? then "Buzz"
|
199
|
+
else num.to_s
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
end
|
91
204
|
|
205
|
+
def fizzbuzz
|
206
|
+
(1..100).map{ |n| Fizznum.new(n).to_s }
|
207
|
+
end
|
208
|
+
```
|
209
|
+
|
210
|
+
|
211
|
+
### Don't Repeat Yourself (DRY)
|
212
|
+
|
213
|
+
|
214
|
+
``` ruby
|
215
|
+
FIZZ = 'Fizz'
|
216
|
+
BUZZ = 'Buzz'
|
217
|
+
|
218
|
+
def divisible_by?(numerator, denominator)
|
219
|
+
numerator % denominator == 0
|
220
|
+
end
|
221
|
+
|
222
|
+
def divisible_by_3?( numerator )
|
223
|
+
divisible_by?( numerator, 3 )
|
224
|
+
end
|
225
|
+
|
226
|
+
def divisible_by_5?( numerator )
|
227
|
+
divisible_by?( numerator, 5 )
|
228
|
+
end
|
229
|
+
|
230
|
+
def fizzbuzz
|
231
|
+
(1..100).map do |n|
|
232
|
+
fizz = divisible_by_3? n
|
233
|
+
buzz = divisible_by_5? n
|
234
|
+
case
|
235
|
+
when fizz && buzz then FIZZ + BUZZ
|
236
|
+
when fizz then FIZZ
|
237
|
+
when buzz then BUZZ
|
238
|
+
else n
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
242
|
+
```
|
243
|
+
|
244
|
+
|
245
|
+
## Enumarator
|
246
|
+
|
247
|
+
```ruby
|
248
|
+
module FizzBuzz
|
249
|
+
def self.enumerator
|
250
|
+
Enumerator.new do |yielder|
|
251
|
+
(1..100).each do |n|
|
252
|
+
yielder << case
|
253
|
+
when n % 3 == 0 && n % 5 == 0 then "FizzBuzz"
|
254
|
+
when n % 3 == 0 then "Fizz"
|
255
|
+
when n % 5 == 0 then "Buzz"
|
256
|
+
else n
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
def fizzbuzz
|
264
|
+
FizzBuzz.enumerator.first( 100 )
|
265
|
+
end
|
266
|
+
```
|
267
|
+
|
268
|
+
Or fetch every value one at a time with `next`:
|
269
|
+
|
270
|
+
``` ruby
|
271
|
+
def fizzbuzz
|
272
|
+
e = FizzBuzz.enumerator
|
273
|
+
[e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next,
|
274
|
+
e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next,
|
275
|
+
e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next,
|
276
|
+
e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next,
|
277
|
+
e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next,
|
278
|
+
e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next,
|
279
|
+
e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next,
|
280
|
+
e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next,
|
281
|
+
e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next,
|
282
|
+
e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next]
|
283
|
+
end
|
284
|
+
```
|
285
|
+
|
286
|
+
|
287
|
+
## Lazy Enumerator to Infinity
|
288
|
+
|
289
|
+
```ruby
|
290
|
+
require "bigdecimal"
|
291
|
+
|
292
|
+
module FizzBuzz
|
293
|
+
def self.enumerator
|
294
|
+
Enumerator::Lazy.new(1..BigDecimal::INFINITY) do |yielder, n|
|
295
|
+
yielder << case
|
296
|
+
when n % 3 == 0 && n % 5 == 0 then "FizzBuzz"
|
297
|
+
when n % 3 == 0 then "Fizz"
|
298
|
+
when n % 5 == 0 then "Buzz"
|
299
|
+
else n
|
300
|
+
end
|
301
|
+
end
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
def fizzbuzz
|
306
|
+
FizzBuzz.enumerator.take( 100 ).force # or first( 100 ) is always eager by default
|
307
|
+
end
|
308
|
+
```
|
309
|
+
|
310
|
+
|
311
|
+
|
312
|
+
## Pattern Matching with Noaidi
|
313
|
+
|
314
|
+
``` ruby
|
315
|
+
require "noaidi"
|
316
|
+
|
317
|
+
def fizzbuzz
|
318
|
+
(1..100).map do |n|
|
319
|
+
Noaidi.match [n % 3, n % 5] do |m|
|
320
|
+
m.(0, 0) { "FizzBuzz" }
|
321
|
+
m.(0, Fixnum) { "Fizz" }
|
322
|
+
m.(Fixnum, 0) { "Buzz" }
|
323
|
+
m.(Fixnum, Fixnum) { n }
|
324
|
+
end
|
325
|
+
end
|
326
|
+
end
|
327
|
+
```
|
328
|
+
|
329
|
+
## Poor Man's (Do-It-Yourself) Pattern Matching
|
330
|
+
|
331
|
+
``` ruby
|
332
|
+
def fizzbuzz
|
333
|
+
(1..100).map do |n|
|
334
|
+
case [n % 3, n % 5].map {|remainder| remainder.zero? }
|
335
|
+
when [true, true] then "FizzBuzz"
|
336
|
+
when [true, false] then "Fizz"
|
337
|
+
when [false, true] then "Buzz"
|
338
|
+
else n
|
339
|
+
end
|
340
|
+
end
|
341
|
+
end
|
342
|
+
```
|
343
|
+
|
344
|
+
|
345
|
+
## Pattern Matching with dry-matcher
|
346
|
+
|
347
|
+
``` ruby
|
348
|
+
require "dry-matcher"
|
349
|
+
|
350
|
+
FizzBuzz = Dry::Matcher.new(
|
351
|
+
fizzbuzz: Dry::Matcher::Case.new(
|
352
|
+
match: -> value { value % 3 == 0 && value % 5 == 0 },
|
353
|
+
resolve: -> value { "FizzBuzz" } ),
|
354
|
+
fizz: Dry::Matcher::Case.new(
|
355
|
+
match: -> value { value % 3 == 0 },
|
356
|
+
resolve: -> value { "Fizz" } ),
|
357
|
+
buzz: Dry::Matcher::Case.new(
|
358
|
+
match: -> value { value % 5 == 0 },
|
359
|
+
resolve: -> value { "Buzz" } ),
|
360
|
+
other: Dry::Matcher::Case.new(
|
361
|
+
match: -> value { true },
|
362
|
+
resolve: -> value { value } ))
|
363
|
+
|
364
|
+
def fizzbuzz
|
365
|
+
(1..100).map do |n|
|
366
|
+
FizzBuzz.(n) do |m|
|
367
|
+
m.fizzbuzz { |v| v }
|
368
|
+
m.fizz { |v| v }
|
369
|
+
m.buzz { |v| v }
|
370
|
+
m.other { |v| v }
|
371
|
+
end
|
372
|
+
end
|
373
|
+
end
|
374
|
+
```
|
375
|
+
|
376
|
+
|
377
|
+
## Rotate / No Conditionals
|
378
|
+
|
379
|
+
``` ruby
|
380
|
+
def fizzbuzz
|
381
|
+
fizzy = [1,0,0]
|
382
|
+
buzzy = [1,0,0,0,0]
|
383
|
+
|
384
|
+
(1..100).map do |n|
|
385
|
+
fizzy.rotate!
|
386
|
+
buzzy.rotate!
|
387
|
+
result = n.to_s * (1 - (fizzy[0] | buzzy[0]))
|
388
|
+
result << "Fizz" * fizzy[0]
|
389
|
+
result << "Buzz" * buzzy[0]
|
390
|
+
result
|
391
|
+
end
|
392
|
+
end
|
393
|
+
```
|
394
|
+
|
395
|
+
Contributed by [John Schank](https://github.com/jschank).
|
396
|
+
|
397
|
+
|
398
|
+
|
399
|
+
## With Parameterization
|
400
|
+
|
401
|
+
``` ruby
|
402
|
+
def fizzbuzz_engine(range, factors)
|
403
|
+
range.map do |n|
|
404
|
+
result = ""
|
405
|
+
factors.each do |(name, predicate)|
|
406
|
+
result << name if predicate.call(n)
|
407
|
+
end
|
408
|
+
result == "" ? n : result
|
409
|
+
end
|
410
|
+
end
|
411
|
+
|
412
|
+
def fizzbuzz
|
413
|
+
fizzbuzz_engine( 1..100, [["Fizz", -> n { n % 3 == 0 }],
|
414
|
+
["Buzz", -> n { n % 5 == 0 }]])
|
415
|
+
end
|
416
|
+
```
|
417
|
+
|
418
|
+
Or with default configuration settings:
|
419
|
+
|
420
|
+
``` ruby
|
421
|
+
FIZZBUZZ_DEFAULT_RANGE = 1..100
|
422
|
+
FIZZBUZZ_DEFAULT_FACTORS = [["Fizz", -> n { n % 3 == 0 }],
|
423
|
+
['Buzz', -> n { n % 5 == 0 }]]
|
424
|
+
|
425
|
+
def fizzbuzz_engine(range=FIZZBUZZ_DEFAULT_RANGE, factors=FIZZBUZZ_DEFAULT_FACTORS)
|
426
|
+
range.map do |n|
|
427
|
+
result = ""
|
428
|
+
factors.each do |(name, predicate)|
|
429
|
+
result << name if predicate.call(n)
|
430
|
+
end
|
431
|
+
result == "" ? n : result
|
432
|
+
end
|
433
|
+
end
|
434
|
+
|
435
|
+
def fizzbuzz
|
436
|
+
fizzbuzz_engine
|
437
|
+
end
|
438
|
+
```
|
92
439
|
|
93
440
|
|
94
441
|
|
data/Rakefile
CHANGED
data/lib/fizzbuzzer.rb
CHANGED
@@ -2,11 +2,12 @@
|
|
2
2
|
|
3
3
|
require 'pp'
|
4
4
|
|
5
|
-
|
6
5
|
## our own code
|
7
6
|
require 'fizzbuzzer/version' # note: let version always go first
|
8
7
|
|
9
8
|
|
9
|
+
|
10
|
+
|
10
11
|
module FizzBuzzer
|
11
12
|
|
12
13
|
module V1
|
@@ -23,7 +24,333 @@ module V1
|
|
23
24
|
end
|
24
25
|
end ## module V1
|
25
26
|
|
27
|
+
module V2a
|
28
|
+
def fizzbuzz
|
29
|
+
(1..100).map do |n|
|
30
|
+
if n % 3 == 0 && n % 5 == 0
|
31
|
+
"FizzBuzz"
|
32
|
+
elsif n % 3 == 0
|
33
|
+
"Fizz"
|
34
|
+
elsif n % 5 == 0
|
35
|
+
"Buzz"
|
36
|
+
else
|
37
|
+
n
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
module V2b
|
44
|
+
def fizzbuzz
|
45
|
+
(1..100).map do |n|
|
46
|
+
if (n % 15).zero? then "FizzBuzz"
|
47
|
+
elsif (n % 3).zero? then "Fizz"
|
48
|
+
elsif (n % 5).zero? then "Buzz"
|
49
|
+
else n
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
module V2c
|
56
|
+
def fizzbuzz
|
57
|
+
(1..100).map do |n|
|
58
|
+
case
|
59
|
+
when n % 3 == 0 && n % 5 == 0 then "FizzBuzz"
|
60
|
+
when n % 3 == 0 then "Fizz"
|
61
|
+
when n % 5 == 0 then "Buzz"
|
62
|
+
else n
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
module V2d
|
69
|
+
def fizzbuzz
|
70
|
+
(1..100).map do |n|
|
71
|
+
next "FizzBuzz" if n % 3 == 0 && n % 5 == 0
|
72
|
+
next "Fizz" if n % 3 == 0
|
73
|
+
next "Buzz" if n % 5 == 0
|
74
|
+
n
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end # module FizzBuzzer
|
79
|
+
|
80
|
+
|
81
|
+
|
82
|
+
## monkey patch for V3 - needs top level namespace
|
83
|
+
## todo/fix: use refinements - why? why not?
|
84
|
+
class Fixnum
|
85
|
+
def to_fizzbuzz
|
86
|
+
if self % 3 == 0 && self % 5 == 0
|
87
|
+
"FizzBuzz"
|
88
|
+
elsif self % 3 == 0
|
89
|
+
"Fizz"
|
90
|
+
elsif self % 5 == 0
|
91
|
+
"Buzz"
|
92
|
+
else
|
93
|
+
self
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
|
99
|
+
module FizzBuzzer
|
100
|
+
module V3
|
101
|
+
def fizzbuzz
|
102
|
+
(1..100).map { |n| n.to_fizzbuzz }
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
|
108
|
+
module V4
|
109
|
+
class Fizznum
|
110
|
+
attr_accessor :num
|
111
|
+
|
112
|
+
def initialize(num)
|
113
|
+
self.num = num
|
114
|
+
end
|
115
|
+
|
116
|
+
def fizzbuzz?() num % 3 == 0 && num % 5 == 0; end
|
117
|
+
def fizz?() num % 3 == 0; end
|
118
|
+
def buzz?() num % 5 == 0; end
|
119
|
+
|
120
|
+
def to_s
|
121
|
+
if fizzbuzz? then "FizzBuzz"
|
122
|
+
elsif fizz? then "Fizz"
|
123
|
+
elsif buzz? then "Buzz"
|
124
|
+
else num.to_s
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def fizzbuzz
|
130
|
+
(1..100).map{ |n| Fizznum.new(n).to_s }
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
|
135
|
+
module V5
|
136
|
+
FIZZ = 'Fizz'
|
137
|
+
BUZZ = 'Buzz'
|
138
|
+
|
139
|
+
def divisible_by?(numerator, denominator)
|
140
|
+
numerator % denominator == 0
|
141
|
+
end
|
142
|
+
|
143
|
+
def divisible_by_3?( numerator )
|
144
|
+
divisible_by?( numerator, 3 )
|
145
|
+
end
|
146
|
+
|
147
|
+
def divisible_by_5?( numerator )
|
148
|
+
divisible_by?( numerator, 5 )
|
149
|
+
end
|
150
|
+
|
151
|
+
def fizzbuzz
|
152
|
+
(1..100).map do |n|
|
153
|
+
fizz = divisible_by_3? n
|
154
|
+
buzz = divisible_by_5? n
|
155
|
+
case
|
156
|
+
when fizz && buzz then FIZZ + BUZZ
|
157
|
+
when fizz then FIZZ
|
158
|
+
when buzz then BUZZ
|
159
|
+
else n
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
|
166
|
+
module V6a
|
167
|
+
module FizzBuzz
|
168
|
+
def self.enumerator
|
169
|
+
Enumerator.new do |yielder|
|
170
|
+
(1..100).each do |n|
|
171
|
+
yielder << case
|
172
|
+
when n % 3 == 0 && n % 5 == 0 then "FizzBuzz"
|
173
|
+
when n % 3 == 0 then "Fizz"
|
174
|
+
when n % 5 == 0 then "Buzz"
|
175
|
+
else n
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
26
181
|
|
182
|
+
def fizzbuzz
|
183
|
+
FizzBuzz.enumerator.first( 100 )
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
|
188
|
+
module V6b
|
189
|
+
module FizzBuzz
|
190
|
+
def self.enumerator
|
191
|
+
Enumerator.new do |yielder|
|
192
|
+
(1..100).each do |n|
|
193
|
+
yielder << if n % 3 == 0 && n % 5 == 0 then "FizzBuzz"
|
194
|
+
elsif n % 3 == 0 then "Fizz"
|
195
|
+
elsif n % 5 == 0 then "Buzz"
|
196
|
+
else n
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
def fizzbuzz
|
204
|
+
e = FizzBuzz.enumerator
|
205
|
+
[e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next,
|
206
|
+
e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next,
|
207
|
+
e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next,
|
208
|
+
e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next,
|
209
|
+
e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next,
|
210
|
+
e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next,
|
211
|
+
e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next,
|
212
|
+
e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next,
|
213
|
+
e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next,
|
214
|
+
e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next, e.next]
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
|
219
|
+
module V7
|
220
|
+
require "bigdecimal"
|
221
|
+
|
222
|
+
module FizzBuzz
|
223
|
+
def self.enumerator
|
224
|
+
Enumerator::Lazy.new(1..BigDecimal::INFINITY) do |yielder, n|
|
225
|
+
yielder << case
|
226
|
+
when n % 3 == 0 && n % 5 == 0 then "FizzBuzz"
|
227
|
+
when n % 3 == 0 then "Fizz"
|
228
|
+
when n % 5 == 0 then "Buzz"
|
229
|
+
else n
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
def fizzbuzz
|
236
|
+
FizzBuzz.enumerator.take( 100 ).force # or first( 100 ) is always eager by default
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
|
241
|
+
module V8
|
242
|
+
require "noaidi"
|
243
|
+
|
244
|
+
def fizzbuzz
|
245
|
+
(1..100).map do |n|
|
246
|
+
Noaidi.match [n % 3, n % 5] do |m|
|
247
|
+
m.(0, 0) { "FizzBuzz" }
|
248
|
+
m.(0, Fixnum) { "Fizz" }
|
249
|
+
m.(Fixnum, 0) { "Buzz" }
|
250
|
+
m.(Fixnum, Fixnum) { n }
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
|
257
|
+
module V9
|
258
|
+
def fizzbuzz
|
259
|
+
(1..100).map do |n|
|
260
|
+
case [n % 3, n % 5].map {|remainder| remainder.zero? }
|
261
|
+
when [true, true] then "FizzBuzz"
|
262
|
+
when [true, false] then "Fizz"
|
263
|
+
when [false, true] then "Buzz"
|
264
|
+
else n
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
|
271
|
+
module V10
|
272
|
+
require "dry-matcher"
|
273
|
+
|
274
|
+
FizzBuzz = Dry::Matcher.new(
|
275
|
+
fizzbuzz: Dry::Matcher::Case.new(
|
276
|
+
match: -> value { value % 3 == 0 && value % 5 == 0 },
|
277
|
+
resolve: -> value { "FizzBuzz" } ),
|
278
|
+
fizz: Dry::Matcher::Case.new(
|
279
|
+
match: -> value { value % 3 == 0 },
|
280
|
+
resolve: -> value { "Fizz" } ),
|
281
|
+
buzz: Dry::Matcher::Case.new(
|
282
|
+
match: -> value { value % 5 == 0 },
|
283
|
+
resolve: -> value { "Buzz" } ),
|
284
|
+
other: Dry::Matcher::Case.new(
|
285
|
+
match: -> value { true },
|
286
|
+
resolve: -> value { value } ))
|
287
|
+
|
288
|
+
def fizzbuzz
|
289
|
+
(1..100).map do |n|
|
290
|
+
FizzBuzz.(n) do |m|
|
291
|
+
m.fizzbuzz { |v| v }
|
292
|
+
m.fizz { |v| v }
|
293
|
+
m.buzz { |v| v }
|
294
|
+
m.other { |v| v }
|
295
|
+
end
|
296
|
+
end
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
|
301
|
+
module V11
|
302
|
+
def fizzbuzz
|
303
|
+
fizzy = [1,0,0]
|
304
|
+
buzzy = [1,0,0,0,0]
|
305
|
+
|
306
|
+
(1..100).map do |n|
|
307
|
+
fizzy.rotate!
|
308
|
+
buzzy.rotate!
|
309
|
+
result = n.to_s * (1 - (fizzy[0] | buzzy[0]))
|
310
|
+
result << "Fizz" * fizzy[0]
|
311
|
+
result << "Buzz" * buzzy[0]
|
312
|
+
result
|
313
|
+
end
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
|
318
|
+
module V12a
|
319
|
+
def fizzbuzz_engine(range, factors)
|
320
|
+
range.map do |n|
|
321
|
+
result = ""
|
322
|
+
factors.each do |(name, predicate)|
|
323
|
+
result << name if predicate.call(n)
|
324
|
+
end
|
325
|
+
result == "" ? n : result
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
def fizzbuzz
|
330
|
+
fizzbuzz_engine( 1..100, [["Fizz", -> n { n % 3 == 0 }],
|
331
|
+
["Buzz", -> n { n % 5 == 0 }]])
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
module V12b
|
336
|
+
FIZZBUZZ_DEFAULT_RANGE = 1..100
|
337
|
+
FIZZBUZZ_DEFAULT_FACTORS = [["Fizz", -> n { n % 3 == 0 }],
|
338
|
+
['Buzz', -> n { n % 5 == 0 }]]
|
339
|
+
|
340
|
+
def fizzbuzz_engine(range=FIZZBUZZ_DEFAULT_RANGE, factors=FIZZBUZZ_DEFAULT_FACTORS)
|
341
|
+
range.map do |n|
|
342
|
+
result = ""
|
343
|
+
factors.each do |(name, predicate)|
|
344
|
+
result << name if predicate.call(n)
|
345
|
+
end
|
346
|
+
result == "" ? n : result
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
def fizzbuzz
|
351
|
+
fizzbuzz_engine
|
352
|
+
end
|
353
|
+
end
|
27
354
|
|
28
355
|
|
29
356
|
module Main ## todo/check: use a class Runner instead (w/ include V1 etc.) - why? why not?
|
data/lib/fizzbuzzer/version.rb
CHANGED
data/test/helper.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
###
|
4
|
+
# to run use
|
5
|
+
# ruby -I ./lib -I ./test test/test_fizzbuzz.rb
|
6
|
+
|
7
|
+
|
8
|
+
require 'helper'
|
9
|
+
|
10
|
+
|
11
|
+
FIZZBUZZES_1_TO_100 =
|
12
|
+
[1, 2, "Fizz", 4, "Buzz", "Fizz", 7, 8, "Fizz", "Buzz", 11, "Fizz", 13, 14,
|
13
|
+
"FizzBuzz", 16, 17, "Fizz", 19, "Buzz", "Fizz", 22, 23, "Fizz", "Buzz", 26,
|
14
|
+
"Fizz", 28, 29, "FizzBuzz", 31, 32, "Fizz", 34, "Buzz", "Fizz", 37, 38,
|
15
|
+
"Fizz", "Buzz", 41, "Fizz", 43, 44, "FizzBuzz", 46, 47, "Fizz", 49, "Buzz",
|
16
|
+
"Fizz", 52, 53, "Fizz", "Buzz", 56, "Fizz", 58, 59, "FizzBuzz", 61, 62,
|
17
|
+
"Fizz", 64, "Buzz", "Fizz", 67, 68, "Fizz", "Buzz", 71, "Fizz", 73, 74,
|
18
|
+
"FizzBuzz", 76, 77, "Fizz", 79, "Buzz", "Fizz", 82, 83, "Fizz", "Buzz", 86,
|
19
|
+
"Fizz", 88, 89, "FizzBuzz", 91, 92, "Fizz", 94, "Buzz", "Fizz", 97, 98,
|
20
|
+
"Fizz", "Buzz"]
|
21
|
+
|
22
|
+
## all strings version
|
23
|
+
## e.g. ["1", "2", "Fizz", ...]
|
24
|
+
FIZZBUZZES_1_TO_100_V2 = FIZZBUZZES_1_TO_100.map {|value| value.to_s }
|
25
|
+
|
26
|
+
|
27
|
+
class TestV1 < MiniTest::Test
|
28
|
+
include FizzBuzzer::V1
|
29
|
+
|
30
|
+
def test_fizzbuzz
|
31
|
+
assert_equal FIZZBUZZES_1_TO_100, fizzbuzz
|
32
|
+
end
|
33
|
+
end # class TestV1
|
34
|
+
|
35
|
+
|
36
|
+
## auto-generate test classes (see model/sample above)
|
37
|
+
## todo/fix: use a version without eval - possible? why? why not?
|
38
|
+
|
39
|
+
%w[V2a V2b V2c V2d V3 V4 V5 V6a V6b V7 V8 V9 V10 V11 V12a V12b].each do |name|
|
40
|
+
eval %Q(
|
41
|
+
class Test#{name} < MiniTest::Test
|
42
|
+
include FizzBuzzer::#{name}
|
43
|
+
|
44
|
+
def test_fizzbuzz
|
45
|
+
puts "running fizzbuzz #{name}..."
|
46
|
+
if %w[V4 V11].include? '#{name}'
|
47
|
+
# use all string version e.g. ["1", "2", "Fizz", ...]
|
48
|
+
assert_equal FIZZBUZZES_1_TO_100_V2, fizzbuzz
|
49
|
+
else
|
50
|
+
# use "mixed" tuple version e.g. [1, 2, "Fizz", ...]
|
51
|
+
assert_equal FIZZBUZZES_1_TO_100, fizzbuzz
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end)
|
55
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
###
|
4
|
+
# to run use
|
5
|
+
# ruby -I ./lib -I ./test test/test_version.rb
|
6
|
+
|
7
|
+
|
8
|
+
require 'helper'
|
9
|
+
|
10
|
+
|
11
|
+
class TestVersion < MiniTest::Test
|
12
|
+
|
13
|
+
def test_version
|
14
|
+
pp FizzBuzzer.version
|
15
|
+
pp FizzBuzzer.banner
|
16
|
+
pp FizzBuzzer.root
|
17
|
+
|
18
|
+
assert true ## (for now) everything ok if we get here
|
19
|
+
end
|
20
|
+
|
21
|
+
end # class TestVersion
|
metadata
CHANGED
@@ -1,15 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fizzbuzzer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gerald Bauer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-01-
|
11
|
+
date: 2018-01-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: noaidi
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: dry-matcher
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
13
41
|
- !ruby/object:Gem::Dependency
|
14
42
|
name: rdoc
|
15
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -59,6 +87,9 @@ files:
|
|
59
87
|
- bin/fizzbuzz
|
60
88
|
- lib/fizzbuzzer.rb
|
61
89
|
- lib/fizzbuzzer/version.rb
|
90
|
+
- test/helper.rb
|
91
|
+
- test/test_fizzbuzz.rb
|
92
|
+
- test/test_version.rb
|
62
93
|
homepage: https://github.com/rubylibs/fizzbuzzer
|
63
94
|
licenses:
|
64
95
|
- Public Domain
|