[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

[QUIZ] One-Liners Mashup (#177 again

Matthew Moss

9/19/2008 11:43:00 PM

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

The three rules of Ruby Quiz 2:

1. This week only -- no waiting period!

2. Support Ruby Quiz 2 by submitting ideas as often as you can! (A
permanent, new website is in the works for Ruby Quiz 2. Until then,
please visit the temporary website at

<http://splatbang.com/rub....

3. Enjoy!

Suggestion: A [QUIZ] in the subject of emails about the problem
helps everyone on Ruby Talk follow the discussion. Please reply to
the original quiz message, if you can.

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

Apologies for being late today... 'twas distracted by my English
report!

## One-Liners Mashup (#177)

This week is going to be very informal, and without any particular
task or submission. It's hunting season, and we're hunting one-liners.

Basically, we'll start with the simple problem I've presented below.
Your solution must fit in one line. (Golfing is okay, but not
necessary. One line *generally* means about 80 chars wide, but we're
flexible here.) If you are writing a method, the `def foo(args)` and
`end` (and `class Whatever` and `end` for adding methods to a class)
doesn't count... the body of the method will.

Of course, your solutions should be generally useful, and not hard-
coded to solve any particular example used to illustrate what the
solution should do.

Post your solution AND a followup problem for others to solve. Repeat
ad nauseum (or until about Wed/Thu).

Ready? Here goes. First problem...
You should know this pattern well:

> [:one, "two", 4] * 3
=> [:one, "two", 4, :one, "two", 4, :one, "two", 4]

Write a single line method on Array that does this instead:

> [:one, "two", 4].repeat(3)
=> [:one, :one, :one, "two", "two", "two", 4, 4, 4]


45 Answers

Matthew Moss

9/20/2008 1:11:00 AM

0

And if it wasn't clear from the very top... no no-spoiler period this
week.


Daniel Moore

9/20/2008 1:21:00 AM

0

def repeat(i)
r = []; each { |x| r.push(*([x] * i)) }; r
end

Challenge:
Print out a Serpinski carpet.

On Fri, Sep 19, 2008 at 4:43 PM, Matthew Moss <matthew.moss@gmail.com> wrote:
> -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
>
> The three rules of Ruby Quiz 2:
>
> 1. This week only -- no waiting period!
>
> 2. Support Ruby Quiz 2 by submitting ideas as often as you can! (A
> permanent, new website is in the works for Ruby Quiz 2. Until then,
> please visit the temporary website at
>
> <http://splatbang.com/rub....
>
> 3. Enjoy!
>
> Suggestion: A [QUIZ] in the subject of emails about the problem
> helps everyone on Ruby Talk follow the discussion. Please reply to
> the original quiz message, if you can.
>
> -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
>
> Apologies for being late today... 'twas distracted by my English
> report!
>
> ## One-Liners Mashup (#177)
>
> This week is going to be very informal, and without any particular
> task or submission. It's hunting season, and we're hunting one-liners.
>
> Basically, we'll start with the simple problem I've presented below.
> Your solution must fit in one line. (Golfing is okay, but not
> necessary. One line *generally* means about 80 chars wide, but we're
> flexible here.) If you are writing a method, the `def foo(args)` and
> `end` (and `class Whatever` and `end` for adding methods to a class)
> doesn't count... the body of the method will.
>
> Of course, your solutions should be generally useful, and not hard-
> coded to solve any particular example used to illustrate what the
> solution should do.
>
> Post your solution AND a followup problem for others to solve. Repeat
> ad nauseum (or until about Wed/Thu).
>
> Ready? Here goes. First problem...
> You should know this pattern well:
>
> > [:one, "two", 4] * 3
> => [:one, "two", 4, :one, "two", 4, :one, "two", 4]
>
> Write a single line method on Array that does this instead:
>
> > [:one, "two", 4].repeat(3)
> => [:one, :one, :one, "two", "two", "two", 4, 4, 4]
>
>
>



--
-Daniel
http:/...

Patrick Doyle

9/20/2008 1:54:00 AM

0

On Fri, Sep 19, 2008 at 9:21 PM, Daniel Moore <yahivin@gmail.com> wrote:
> def repeat(i)
> r = []; each { |x| r.push(*([x] * i)) }; r
> end
>
Here's mine:
def repeat(i)
self.map {|x| [x] * i}.flatten
end

I don't appreciate Ruby syntax enough to understand the significance
of the *(...) construct in Daniel's solution. What does that do? Can
you show an example where the results are different than my solution?

--wpd

James Gray

9/20/2008 1:55:00 AM

0

On Sep 19, 2008, at 6:43 PM, Matthew Moss wrote:

> First problem...
> You should know this pattern well:
>
>> [:one, "two", 4] * 3
> => [:one, "two", 4, :one, "two", 4, :one, "two", 4]
>
> Write a single line method on Array that does this instead:
>
>> [:one, "two", 4].repeat(3)
> => [:one, :one, :one, "two", "two", "two", 4, 4, 4]

class Array; def repeat(n) zip(*([self] * (n - 1))).flatten end end

> Post your solution AND a followup problem for others to solve.

Given the class:

class Data2D
def initialize
@data = [ ] # in row major form
end

def add_row(*row)
@data << row
end
end

And this setup for an object:

data = Data2D.new
data.add_row(1, 2, 3, 4)
data.add_row(5, 6, 7, 8)

Define a [] method for the class that makes this form of access
possible:

x = 2
y = 1
data[x][y] # => 7

James Edward Gray II

Patrick Doyle

9/20/2008 2:11:00 AM

0

> Given the class:
>
> class Data2D
> def initialize
> @data = [ ] # in row major form
> end
>
> def add_row(*row)
> @data << row
> end
> end
>
> And this setup for an object:
>
> data = Data2D.new
> data.add_row(1, 2, 3, 4)
> data.add_row(5, 6, 7, 8)
>
> Define a [] method for the class that makes this form of access possible:
>
> x = 2
> y = 1
> data[x][y] # => 7
>
How about

def [](i)
@data.map {|row| row[i]}
end

>> Post your solution AND a followup problem for others to solve.
Oops, I'll have to think about that... but not tonight

... on a completely different topic... I've noticed that whenever I
post a message to ruby-talk@ruby-lang.org from my gmail account, I get
the message twice in my inbox, making me wonder three things...
1) Does everybody get my messages twice? If so, I humbly apologize
and will stop posting immediately as I can see where this could be
just a tiny little bit annoying.
2) Does anybody else have this problem? If so
3) How did you solve it (assuming it's a solvable problem)?

--wpd

Daniel Moore

9/20/2008 2:15:00 AM

0

It splats an array into it's components:
http://theplana.wordpress.com/2007/03/03/ruby-idioms-the-splat...
I couldn't use flatten because it would destroy nested arrays.

[[1,2],[3,4]].repeat(2) => [1, 2, 1, 2, 3, 4, 3, 4] #With flatten

[[1,2],[3,4]].repeat(2) => [[1, 2], [1, 2], [3, 4], [3, 4]] #Without flatten

On Fri, Sep 19, 2008 at 6:53 PM, Patrick Doyle <wpdster@gmail.com> wrote:
> On Fri, Sep 19, 2008 at 9:21 PM, Daniel Moore <yahivin@gmail.com> wrote:
>> def repeat(i)
>> r = []; each { |x| r.push(*([x] * i)) }; r
>> end
>>
> Here's mine:
> def repeat(i)
> self.map {|x| [x] * i}.flatten
> end
>
> I don't appreciate Ruby syntax enough to understand the significance
> of the *(...) construct in Daniel's solution. What does that do? Can
> you show an example where the results are different than my solution?
>
> --wpd
>
>



--
-Daniel
http:/...

Bill Kelly

9/20/2008 2:33:00 AM

0


From: "Matthew Moss" <matthew.moss@gmail.com>
>
> Ready? Here goes. First problem...
> You should know this pattern well:
>
> > [:one, "two", 4] * 3
> => [:one, "two", 4, :one, "two", 4, :one, "two", 4]
>
> Write a single line method on Array that does this instead:
>
> > [:one, "two", 4].repeat(3)
> => [:one, :one, :one, "two", "two", "two", 4, 4, 4]


# SOLUTION 1:
# Partial solution, we would need a flatten(1) to prevent it from
# messing up nested arrays like [:one, "two", [3]] -- since flatten
# unarrays recursively.

class Array; def repeat(n); ([self]*n).transpose.flatten; end; end


# SOLUTION 2:
# Avoids flatten, so won't break nested arrays:

class Array; def repeat(n); ([self]*n).transpose.inject([]){|a,e| a += e}; end; end



--------------
NEW CHALLENGE:
--------------

# Given one or more input filenames on the command line,
# report the number of unique IP addresses found in all the
# data.
#
# (For our purposes, an IP address may simply be considered
# four integerers separated by dots, e.g.: 6.54.123.9 )
#
# Optionally, the solution should read stdin if no filenames
# were specified.
#
# Preferably, the solution should be expressed in the form of
# a ruby command-line invocation. (Optional.)



Regards,

Bill



David Masover

9/20/2008 2:35:00 AM

0

On Friday 19 September 2008 21:11:21 Patrick Doyle wrote:
> > Given the class:
> >
> > class Data2D
> > def initialize
> > @data = [ ] # in row major form
> > end
> >
> > def add_row(*row)
> > @data << row
> > end
> > end
> >
> > And this setup for an object:
> >
> > data = Data2D.new
> > data.add_row(1, 2, 3, 4)
> > data.add_row(5, 6, 7, 8)
> >
> > Define a [] method for the class that makes this form of access possible:
> >
> > x = 2
> > y = 1
> > data[x][y] # => 7
> >
> How about
>
> def [](i)
> @data.map {|row| row[i]}
> end

Curses! You beat me to it, so I wrote a more complex solution:

class Data2D
def [](x)
d=@data; Class.new{ define_method('[]') {|y| d[y][x]}}.new
end
end

Counting spaces, it's 64 characters, so it still fits. It has the advantage of
probably being faster on very large datasets, at least for that single
lookup, as no array splicing is done.

I didn't really have a problem in mind, but here's an easy one: Write an []=
method to solve the following:

obj = YourClass.new
obj['answer'] = 42
obj.answer # => 42

James Gray

9/20/2008 4:28:00 AM

0

On Sep 19, 2008, at 9:34 PM, David Masover wrote:

> On Friday 19 September 2008 21:11:21 Patrick Doyle wrote:
>>> Given the class:
>>>
>>> class Data2D
>>> def initialize
>>> @data = [ ] # in row major form
>>> end
>>>
>>> def add_row(*row)
>>> @data << row
>>> end
>>> end
>>>
>>> And this setup for an object:
>>>
>>> data = Data2D.new
>>> data.add_row(1, 2, 3, 4)
>>> data.add_row(5, 6, 7, 8)
>>>
>>> Define a [] method for the class that makes this form of access
>>> possible:
>>>
>>> x = 2
>>> y = 1
>>> data[x][y] # => 7
>>>
>> How about
>>
>> def [](i)
>> @data.map {|row| row[i]}
>> end
>
> Curses! You beat me to it, so I wrote a more complex solution:
>
> class Data2D
> def [](x)
> d=@data; Class.new{ define_method('[]') {|y| d[y][x]}}.new
> end
> end
>
> Counting spaces, it's 64 characters, so it still fits. It has the
> advantage of
> probably being faster on very large datasets, at least for that single
> lookup, as no array splicing is done.

When I wrote the problem, I was thinking of this solution:

class Data2D; def [](x) lambda { |y| @data[y][x] } end

James Edward Gray II

James Gray

9/20/2008 4:28:00 AM

0

On Sep 19, 2008, at 9:32 PM, Bill Kelly wrote:

> --------------
> NEW CHALLENGE:
> --------------
>
> # Given one or more input filenames on the command line, # report
> the number of unique IP addresses found in all the
> # data.
> #
> # (For our purposes, an IP address may simply be considered
> # four integerers separated by dots, e.g.: 6.54.123.9 )
> #
> # Optionally, the solution should read stdin if no filenames
> # were specified.
> #
> # Preferably, the solution should be expressed in the form of
> # a ruby command-line invocation. (Optional.)

ruby -e 'p ARGF.read.scan(/\d{1,3}(\.\d{1,3}){3}/).uniq.size'

New puzzle: Provide a one-liner that can wrap a body of text at a
requested maximum length.

James Edward Gray II