Skip to content

Followup: Converting from Java to Groovy one step at a time

April 18, 2008

Charles Nutter is in on the fun with a Ruby version:


def subn(n, list)
    return [[]] if n == 0
    return [] if list.empty?

    remainder = list[1..-1]
    subn(n-1, remainder).collect {|it| [list[ 0 ]] + it } + subn(n, remainder)
end

That made me realise there was some further things I could do to cut things down although realistically I don’t think you gain much at this point:


def subn(n, list) {
    if (n == 0) return [[]]
    if (list.empty) return []

    def remainder = list.subList(1, list.size())
    subn(n-1, remainder).collect { [list[ 0 ]] + it } + subn(n, remainder)
}

As with the Ruby version I’ve removed the semicolons and the return statement at the end. I would have liked to use the 1..-1 array range to get the remainder but could not. Groovy supports this however there is a slight difference between list.subList(1, list.size()) and 1..-1 in Groovy. In Ruby this does not seem to be the case.

Take the following:


a = [1, 2, 3]
b = a[1..-1]

In Groovy b will be [2, 3] as expected. If however our array is only 1 element long as follows:


a = [1]
b = a[1..-1]

We get an error:

Caught: java.lang.IndexOutOfBoundsException: toIndex = 2

So what’s going on here? Well, if I understand correctly our range is being mapped to 1..0 at runtime which is not really what we want. I’m told on the mailing list that 1.5.5 and 1.6 has included the methods list.head() and list.tail(). This should mean we can do something like:


def subn(n, list) {
    if (n == 0) return [[]]
    if (list.empty) return []

    subn(n-1, list.tail()).collect { [list.head()] + it } + subn(n, list.tail())
}

Obviously Ruby array indexing is resolved differently from Groovy.

Advertisements

From → Groovy, Java

Leave a Comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: