From: Josh Cheek Date: 2013-05-31T12:14:58+09:00 Subject: Re: Eloquent Ruby Kaprekar's Number --001a11c2af3ad612dc04ddfb0458 Content-Type: text/plain; charset=ISO-8859-1 On Thu, May 30, 2013 at 6:59 PM, Alphonse 23 wrote: > Which way is the eloquent ruby way to write this algorithm? > > Kaprekar Number > > 9 is a Kaprekar number since > 9 ^ 2 = 81 and 8 + 1 = 9 > > 297 is also Kaprekar number since > 297 ^ 2 = 88209 and 88 + 209 = 297. > > In short, for a Kaprekar number k with n-digits, if you square it and > add the right n digits to the left n or n-1 digits, the resultant sum is > k. > > !Spoiler Below! > > # way one > def kaprekar?(k) > ks = k**2 > lenf = (ks.to_s.length)-1 > lenh = (ks.to_s.length / 2) - 1 > a = ks.to_s[0..lenh].to_i > b = ks.to_s[lenh+1..lenf].to_i > k == (a+b) > end > > # way two > def kaprekar?(k) > a = (k**2).to_s[0..((((k**2).to_s.length) / 2) - 1)].to_i > b = (k**2).to_s[(((((k**2).to_s.length) / 2) - > 1)+1)..(((k**2).to_s.length)-1)].to_i > k == (a+b) > end > > # way three > def kaprekar?(k) > k == ((k**2).to_s[0..((((k**2).to_s.length) / 2) - > 1)].to_i)+((k**2).to_s[(((((k**2).to_s.length) / 2) - > 1)+1)..(((k**2).to_s.length)-1)].to_i) > end > > def simple_test(i) > if kaprekar?(i) == true then p "success on #{i}" else "fail on #{i}" > end > end > > simple_test(9) > simple_test(297) > > All three pass my tests, but which of the three would be considered the > most eloquent written ruby way? As in, which would be consider best > style-wise? The first takes up the most lines, but uses less nesting. > The last uses only one line but uses lots of nesting. > > -- > Posted via http://www.ruby-forum.com/. > > I'd write it like this: def kaprekar?(num) return false if num.zero? || num.to_s =~ /^10+$/ # IDK why 0 and 10.. are disallowed when 1 is allowed, but w/e square = (num * num).to_s midpoint = square.size / 2 (0..midpoint).any? do |separation_index| first = square[0...separation_index].to_i second = square[separation_index..-1].to_i num == first + second end end RSpec.configure { |config| config.fail_fast = true } # numbers taken from http://en.wikipedia.org/wiki/Kaprekar_number describe 'kaprekar number' do def check_kaprekars(kaprekars) (0..kaprekars.last).select { |n| kaprekar? n }.should == kaprekars end example 'quick match' do check_kaprekars [1, 9, 45, 55, 99, 297, 703, 999] end example 'medium match' do check_kaprekars [1, 9, 45, 55, 99, 297, 703, 999 , 2223, 2728, 4879, 4950, 5050, 5292, 7272, 7777, 9999] end example 'these should match' do check_kaprekars [1, 9, 45, 55, 99, 297, 703, 999 , 2223, 2728, 4879, 4950, 5050, 5292, 7272, 7777, 9999 , 17344, 22222, 38962, 77778, 82656, 95121, 99999, 142857, 148149, 181819, 187110, 208495, 318682, 329967, 351352, 356643, 390313, 461539, 466830, 499500, 500500, 533170] end end --001a11c2af3ad612dc04ddfb0458 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable On Thu, May 30, 2013 at 6:59 PM, Alphonse 23 <lists@ruby-forum.com= > wrote:
Which way is the eloquent ruby way to write this algorithm?

Kaprekar Number

9 is a Kaprekar number since
9 ^ 2 =3D 81 and 8 + 1 =3D 9

297 is also Kaprekar number since
297 ^ 2 =3D 88209 and 88 + 209 =3D 297.

In short, for a Kaprekar number k with n-digits, if you square it and
add the right n digits to the left n or n-1 digits, the resultant sum is k.

!Spoiler Below!

# way one
def kaprekar?(k)
=A0 ks =3D k**2
=A0 lenf =3D (ks.to_s.length)-1
=A0 lenh =3D (ks.to_s.length / 2) - 1
=A0 a =3D ks.to_s[0..lenh].to_i
=A0 b =3D ks.to_s[lenh+1..lenf].to_i
=A0 k =3D=3D (a+b)
end

# way two
def kaprekar?(k)
=A0 a =3D (k**2).to_s[0..((((k**2).to_s.length) / 2) - 1)].to_i
=A0 b =3D (k**2).to_s[(((((k**2).to_s.length) / 2) -
1)+1)..(((k**2).to_s.length)-1)].to_i
=A0 k =3D=3D (a+b)
end

# way three
def kaprekar?(k)
=A0 k =3D=3D ((k**2).to_s[0..((((k**2).to_s.length) / 2) -
1)].to_i)+((k**2).to_s[(((((k**2).to_s.length) / 2) -
1)+1)..(((k**2).to_s.length)-1)].to_i)
end

def =A0simple_test(i)
=A0 if kaprekar?(i) =3D=3D true then p "success on #{i}" else &qu= ot;fail on #{i}"
end
end

simple_test(9)
simple_test(297)

All three pass my tests, but which of the three would be considered the
most eloquent written ruby way? As in, which would be consider best
style-wise? The first takes up the most lines, but uses less nesting.
The last uses only one line but uses lots of nesting.

--
Posted via http://= www.ruby-forum.com/.



I'd writ= e it like this:

def kaprekar?(num)
=A0 re= turn false if num.zero? || num.to_s =3D~ /^10+$/ # IDK why 0 and 10.. are d= isallowed when 1 is allowed, but w/e
=A0 square =A0 =3D (num * num).to_s
=A0 midpoint =3D square.= size / 2
=A0 (0..midpoint).any? do |separation_index|
= =A0 =A0 first =A0=3D square[0...separation_index].to_i
=A0 =A0 se= cond =3D square[separation_index..-1].to_i
=A0 =A0 num =3D=3D first + second
=A0 end
end

RSpec.configure { |config| config.fail_fast =3D true }=

describe 'kaprekar number' do
=A0 def check_kaprekar= s(kaprekars)
=A0 =A0 (0..kaprekars.last).select { |n| kaprekar? n= }.should =3D=3D kaprekars
=A0 end
=A0=A0
=A0= example 'quick match' do
=A0 =A0 check_kaprekars [1, 9, 45, 55, 99, 297, 703, 999]
= =A0 end
=A0=A0
=A0 example 'medium match' do
=A0 =A0 check_kaprekars [1, 9, 45, 55, 99, 297, 703, 999 , 2223, 27= 28, 4879, 4950, 5050, 5292, 7272, 7777, 9999]
=A0 end
=A0=A0
=A0 example 'these should match= ' do
=A0 =A0 check_kaprekars [1, 9, 45, 55, 99, 297, 703, 999= , 2223, 2728, 4879, 4950, 5050, 5292, 7272, 7777, 9999 , 17344, 22222, 389= 62, 77778, 82656, 95121, 99999, 142857, 148149, 181819, 187110, 208495, 318= 682, 329967, 351352, 356643, 390313, 461539, 466830, 499500, 500500, 533170= ] =A0 =A0
=A0 end
end
--001a11c2af3ad612dc04ddfb0458--