Feature #3591
closedAdding Numeric#divisor? (Have working implementation)
Description
=begin
On the 'duckinator' branch of my fork of ruby on github, I have added Numeric#divisor?:
num.divisor?(other)
is the same as:
(num % other == 0)
Example usage:
4.divisor?(2) #=> true
1.divisor?(2) #=> false
2.4.divisor?(1.2) #=> true
2.4.divisor?(1.3) #=> false
126.divisor?(9) #=> true
I think this would be a very nice feature to add, and would make code using the old (num % other == 0) method much cleaner and easier to understand.
There is a unified diff of it: http://gist.github.com/raw/484144/07b1a6e696cd9301e658ccbc8f90dfcd4d4ef3f1/Numeric_divisor.patch
The original commits can be seen here:
http://github.com/RockerMONO/ruby/commit/f7959f964cb0bf38418904ccb5643db6b689d29c -- First attempt, only worked with Integers
http://github.com/RockerMONO/ruby/commit/12376a6bb1c3ffbd4b470850dd758e2dcd783dda -- Second attempt, should work with anything derived from Numeric that can be used as (num % other == 0)
=end
Updated by shyouhei (Shyouhei Urabe) over 14 years ago
I think this would be a very nice feature to add, and would make code using the old (num % other == 0) method much cleaner and easier to understand.
+1, I have written tons of such code.
Updated by nobu (Nobuyoshi Nakada) over 14 years ago
Hi,
At Wed, 21 Jul 2010 15:28:35 +0900,
Nick Markwell wrote in [ruby-core:31385]:
Example usage:
4.divisor?(2) #=> true
1.divisor?(2) #=> false
2.4.divisor?(1.2) #=> true
2.4.divisor?(1.3) #=> false
126.divisor?(9) #=> true
I suspect if Float#divisor?
makes a sense, and the name doesn't feel appropriate very much. The first example seems ‘four is a divisor of two?’. What about ‘4.multiple?(2)’?
--
Nobu Nakada
Updated by duckinator (Marie Markwell) over 14 years ago
I agree, Numeric#multiple?
seems more appropriate.
Different patch providing Numeric#multiple?
with the same usage: http://gist.github.com/raw/484193/65ffa0cb48ca4b838900dc105b246ced5bc0ac80/Numeric_multiple.patch
Updated by injekt (Lee Jarvis) over 14 years ago
On 21 July 2010 08:22, Nobuyoshi Nakada nobu@ruby-lang.org wrote:
Hi,
At Wed, 21 Jul 2010 15:28:35 +0900,
Nick Markwell wrote in [ruby-core:31385]:Example usage:
4.divisor?(2) #=> true
1.divisor?(2) #=> false
2.4.divisor?(1.2) #=> true
2.4.divisor?(1.3) #=> false
126.divisor?(9) #=> trueI suspect if
Float#divisor?
makes a sense, and the name doesn't feel appropriate very much. The first example seems ‘four is a divisor of two?’. What about ‘4.multiple?(2)’?--
Nobu Nakada
+1 for multiple?
Updated by nobu (Nobuyoshi Nakada) over 14 years ago
Hi,
At Wed, 21 Jul 2010 16:35:49 +0900,
Nick Markwell wrote in [ruby-core:31391]:
I agree,
Numeric#multiple?
seems more appropriate.
Or Numeric#divisible?
, I'm not sure which is better. Maybe
define both?
And, it's arguable about inexact numbers, I guess.
--
Nobu Nakada
Updated by hasari (Hiro Asari) over 14 years ago
On Jul 21, 2010, at 3:55 AM, Nobuyoshi Nakada wrote:
Hi,
At Wed, 21 Jul 2010 16:35:49 +0900,
Nick Markwell wrote in [ruby-core:31391]:I agree,
Numeric#multiple?
seems more appropriate.Or
Numeric#divisible?
, I'm not sure which is better. Maybe
define both?And, it's arguable about inexact numbers, I guess.
--
Nobu Nakada
"divisible" and "divisor" should not mean the same thing, and I vote for Numeric#divisible?
(or more verbosely, Numeric#divisible_by?
) for the present concept under discussion.
When I see "10.divisor? 5
", it reads to me "Is 10 a divisor of 5?", just like "h.kind_of? Hash
" reads "Is h a kind of Hash?".
On the other hand, "10.divisible? 5
" reads "Is 10 divisible by 5?".
Updated by duckinator (Marie Markwell) over 14 years ago
Toss out some more ideas/opinions, I'll make a patch for the one that the most people agree with :)
Updated by akr (Akira Tanaka) over 13 years ago
- Project changed from Ruby to Ruby master
Updated by mame (Yusuke Endoh) over 12 years ago
- Description updated (diff)
- Status changed from Open to Assigned
- Assignee set to mrkn (Kenta Murata)
Updated by duckinator (Marie Markwell) over 12 years ago
I ran across this again, and decided to just implement it as Numeric#divisible_by?
, since that makes the most sense to me.
Branch on github: https://github.com/duckinator/ruby/compare/feature/numeric_divisible_by
Patch: https://github.com/duckinator/ruby/compare/feature/numeric_divisible_by.patch
Diff: https://github.com/duckinator/ruby/compare/feature/numeric_divisible_by.diff
Updated by marcandre (Marc-Andre Lafortune) over 12 years ago
Hi,
nobu (Nobuyoshi Nakada) wrote:
And, it's arguable about inexact numbers, I guess.
Agreed. divisible_by makes sense only for Integers. Float, BigDecimal, Complex... and Rational which can be exact, for them it does not make sense.
I am not convinced about the need for this. There is already odd?
or even?
, and for other divisors I feel usage is much less frequent.
In those cases 42 % 5 == 0
is shorter to write and faster than 42.divisible_by?(5)
. Unless we talk about big integers in which case there might be an optimization possible, but I feel that falls outside of the core of Ruby.
Updated by duckinator (Marie Markwell) over 12 years ago
Regarding Float, BigDecimal, Complex, and Rational: Agreed.
Regarding 42 % 5 == 0
, I somewhat agree: it can be accomplished now, and it is not done often (excluding x % 2 == 0), so it may not be a good fit for core Ruby. When splitting it out so it does not cover things it does not apply to, it'd likely become more complex than it is worth dealing with.
Updated by naruse (Yui NARUSE) over 12 years ago
We talked about this before, and find the name Numeric#factor?(n).
Updated by marcandre (Marc-Andre Lafortune) over 12 years ago
I still curious as to actual use cases. Looking at Rails' code, there is one instance of this, and followed immediately by the more general foo % bar == baz
(when implementing nth_child
).
Also, I see that ActiveSupport already has 42.multiple_of?(2)
, and that's a good name too. It's not used in Rails itself, btw.
naruse (Yui NARUSE) wrote:
We talked about this before, and find the name Numeric#factor?(n).
2 is a factor of 4, so which is true: 4.factor?(2) or 2.factor?(4) ? There is no ambiguity with divisible?
or multiple_of?
Updated by marcandre (Marc-Andre Lafortune) over 12 years ago
- Category set to core
- Assignee changed from mrkn (Kenta Murata) to matz (Yukihiro Matsumoto)
Updated by mame (Yusuke Endoh) about 12 years ago
- Target version set to 2.6
Updated by mame (Yusuke Endoh) about 7 years ago
marcandre (Marc-Andre Lafortune) wrote:
I still curious as to actual use cases. Looking at Rails' code, there is one instance of this, and followed immediately by the more general
foo % bar == baz
(when implementingnth_child
).
With regard to this feature, there is no room for doubt about use cases, I think. I don't know Rails, but this method would be frequently useful when enjoying mathematical programming. I can find many actual use cases in my programs for Project Euler:
$ egrep "% \w+ == 0" ~/work/peuler/*.rb | wc -l
86
Of course, this feature is NOT indispensable, though.
Updated by mame (Yusuke Endoh) about 7 years ago
Summary:
- Name candidates are:
-
divisor?
(the original proposal) divisible?
-
divisible_by?
(OP's final choice) multiple?
-
multiple_of?
(ActiveSupport's choice) factor?
-
- There is no objection to
Integer#divisor?
. ButFloat#divisor?
is arguable.
Updated by matz (Yukihiro Matsumoto) about 7 years ago
- Status changed from Assigned to Rejected
Use-case? Is it more useful than n % m == 0
?
Matz.
Updated by e8c (Viktor Reznov) almost 2 years ago
matz (Yukihiro Matsumoto) wrote in #note-19:
Is it more useful than
n % m == 0
?
Yes, statement n .has_divisor? m
(or m .divisor_of? n
) has 3 parts instead of 5, and gives a direct answer to the question.
The "problem": https://leetcode.com/problems/count-the-digits-that-divide-a-number/
Two solutions:
def count_digits(n) = n.digits.count { n % _1 == 0 }
def count_digits(n) = n.digits.count { _1.divisor_of?(n) }
The first is shorter, but the second is clearer.
Updated by e8c (Viktor Reznov) almost 2 years ago
e8c (Viktor Reznov) wrote in #note-20:
Two solutions:
3rd:
def count_digits(n) = n.digits.count { n.modulo(_1).zero? }