[QUIZ] Hello, world? (#158)

M

Matthew D Moss

The three rules of Ruby Quiz 2:
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 2 by submitting ideas as often as you can! (A
permanent, new website is in the works for Ruby Quiz 2. Until then,
please visit the temporary website at

<http://matthew.moss.googlepages.com/home>.

3. Enjoy!

Suggestion: A [QUIZ] in the subject of emails about the problem
helps everyone on Ruby Talk follow the discussion. Please reply to
the original quiz message, if you can.

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

Hello, world?


The first program any new programmer typically sees is one that
prints out "Hello, world!" to the console. This tends to be something
experienced programmers also see when learning a new language. The
first Hello World program was written in B [1] by Kernighan and
looked like this:

main( ) {
extrn a, b, c;
putchar(a); putchar(b); putchar(c); putchar('!*n');
}

a 'hell';
b 'o, w';
c 'orld';

Most programmers are probably more familiar with the typical C
implementation:

main() {
printf("Hello, world!\n");
}

Ruby can present the same output very simply:

puts "Hello, world!"

But that's too simple... I mean, really... *anyone* can print a
simple string to standard output. Can't we get more interesting?
Hmmm, how about:

puts sprintf("%s, %s!", "Hello", "world")

Eh, that looks too much like C. Maybe...

puts %w(Hello world).join(", ") + "!"

Yeah, that's definitely looking Ruby-ish.

Your task this week is to print "Hello, world!" to standard output
using Ruby in atypical fashion. Some guildlines:

- DO submit multiple variants in your submission, but we don't need
100 variants from everyone. Try to limit yourself to your best dozen.
- DO keep things reasonably simple. I would expect many solutions to
be one- or two-liners, some solutions to involve classes and
functions, and a variety in-between. But we're looking for Ruby-isms,
not volume of code, so don't write pages upon pages of code just to
print "Hello, world!"
- DON'T obfuscate unnecessarily. We're looking for interesting Ruby
tricks, not utter confusion. A little obfuscation is okay, but a lot
is to be avoided.
- DON'T send me my own examples from above. I already did them. Do
other stuff. It *is* okay if your solution is similar to mine,
provided you make some interesting modifications.


[1] http://cm.bell-labs.com/cm/cs/who/dmr/btut.html
 
B

Bill Kelly

Greetings!

Here's the result of my quiz solution(s) so far:

$ ruby 158_hello_world.rb
Hello, World!
Hello, World!
Hello, World!
Hello, World!



<grin>


Regards,

Bill
 
R

Robert Dober

Greetings!

Here's the result of my quiz solution(s) so far:

$ ruby 158_hello_world.rb
Hello, World!
Hello, World!
Hello, World!
Hello, World!



<grin>


Regards,

Bill
How did you do that?????
Amazing.
R.
 
B

Bill Kelly

Greetings,

My quiz solution(s) are here:

http://tastyspleen.net/~billk/ruby/quiz/158-hello-world/158_hello_world.rb


I did five Hello World variations. Thus, the output of the program
when run, is simply:

Hello, World!
Hello, World!
Hello, World!
Hello, World!
Hello, World!


I think I had the most fun with #4, the maze solver:

m = <<MAZE
###+---+---+
^ H| l| o|
#| e| l| |
#+---+-+-+ |
#| d !*| , |
#| +--++ -+#
#|l | _ |#
#+--+ +-+ |#
####|r |W|#
##+-+- -+ |#
##| o |#
##+--+----+#
MAZE



Regards,

Bill
 
G

Gaspard Bucher

I love the maze !

Can ruby solve it ?

Isn't that better suited for a pure functional language ?
 
B

Bill Kelly

Hi,

From: "Gaspard Bucher said:
I love the maze !

Can ruby solve it ?

The code to solve the maze is included in the quiz solution, here:

http://tastyspleen.net/~billk/ruby/quiz/158-hello-world/158_hello_world.rb

See: Variation 4: Ambulatory greeting

Isn't that better suited for a pure functional language ?

Although I have books on Haskell and Erlang, I have only tinkered
with functional programming so far. However, there is definitely
nothing uncommon about solving mazes in an imperative programming
style.

The algorithm I used in the quiz was a very simplistic, non-recursive
breadcrumb approach.


Regards,

Bill
 
J

Jesse Merriman

Here's 6 little solutions (pastied http://pastie.caboo.se/160330 too). The
last two just print the file name, so they'll have to be in a "Hello, world!"
file (or as close as your OS supports).

## attempt 1

def print_caller
print caller.first.match(/`(.*)'$/)[1]
end

def H; print_caller; end
def e; print_caller; end
def l; print_caller; end
def o; print_caller; end
def comma; print ','; end
def space; print ' '; end
def w; print_caller; end
def r; print_caller; end
def d!; print_caller; end
def newline; print "\n"; end

H(); e; l; l; o; comma; space; w; o; r; l; d!; newline

## attempt 2

class Hello
def self.printer s; define_method(s) { print s; self }; end
%w{H e l o w r d!}.each { |s| printer(s) }
end

Hello.new.H.e.l.l.o.w.o.r.l.d!

## attempt 3

class Hello
def method_missing m; print m; self; end
end

Hello.new.H.e.l.l.o.send(', ').w.o.r.l.d!.send("\n")

## attempt 4, quine-ish

#!/usr/bin/env ruby

require 'enumerator'

lines = File.readlines(__FILE__)
[20, 0,
0, 11,
4, 0,
4, 0,
2, 17,
5, 3,
0, 14,
18, 28,
2, 17,
0, 5,
4, 0,
4, 16,
0, 1,
1, 0].each_slice(2) { |row, col| print lines[row][col..col] }

Hash

## attempt 5

# Must be in a file called "Hello, world!"
begin
raise :foo
rescue StandardError => se
puts se.backtrace.first.match(/([^\/\\:]+):/)[1]
end

## attempt 6

# Must be in a file called "Hello, world!"
puts __FILE__
 
T

Trans

I decided to take a "meta" approach and created a quick and dirty code
generator. I taught it some basic Ruby Identities and hen let it have
at it. With just the 5 silly identities that it currently has it can
generate never ending variations, though they get repetitive very
quickly --nevertheless there are already some unexpected solutions. I
suppose with maybe a few dozen identities it could get pretty
interesting.

Try running like so:

ruby helloword.rb 100
ruby helloword.rb test 100
ruby helloword.rb output 100

The number is the number of solutions to generate, 'test' will run it
through test/unit to make sure it all checks out and 'output' will
print a whole bunch of "Hello, World!"s :)

Oh, and yes, I know it's not all that robust. It was just a fun quick
hack. But feel free to improve it and let me know if you have any good
identities to add.

T.

---

class SimpleCodeGenerator

def self.identities
@identities ||= []
end

def self.identity(&block)
identities << block
end

attr_reader :eek:riginal
attr_accessor :alternates

def initialize(original)
@original = original
@alternates = [original]
end

def generate(limit=100)
work = original.dup
while(alternates.size < limit) do
alts = alternates.dup
size = alternates.size
alts.each do |alt|
self.class.identities.each do |identity|
self.alternates |= [identity[alt]]
break if alternates.size >= limit
end
end
end
end

def show_code
alternates.each do |code|
puts code
end
end

def show_output
alternates.each do |code|
puts run(code)
end
end

def generate_tests
original_run = run(original)
runner = method:)run)
testcase = Class.new(Test::Unit::TestCase)
alternates.each_with_index do |code, index|
testcase.class_eval do
define_method("test_#{index}") do
assert_equal(original_run, runner
Code:
)
end
end
end
end

def run(code)
so = $stdout
sio = StringIO.new
$stdout, $stderr = sio, sio
eval code, $TOPLEVEL_BINDING
result = $stdout.string
$stdout = so
result
end

# code identities

identity do |code|
code.sub(/puts ["](.*)["]/, 'print "\1\n"')
end

identity do |code|
code.sub(/puts ["](.*)["]/, 'printf "%s\n" % ["\1"]')
end

identity do |code|
code.gsub(/["](.*)["]/, '"\1".reverse.reverse')
end

identity do |code|
code.gsub(/['](.*)[']/){ $1.inspect }
end

identity do |code|
code.gsub(/['](.*)[']/){ "#{$1.split(//).inspect}.join('')" }
end

end

if __FILE__ == $0
cnt = (ARGV.find{ |a| /\d+/ =~ a } || 20).to_i

scg = SimpleCodeGenerator.new("puts 'Hello, World!'")
scg.generate(cnt)

case ARGV[0]
when 'test'
require 'test/unit'
scg.generate_tests
when 'output'
scg.show_output
else
scg.show_code
end
end
 
J

Joel VanderWerf

Jesse said:
## attempt 3

class Hello
def method_missing m; print m; self; end
end

Hello.new.H.e.l.l.o.send(', ').w.o.r.l.d!.send("\n")

A variation:

def method_missing(*a) print *a end;h.e.l.l.o(", ").w.o.r.l.d("!\n")
 
J

Jason Dew

Here's all I came up with:

class Hello; def self.world!; [self, __callee__].join(' '); end; end

puts Hello.world!

Only works with Ruby 1.9 though...

The three rules of Ruby Quiz 2:
1. =A0Please do not post any solutions or spoiler discussion for this =A0
quiz until 48 hours have passed from the time on this message.

2. =A0Support Ruby Quiz 2 by submitting ideas as often as you can! (A =A0
permanent, new website is in the works for Ruby Quiz 2. Until then, =A0
please visit the temporary website at

=A0 =A0 =A0<http://matthew.moss.googlepages.com/home>.

3. =A0Enjoy!

Suggestion: =A0A [QUIZ] in the subject of emails about the problem =A0
helps everyone on Ruby Talk follow the discussion. =A0Please reply to =A0
the original quiz message, if you can.

-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-= =3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-

Hello, world?

The first program any new programmer typically sees is one that =A0
prints out "Hello, world!" to the console. This tends to be something =A0
experienced programmers also see when learning a new language. The =A0
first Hello World program was written in B [1] by Kernighan and =A0
looked like this:

=A0 =A0 =A0 =A0 =A0main( ) {
=A0 =A0 =A0 =A0 =A0 =A0 =A0extrn a, b, c;
=A0 =A0 =A0 =A0 =A0 =A0 =A0putchar(a); putchar(b); putchar(c); putchar('!*= n');
=A0 =A0 =A0 =A0 =A0}

=A0 =A0 =A0 =A0 =A0a 'hell';
=A0 =A0 =A0 =A0 =A0b 'o, w';
=A0 =A0 =A0 =A0 =A0c 'orld';

Most programmers are probably more familiar with the typical C =A0
implementation:

=A0 =A0 =A0 =A0 =A0main() {
=A0 =A0 =A0 =A0 =A0 =A0 =A0printf("Hello, world!\n");
=A0 =A0 =A0 =A0 =A0}

Ruby can present the same output very simply:

=A0 =A0 =A0 =A0 =A0puts "Hello, world!"

But that's too simple... I mean, really... *anyone* can print a =A0
simple string to standard output. Can't we get more interesting? =A0
Hmmm, how about:

=A0 =A0 =A0 =A0 =A0puts sprintf("%s, %s!", "Hello", "world")

Eh, that looks too much like C. Maybe...

=A0 =A0 =A0 =A0 =A0puts %w(Hello world).join(", ") + "!"

Yeah, that's definitely looking Ruby-ish.

Your task this week is to print "Hello, world!" to standard output =A0
using Ruby in atypical fashion. Some guildlines:

- DO submit multiple variants in your submission, but we don't need =A0
100 variants from everyone. Try to limit yourself to your best dozen.
- DO keep things reasonably simple. I would expect many solutions to =A0
be one- or two-liners, some solutions to involve classes and =A0
functions, and a variety in-between. But we're looking for Ruby-isms, =A0
not volume of code, so don't write pages upon pages of code just to =A0
print "Hello, world!"
- DON'T obfuscate unnecessarily. We're looking for interesting Ruby =A0
tricks, not utter confusion. A little obfuscation is okay, but a lot =A0
is to be avoided.
- DON'T send me my own examples from above. I already did them. Do =A0
other stuff. It *is* okay if your solution is similar to mine, =A0
provided you make some interesting modifications.

[1]http://cm.bell-labs.com/cm/cs/who/dmr/btut.html
 
P

Paul McMahon

def method_missing(method) puts method end
def Object.const_missing(const) print const.to_s + ", " end
[Hello, World!]
 
M

Morton Goldberg

To me, the essence of a "hello, world" program is to get the phase on
the computer screen. But "on the screen" doesn't have to mean "write
to stdout". My three solutions all avoid stdout.

The first solution highjacks Apple's TextEdit application.

<code>
require "appscript"
include Appscript
te = app('TextEdit')
te.launch
te.documents.end.make:)new => :document,
:with_properties => {:text => "hello, world\n"})
</code>

The second solution uses an AppleScript dialog.

<code>
require "osax"
include OSAX
osax.display_dialog("hello, world")
</code>

These first two solutions are Apple-centric. I don't apologize for
that. I also employed the classic Kernighan and Ritchie version, just
"hello, world", no caps or exclamation point.

The third solution uses Tk and should run on any system with a
functioning Ruby/Tk library, but you may have to specify another
font. This one is not so minimalist as the first two. Here I use what
today seems to be the most common version of the phrase ("Hello,
World!") just because it looks prettier in 72-point Brush Script.

<code>
require 'tk'

root = Tk.root
root.title('Ruby/Tk Hello')
win_w, win_h = 360, 160
win_x = (root.winfo_screenwidth - win_w) / 2
root.geometry("#{win_w}x#{win_h}+#{win_x}+50")
root.resizable(false, false)

TkLabel.new(root) {
text 'Hello, World!'
relief 'solid'
borderwidth 1
font('family'=>'Brush Script MT', 'size'=>72)
place("x"=>10, "y"=>10, "height"=>92, "width"=>340)
}

TkButton.new(root) {
text 'Goodbye'
command { Tk.root.destroy }
place("x"=>138, "y"=>122, "height"=>28, "width"=>83)
}

Tk.mainloop
</code>

The use of 'place', rather than 'pack' may seem strange. I confess I
wrote the Ruby/Tk version quite some time ago when I was
experimenting with the 'place' layout manager.

Regards, Morton
 
F

fedzor

Nothing too much for now. Wasn't sure _how_ unobfuscated to do them,
so i just did simple ones. Except for my first one, which flashes
different colors.

Hit <enter> to stop the loop!

http://pastie.caboo.se/160366


~ Ari
English is like a pseudo-random number generator - there are a
bajillion rules to it, but nobody cares.
 
J

Justin Ethier

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

Here's my solution:

hello, world = "", 2645608968345021733469237830984
(hello << (world % 256); world /= 256) until world == 0
puts hello

Have a good one,

Justin


The three rules of Ruby Quiz 2:
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 2 by submitting ideas as often as you can! (A
permanent, new website is in the works for Ruby Quiz 2. Until then,
please visit the temporary website at

<http://matthew.moss.googlepages.com/home>.

3. Enjoy!

Suggestion: A [QUIZ] in the subject of emails about the problem
helps everyone on Ruby Talk follow the discussion. Please reply to
the original quiz message, if you can.

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

Hello, world?


The first program any new programmer typically sees is one that
prints out "Hello, world!" to the console. This tends to be something
experienced programmers also see when learning a new language. The
first Hello World program was written in B [1] by Kernighan and
looked like this:

main( ) {
extrn a, b, c;
putchar(a); putchar(b); putchar(c); putchar('!*n');
}

a 'hell';
b 'o, w';
c 'orld';

Most programmers are probably more familiar with the typical C
implementation:

main() {
printf("Hello, world!\n");
}

Ruby can present the same output very simply:

puts "Hello, world!"

But that's too simple... I mean, really... *anyone* can print a
simple string to standard output. Can't we get more interesting?
Hmmm, how about:

puts sprintf("%s, %s!", "Hello", "world")

Eh, that looks too much like C. Maybe...

puts %w(Hello world).join(", ") + "!"

Yeah, that's definitely looking Ruby-ish.

Your task this week is to print "Hello, world!" to standard output
using Ruby in atypical fashion. Some guildlines:

- DO submit multiple variants in your submission, but we don't need
100 variants from everyone. Try to limit yourself to your best dozen.
- DO keep things reasonably simple. I would expect many solutions to
be one- or two-liners, some solutions to involve classes and
functions, and a variety in-between. But we're looking for Ruby-isms,
not volume of code, so don't write pages upon pages of code just to
print "Hello, world!"
- DON'T obfuscate unnecessarily. We're looking for interesting Ruby
tricks, not utter confusion. A little obfuscation is okay, but a lot
is to be avoided.
- DON'T send me my own examples from above. I already did them. Do
other stuff. It *is* okay if your solution is similar to mine,
provided you make some interesting modifications.


[1] http://cm.bell-labs.com/cm/cs/who/dmr/btut.html
 
P

Philipp Hofmann

# i -- raising an HelloWorldError

class HelloWorldError < StandardError
def to_s
"Hello, World!"
end
end
module Kernel
def raise(e)
puts e
end
end
raise HelloWorldError.new


# ii -- a lost and found HelloWorld

class HelloWorld
def to_s
"Hello, World!"
end
end
HelloWorld.new
ObjectSpace.each_object { |o| puts o if o.is_a?(HelloWorld) }


# iii -- a little curry

hello = lambda { |a| "Hello, #{a.call}"}
world = lambda { "World!" }
puts hello.call(world)


# iv -- in only one line but to ruby instances

puts `ruby -e 'puts "Hello, World!"'`


# v -- and finally a probabilistic approach
# beware this one is not tested yet!
# which means the the test is still running and at
# least it didn't raise any errors so far ;)

goal = "Hello, World!\n"
bytes = goal.split(//).map { |e| e[0] }.uniq

seed = 0
until false
srand(seed)
i = 0
while i < goal.size
c = rand(bytes.size)
break if bytes[c] != goal
i += 1
end
break if i == goal.size
seed += 1
end

goal.size.times { print bytes[rand(bytes.size)].chr }



g phil
 
T

ThoML

Only a set of very basic solutions:


#!/usr/bin/env ruby19

puts '-- Exact solutions --'

STDOUT << 'Hello' << ', ' << 'world' << '!' << "\n"

puts 'Holle, werld!'.tr('eo', 'oe')

puts '!dlrow ,olleH'.reverse

def method_missing(*a); puts 'Hello, world!'; end; say_hi

a = [1,2,3]; def a.to_s; 'Hello, world!'; end; puts "#{a}"

require 'zlib'
hw = Zlib::Deflate.new.deflate("Hello, world!", Zlib::FINISH)
puts Zlib::Inflate.new.inflate(hw)

puts [1819043144, 1998597231, 1684828783,
538976289].pack('VVVV').strip

puts ('%x' % 10484973469620254453249450853906).scan(/../).pack('h2' *
13)



puts '-- Approximative solutions --'

puts 'Hello, world!'.split('').map {|c| /\l/ =~ c ? '%c' % (c.ord +
rand(3) - 1) : c}.join

puts 'Hello, world!'.gsub(/\b\w{4,}?\b/) {|t| t[1..-2] =
t[1..-2].split('').shuffle.join; t }

puts [6.51886850036479e+265, 6.01347722536415e-154].pack('EE').strip
 
R

Robert Dober

Just wanted to say "Hello" ;)


# Probably my only solution that makes sense ;)
puts "hello, world!".split.map{ |x| x.capitalize }.join(' ')

# Amazingly you can do << with ints to strings
puts [?H, ?e, ?l, ?l, ?o, ?,, ?\s, ?W, ?o, ?r, ?l, ?d, ?!].
inject(""){|s,char| s << char}

# A tribute to perl ;)
def method_missing *args, &blk
puts "Hello, World"
end

croak


# You cannot add strings and ints
begin
puts [?h, ?e, ?l, ?l, ?o, ?,, ?\s, ?w, ?o, ?r, ?l, ?d, ?!].
inject(""){|s,char| s + char}
abort "If you do not succeed..."
rescue
puts "!dlroW ,olleH".reverse
end
#

# What Mixins can do for you
module Hello
def hello_world
"Hello,"
end
end

module World
def hello_world
super <<
" World!"
end
end

class HelloWorld
extend Hello
extend World
def self.hello_world
puts super
end
end

HelloWorld.hello_world

# Abusing Kernel
module Kernel
alias_method :_puts, :puts
def puts *args, &blk
_puts "Hello, World!"
end
end

puts


# Metaprogramming on classes
class A
def self.inherited dummy
print "Hello,"
end
end

class B < A
class << self
def inherited dummy
print " World!"
end
end
end

class << C =3D Class::new( B )
def inherited dummy
puts
end
end

Class::new C


# A Hommage to James' G=F6del Quiz and showing that Integers are immutable
class Integer
def inject_chars istring, &blk
return istring if zero?
( self / 256 ).inject_chars( blk.call( istring, self % 256 ), &blk )
end
end
puts 2645608968345021733469237830984.inject_chars(""){ |s,n| s+n.chr }


#
#

# A more sensible approach of abusing Kernel::puts ;)
module Sensible
def puts *args
return Kernel::puts( *args ) unless args.empty?
Kernel::puts "Hello, World!"
end
end

include Sensible
puts
puts "Hello, Ruby Quiz!"

# A functional approach, introducing the splash
def print_strings *strings
return puts if strings.empty?
print strings.shift
print_strings *strings
end

print_strings %{Hello, World!}

# Blocks and Procs, split(//)
module Printable
def to_proc
lambda {
each do |elem| print elem end
}
end
end
Array.send :include, Printable

def yielder
yield
end

yielder &("Hello, World!" << 10).split(//)

# A radical and viral solution
ObjectSpace.each_object(Module) do |mod|
mod.send :define_method, :hello_world do puts "Hello, World!" end
end

42.hello_world
Object.hello_world
nil.hello_world

(A =3D Class::new).hello_world


--=20
http://ruby-smalltalk.blogspot.com/
 

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,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top