fizzbuzzer 0.1.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|