Elegantly small!
···
On Feb 11, 4:40 pm, Alex Young <a...@blackkettle.org> wrote:
# One-level flatten().
r=;quiz.each{|a|r+=[*a]};r
Elegantly small!
On Feb 11, 4:40 pm, Alex Young <a...@blackkettle.org> wrote:
# One-level flatten().
r=;quiz.each{|a|r+=[*a]};r
I don't think my solutions contribute much that is new, but you can
see them below and on pastie: http://pastie.caboo.se/39741.
I thought it was interesting that many previous solutions to the
commify problem posted on lists and on RubyForge fail for numbers like
0.23423423.
Looking at others' solutions, I really like Robert Dober's
sort_by{rand} solution to the array shuffle.
cheers,
Krishna
----------------------------------------------------------------
require 'test/unit'
# test setup mostly borrowed from Jamie Macey
class OneLiner
class << self
# this was the hardest one for me. this answer is not
# entirely my own, as it was inspired by
# http://rubyforge.org/snippet/detail.php?type=snippet&id=8
# (which does not work for numbers like 0.234234234234)
def commaize(quiz)
quiz.to_s.sub(/^(-*)(\d+)/){|m| $1 + $2.gsub(/(\d)(?=\d{3}+$)/, '\1,')}
end
def flatten_once(quiz)
quiz.inject([]){|n, e| e.is_a?(Array) ? n + e : n << e }
end
def shuffle(quiz)
a = quiz.dup; Array.new(a.size).map{|i| a.delete_at(rand(a.size)) }
end
def get_class(quiz)
require quiz.downcase.split("::")[0..-2].join("/"); eval quiz
end
def wrap_text(quiz)
quiz.gsub(/(.{1,40}(\s|$))/, '\1' + "\n").chop
end
def find_anagrams(quiz)
quiz.select{|w| w.scan(/./).sort == quiz[0].scan(/./).sort}
end
def binarize(quiz)
s = ""; quiz.each_byte {|c| c == 32 ? s << "\n" : s << "%b" % c}; s
end
# using #readlines would be easiest, but unlike that, this solution
# should work fine on files that are too big to hold in memory.
# unfortunately, it is more than 80 chars when using a variable
# named 'quiz'
def random_line(quiz)
i = rand(quiz.each{|l|}.lineno); quiz.rewind; quiz.each{|l|
return l if quiz.lineno == i+1}
end
# i know. it's 6 lines, not one. and more than 80 chars
def wondrous_sequence(quiz)
a = [n = quiz]; while n != 1; n = (n % 2 > 0 ? n * 3 + 1 : n /
2); a << n; end; a
end
# i guess it is cheating to use recursion (two lines)
# but it worked too nicely to resist here.
def nested_hash(quiz)
quiz.size > 1 ? {quiz[0] => nested_hash(quiz[1..-1])} : quiz[0]
end
end
end
require 'tempfile'
class TestOneLiner < Test::Unit::TestCase
# Given a Numeric, provide a String representation with commas inserted
# between each set of three digits in front of the decimal. For example,
# 1999995.99 should become "1,999,995.99".
def test_commaize
assert_equal "995", OneLiner.commaize(995)
assert_equal "1,995", OneLiner.commaize(1995)
assert_equal "12,995", OneLiner.commaize(12995)
assert_equal "123,995", OneLiner.commaize(123995)
assert_equal "1,234,995", OneLiner.commaize(1234995)
assert_equal "1,234,567,890,995", OneLiner.commaize(1234567890995)
assert_equal "99,995.992349834", OneLiner.commaize(99995.992349834)
assert_equal "0.992349834", OneLiner.commaize(0.992349834)
assert_equal "-0.992349834", OneLiner.commaize(-0.992349834)
assert_equal "999,995.99", OneLiner.commaize(999995.99)
assert_equal "-1,999,995.99", OneLiner.commaize(-1999995.99)
end
# Given a nested Array of Arrays, perform a flatten()-like operation that
# removes only the top level of nesting. For example, [1, [2, [3]]] would
# become [1, 2, [3]].
def test_flatten_once
ary = [1, [2, [3, 4]]]
flatter_ary = [1, 2, [3, 4]]
assert_equal flatter_ary, OneLiner.flatten_once(ary)
end
# Shuffle the contents of a provided Array.
def test_shuffle
ary = [3,1,4,1,5,9]
shuffled_ary = OneLiner.shuffle(ary)
assert_not_equal ary, shuffled_ary
assert_equal ary.sort, shuffled_ary.sort
end
# Given a Ruby class name in String form (like
# "GhostWheel::Expression::LookAhead"), fetch the actual class object.
def test_get_class
assert_equal Test::Unit::TestCase,
OneLiner.get_class("Test::Unit::TestCase")
end
# Insert newlines into a paragraph of prose (provided in a String) so
# lines will wrap at 40 characters.
def test_wrap_text
wrapped = "Insert newlines into a paragraph of " + "\n" +
"prose (provided in a String) so lines " + "\n" +
"will wrap at 40 characters."
paragraph = "Insert newlines into a paragraph of " +
"prose (provided in a String) so lines " +
"will wrap at 40 characters."
assert_equal wrapped, OneLiner.wrap_text(paragraph)
end
# Given an Array of String words, build an Array of only those words that
# are anagrams of the first word in the Array.
def test_find_anagrams
anagrams = %w(tac cat act)
assert_equal anagrams, OneLiner.find_anagrams(%w(tac bat cat rat act))
end
# Convert a ThinkGeek t-shirt slogan (in String form) into a binary
# representation (still a String). For example, the popular shirt
# "you are dumb" is actually printed as:
# 111100111011111110101
# 110000111100101100101
# 1100100111010111011011100010
def test_binarize
output = "111100111011111110101" + "\n" +
"110000111100101100101" + "\n" +
"1100100111010111011011100010"
assert_equal output, OneLiner.binarize("you are dumb")
end
# Provided with an open File object, select a random line of content.
#
# NOTE: This test assumes you're using File#read to get the string data
# from the file - if doing otherwise, update the test?
def test_random_line
f = Tempfile.new("foo")
f.print("development:
adapter: mysql
database: redvase_development
host: localhost
username: root
password:")
f.flush
f.rewind
lines = f.readlines
line = OneLiner.random_line(f)
assert_equal true, lines.include?(line)
end
# Given a wondrous number Integer, produce the sequence (in an Array). A
# wondrous number is a number that eventually reaches one, if you apply
# the following rules to build a sequence from it. If the current number
# in the sequence is even, the next number is that number divided by two.
# When the current number is odd, multiply that number by three and add
# one to get the next number in the sequence. Therefore, if we start with
# the wondrous number 15, the sequence is [15, 46, 23, 70, 35, 106, 53,
# 160, 80, 40, 20, 10, 5, 16, 8, 4, 2, 1].
def test_wondrous_sequence
seq = [23, 70, 35, 106, 53, 160, 80, 40, 20, 10, 5, 16, 8, 4, 2, 1]
assert_equal seq, OneLiner.wondrous_sequence(23)
end
# Convert an Array of objects to nested Hashes such that %w[one two three
# four five] becomes {"one" => {"two" => {"three" => {"four" => "five"}}}}.
def test_nested_hash
hash = {:o => {:t => {:t => {:f => :f}}}}
assert_equal hash, OneLiner.nested_hash([:o, :t, :t, :f, :f])
end
end
You read (Past Tense) me perfectly
Thx
Robert
On 2/9/07, James Edward Gray II <james@grayproductions.net> wrote:
On Feb 9, 2007, at 1:40 PM, Robert Dober wrote:
> On 2/9/07, Ruby Quiz <james@grayproductions.net> wrote:
>>
>> The three rules of Ruby Quiz:
>>
>> <snip>
>>
> Sounds like fun,
> Now the stupid question of the day: will a comment before the line
> be a
> problem for your tools, I guess they are countingI don't have any tools. Someone should build a test suite and post
it though, if they feel motivated to do so.For my solutions though, I put the questions as comments before each
solution.
--
We have not succeeded in answering all of our questions.
In fact, in some ways, we are more confused than ever.
But we feel we are confused on a higher level and about more important
things.
-Anonymous
Okay. The only one I'm taking significant liberties with is the
random-line-from-a-file - the test is expecting that the contents of
the file be loaded using File#read, and uses OpenStruct to provide a
test stub with that functionality. Other than that, these tests are a
pretty direct translation from the initial description. Method stubs
for the implementation are also provided.
require 'test/unit'
require 'ostruct'
class OneLiner
class << self
def commaize(number)
end
def flatten_once(ary)
end
def shuffle(ary)
end
def get_class(name)
end
def wrap_text(paragraph)
end
def find_anagrams(words)
end
def binarize(slogan)
end
def random_line(file)
end
def wondrous_sequence(n)
end
def nested_hash(ary)
end
end
end
class TestOneLiner < Test::Unit::TestCase
# Given a Numeric, provide a String representation with commas inserted
# between each set of three digits in front of the decimal. For example,
# 1999995.99 should become "1,999,995.99".
def test_commaize
assert_equal "1,999,995.99", OneLiner.commaize(1999995.99)
end
# Given a nested Array of Arrays, perform a flatten()-like operation that
# removes only the top level of nesting. For example, [1, [2, [3]]] would
# become [1, 2, [3]].
def test_flatten_once
ary = [1, [2, [3, 4]]]
flatter_ary = [1, 2, [3, 4]]
assert_equal flatter_ary, OneLiner.flatten_once(ary)
end
# Shuffle the contents of a provided Array.
def test_shuffle
ary = [3,1,4,1,5,9]
shuffled_ary = OneLiner.shuffle(ary)
assert_not_equal ary, shuffled_ary
assert_equal ary.sort, shuffled_ary.sort
end
# Given a Ruby class name in String form (like
# "GhostWheel::Expression::LookAhead"), fetch the actual class object.
def test_get_class
assert_equal Test::Unit::TestCase,
OneLiner.get_class("Test::Unit::TestCase")
end
# Insert newlines into a paragraph of prose (provided in a String) so
# lines will wrap at 40 characters.
def test_wrap_text
wrapped = "Insert newlines into a paragraph of " + "\n" +
"prose (provided in a String) so lines " + "\n" +
"will wrap at 40 characters."
paragraph = "Insert newlines into a paragraph of " +
"prose (provided in a String) so lines " +
"will wrap at 40 characters."
assert_equal wrapped, OneLiner.wrap_text(paragraph)
end
# Given an Array of String words, build an Array of only those words that
# are anagrams of the first word in the Array.
def test_find_anagrams
anagrams = %w(cat act)
assert_equal anagrams, OneLiner.find_anagrams(%w(tac bat cat rat act))
end
# Convert a ThinkGeek t-shirt slogan (in String form) into a binary
# representation (still a String). For example, the popular shirt
# "you are dumb" is actually printed as:
# 111100111011111110101
# 110000111100101100101
# 1100100111010111011011100010
def test_binarize
output = "111100111011111110101" + "\n" +
"110000111100101100101" + "\n" +
"1100100111010111011011100010"
assert_equal output, OneLiner.binarize("you are dumb")
end
# Provided with an open File object, select a random line of content.
On 2/9/07, James Edward Gray II <james@grayproductions.net> wrote:
Someone should build a test suite and post
it though, if they feel motivated to do so.
#
# NOTE: This test assumes you're using File#read to get the string data
# from the file - if doing otherwise, update the test?
def test_random_line
file = OpenStruct.new(:read => "development:
adapter: mysql
database: redvase_development
host: localhost
username: root
password:")
lines = file.read.split("\n")
line = OneLiner.random_line(file)
assert_equal true, lines.include?(line)
end
# Given a wondrous number Integer, produce the sequence (in an Array). A
# wondrous number is a number that eventually reaches one, if you apply
# the following rules to build a sequence from it. If the current number
# in the sequence is even, the next number is that number divided by two.
# When the current number is odd, multiply that number by three and add
# one to get the next number in the sequence. Therefore, if we start with
# the wondrous number 15, the sequence is [15, 46, 23, 70, 35, 106, 53,
# 160, 80, 40, 20, 10, 5, 16, 8, 4, 2, 1].
def test_wondrous_sequence
seq = [23, 70, 35, 106, 53, 160, 80, 40, 20, 10, 5, 16, 8, 4, 2, 1]
assert_equal seq, OneLiner.wondrous_sequence(23)
end
# Convert an Array of objects to nested Hashes such that %w[one two three
# four five] becomes {"one" => {"two" => {"three" => {"four" => "five"}}}}.
def test_nested_hash
hash = {:o => {:t => {:t => {:f => :f}}}}
assert_equal hash, OneLiner.nested_hash([:o, :t, :t, :f, :f])
end
end
Technically those are constants, not classes. For example, OpenSSL is a module. That neatly foils a solution someone sent me off list today.
James Edward Gray II
On Feb 9, 2007, at 5:35 PM, Phrogz wrote:
# Built-in classes for testing #4
:class_from_string => [
["OpenSSL", OpenSSL ],
["OpenSSL::Digest", OpenSSL::Digest ],
["OpenSSL::Digest::DigestError", OpenSSL::Digest::DigestError ],
],
Not that there are any known positive numbers that are not wondrous... indeed, it would be wondrous to find such a number. Brute force attacks from eight years ago place any non-wondrous number, should it exist, above 2E16.
That said, there are three known cycles of /negative/ non-wondrous numbers.
The real name of this problem is the Collatz Problem.
Dan
On Feb 9, 2007, at 2:15 PM, James Edward Gray II wrote:
On Feb 9, 2007, at 3:10 PM, Luke Ivers wrote:
* Given a wondrous number Integer, produce the sequence (in an Array). A
wondrous number is a number that eventually reaches one, if you apply the
following rules to build a sequence from it. If the current number in the
sequence is even, the next number is that number divided by two. When the
current number is odd, multiply that number by three and add one to get
the next
number in the sequence. Therefore, if we start with the wondrous number
15, the
sequence is [15, 46, 23, 70, 35, 106, 53, 160, 80, 40, 20, 10, 5, 16, 8,
4, 2,
1].One final question: you say "given a wondrous number"... does this mean that
the input is guaranteed to be wondrous, and we therefore don't need to check
it...Correct.
When I saw that, I thought that it could definitely be shortened by
using an inject. After all, there'd be no assignments of r, no final
returning of r, no semicolons. But when all was said and done, it
ended up being the same length. Compare:
quiz.inject(){|r,a|r+[*a]}
r=;quiz.each{|a|r+=[*a]};r
Oh well....
Eric
On Feb 12, 1:07 am, "Phrogz" <g...@refinery.com> wrote:
On Feb 11, 4:40 pm, Alex Young <a...@blackkettle.org> wrote:
> # One-level flatten().
> r=;quiz.each{|a|r+=[*a]};rElegantly small!
----------------
Are you interested in on-site Ruby training that uses well-designed,
real-world, hands-on exercises? http://LearnRuby.com
<cut>
Looking at others' solutions, I really like Robert Dober's
sort_by{rand} solution to the array shuffle.
That is kind of you but there is a funny story behind it.
Many others came up with it and it is a known idiom.
But yet I got so confused that I failed to post this solution.
I was about to post, DO NOT LAUGH
sort{ rand <=> rand} (which works BTW)
and eventually there was a thread about the issue and I (not even so kindly)
asked the people to wait for the spoiler period and it was my full intention
to tell them later that
sort_by { rand } was stupid when I found out -in time- that sort {rand} was
stupid and not sort_by{ rand }.
Actually I really do not deserve credit for this one.
<cut>
Cheers
Robert
On 2/12/07, Krishna Dole <dontfall@gmail.com> wrote:
--
We have not succeeded in answering all of our questions.
In fact, in some ways, we are more confused than ever.
But we feel we are confused on a higher level and about more important
things.
-Anonymous
What if it's a file too big to read into memory?
James Edward Gray II
On Feb 9, 2007, at 3:19 PM, Jamie Macey wrote:
On 2/9/07, James Edward Gray II <james@grayproductions.net> wrote:
Someone should build a test suite and post
it though, if they feel motivated to do so.Okay. The only one I'm taking significant liberties with is the
random-line-from-a-file - the test is expecting that the contents of
the file be loaded using File#read...
[snip]
# Given an Array of String words, build an Array of only those words that
# are anagrams of the first word in the Array.
def test_find_anagrams
anagrams = %w(cat act)
assert_equal anagrams, OneLiner.find_anagrams(%w(tac bat cat rat act))
end
[snip]
I changed anagrams to %w(tac cat act). I'm the sort of person that
thinks a word is an anagram of itself (although, I have a feeling
"tac" isn't a word).
I had wondered about that. The wording of the quiz says "class", but I
figure that:
a) Given the number of modules-as-namespaces over classes-as-
namespaces, a good solution to the problem allows module stops along
the way, and thus
b) If you're going to allow non-classes along the way, you generally
want the "resolve this as though I typed it" functionality, which may
end in constants.
BUT...if the quiz has the wrinkle that only Classes should be returned
(and thus you should get nil for the cases above), that would be
interesting to program, too.
On Feb 9, 4:46 pm, James Edward Gray II <j...@grayproductions.net> wrote:
On Feb 9, 2007, at 5:35 PM, Phrogz wrote:
> # Built-in classes for testing #4
> :class_from_string => [
> ["OpenSSL", OpenSSL ],
> ["OpenSSL::Digest", OpenSSL::Digest ],
> ["OpenSSL::Digest::DigestError", OpenSSL::Digest::DigestError ],
> ],Technically those are constants, not classes. For example, OpenSSL
is a module. That neatly foils a solution someone sent me off list
today.
I guess it is time now
This was a great quiz and it thought me that I did not *know anything about
Regexps*.
Now I know a little bit:
I also got acquainted with an old enemy of mine, #inject
# Given an Array of String words, build an Array of only those words that
are
# anagrams of the first word in the Array.
quiz.select{ |ele| ele.split("").sort == quiz.first.split("").sort }
# I left the first word in the list one could discard it within the 80 chars
limit be deleting WS in my solution.
# Given a Ruby class name in String form (like
# "GhostWheel::Expression::LookAhead"), fetch the actual class object.
sol113.tgz (4.53 KB)
#
x=quiz.split("::").inject(self.class){|k,m|k.const_get(m)};Class===x ? x :
nil
# * Given a Numeric, provide a String representation with commas inserted
between
# each set of three digits in front of the decimal. For example, 1999995.99
# should become "1,999,995.99".
m=/[^\.]*/.match(quiz.to_s
);p=$';m[0].reverse.gsub(/\d{3}\B/,'\&,').reverse+p
# I could not believe how tough this one was for me!!!!
# * Given a nested Array of Arrays, perform a flatten()-like operation that
# removes only the top level of nesting. For example, [1, [2, [3]]] would
become
# [1, 2, [3]].
#
quiz.inject( [] ) { |a,e| a + ( Array === e ? e : [e] ) }
# Convert a ThinkGeek t-shirt slogan (in String form) into a binary
# representation (still a String). For example, the popular shirt "you are
dumb"
# is actually printed as:
#
# 111100111011111110101
# 110000111100101100101
# 1100100111010111011011100010
#
quiz.split.map{ |w| s=""; w.each_byte{ |b| s<<b.to_s(2)}; s}.join("\n")
# * Convert an Array of objects to nested Hashes such that %w[one two three
four
# five] becomes {"one" => {"two" => {"three" => {"four" => "five"}}}}.
quiz[0..-3].reverse.inject( { quiz[-2] => quiz[-1] } ){ |h,e| { e => h } }
# I found a fitting solution with a recursive method in 80 chars but
eventually
# I was saved by #inject from ridiculing myself.
# Provided with an open File object, select a random line of content.
q=quiz.readlines; q[ rand( q.size ) ].chomp
# * Shuffle the contents of a provided Array.
#
quiz.sort_by{ rand }
# This was a great Quiz but this problem was somehow an anticlimax for me,
did I miss something?
# Given a wondrous number Integer, produce the sequence (in an Array). A
# wondrous number is a number that eventually reaches one, if you apply the
# following rules to build a sequence from it. If the current number in the
# sequence is even, the next number is that number divided by two. When the
# current number is odd, multiply that number by three and add one to get
the next
# number in the sequence. Therefore, if we start with the wondrous number
15, the
# sequence is [15, 46, 23, 70, 35, 106, 53, 160, 80, 40, 20, 10, 5, 16, 8,
4, 2,
# 1].
q=quiz; x=[q]; until x[-1]==1 do x << ( q= q%2==0 ? q/2 : 3 * q + 1 ); end;
x
# Maybe not very challenging but a good read on Google:)
# Insert newlines into a paragraph of prose (provided in a String) so lines
will
# wrap at 40 characters.
#
quiz.gsub(/(.{1,40})(\b|\z)/){$1+"\n"}.gsub(/\s*\n\s*/,"\n").chomp
# tougher than I thought I am not sure about all edge cases
I attached a test suite and the solutions
Cheers
Robert
--
We have not succeeded in answering all of our questions.
In fact, in some ways, we are more confused than ever.
But we feel we are confused on a higher level and about more important
things.
-Anonymous
# Largely just to play around with rspec a bit.
# The random_line solution too long as well.
require 'rubygems'
require 'spec'
def commify(quiz)
quiz.to_s.reverse.gsub(/(\d{3})(?=\d)(?!\d*\.)/) {"#$1,"}.reverse
end
context "integers to strings" do
specify "should get commas every three digits from the right" do
commify(123).should == '123'
commify(1234).should == '1,234'
commify(123456).should == '123,456'
commify(-12345).should == '-12,345'
commify(-1001001).should == '-1,001,001'
end
end
context "floats to strings" do
specify "should not get commas after decimal" do
commify(123.456).should == '123.456'
commify(123.456789).should == '123.456789'
commify(123456.789).should == '123,456.789'
commify(-123456.789).should == '-123,456.789'
end
end
def flatten1(quiz)
quiz.inject([]){|r,n| n.respond_to?(:each) ? n.each {|i| r<< i} : (r<< n) ; r}
end
context "arrays nested arrays only one level deep" do
setup do
@ary = [[1],2,[:symbol],'foo']
@random = []
10.times do
n = rand(100)
@random << (rand > 0.5 ? n : [n] )
end
end
specify "should flatten1 the same as flatten" do
flatten1(@ary).should == @ary.flatten
flatten1(@random).should == @random.flatten
end
end
context "arrays nested multiple levels" do
specify "should only loose 1 level of arrays" do
flatten1([1, [2, [3]]]).should == [1,2,[3]]
flatten1([[[[[1]]]]]).should == [[[[1]]]]
end
end
def shuffle(quiz)
quiz.sort_by { rand }
end
context "An array with several elements" do
setup do
@rands = [3,2,1,6,5,4,9,8,7,10]
@a = (1..@rands.length).to_a
x = -1
self.stub!(:rand).and_return { @rands[x+= 1] }
end
specify "should sort randomly w/ shuffle" do
shuffle(@a).should == @rands[0..@a.length-1]
end
end
module GhostWheel
module Expression
class LookAhead
end
end
end
def to_class(quiz)
quiz.split(/::/).inject(Object) {|s,c| s.const_get(c.to_sym)}
end
context %{given a "class expression"} do
specify "to_class should return that class" do
GhostWheel.should_receive(:const_get).with(:Expression).and_return(GhostWheel::Expression)
GhostWheel::Expression.should_receive(:const_get).with(:LookAhead).and_return(GhostWheel::Expression::LookAhead)
to_class("GhostWheel::Expression::LookAhead")
end
specify "to_class should work for built-in classes" do
to_class("Net::HTTP").should == Net::HTTP
end
end
def wrap(quiz)
quiz.gsub(/(.{1,40})\s+/){ "$1\n" }
end
context "A paragraph of text w/ less than 40 lines" do
setup do
@text = 'f' * 40
end
specify "should not be changed by wrap" do
wrap(@text).should == @text
end
end
context "A paragraph with more than 40 characters" do
setup do
@paragraph = <<-END_PARA.gsub(/\s+/, ' ').strip
Given a wondrous number Integer, produce the sequence (in an
Array). A wondrous number is a number that eventually
reaches one, if you apply the following rules to build a
sequence from it. If the current number in the sequence is
even, the next number is that number divided by two. When
the current number is odd, multiply that number by three and
add one to get the next number in the sequence. Therefore,
if we start with the wondrous number 15, the sequence is
[15, 46, 23, 70, 35, 106, 53, 160, 80, 40, 20, 10, 5, 16, 8,
4, 2, 1].
END_PARA
end
specify "should have no lines longer than 40 wide after wrapping" do
wrap(@paragraph).split(/\n/).each do |line|
line.length.should_not > 40
end
end
end
context "An paragraph with a word longer than 40 characters" do
setup do
@text = 'f' * 60
end
specify "should not be split mid word" do
wrap(@text).should_not_include '\n'
end
end
def anagrams(quiz)
n=quiz[0].split(//).sort; quiz.select {|i| i.split(//).sort == n }
end
context "An array of words" do
setup do
@a = %w/silly lilsi looloo yllis yuf silly2 islyl/
end
specify "anagrams should contain words with same letters same number
of times" do
anagrams(@a).should == %w/silly yllis islyl/
end
end
def to_bin(quiz)
quiz.scan(/\w/).collect {|c| sprintf "%b", c[0] }.join('')
end
context "A ascii string" do
setup do
@str = "you are dumb"
end
specify "should be converted to binary by to_bin" do
to_bin(@str).should == '111100111011111110101' +
'110000111100101100101' +
'1100100111010111011011100010'
end
end
def rand_line(quiz)
z=0;quiz.each{z+=1};quiz.seek 0;n=rand
z;quiz.each_with_index{|x,i|;return x if i==n}
end
context "an open file handle" do
setup do
require 'stringio'
@fh = StringIO.new <<-END
one
two
three
four
END
end
specify "should return a random line" do
line = rand_line(@fh).strip
%w/one two three four/.should_include(line)
end
end
def wonder(quiz)
@a=[quiz];until quiz==1;@a<< quiz=quiz%2==0?quiz/2: quiz*3+1 end;@a
end
context "The wonderous sequence for 15" do
setup { @w = wonder(15) }
specify "should end with 1" do
@w[@w.length-1].should == 1
end
specify "should match the test data" do
@w.should == [15, 46, 23, 70, 35, 106, 53, 160, 80, 40, 20, 10, 5,
16, 8, 4, 2, 1]
end
end
def hashify(quiz)
quiz.reverse.inject(){|m,i|{i=>m}}
end
context "An array of strings" do
specify "should return nested hashes when hashified" do
hashify(%w/one two three four five/).should ==
{"one" => {"two" => {"three" => {"four" => "five"}}}}
end
end
Comparing this with James' solution we can it down to
quiz.inject{|r,a|[*r]+[*a]}
On 2/12/07, Eric I. <rubytraining@gmail.com> wrote:
On Feb 12, 1:07 am, "Phrogz" <g...@refinery.com> wrote:
> On Feb 11, 4:40 pm, Alex Young <a...@blackkettle.org> wrote:
>
> > # One-level flatten().
> > r=;quiz.each{|a|r+=[*a]};r
>
> Elegantly small!When I saw that, I thought that it could definitely be shortened by
using an inject. After all, there'd be no assignments of r, no final
returning of r, no semicolons. But when all was said and done, it
ended up being the same length. Compare:quiz.inject(){|r,a|r+[*a]}
r=;quiz.each{|a|r+=[*a]};rOh well....
Eric
=================
I think this quiz is just lovely!!!
Robert
----------------
Are you interested in on-site Ruby training that uses well-designed,
real-world, hands-on exercises? http://LearnRuby.com
--
We have not succeeded in answering all of our questions.
In fact, in some ways, we are more confused than ever.
But we feel we are confused on a higher level and about more important
things.
-Anonymous
Neither did I, I was just looking for an easy test. And yet, lo and behold:
http://cancerweb.ncl.ac.uk/cgi-bin/omd?query=tac
A kind of customary payment by a tenant; a word used in old records.
Origin: Cf. Tack, 4.
Source: Websters Dictionary
On 2/9/07, Chris Shea <cmshea@gmail.com> wrote:
[snip]
> # Given an Array of String words, build an Array of only those words that
> # are anagrams of the first word in the Array.
> def test_find_anagrams
> anagrams = %w(cat act)
> assert_equal anagrams, OneLiner.find_anagrams(%w(tac bat cat rat act))
> end
[snip]I changed anagrams to %w(tac cat act). I'm the sort of person that
thinks a word is an anagram of itself (although, I have a feeling
"tac" isn't a word).
My solution handles either.
James Edward Gray II
On Feb 9, 2007, at 6:00 PM, Phrogz wrote:
On Feb 9, 4:46 pm, James Edward Gray II <j...@grayproductions.net> > wrote:
On Feb 9, 2007, at 5:35 PM, Phrogz wrote:
# Built-in classes for testing #4
:class_from_string => [
["OpenSSL", OpenSSL ],
["OpenSSL::Digest", OpenSSL::Digest ],
["OpenSSL::Digest::DigestError", OpenSSL::Digest::DigestError ],
],Technically those are constants, not classes. For example, OpenSSL
is a module. That neatly foils a solution someone sent me off list
today.I had wondered about that. The wording of the quiz says "class", but I
figure that:
a) Given the number of modules-as-namespaces over classes-as-
namespaces, a good solution to the problem allows module stops along
the way, and thus
b) If you're going to allow non-classes along the way, you generally
want the "resolve this as though I typed it" functionality, which may
end in constants.BUT...if the quiz has the wrinkle that only Classes should be returned
(and thus you should get nil for the cases above), that would be
interesting to program, too.
def anagrams(quiz)
n=quiz[0].split(//).sort; quiz.select {|i| i.split(//).sort == n }
end
Argh! #select is exactly what I should have used. Nice.
def hashify(quiz)
quiz.reverse.inject(){|m,i|{i=>m}}
end
How very elegant. I kept thinking there should be a way to bootstrap
the inner pair to be like all the outers, but couldn't find it. Well
done.
On Feb 11, 9:27 am, "Louis J Scoras" <louis.j.sco...@gmail.com> wrote:
please kindly insert the string "get" on the appropriate place in my last
post
Robert Dober wrote:
>
> > # One-level flatten().
> > r=;quiz.each{|a|r+=[*a]};r
>
> Elegantly small!When I saw that, I thought that it could definitely be shortened by
using an inject. After all, there'd be no assignments of r, no final
returning of r, no semicolons. But when all was said and done, it
ended up being the same length. Compare:quiz.inject(){|r,a|r+[*a]}
Given the equal lengths, I prefer this - the r=;...;r idiom strikes me as rather ugly.
r=;quiz.each{|a|r+=[*a]};r
Oh well....Eric
Comparing this with James' solution we can it down to
quiz.inject{|r,a|[*r]+[*a]}
Wow
On 2/12/07, Eric I. <rubytraining@gmail.com> wrote:
On Feb 12, 1:07 am, "Phrogz" <g...@refinery.com> wrote:
> On Feb 11, 4:40 pm, Alex Young <a...@blackkettle.org> wrote:
--
Alex
Alex Young wrote:
Robert Dober wrote:
Hi All! Hi James! Hi Robert!
just wanted to note that there seems to be not a single message
from Robert on the newsgroup side of life.
(i'm not using googles interface, but to clarify)
If this is old news, feel free to ignore me.
cheers
Simon