One-Liners Mashup (#177 again)

I’m no metaprogramming wizard… I keep trying variations until it
works. :smiley: This seems to work.

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

Oops… I forgot to put up a new one-liner question! (Don’t forget you
guys!!!)

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|####

Oops… I forgot to put up a new one-liner question! (Don’t forget you
guys!!!)

Really sorry, just can’t think of anything immediately… if something
pops
up I’ll post it, promise!

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|####

def roll(n,s)
(1…n).map { |x| “#{x}|#{’#’ * (1 + rand(s))}” } * “\n”
end

puts roll(20,4)

2008/9/20 Pit C. [email protected]:

I don’t think that your method rolls the dice s times.

…and I got n and s reversed :frowning:

Regards,
Pit

On Sep 20, 2008, at 4:07 AM, Sebastian H. wrote:

James G. wrote:

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

Wasn’t that a question in the old one liner quiz?

Ouch, it was. Your memory is better than mine! :slight_smile:

James Edward G. II

2008/9/20 James C. [email protected]:

def roll(n,s)
(1…n).map { |x| “#{x}|#{’#’ * (1 + rand(s))}” } * “\n”
end

puts roll(20,4)

I don’t think that your method rolls the dice s times.

def roll(n, s)
a=(1…n).map{|x|"#{x}|"};s.times{a[rand(n)]<<?#};puts a
end

Regards,
Pit

Periodicity of 1/n -> length of the recurring sequence of the decimal
fraction of 1/n

  • 1/3 = 0.3333333… -> “3” -> 1
  • 1/7 = 0.1428571428571… -> “142957” -> 6
  • 1/11 = 0.09090909… -> “09” -> 2

a bonus point: other than decimal fraction

Regards
Holger

2008/9/20 Matthew M. [email protected]

Shorter carpet solution, still not very nice:

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

puts carpet(2)

next quiz:

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.

Regards
Holger

2008/9/20 Matthew M. [email protected]

On Friday 19 September 2008 23:27:43 James G. wrote:

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

Nice! That’s definitely an improvement over mine.
Also didn’t know about [] for procs.

2008/9/20 Holger M. [email protected]

Periodicity of 1/n -> length of the recurring sequence of the decimal
fraction of 1/n

  • 1/3 = 0.3333333… -> “3” -> 1
  • 1/7 = 0.1428571428571… -> “142957” -> 6
  • 1/11 = 0.09090909… -> “09” -> 2

a bonus point: other than decimal fraction

def per(n, p = 16)
(1…(p/2)).detect { |x| ("%.#{p}f" %
(1.0/n)).split(".").last.scan(%r{.{#{x}}}).uniq.size == 1 } || 0
end

This produces correct output for the numbers you specified. The optional
‘p’
param sets the precision level for converting the number to a string.

James G. [email protected] wrote:

(For our purposes, an IP address may simply be considered

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

Hey, you posed that one already in Ruby Q. 113

class String; def wrap length
scan(/.{1,#{length}}\s+/).join(" \n")
end; end

New challange:

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.

James C. wrote:

def per(n, p = 16)
(1…(p/2)).detect { |x| ("%.#{p}f" %
(1.0/n)).split(".").last.scan(%r{.{#{x}}}).uniq.size == 1 } || 0
end

This produces correct output for the numbers you specified.

It produces 0 for 6 though (because printf rounds instead of truncating
so you
get a 7 at the end).
Here’s one that should always be accurate and it’s even in 1 line and
handles
different bases:
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

2008/9/21 Sebastian H. [email protected]

get a 7 at the end).
Here’s one that should always be accurate and it’s even in 1 line and
handles
different bases:
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

Would be interested to see if you could produce a version with no
assignments or semicolons. With Ruby’s functional and OO capabilities,
it’s
always more satisfying if you can solve a problem with a single
statement,
and I think these little one-liner problems are great for getting you
thinking in functional style.

James C. 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

Would be interested to see if you could produce a version with no
assignments or semicolons.

def per(n, b=10)
(1…1.0/0).inject([b,{}]) { |(x,h),i| if x==0 then break 0 elsif
h[x%nb]
then break i-h[x%n
b] else [x%nb, h.merge(x%nb=>i)] end}
end
But frankly, I like my first solution better. And this one clearly does
not
fit in one line.

wrap text with single regexp and strict maximum length

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

Last one for now, and no followup (we had one for this quiz already)

Regards
Holger

2008/9/20 James C. [email protected]

On Sep 20, 2008, at 10:32 PM, Ken B. wrote:

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

Hey, you posed that one already in Ruby Q. 113

Yeah, this was pointed out earlier. I must me losing my mind. Sorry!

James Edward G. II

In article [email protected]
you wrote:

a=(1…n).map{|x|"#{x}|"};s.times{a[rand(n)]<<?#};puts a
end

Here’s a ruby 1.9 version that doesn’t use semicolons or mutable data
structures.

def roll n, s
((1…s).to_a+n.times.map{|x| rand(s)+1}).group_by{|x| x}.map{|k,v|
“#{k}|”+"#"*(v.size-1)}.join("\n")
end

–Ken

New challange:

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.

I was tempted to port the C++ next_permutation code, but then I
realized I have class. :frowning:

class Array

the classic

def repeat(n)
r = []; each { |e| n.times { r << e } }; r
end

the nice

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

the probably most efficient

def repeat(n)
Array.new(size*n) { |i| self[i/n] }
end
end

next challenge: return the power set of an Array’s elements

(my solution: https://gist.github.com/e05c3be86abf74b44853)

next challenge: return the power set of an Array’s elements

(my solution:https://gist.github.com/e05c3be86abf74b44853)

I’m not sure that providing your succinct solution right alongside the
challenge will encourage additional solutions. :slight_smile:

On Mon, Sep 22, 2008 at 2:07 PM, Matthew M. [email protected]
wrote:

Too many solvers not providing additional problems!

Here’s another… 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]

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

Followon: 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

martin