The Man or Boy Recursion Test

Hello,

being new to ruby I try to understand the language. In a different
context I came across the following:

Out of curiosity I tried to write an equivalent piece of code in ruby
but apparently my depth of knowledge is not good enough.

Is there anyone who could enlighten me?

Thanks and Best Regards

Werner Dahn

Werner wrote:

Is there anyone who could enlighten me?

Thanks and Best Regards

Werner Dahn

Man or boy test

def a(k, x1, x2, x3, x4, x5)
b ||= Proc.new { k -= 1; a(k, b, x1, x2, x3, x4) }
return k <= 0 ? x4[] + x5[] : b[]
end

puts a(10, Proc.new {1}, Proc.new {-1}, Proc.new {-1}, Proc.new {1},
Proc.new {0})

Man or boy test

def a(k, x1, x2, x3, x4, x5)
b ||= Proc.new { k -= 1; a(k, b, x1, x2, x3, x4) }
return k <= 0 ? x4[] + x5[] : b[]
end

puts a(10, Proc.new {1}, Proc.new {-1}, Proc.new {-1}, Proc.new {1},
Proc.new {0})

Thank you very much! I am impressed.
Best Regards
Werner Dahn

Lloyd L. wrote:

b ||= Proc.new { k -= 1; a(k, b, x1, x2, x3, x4) }
return k <= 0 ? x4[] + x5[] : b[]
end

puts a(10, Proc.new {1}, Proc.new {-1}, Proc.new {-1}, Proc.new {1},
Proc.new {0})

Nice post, Tim. I tested it and, when it gave the correct answer, I
decided to share it with the world.

Man or boy test - Wikipedia

Sweet!

I realized last night that the ||= is superfluous. A simple assignment
is enough.

b = Proc.new { k -= 1; a(k, b, x1, x2, x3, x4) }

On Nov 11, 2007 9:21 AM, Tim H. [email protected] wrote:

I realized last night that the ||= is superfluous. A simple assignment
is enough.

b = Proc.new { k -= 1; a(k, b, x1, x2, x3, x4) }

Right, because b will always be nil here, it’s a local variable so
there’s a new b for each resursion. Otherwise it would kind of defeat
what the Man Or Boy example is trying to illustrate.

And it can be made a little shorter, and more computer sciency , by
replacing all those "Proc.new"s with "lambda"s.

Man or boy test

def a(k, x1, x2, x3, x4, x5)
b = lambda { k -= 1; a(k, b, x1, x2, x3, x4) }
return k <= 0 ? x4[] + x5[] : b[]
end

puts a(10, lambda {1}, lambda {-1}, lambda {-1}, lambda {1}, lambda {0})


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

Since I posted your ruby version, there have been more posts in C,
haskell, smalltalk. I sense that a snowball has started an avalanche!
:slight_smile:

On Nov 11, 2007, at 9:59 AM, Rick DeNatale wrote:

what the Man Or Boy example is trying to illustrate.
puts a(10, lambda {1}, lambda {-1}, lambda {-1}, lambda {1}, lambda
{0})

Surely we can eliminate the ‘return’ too and make it even shorter:

def a(k, x1, x2, x3, x4, x5)
b = lambda { k -= 1; a(k, b, x1, x2, x3, x4) }
k <= 0 ? x4[] + x5[] : b[]
end

puts a(10, lambda {1}, lambda {-1}, lambda {-1}, lambda {1}, lambda {0})

Regards, Morton

Lloyd L. wrote:

Since I posted your ruby version, there have been more posts in C,
haskell, smalltalk. I sense that a snowball has started an avalanche!
:slight_smile:

Well, the Ruby version certainly wins the Man-or-boy-test-golf contest.
But I’ve been programming in C for over 20 years and I can say with
authority that whoever did the C version has C-coding cojones the size
of hubcaps.

On Nov 11, 2007 3:18 PM, Tim H. [email protected] wrote:

Well, the Ruby version certainly wins the Man-or-boy-test-golf contest.
But I’ve been programming in C for over 20 years and I can say with
authority that whoever did the C version has C-coding cojones the size
of hubcaps.

I was surprised and amused to find that there was already an PL/I
implementation in the wikipedia article.

A much (unnecessarily) maligned language deep in my past.


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

Rick DeNatale wrote:

A much (unnecessarily) maligned language deep in my past.

Ummmm…before I wrote C I wrote PL/I. Not a lot, but enough to be able
to use the PL/I version of the Man or Boy test to figure out how to code
the Ruby version.

Tim H. wrote:

Werner wrote:

Is there anyone who could enlighten me?

Thanks and Best Regards

Werner Dahn

Man or boy test

def a(k, x1, x2, x3, x4, x5)
b ||= Proc.new { k -= 1; a(k, b, x1, x2, x3, x4) }
return k <= 0 ? x4[] + x5[] : b[]
end

puts a(10, Proc.new {1}, Proc.new {-1}, Proc.new {-1}, Proc.new {1},
Proc.new {0})

Nice post, Tim. I tested it and, when it gave the correct answer, I
decided to share it with the world.

On Nov 11, 2007 6:42 PM, Tim H. [email protected] wrote:

A much (unnecessarily) maligned language deep in my past.

Ummmm…before I wrote C I wrote PL/I. Not a lot, but enough to be able
to use the PL/I version of the Man or Boy test to figure out how to code
the Ruby version.

Sometimes I feel my age.

Last week I gave a talk to the local “agile” meetup group about “A
History of Agility” When I introduced myself I said that I started
programming in College in 1970. Out of the 15-20 people in the
audience, only about 3-4 were born then, some by only a few months.


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

Morton G. wrote:

$RecursionLimit = 1665; (* anything less fails for k0 = 10 *)

Regards, Morton

Another one for Wikipedia. I guess we owe Werner (the OP) a big “thanks”
for introducing such an interesting thread. Thanks, Werner!

Morton,

Your post did not have the formatting that the other languages did. I
added that for you so the other kids would not make fun of your code.
:slight_smile: I did not use any language coloring as the wiki does not recognize
mathmatica.

I hope that you do not mind.

On Nov 11, 2007, at 6:42 PM, Tim H. wrote:

Ummmm…before I wrote C I wrote PL/I. Not a lot, but enough to be
able to use the PL/I version of the Man or Boy test to figure out
how to code the Ruby version.

Interesting. I used your Ruby version to figure out how to code it in
Mathematica. I was able to make a fairly direct translation.

$RecursionLimit = 1665; (* anything less fails for k0 = 10 *)

a[k0_, x1_, x2_, x3_, x4_, x5_] := Module[{k, b },
k = k0;
b = (k–; a[k, b, x1, x2, x3, x4]) &;
If[k <= 0, x4[] + x5[], b[]]]

a[10, 1 &, -1 &, -1 &, 1 &, 0 &] (* => -67 *)

Note how compact the Mathematica notation for the thunks is.

Regards, Morton

On Nov 11, 2007, at 9:50 PM, Lloyd L. wrote:

Morton,

Your post did not have the formatting that the other languages
did. I
added that for you so the other kids would not make fun of your code.
:slight_smile: I did not use any language coloring as the wiki does not recognize
mathmatica.

I’m glad you fixed it up. That was my first post on Wikipedia. I
tried , but as you pointed out, that
doesn’t work. I didn’t know that was the best
alternative. But I do now :). Thanks.

Regards, Morton

On Nov 11, 2007, at 8:46 PM, Tim H. wrote:

k = k0;
b = (k–; a[k, b, x1, x2, x3, x4]) &;
If[k <= 0, x4[] + x5[], b[]]]
a[10, 1 &, -1 &, -1 &, 1 &, 0 &] (* => -67 *)

Note how compact the Mathematica notation for the thunks is.
Regards, Morton

Another one for Wikipedia.

I’ve posted it there. I like the Smalltalk example also – very
concise yet still readable.

I guess we owe Werner (the OP) a big “thanks” for introducing such
an interesting thread. Thanks, Werner!

Indeed.

Regards, Morton