# One-Liners Mashup (#177)

**URL:** <https://www.ruby-forum.com/t/one-liners-mashup-177/149551>\
**Category:** Ruby\
**Created:** [September 26, 2008, 4:19am UTC](https://www.ruby-forum.com/t/one-liners-mashup-177/149551 "2008-09-26T04:19:27Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![mansfiem](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/fbc32d/32.png) [@mansfiem](https://www.ruby-forum.com/u/mansfiem)\
**Post date:** [September 26, 2008, 4:19am UTC](https://www.ruby-forum.com/t/one-liners-mashup-177/149551/1 "2008-09-26T04:19:27Z")

</div>

Thanks to everyone who joined in on the one-liners mashup. I think  
part of the challenge to the mashup was coming up with new problems.  
It seems that, unless you’ve already solved the problem, it takes a  
bit of intuition to come up with a problem that isn’t trivial, but  
also that can be done within a typical line or two. All the problems  
presented seemed to fit right in.

I’m not going to do a regular summary here: the discussion on Ruby  
Talk pretty much _is_ the summary. I will run through all the problems  
very quickly, just pulling out the solution that appealed to me the  
most in each case.

The problem:

```
Write a single line method for Array that does this:
  > [:one, "two", 4].repeat(3)
  => [:one, :one, :one, "two", "two", "two", 4, 4, 4]

```

“The Nice” solution (I agree):

```
def repeat(n)
  inject([]) { |a,e| a.concat [e]*n }
end

```

The problem:

```
Print out a Sierpinski carpet.

```

The shorter (but still kinda long) solution:

```
def carpet(n)
  n==0?"#\n":carpet(n-1).map{|l| ['\0\0\0','\0

```

\0’,’\0\0\0’].map{|c| l.gsub(/#| /,c)}}.join  
end

The problem:

```
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 that makes this form of access possible:
  data[2][1] # => 7

```

The tricksy call-you-later solution:

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

```

The problem:

```
Write an []= method to solve the following:
  obj = YourClass.new
  obj['answer'] = 42
  obj.answer # => 42

```

The what-the-heck-with-all-the-eval solution:

```
class YourClass
  def []=(f, v)
    class << self; self end.instance_eval{ attr_accessor f };

```

instance\_eval “@#{f}=v”  
end  
end

The problem:

```
Given one or more input filenames on the command line, report the

```

number of unique IP addresses  
found in all the data.

The command-line solution:

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

```

The problem:

```
Here's something simple: define method roll(n, s) to roll a s-sided
die n times and display a bar graph of the results. So roll(20, 4)
might look like this:
 1|#####
 2|#####
 3|######
 4|####

```

A random solution:

```
def roll(n,s)
  (1..n).map { |x| "#{x}|#{'#' * (1 + rand(s))}" } * "\n"
end

```

The problem:

```
Provide a one-liner that can wrap a body of text at a requested

```

maximum length.

The “Didn’t we do this before?” solution:

```
text.gsub(/(.{1,80})\s|(\w{80})/, "\\1\\2\n")

```

The problem:

```
Sort an array of words by the words' values where a word's value is 

```

the  
sum of the values of its letters and a letter’s value is its  
position in  
the alphabet. So the value of “Hello” is 8+5+12+12+15.

The “I mutated two solutions into one I like the bestest” solution:

```
class Array
  def sortval()
    sort_by { |x| x.upcase.sum - x.length * ?@ }
  end
end

```

The problem:

```
Write a function per(n) which returns the periodicity of 1/n, i.e.
  per(3) => 1
  per(4) => 0
  per(7) => 6
  per(11) => 2

```

The “Ummm… yeah… how do these work?” solution:

```
def per(n, b=10)
  i=1;x=b;h={};loop {x=x%n*b;break 0 if x==0;h[x]?(break

```

i-h[x]):h[x]=i; i+=1}  
end

The problem:

```
Return the power set of an Array's elements.

```

The “Don’t get up, I’ll take care of it” solution:

```
class Array
  def powerset
    inject([[]]) { |a,e| a + a.map { |b| b+[e] } }
  end
end

```

The problem:

```
Assuming you have an array of numeric data, write a method that

```

returns an array of progressive  
sums. That is:  
prog\_sum( [1, 5, 13, -6, 20] ) =\> [1, 6, 19, 13, 33]

The obligatory inject solution:

```
def prog_sum(ary)
  ary.inject([0, []]) {|(s, a), i| [s+i, a<<(s+i)]}.last
end

```

The problem:

```
Given an s-expression, print it out as a tree, where [:a,
:b, :c, :d] is the node with parent a and children b, c and d

[:foo, [:bar, [:baz, :quux], :hello, :world], :done] #=>

foo
| -- bar
| | -- baz
| | | -- quux
| | -- hello
| | -- world
| -- done

```

The last solution of the summary… solution:

```
class Array
  def to_s
    collect{|x| x.to_s.gsub(/\n/,"\n| ")}.join("\n|-- ")
  end
end

```

Any unsolved problems? You bet! Here are the problems that didn’t get  
answered, in case you’ve got an itch for more.

```
1. Given a text from STDIN and a regexp, print each line which (in 

```

part)  
matches regexp with two preceding and two successional lines. Do not  
output  
a line more than once.

```
2. Starting with an array, find the first permutation of the 

```

elements of  
that array that is lexicographically greater than (i.e. sorts after)  
the given array.

```
3. Write a oneliner next_fib(n) which gives the smallest Fibonacci 

```

number  
greater than n.

```
4. Given an epsilon, compute PI to that precision.
```

---

<div class="post-metadata">

**Author:** ![mansfiem](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/fbc32d/32.png) [@mansfiem](https://www.ruby-forum.com/u/mansfiem)\
**Post date:** [September 26, 2008, 4:24am UTC](https://www.ruby-forum.com/t/one-liners-mashup-177/149551/2 "2008-09-26T04:24:09Z")

</div>

> ```
> def carpet(n)
> n==0?"#\n":carpet(n-1).map{|l| ['\0\0\0','\0
> 
> ```
> 
> \0’,’\0\0\0’].map{|c| l.gsub(/#| /,c)}}.join  
> end

If you saw this the way I saw it here, this is an unfortunate line-  
wrap. That array in the first map call should be:

```
['\0\0\0','\0 \0','\0\0\0']
```

---

<div class="post-metadata">

**Author:** ![mansfiem](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/fbc32d/32.png) [@mansfiem](https://www.ruby-forum.com/u/mansfiem)\
**Post date:** [September 26, 2008, 10:49am UTC](https://www.ruby-forum.com/t/one-liners-mashup-177/149551/3 "2008-09-26T10:49:29Z")

</div>

Matthew M. wrote:

> ```
> def per(n, b=10)
> i=1;x=b;h={};loop {x=x%n*b;break 0 if x==0;h[x]?(break
> 
> ```
> 
> i-h[x]):h[x]=i; i+=1}  
> end

It works like this:  
[http://img243.imageshack.us/img243/9296/perwt4.png](http://img243.imageshack.us/img243/9296/perwt4.png)  
It simply divides until the remainder repeats itself (storing the  
position  
where each remainder occured in a hash) and then returns the difference  
between the first position where the remainder occured (i.e. the start  
of the  
period) and the current position.

---

<div class="post-metadata">

**Author:** ![mansfiem](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/fbc32d/32.png) [@mansfiem](https://www.ruby-forum.com/u/mansfiem)\
**Post date:** [September 26, 2008, 11:58am UTC](https://www.ruby-forum.com/t/one-liners-mashup-177/149551/4 "2008-09-26T11:58:50Z")

</div>

On Fri, Sep 26, 2008 at 1:48 AM, Sebastian H.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> It works like this:  
> [http://img243.imageshack.us/img243/9296/perwt4.png](http://img243.imageshack.us/img243/9296/perwt4.png)  
> It simply divides until the remainder repeats itself (storing the position  
> where each remainder occured in a hash) and then returns the difference  
> between the first position where the remainder occured (i.e. the start of the  
> period) and the current position.

Neat 🙂

martin

---

<div class="post-metadata">

**Author:** ![mansfiem](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/fbc32d/32.png) [@mansfiem](https://www.ruby-forum.com/u/mansfiem)\
**Post date:** [September 26, 2008, 12:25pm UTC](https://www.ruby-forum.com/t/one-liners-mashup-177/149551/5 "2008-09-26T12:25:50Z")

</div>

Sebastian H. wrote:

> It works like this:  
> [http://img243.imageshack.us/img243/9296/perwt4.png](http://img243.imageshack.us/img243/9296/perwt4.png)

Well, almost. “h[30] - i = 6” should of course be “i - h[30] = 6”.

---

<div class="post-metadata">

**Author:** ![mansfiem](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/fbc32d/32.png) [@mansfiem](https://www.ruby-forum.com/u/mansfiem)\
**Post date:** [September 26, 2008, 12:05pm UTC](https://www.ruby-forum.com/t/one-liners-mashup-177/149551/6 "2008-09-26T12:05:52Z")

</div>

From: Matthew M. [[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)]  
#…

# def prog\_sum(ary)

# ary.inject([0, []]) {|(s, a), i| [s+i, a\<\<(s+i)]}.last

# end

non-inject:

prev=0; ary.map{|x| prev+=x}
