Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[QUIZ] Ducksay (#52)

9 views
Skip to first unread message

Ruby Quiz

unread,
Oct 21, 2005, 8:45:40 AM10/21/05
to
The three rules of Ruby Quiz:

1. Please do not post any solutions or spoiler discussion for this quiz until
48 hours have passed from the time on this message.

2. Support Ruby Quiz by submitting ideas as often as you can:

http://www.rubyquiz.com/

3. Enjoy!

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

by Jonas Pfenniger

__________________________________
< Welcome to this week's Ruby Quiz >
----------------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||

This week, we will make some ascii-art for fun.

Produce a script that generates funny talking animals. The executable
consists of three parts.

Part One : The balloon
=====================

The balloon is the surrounding part, in which the text will be shown. You can
make it like you want.

Examples :

One-liner
_______________
< I love ruby ! >
---------------

Multiple lines with text wrapping and carriage return
__________________________________________
/ Q:How do you stop an elephant from \
| charging? |
\ A:Take away his credit cards. /
------------------------------------------

Part Two : The template
=======================

To make it flexible, we'll need a template language that can combine the animal
and the text. You'll have to think about how you want to make it flexible
enough.

Example :

# thoughts is the balloon's tail
def animal(thoughts = '\', eyes = 'oo', tongue=' ')
%[#{baloon}
#{thoughts} ^__^
#{thoughts} (#{eyes})\\_______
(__)\\ )\\/\\
#{tongue} ||----w |
|| ||
]
end

Part Three : The command-line arguments
=======================================

There are no special arguments. I would suggest asking for a text input, but you
can also get the text from `fortune` or make it editable in place. Optional
arguments can be given to change the selected template and some of its
variables like the eyes, the tongue, and the balloon's tail.

Use your imagination !

So that's it for the quiz. Extra points are given to the person who
provides a duck template.

Credits
=======

- cowsay : http://www.cowsay.net/


Ezra Zygmuntowicz

unread,
Oct 21, 2005, 3:20:13 PM10/21/05
to
This looks like a really fun quiz!

-Ezra Zygmuntowicz
Yakima Herald-Republic
WebMaster
http://yakimaherald.com
509-577-7732
ez...@yakima-herald.com

James Edward Gray II

unread,
Oct 21, 2005, 7:11:53 PM10/21/05
to
On Oct 21, 2005, at 2:20 PM, Ezra Zygmuntowicz wrote:

> This looks like a really fun quiz!

I thought so too. Submitters always make better quizzes than me,
which is why I encourage them so much. ;)

This is a terrific problem for beginners, so hopefully we'll see some
new names in the solutions!

James Edward Gray II


JB Eriksson

unread,
Oct 22, 2005, 7:57:18 AM10/22/05
to

Well, I'm new on this quiz thingy... And I've already have some results to
show off (which I hope isn't a spoiler):
_________________________
/The quick brown fox jumps\
\ over the lazy dog. /
-------------------------
\
` >(o)____,
(` =~~/
^~^~^~^~^~`---'^~^~^~^~^~^~^~^~^~^~
I've sacrificed a couple of characters to get flexibility on the template,
however. and no tongue. I also have the commandline arguments to take care
of as well.
/Johan

James Edward Gray II

unread,
Oct 22, 2005, 11:52:11 AM10/22/05
to
On Oct 22, 2005, at 6:57 AM, JB Eriksson wrote:

> Well, I'm new on this quiz thingy... And I've already have some
> results to
> show off (which I hope isn't a spoiler):
> _________________________
> /The quick brown fox jumps\
> \ over the lazy dog. /
> -------------------------
> \
> ` >(o)____,
> (` =~~/
> ^~^~^~^~^~`---'^~^~^~^~^~^~^~^~^~^~

Looking great! Can't wait to see it.

James Edward Gray II


Dave Burt

unread,
Oct 23, 2005, 10:44:45 AM10/23/05
to
#!/usr/bin/ruby
#
# Ducksay
#
# A response to Ruby Quiz of the Week #52 [ruby-talk:161834]
#
# It's a script that generates funny talking animals, like the one at
# http://www.cowsay.net/
#
# From the command line, use --help for usage info.
# Basically, you can give some parameters, and you have to give the duck's
# speech on STDIN.
#
# Create a new template by subclassing Duck.
#
# You can also use it from inside Ruby -- use the say method of Duck, etc.
#
# Author: Dave Burt <dave at burt.id.au>
#
# Created: 23 Oct 2005
#
# Last modified: 24 Oct 2005
#
# Fine print: Provided as is. Use at your own risk. Unauthorized copying is
# not disallowed. Credit's appreciated if you use my code. I'd
# appreciate seeing any modifications you make to it.

class String
def width
inject(0) {|w, line| [w, line.chomp.size].max }
end
def height
to_a.size
end
def top
to_a.first
end
def middle
to_a.values_at(1..-1)
end
def bottom
to_a.last
end
end

class Duck
def self.say(speech="quack?", *args)
balloon(speech) + body(*args)
end

def self.balloon(speech)
" _#{ '_' * speech.width }_\n" +
if speech.chomp =~ /\n/
"/ %-#{ speech.width }s \\\n" % speech.top.chomp +
speech.middle.map do |line|
"| %-#{ speech.width }s |\n" % line.chomp
end.join +
"\\ %-#{ speech.width }s /\n" % speech.bottom.chomp
else
"< #{ speech.chomp } >\n"
end +
" -#{ '-' * speech.width }-\n"
end

def self.body(thoughts='\\', eyes='cc', tongue=' ')
" #{thoughts}
#{thoughts}
_ ___
/ \\ / \\
\\. |: #{eyes}|
(.|:,---,
(.|: \\( |
(. y-'
\\ _ / #{tongue}
m m
"
end
end

class Cow < Duck
def self.body(thoughts='\\', eyes='oo', tongue=' ')


" #{thoughts} ^__^
#{thoughts} (#{eyes})\\_______
(__)\\ )\\/\\
#{tongue} ||----w |
|| ||
"
end

end

class DuckOnWater < Duck
def self.body(thoughts='\\', eyes='º', tongue='>')
" #{thoughts}
` #{tongue[0, 1]}(#{eyes[0, 1]})____,
(` =~~/
~^~^~^~^~`---'^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~
"
end
end

if $0 == __FILE__
if ARGV.include?("--help")
puts "usage: #$0 animal thoughts eyes tongue <speech\n"
puts "animals: Duck Cow DuckOnWater\n"
puts "e.g.: #$0 DuckOnWater o x ) </etc/fortune\n"
else
animal = Object.const_get(ARGV.shift) rescue Duck
puts animal.say(STDIN.read, *ARGV)
end
end


JB Eriksson

unread,
Oct 23, 2005, 11:40:06 AM10/23/05
to
my solution. not very OO at all, however. I just hope the formatting doesn't
screw up on the animal template files...

/Johan B Eriksson

-----------
cowsay.rb:
-----------
# Rubyquiz #52, Ducksay
# ascii animals talking using ascii comic balloons.
#
#
# I couldn't get commandline arguments working properly on my machine, so I
skipped it.
# Instead, change the variable values to suit your needs.
#
# This solution does not automatically wordwrap the sayings. Do it manually

Jacob Quinn Shenker

unread,
Oct 23, 2005, 4:02:03 PM10/23/05
to
Hey all, here's my first RQ submition and my first golf. Hurray!
I know golfs aren't encouraged at all... but I couldn't resist... Sorry! ;-)

######################
#!/usr/bin/env ruby
# ~383 chars
# y = "eye"
# m = "beak/mouth"
# z = "balloon tail"
# f = "text" (defaults to fortune)
y="º"[0..1];m=">"[0..1];z="\\";w=40;N="\n";BS="\\"+N;S="
";f=`fortune`.split(N);e=f.collect{|v|v.split(/\s+/)};t="
#{"_"*w}\n/"+S*w+BS;while e.size>0;l="|";d=e.shift;while
d.size>0;while d.size>0&&(l+d.first).length<w;l+=d.shift+S;end;t+=l+S*(w-l.length+1)+"|"+N;l="|";end;end;t+="\\#{'_'*w}/"+N;h=S*3+z+N;b=S*5+"`
#{m}(#{y})____,\n"+S*8+"(` =~~/\n"+"^~"*5+"`---'"+"^~"*30;puts t+h+b
#######################

output:
________________________________________
/ \
|Q: What do you call the money you pay |
|to the government when |
| you ride into the country on the back |
|of an elephant? |
|A: A howdah duty. |
\________________________________________/
\
` >(º)____,
(` =~~/
^~^~^~^~^~`---'^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~

Jacob

Ryan Leavengood

unread,
Oct 23, 2005, 9:20:08 PM10/23/05
to
This was quite fun. I decided not to go into ASCII art creation and
"cheated" by getting some wacky animals from http://www.ascii-art.de,
including several ducks. As noted in the source I developed this on a
Windows machine which does not have fortune (at least without getting
Cygwin, etc.), so I found a CGI script online which has fortune, and I
use open-uri to access it.

I'm sure my "bubble maker" could be golfed down a bit, but I preferred
clarity over terseness.

All the animals in the "zoo" are embedded in the DATA section of the
script, with a special format to delimit them. It is fairly easy to
add new animals should one want to.

I also used a different style of command-line options, since it fit
this problem. Here is an example run:

C:\_Ryan\ruby\quiz\52_ducksay>ruby ducksay.rb gecko.say "Ruby Rocks!"
_____________
< Ruby Rocks! >
-------------
\
\
___
)/_ ,@ /
|(_,' _@/
| /
\)/ / (_)/
((_/ ,----~
\ (_)/
/ ,-----~
((' _,-.
\\=//

The text after my name will be the code for my solution.

Ryan

require 'open-uri'
require 'singleton'

# Here we have a bubble machine
class Bubble
def self.make(text)
return '' if text.nil? or text == ''
result = ''
lines = text.split("\n")
max_length = lines.max{|a,b| a.length <=> b.length}.length
hf = proc {|s| " #{s * (max_length+2)} \n"}
result << hf['_']
case lines.length
when 1: result << "< #{lines[0]} >\n"
else
pad_it = proc {|s| s.ljust(max_length)}
result << "/ #{pad_it[lines.shift]} \\\n"
0.upto(lines.length-2) do |i|
result << "| #{pad_it[lines[i]]} |\n"
end
result << "\\ #{pad_it[lines[-1]]} /\n"
end
result << hf['-']
end
end

# Our lovely Zoo, full of many wacky animals
class Zoo
include Singleton
attr_reader :animals
def initialize
@animals = {}
current_key = nil
DATA.each do |line|
if line.chomp =~ /^'(\w*)':$/
current_key = $1
@animals[current_key] = []
elsif current_key
@animals[current_key] << line
end
end
end

# A random animal has escaped!
def escape
choices = @animals.keys
@animals[choices[rand(choices.length)]]
end
end

# Since I wrote this on Windows I don't have fortune...but the
# internet does!
def get_fortune
open('http://www.coe.neu.edu/cgi-bin/fortune') do |page|
page.read.scan(/<pre>(.*)<\/pre>/m)[0][0].gsub("\t",' ')
end
end

if $0 == __FILE__
animal = nil
message = nil
case ARGV[0]
when 'list':
puts "Your zoo contains the following animals:"
puts Zoo.instance.animals.keys.sort.join("\n")
exit(0)
when /\A(\w*)\.say/:
animal = Zoo.instance.animals[$1]
unless animal
puts "Unknown animal #$1! Try 'list' to list your animals."
exit(1)
end
if ARGV.length > 1
message = ARGV[1..-1].join(" ")
end
when nil:
animal = Zoo.instance.escape
else
puts "Usage: #$0 <command>",
"Where command is",
"\tlist: to list your animals.",
"\t<animal>.say \"<message>\": to have that animal say that",
"\t\tmessage, where the message is optional.",
"\nWith no command the default is a random animal, with a",
"message from fortune."
exit(1)
end
unless message
message = get_fortune
end
puts Bubble.make(message)
puts animal
end

# The ASCII animals below are courtesy of http://www.ascii-art.de
__END__
'crazyduck':
\ _____
\ \\_-~~ ~~-_
\ /~ ~\
\ _| _ |
\ ___) ~~) ~~~--_ |
\ _-~ ~-_ ___ \ |/
\ / _-~ ~-_ /
\ | / \ |
\ | O) | | |
| | | |
| | (O | |
\ | | |\
(~-_ _-\ / _--_ / \
\__~~~ ~-_ _-~ / ~\
/ ~---~~-_ ~~~ _-~ /| |
_-~ / \ ~~--~ | | |
_-~ | / |
,-~~-_ __--~~ |-~ /
| \ | _-~
\ |--~~
\ | |
~-_ _ | |
~-_ ~~---__ _--~~\ |
~~--__ / |
~~---___ __--~~| |
~~~~~ | |
| |
'lazyduck':
\
\ .-"""-. _.---..-;
:.) ;"" \/
__..--'\ ;-"""-. ;._
`-.___.^.___.'-.____J__/-._J
'duck':
\
\ _.-.
__.-' , \
'--'-'._ \
'. \
)-- \ __.--._
/ .' '--.
. _/-._
: ____._/ _-'
'._ _.'-'
'-._ _.'
\_|/
__|||
>__/'
'chunkybacon':
\
\ __ _.._
.-'__`-._.'.--.'.__.,
/--' '-._.' '-._./
/__.--._.--._.'``-.__/
'._.-'-._.-._.-''-..'
'raccoon':
\
\ __ .-.
\ .-"` .`'. /\\|
_(\-/)_" , . ,\ /\\\/
{(#b^d#)} . ./, |/\\\/
`-.(Y).-` , | , |\.-`
/~/,_/~~~\,__.-`
////~ // ~\\
==`==` ==` ==`
'bat':
\
\
, \ ,
./( )\.
) \/\_/\/ (
`) (^Y^) (`
`),-(~)-,(`
'"'
'buffalo':
\
\ _.-````'-,_
_,.,_ ,-'` `'-.,_
/) (\ '``-.
(( ) ) `\
\) (_/ )\
| /) ' ,' / \
`\ ^' ' ( / ))
| _/\ , / ,,`\ ( "`
\Y, | \ \ | ````| / \_ \
`)_/ \ \ ) ( > ( >
\( \( |/ |/
/_(/_( /_( /_(
'gecko':
\
\
___
)/_ ,@ /
|(_,' _@/
| /
\)/ / (_)/
((_/ ,----~
\ (_)/
/ ,-----~
((' _,-.
\\=//
'gorilla':
\
\
\ ."`".
.-./ _=_ \.-.
{ (,(oYo),) }}
{{ | " |} }
{ { \(---)/ }}
{{ }'-=-'{ } }
{ { }._:_.{ }}
{{ } -:- { } }
{_{ }`===`{ _}
((((\) (/))))
'gryphon':
\ ______
\ ______,---'__,---'
\ _,-'---_---__,---'
/_ (, ---____',
/ ',, `, ,-'
;/) ,',,_/,'
| /\ ,.'//\
`-` \ ,,' `.
`', ,-- `.
'/ / | `, _
//'',.\_ .\\ ,{==>-
__// __;_`- \ `;.__,;'
((,--,) (((,------; `--'
``` ' ```
'wombat':
\ ,.--""""--.._
\ ." .' `-.
\ ; ; ;
\ ' ; )
\ / ' . ;
/ ; `. `;
,.' : . : )
;|\' : `./|) \ ;/
;| \" -,- "-./ |; ).;
/\/ \/ );
: \ ;
: _ _ ; )
`. \;\ /;/ ; /
! : : ,/ ;
(`. : _ : ,/"" ;
\\\`"^" ` : ;
( )
////
'seaturtle':
/
/ _,.---.---.---.--.._
/ _.-' `--.`---.`---'-. _,`--.._
/ /`--._ .'. `. `,`-.`-._\
|| \ `.`---.__`__..-`. ,'`-._/
_ ,`\ `-._\ \ `. `_.-`-._,``-.
,` `-_ \/ `-.`--.\ _\_.-'\__.-`-.`-._`.
(_.o> ,--. `._/'--.-`,--` \_.-' \`-._ \
`---' `._ `---._/__,----` `-. `-\
/_, , _..-' `-._\
\_, \/ ._(
\_, \/ ._\
`._,\/ ._\
`._// ./`-._
`-._-_-_.-'
'lemur':
\ ,,
\ ==
\ ==
\ ==
\ ==
== ==
== == ==
== ==
, , ==
|\/| ,-..-,
,d__(..)\_/ \
;-,_`o/ |
'-| \_,' /^| /
( // / \ \
|| \ < \ )
_\| \ ) _\\
~` _\| ~`
~`
'koala':
\
\ ) ( |
\ ) ( / .-
_ ,---. _ ( / /
(~-| . . |-~) V /
\._ 0 _,/ /
/ `-^-'`-._ /
' `-. (
: )E
: ,---' (
. )E (
'._____,---' (
) (
) (
) (
) (
'armadillo':
\
\ __-----.,
.-:::,\\\\\::::,
\|\;`:::`` \\\\\\\'':\
/`'\\:: |||||| '\
/ e (\` |||||| , '.
.` _.-`~\_____/`````_X__/'-__~===-
'-~` ~~ ~~


Martin DeMello

unread,
Oct 25, 2005, 5:10:18 AM10/25/05
to
Dave Burt <da...@burt.id.au> wrote:
>
> class Cow < Duck

Best line of Ruby code ever!

martin

Dave Burt

unread,
Oct 25, 2005, 5:16:50 AM10/25/05
to
>> class Cow < Duck
>
> Best line of Ruby code ever!
>
> martin

It's my favourite line in the program, too. I was going to point it out in
my post, but I decided to paste instead of link.

Historical note: I originally wrote it the other way around, basing
everything on the Cow, but that's clearly not how it's meant to be.

BTW, another Cowsay reference:
http://www.nog.net/~tony/warez/cowsay.shtml

The above lists the cowsay perl software in its various forms, including the
CPAN module Acme::Cow.

Cheers,
Dave


0 new messages