[QUIZ] One-Liners Mashup (#177 again)

M

Matthew Moss

Challenge:
=A0 Print out a Serpinski carpet.

Here ya go. Non-negative parameter to the function is recursion depth,
so should be 0 for the "null 1x1 carpet", 1 for the 3x3, 2 for the
9x9, etc. This is golfed, and probably a bit more than 80 chars
(gonna wrap in email, I bet).

def carpet(n)
def k(s,x,y) (s<=3D3||k(s/3,x/3,y/3))&&!(x%3=3D=3D1&&y%3=3D=3D1)
end;s=3D3**n;s.times{|y|s.times{|x| print k(s,x,y)?"#":" "};puts}
end


Followup: Make my solution shorter. (There's got to be something nicer
than using `times` twice and `print` once.
 
J

James Coglan

[Note: parts of this message were removed to make it a legal post.]
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)
 
P

Pit Capitain

2008/9/20 James Coglan said:
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
 
H

Holger Mack

[Note: parts of this message were removed to make it a legal post.]

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
 
H

Holger Mack

[Note: parts of this message were removed to make it a legal post.]

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
 
H

Holger Mack

[Note: parts of this message were removed to make it a legal post.]

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
 
J

James Coglan

[Note: parts of this message were removed to make it a legal post.]

2008/9/20 Holger Mack said:
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.
 
K

Ken Bloom

James Gray said:
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.

Hey, you posed that one already in Ruby Quiz 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.
 
S

Sebastian Hungerecker

James said:
def per(n, p =3D 16)
=A0 (1..(p/2)).detect { |x| ("%.#{p}f" %
(1.0/n)).split(".").last.scan(%r{.{#{x}}}).uniq.size =3D=3D 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=20
get a 7 at the end).
Here's one that should always be accurate and it's even in 1 line and handl=
es=20
different bases:
def per(n, b =3D 10)
i=3D1;x=3Db;h=3D{};loop {x=3Dx%n*b;break 0 if x=3D=3D0;h[x]?(break i-h[x]=
):h[x]=3Di; i+=3D1}
end

=2D-=20
Jabber: (e-mail address removed)
ICQ: 205544826
 
J

James Coglan

[Note: parts of this message were removed to make it a legal post.]

2008/9/21 Sebastian Hungerecker said:
James said:
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


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.
 
S

Sebastian Hungerecker

James said:
def per(n, b =3D 10)
=A0i=3D1;x=3Db;h=3D{};loop {x=3Dx%n*b;break 0 if x=3D=3D0;h[x]?(break i= =2Dh[x]):h[x]=3Di;
i+=3D1}
end

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

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

=2D-=20
NP: Disbelief - Spill The Blood (Bonus Track)
Jabber: (e-mail address removed)
ICQ: 205544826
 
K

Ken Bloom

2008/9/20 James Coglan said:
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

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
 
M

Matthew Moss

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. :(
 
M

Matthew Moss

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]
 
M

Martin DeMello

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,967
Messages
2,570,148
Members
46,694
Latest member
LetaCadwal

Latest Threads

Top