Chinese people do not like numbers with a digit 4 in it. I am going to implement a membership program with membership numbers not including the digit 4, say:
number = 3
number.next.has4?
=> true
how the has4?
method can be done (efficiently)?
** EDIT
Thanks for the answers, I performed simple benchmarking as a reference:
class Fixnum
def has4a?
String(self).index('4') != nil
end
end
class Fixnum
def has4b?
self.to_s[/4/]
end
end
number = 3
puts Time.now
n = 0
while n < 1000000
number.next.has4a?
n += 1
end
puts Time.now
n = 0
while n < 1000000
number.next.has4b?
n += 1
end
puts Time.now
the result on my PC shows index
is faster than regex
:
> ruby has4.rb
Tue May 11 18:36:04 +0800 2010
Tue May 11 18:36:05 +0800 2010
Tue May 11 18:36:11 +0800 2010
Edited below to include all 4 solutions, and make it easy to see duration of each:
class Fixnum
def has4a?
String(self).index('4') != nil
end
end
class Fixnum
def has4b?
self.to_s[/4/]
end
end
class Fixnum
def has4c?
temp = self
while temp > 0
if (temp % 10) == 4
return true
end
temp /= 10
end
false
end
end
class Fixnum
def digits
d, m = divmod(10)
d > 0 ? d.digits + [m] : [m]
end
def has4d?
self.digits.member?(4)
end
end
before_A = Time.now
n = 0
has4 = 0
no4 = 0
while n < 5000000
has4 += 1 if n.has4a?
no4 += 1 if !n.has4a?
n += 1
end
after_A = Time.now
puts after_A, has4, no4
puts "A duration: " + (after_A - before_A).to_s
before_B = Time.now
n = 0
has4 = 0
no4 = 0
while n < 5000000
has4 += 1 if n.has4b?
no4 += 1 if !n.has4b?
n += 1
end
after_B = Time.now
puts after_B, has4, no4
puts "B duration: " + (after_B - before_B).to_s
before_C = Time.now
n = 0
has4 = 0
no4 = 0
while n < 5000000
has4 += 1 if n.has4c?
no4 += 1 if !n.has4c?
n += 1
end
after_C = Time.now
puts after_C, has4, no4
puts "C duration: " + (after_C - before_C).to_s
before_D = Time.now
n = 0
has4 = 0
no4 = 0
while n < 5000000
has4 += 1 if n.has4d?
no4 += 1 if !n.has4d?
n += 1
end
after_D = Time.now
puts after_D, has4, no4
puts "D duration: " + (after_D - before_D).to_s
result (ruby 1.8.7 (2009-06-12 patchlevel 174) [i486-linux] on Karmic). Feel free to post data from other machines.
Tue May 11 16:25:38 -0400 2010
2874236
2125764
A duration: 35.375095
Tue May 11 16:26:19 -0400 2010
2874236
2125764
B duration: 40.659878
Tue May 11 16:27:38 -0400 2010
2874236
2125764
C duration: 79.12419
Tue May 11 16:31:28 -0400 2010
2874236
2125764
D duration: 229.573483
sorry for my previous typo and thanks Matthew Flaschen for fixing it. here's my benchmark:
>ruby has4.rb
Wed May 12 09:14:25 +0800 2010
2874236
2125764
A duration: 18.186685
Wed May 12 09:15:06 +0800 2010
2874236
2125764
B duration: 40.388816
Wed May 12 09:15:38 +0800 2010
2874236
2125764
C duration: 32.639162
Wed May 12 09:18:08 +0800 2010
2874236
2125764
D duration: 150.024529
>ruby -v
ruby 1.8.7 (2010-01-10 patchlevel 249) [i386-mingw32]