Hi All,

My middle-school granddaughter posed the following challenge to me:

Within 10 minutes, Use the digits 3 to 7 in any order

to form a three-digit multiplicand and a two-digit multiplier

such that their product is minimal.

Out of curiosity as to whether my guess was right,

and with a view toward eliciting an interest in her

for Ruby programming, I wrote the program posted at

http://www.pastie.org/266447

The program reveals that I was wrong, but it took me about 40 lines of

code,

ignoring comments. That would probably overwhelm her. I was hoping

that

the code could be condensed with Ruby-isms. BTW, I left some put’s in

there

intended to give her a sense of the programs functionality.

Any ideas/suggestions?

Thanks in Advance,

Richard

From: RichardOnRails

# My middle-school granddaughter posed the following challenge to me:

cool daughter. me, only sons, very terrible when they fight each other

:))

# Within 10 minutes, Use the digits 3 to 7 in any order

# to form a three-digit multiplicand and a two-digit multiplier

# such that their product is minimal.

# Out of curiosity as to whether my guess was right,

# and with a view toward eliciting an interest in her

# for Ruby programming, I wrote the program posted at

# The program reveals that I was wrong, but it took me about 40 lines of

# code, ignoring comments. That would probably overwhelm her.

# I was hoping that the code could be condensed with Ruby-isms.

# BTW, I left some put’s in there

# intended to give her a sense of the programs functionality.

my try,

[email protected]:~$ cat test.rb

digits = [3,4,5,6,7]

min_product=1/0.0

min_multiplicand = 0

min_multiplier = 0

digits.permutation(3).each do |multiplicand_digits|

h,t,ones = multiplicand_digits

multiplicand = h*100 + t*10 + ones

(digits-multiplicand_digits).permutation(2).each do

|multiplier_digits|

t,ones = multiplier_digits

multiplier = t*10 + ones

prod = multiplicand * multiplier

if prod < min_product

min_product = prod

min_multiplicand = multiplicand

min_multiplier = multiplier

end

end

end

puts “#{min_multiplicand} * #{min_multiplier} = #{min_product}”

[email protected]:~$ ruby test.rb

467 * 35 = 16345

is that ok?

kind regards -botp

On Sep 4, 9:40 pm, RichardOnRails

[email protected] wrote:

for Ruby programming, I wrote the program posted athttp://www.pastie.org/266447

The program reveals that I was wrong, but it took me about 40 lines of

code,

ignoring comments. That would probably overwhelm her. I was hoping

that

the code could be condensed with Ruby-isms. BTW, I left some put’s in

there

intended to give her a sense of the programs functionality.

Any ideas/suggestions?

Here’s one solution that requires the ‘permutation’ gem:

====

require ‘rubygems’

require ‘permutation’

perm = Permutation.for((3…7).to_a)

min_product = 10**5

min_values = nil

perm.map do |p|

a = p.project

v1 = a[0, 3].to_s.to_i

v2 = a[3, 2].to_s.to_i

product = v1 * v2

if product < min_product

min_product = product

min_values = [v1, v2]

end

end

puts “#{min_values.first} * #{min_values.last} = #{min_product}”

====

Eric

====

Are you interested in on-site Ruby or Ruby on Rails training

that uses well-designed, real-world, hands-on exercises?

http://LearnRuby.co

I believe it can easily be seen that a number of form xy or abc where

xy and abc are not ordered in ascending order

cannot yield a solution hence:

ruby -e ‘p (3…7).map{|x|([*3…7]-[x]).map{|y| three=[*3…7]-[x,y];

two=[x,y]; [three.join.to_s.to_i * two.join.to_s.to_i, three,

two]}}.sort.first.sort.first’

[16345, [4, 6, 7], [3, 5]]

HTH

Robert

–

C’est véritablement utile puisque c’est joli.

Antoine de Saint Exupéry

2008/9/5 RichardOnRails [email protected]:

for Ruby programming, I wrote the program posted at

Any ideas/suggestions?

Here is a simple and stupid solution.

a = [3,4,5,6,7]

d = {}

(a[0,3].to_s.to_i … a.reverse[0,3].to_s.to_i).each{|i|

(a[0,2].to_s.to_i … a.reverse[0,2].to_s.to_i).each{|j|

d[[i,j]]=i*j if a.to_s==((i.to_s+j.to_s).split(//).sort.to_s)

}

}

p d.sort{|a,b| a[1]<=>b[1]}[0]

Regards,

Park H.

On Sep 5, 1:34 am, “Eric I.” [email protected] wrote:

to form a three-digit multiplicand and a two-digit multiplier

the code could be condensed with Ruby-isms. BTW, I left some put’s in

require ‘permutation’

product = v1 * v2

Eric

====

Are you interested in on-site Ruby or Ruby on Rails training

that uses well-designed, real-world, hands-on exercises?http://LearnRuby.co

Thanks, Eric,

I should have thought of looking for that. I certainly know I was

analyzing 5! permutations.

My granddaughter is much more likely to delve into that a little

ways. I doesn’t look so intimidating

Best wishes,

Richard

On Sep 5, 7:34 am, “Eric I.” [email protected] wrote:

On Sep 4, 9:40 pm, RichardOnRails

Any ideas/suggestions?

Here’s one solution that requires the ‘permutation’ gem:

Ruby 1.8.7 and 1.9 has Array#permutation:

(3…7).to_a.permutation.sort_by { |a| a[0…2].to_s.to_i *

a[3…4].to_s.to_i }.first

Golf anyone?

Lars

On Fri, Sep 5, 2008 at 9:29 AM, Lars C. [email protected]

wrote:

Golf anyone?

(i) A trivial trick is to replace (3…7).to_a with [*3…7]

(ii) sort_by( &blk ).first can be replaced with min_by( &blk )

## R

C’est véritablement utile puisque c’est joli.

Antoine de Saint Exupéry

On Sep 4, 11:40 pm, RichardOnRails

[email protected] wrote:

for Ruby programming, I wrote the program posted athttp://www.pastie.org/266447

Thanks in Advance,

Richard

min = 1_000_000

answer = nil

“34567”.upto(“76543”){|s|

next if s !~ /^[3-7]+$/

next if s.split("").uniq.size < 5

m1,m2 = s[0,3].to_i, s[3,2].to_i

if m1 * m2 < min

min = m1 * m2

answer = m1, m2

end

}

p answer

p (“34567”…“76543”).select{|s|

s =~ /^[3-7]+$/ and s.split("").uniq.size == 5 }.

sort_by{|s| s[0,3].to_i * s[3,2].to_i }.first

On Fri, Sep 5, 2008 at 2:26 AM, Robert D. [email protected]

wrote:

I believe it can easily be seen that a number of form xy or abc where

xy and abc are not ordered in ascending order

cannot yield a solution hence:

Building on that observation:

#!/usr/bin/env ruby

digits = [3, 4, 5, 6, 7]

digits.sort!

multiplier = “#{digits.shift}”

multiplicand = “#{digits.shift}”

multiplier << “#{digits.shift}”

multiplicand << “#{digits.shift}”

multiplicand << “#{digits.shift}”

product = multiplicand.to_i * multiplier.to_i

puts “#{multiplicand} * #{multiplier} = #{product}”

# => 467 * 35 = 16345

On Sep 5, 3:30 am, Lars C. [email protected] wrote:

a[3…4].to_s.to_i }.first

Golf anyone?

Lars

Hi Lars,

If this were the Olympics for succinct Ruby, you’d get the Gold!!

Thanks for this expression.

Ruby 1.8.7 and 1.9 has Array#permutation:

I’m running ruby 1.8.6, so of course “(3…7).to_a.permutation” failed

My work-around (which produced a correct result) is:

a=[]; Permutation.new(5).each { |p| a << ((p.value.to_s.to_i +

3333).to_s)

=> 34567, 34576, 34657, 34675, 34756, 34765, 35467, [snip]

a.sort_by { |a| (a[0…2].to_s.to_i )*(a[3…4].to_s.to_i) }.first

=> 46735

Note that I compensated for the (3…7) … construct not working by

adding 33333 to each permutation.

Also, I had to fix one blemish: parentheses were needed around the

multiplicative factors; a radix diagnostic was issued without them…

Maybe it’s another 1.8.6 problem

Again, thanks for this neat construct. I’m going to introduce to my

granddaughter as a first step of a programmed solution to the problem

she presented. But then, I’ll admit it takes a Ruby pro to achieve

that level of brevity. I’ll follow that with my more mundane approach

and see whether she’ll hang in there until achieving a glimmer of

insight into Ruby programming.

If you have any more enlightenment on these issues, I’d be pleased to

receive them.

Best wishes,

Richard

Is using a computer a requirement?

The simplest method to me seems (building on what Robert D. wrote) is

to

recognize that you want the lowest possible numbers for both the

multiplier

and multiplicand, so you only need to test these 4 pairs of numbers:

356 x 47

367 x 46

456 x 37

467 x 35

Of course, trying to write a computer program to solve it is more

challenging.

## Randy K.

“I didn’t have time to write a short letter, so I created a video

instead.”–with apologies to Cicero, et.al.