[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Mutually-Recursive Functions

Revence Kalibwani

6/7/2007 8:33:00 AM

Ruby doesn't seem to do mutually-recursive functions. Or is it some
particular idiom I know not about? I am using an array to implement
them, and it stinks a bit. Any way to do it?

Thanks.

Revence

15 Answers

Dan Zwell

6/7/2007 9:24:00 AM

0

Revence Kalibwani wrote:
> Ruby doesn't seem to do mutually-recursive functions. Or is it some
> particular idiom I know not about? I am using an array to implement
> them, and it stinks a bit. Any way to do it?
>
> Thanks.
>
> Revence
>
>

Could you show us what you mean? I for one do not know what a mutually
recursive function is.

Dan

Revence Kalibwani

6/7/2007 10:03:00 AM

0

Dan Zwell wrote:
> Revence Kalibwani wrote:
>> Ruby doesn't seem to do mutually-recursive functions. Or is it some
>> particular idiom I know not about? I am using an array to implement
>> them, and it stinks a bit. Any way to do it?
>>
>
> Could you show us what you mean? I for one do not know what a mutually
> recursive function is.
I have written it all out. Now, since I'm fresh to this list, I dunno if
attachments show. Indulge me, please. I'll paste all the code (it's a
bit literate') and also attach it (as mutrec.rb). :-)
By the way, ruby -v is: 1.8.5

#! /usr/bin/ruby
# Two examples of a mutually-recursive function.

# These are functions that depend on each other - recursively.

# even and odd:
# If a number is zero, then it is even. Otherwise, it is even if the one before it is odd.
# A number is odd if it is not zero. Otherwise, it is odd if it the one before it is even. :o)
# This is the canonical example.
def my_even(x)
x == 0 or odd(x - 1)
end

def my_odd(x)
x != 0 and even(x - 1)
end

# That is, of course, a silly way to implemet even and odd. So, let me give you the problem
# I was trying to solve.
#
# To generate the lettering similar to that above the spreadsheet columns, where the first
# column has 'A', the second 'B' ... the twenty-sixth 'Z'. Then, the twenty-seventh has
# 'AA', the twenty-eight has 'AB', and so on. This is recursive by nature. Here is what
# should work:


Letters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
'U', 'V', 'W', 'X', 'Y', 'Z']

def alphabetise(pos)
pile_letters(0, pos) # LABEL: 1
end
def pile_chars(thus_far, pos)
len = Letters.length
if pos < len then
Letters[pos]
else
alphabeticise(thus_far) + pile_chars(thus_far + 1, pos - len)
end

end

# Labels:
# 1. That's where it fails. I guess 'tis because the scope is searched backwards
# from that point.
# OCaml, for example, requires me to put the `and' keyword between mutually-recursive
# functions. I'd not mind doing that in Ruby, but I don't know how. n00b. ;-)
# Also, it works in That Other Language.
#

# Now, the (dirty) solution I found. I think you will help me with how to get it done
# without all this voodoo:

Funcs = [lambda do |pos|
Funcs[1].call(0, pos)
end,
lambda do |thus_far, pos|
len = Letters.length
if pos < len then
Letters[pos]
else
Funcs[0].call(thus_far) + Funcs[1].call(thus_far + 1, pos - len)
end
end]

def main(args)
puts Funcs[0].call((26 * 26) - 1) # Prints A to Z. But see how un-Rubyistic it is!
# puts alphabetise(675) # This fails.
# if my_even 4 and my_odd 5 then 0 else 1 end # This also fails
0
end

exit(main(ARGV))


#! /usr/bin/ruby
# Two examples of a mutually-recursive function.

# These are functions that depend on each other - recursively.

# even and odd:
# If a number is zero, then it is even. Otherwise, it is even if the one before it is odd.
# A number is odd if it is not zero. Otherwise, it is odd if it the one before it is even. :o)
# This is the canonical example.
def my_even(x)
x == 0 or odd(x - 1)
end

def my_odd(x)
x != 0 and even(x - 1)
end

# That is, of course, a silly way to implemet even and odd. So, let me give you the problem
# I was trying to solve.
#
# To generate the lettering similar to that above the spreadsheet columns, where the first
# column has 'A', the second 'B' ... the twenty-sixth 'Z'. Then, the twenty-seventh has
# 'AA', the twenty-eight has 'AB', and so on. This is recursive by nature. Here is what
# should work:


Letters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
'U', 'V', 'W', 'X', 'Y', 'Z']

def alphabetise(pos)
pile_letters(0, pos) # LABEL: 1
end
def pile_chars(thus_far, pos)
len = Letters.length
if pos < len then
Letters[pos]
else
alphabeticise(thus_far) + pile_chars(thus_far + 1, pos - len)
end

end

# Labels:
# 1. That's where it fails. I guess 'tis because the scope is searched backwards
# from that point.
# OCaml, for example, requires me to put the `and' keyword between mutually-recursive
# functions. I'd not mind doing that in Ruby, but I don't know how. n00b. ;-)
# Also, it works in That Other Language.
#

# Now, the (dirty) solution I found. I think you will help me with how to get it done
# without all this voodoo:

Funcs = [lambda do |pos|
Funcs[1].call(0, pos)
end,
lambda do |thus_far, pos|
len = Letters.length
if pos < len then
Letters[pos]
else
Funcs[0].call(thus_far) + Funcs[1].call(thus_far + 1, pos - len)
end
end]

def main(args)
puts Funcs[0].call((26 * 26) - 1) # Prints A to Z. But see how un-Rubyistic it is!
# puts alphabetise(675) # This fails.
# if my_even 4 and my_odd 5 then 0 else 1 end # This also fails
0
end

exit(main(ARGV))

Bruno Michel

6/7/2007 10:29:00 AM

0

For the even and odd example, it works if you remplace odd by my_odd in
the my_even function, and even by my_even in the my_odd function. Like this:

def my_even(x)
x == 0 or my_odd(x - 1)
end

def my_odd(x)
x != 0 and my_even(x - 1)
end

my_even(10) #=> true


Hope this helps.

--
Bruno Michel

Revence Kalibwani

6/7/2007 10:36:00 AM

0

Bruno Michel wrote:
> For the even and odd example, it works if you remplace odd by my_odd
> in the my_even function, and even by my_even in the my_odd function.
> Like this:
>
> def my_even(x)
> x == 0 or my_odd(x - 1)
> end
>
> def my_odd(x)
> x != 0 and my_even(x - 1)
> end
>
> my_even(10) #=> true
>
>
> Hope this helps.
>
Yeah. Solved it. Lots of typos. That happens under stress. Thanks a lot,
everyone. :-)


Jano Svitok

6/7/2007 10:42:00 AM

0

On 6/7/07, Revence Kalibwani <revence27@gmail.com> wrote:
> Bruno Michel wrote:
> > For the even and odd example, it works if you remplace odd by my_odd
> > in the my_even function, and even by my_even in the my_odd function.
> > Like this:
> >
> > def my_even(x)
> > x == 0 or my_odd(x - 1)
> > end
> >
> > def my_odd(x)
> > x != 0 and my_even(x - 1)
> > end
> >
> > my_even(10) #=> true
> >
> >
> > Hope this helps.
> >
> Yeah. Solved it. Lots of typos. That happens under stress. Thanks a lot,
> everyone. :-)

For this very case, String#succ and String.succ! might be helpful
('A'.succ -> 'B', 'Z'.succ -> 'AA').

Harry Kakueki

6/7/2007 11:00:00 AM

0

On 6/7/07, Revence Kalibwani <revence27@gmail.com> wrote:
>
> # That is, of course, a silly way to implemet even and odd. So, let me give you the problem
> # I was trying to solve.
> #
> # To generate the lettering similar to that above the spreadsheet columns, where the first
> # column has 'A', the second 'B' ... the twenty-sixth 'Z'. Then, the twenty-seventh has
> # 'AA', the twenty-eight has 'AB', and so on. This is recursive by nature. Here is what
> # should work:
>
>
>
>

I may be missing something, but..

If you just want to do that then try something like this.

arr = []
("a".."ff").each {|x| arr << x}
p arr

Harry


--

A Look into Japanese Ruby List in English
http://www.ka...

dblack

6/7/2007 11:06:00 AM

0

Harry Kakueki

6/7/2007 11:22:00 AM

0

On 6/7/07, dblack@wobblini.net <dblack@wobblini.net> wrote:
> Hi --
>
> On Thu, 7 Jun 2007, Harry Kakueki wrote:
>
> >
> > I may be missing something, but..
> >
> > If you just want to do that then try something like this.
> >
> > arr = []
> > ("a".."ff").each {|x| arr << x}
> > p arr
>
> Work-saving tip for the day:
>
> p [*"a".."ff"]
>
> :-)
>
>
> David
>
> --
> Q. What is THE Ruby book for Rails developers?
> A. RUBY FOR RAILS by David A. Black (http://www.manning...)
> (See what readers are saying! http://www.r.../r...)
> Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
> A. Ruby Power and Light, LLC (http://www.r...)
>
>
I was going to do this.

p ("a".."ff").each {|x| p x}

But I didn't want it to run off the screen.
But you did the same thing in a better way.
Thanks for the tip.

Harry


--

A Look into Japanese Ruby List in English
http://www.ka...

Harry Kakueki

6/7/2007 12:08:00 PM

0

On 6/7/07, Harry Kakueki <list.push@gmail.com> wrote:
> On 6/7/07, dblack@wobblini.net <dblack@wobblini.net> wrote:
> >
> > Work-saving tip for the day:
> >
> > p [*"a".."ff"]
> >
> > :-)
> >
> >
> > David
> >
> > --
> > Q. What is THE Ruby book for Rails developers?
> > A. RUBY FOR RAILS by David A. Black (http://www.manning...)
> > (See what readers are saying! http://www.r.../r...)
> > Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
> > A. Ruby Power and Light, LLC (http://www.r...)
> >
> >
> I was going to do this.
>
> p ("a".."ff").each {|x| p x}
>
> Harry
>
Oops.
Don't need 2 p's.

("a".."ff").each {|x| p x}

Harry


--

A Look into Japanese Ruby List in English
http://www.ka...

ara.t.howard

6/7/2007 1:32:00 PM

0


On Jun 7, 2007, at 5:06 AM, dblack@wobblini.net wrote:

> Hi --
>
> On Thu, 7 Jun 2007, Harry Kakueki wrote:
>
>> On 6/7/07, Revence Kalibwani <revence27@gmail.com> wrote:
>>> # That is, of course, a silly way to implemet even and odd.
>>> So, let me give you the problem
>>> # I was trying to solve.
>>> #
>>> # To generate the lettering similar to that above the
>>> spreadsheet columns, where the first
>>> # column has 'A', the second 'B' ... the twenty-sixth 'Z'.
>>> Then, the twenty-seventh has
>>> # 'AA', the twenty-eight has 'AB', and so on. This is
>>> recursive by nature. Here is what
>>> # should work:
>>
>> I may be missing something, but..
>>
>> If you just want to do that then try something like this.
>>
>> arr = []
>> ("a".."ff").each {|x| arr << x}
>> p arr
>
> Work-saving tip for the day:
>
> p [*"a".."ff"]
>
> :-)
>

seems a bit perlish no?

cfp:~ > cat a.rb
p ('a' .. 'ff').to_a


cfp:~ > ruby a.rb
["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",
"n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
"aa", "ab", "ac", "ad", "ae", "af", "ag", "ah", "ai", "aj", "ak",
"al", "am", "an", "ao", "ap", "aq", "ar", "as", "at", "au", "av",
"aw", "ax", "ay", "az", "ba", "bb", "bc", "bd", "be", "bf", "bg",
"bh", "bi", "bj", "bk", "bl", "bm", "bn", "bo", "bp", "bq", "br",
"bs", "bt", "bu", "bv", "bw", "bx", "by", "bz", "ca", "cb", "cc",
"cd", "ce", "cf", "cg", "ch", "ci", "cj", "ck", "cl", "cm", "cn",
"co", "cp", "cq", "cr", "cs", "ct", "cu", "cv", "cw", "cx", "cy",
"cz", "da", "db", "dc", "dd", "de", "df", "dg", "dh", "di", "dj",
"dk", "dl", "dm", "dn", "do", "dp", "dq", "dr", "ds", "dt", "du",
"dv", "dw", "dx", "dy", "dz", "ea", "eb", "ec", "ed", "ee", "ef",
"eg", "eh", "ei", "ej", "ek", "el", "em", "en", "eo", "ep", "eq",
"er", "es", "et", "eu", "ev", "ew", "ex", "ey", "ez", "fa", "fb",
"fc", "fd", "fe", "ff"]

;-)


-a
--
we can deny everything, except that we have the possibility of being
better. simply reflect on that.
h.h. the 14th dalai lama