[QUIZ] Ducksay (#52)

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 >
   ----------------------------------
          \ :slight_smile:
           \ (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} :slight_smile:
           #{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/

This looks like a really fun quiz!

···

On Oct 21, 2005, at 5:45 AM, Ruby Quiz wrote:

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 >
     ----------------------------------
            \ :slight_smile:
             \ (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} :slight_smile:
             #{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
Yakima Herald-Republic
WebMaster

509-577-7732
ezra@yakima-herald.com

#!/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} :slight_smile:
   #{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

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.

#templates are text files with ascii character and "#tail#" for
#the tail character, "#eye#" for one eye and "#eyes#" for two eyes.
#example templates are cow.txt, duck.txt and duck2.txt
template = "duck2.txt"
#edit saying as per your wishes
saying = "Fourscore and seven years ago our fathers brought\nforth on this
continent a new nation,\nconceived in liberty and dedicated to
the\nproposition that all men are created equal."
#edit eye-style, "eyes" is for templates with two eyes, "eye" for one-eyed
templates
eyes = "oo"
eye = "o"
#tongue, two chars
tongue = "@ "

#"think" for think-cloud, atm, there's only think and the default ("say") as
per cowsay.net <http://cowsay.net>
cloud_type = "say"

#If you want another style of cloud, add one here.
#Also, the clouds tail-style is decided here as well.
#Remember to escape special characters.
if cloud_type == "think" then
cloud_oneline_left = "("
cloud_oneline_right = ")"
cloud_upper_left = "("
cloud_upper_right = ")"
cloud_middle_left = "("
cloud_middle_right = ")"
cloud_lower_left = "("
cloud_lower_right = ")"
tail = "o"
else
cloud_oneline_left = "<"
cloud_oneline_right = ">"
cloud_upper_left = "/"
cloud_upper_right = "\\"
cloud_middle_left = "|"
cloud_middle_right = "|"
cloud_lower_left = "\\"
cloud_lower_right = "/"
tail = "\\"
end

#The ducksay application

#prints out as many spaces as the first argument (an integer),
#then puts the string, which defaults to ""
def output_spaces (intnumber, string="")
intnumber.times { print " " }
puts string
end
def output_chars (intnumber, string=" ")
intnumber.times { print string }
puts
end

#the balloon, and the saying
print " " #put start of the balloon at proper place
unless saying.include? ?\n then
#single line saying
output_chars(saying.length, "_")
puts " " + cloud_oneline_left + saying + cloud_oneline_right
print " " #put closing of balloon at proper place
output_chars(saying.length, "-")
puts
else
#multiple line saying
saying = saying.split("\n")
longest_line = 0
saying.each do |x|
longest_line = x.length if (x.length > longest_line)
end
output_chars(longest_line, "_")
#First line of the multi-line cloud
current_line = saying.shift
print_spaces = longest_line - current_line.length
print " " + cloud_upper_left + current_line
output_spaces(print_spaces, cloud_upper_right)
#The rest of the lines
while not saying.empty?
current_line = saying.shift
print_spaces = longest_line - current_line.length
if saying.empty? then
#When on the last line, "close" the cloud with cloud_lower_left and _right
chars
print " " + cloud_lower_left + current_line
output_spaces(print_spaces, cloud_lower_right)
else
#Put proper left and right chars for the cloud when in the "middle" of it
print " " + cloud_middle_left + current_line
output_spaces(print_spaces, cloud_middle_right)
end
end
print " " # put the clouds closing at proper place
output_chars(longest_line, "-")
end
#print out the template, aka, the ascii animal
#in the template files, "Å" substitutes the tail, "Ä" one eye, and "ÄÄ" two
eyes
File.open(template) do |file|
while line = file.gets
#substitute the placeholder characters with the cloud tail and eye(s), then
print it out
line.gsub!("#tail#", tail)
line.gsub!("#eyes#", eyes)
line.gsub!("#eye#", eye)
line.gsub!("#tongue#", tongue)
puts line
end
end

-----------
cow.txt:
-----------
#tail# :slight_smile:
#tail# (#eyes#)\_______
(__)\ )\/\
#tongue# ||----w |

>>

-----------
duck.txt:
-----------
#tail#
#tail# .~~.
'_-( #eyes# )
'-'==(___/)
( ( . /
\ '- ' /

-----------
duck2.txt:
-----------
#tail#
` >(#eye#)____,
(` =~~/
^~^~^~^~^~`---'^~^~^~^~^~
-----------

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

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

James Edward Gray II

···

On Oct 21, 2005, at 2:20 PM, Ezra Zygmuntowicz wrote:

This looks like a really fun quiz!

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! :wink:

···

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

Best line of Ruby code ever!

martin

···

Dave Burt <dave@burt.id.au> wrote:

class Cow < Duck

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

···

On 10/22/05, James Edward Gray II <james@grayproductions.net> wrote:

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. :wink:

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

James Edward Gray II

_________________________
/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

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

Looking great! Can't wait to see it.

James Edward Gray II

···

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)____,
(` =~~/
^~^~^~^~^~`---'^~^~^~^~^~^~^~^~^~^~