[The Original Shootout]   [NEWS]   [FAQ]   [Methodology]   [Platform Details]   [Acknowledgements]   [Scorecard]
All Source For ruby
Ackermann's Function
```#!/usr/local/bin/ruby
# -*- mode: ruby -*-
# \$Id: ackermann.ruby,v 1.6 2000/11/27 03:39:25 doug Exp \$
# http://www.bagley.org/~doug/shootout/

def ack(m, n)
if m == 0 then
n + 1
elsif n == 0 then
ack(m - 1, 1)
else
ack(m - 1, ack(m, n - 1))
end
end

NUM = Integer(ARGV.shift || 1)
print "Ack(3,", NUM, "): ", ack(3, NUM), "\n"

```
Array Access
```#!/usr/local/bin/ruby
# -*- mode: ruby -*-
# \$Id: ary3.ruby,v 1.1 2001/05/31 02:27:48 doug Exp \$
# http://www.bagley.org/~doug/shootout/

n = Integer(ARGV.shift || 1)

i = 0
x = Array.new(n)
y = Array.new(n)
last = n-1

for i in 0 .. last
x[i] = i + 1
y[i] = 0
end
for k in 0 .. 999
last.step(0,-1) do |i|
y[i] += x[i]
end
end

puts "#{y[0]} #{y[last]}"
```
Count Lines/Words/Chars
```#!/usr/local/bin/ruby
# -*- mode: ruby -*-
# \$Id: wc.ruby,v 1.5 2001/06/26 05:07:54 doug Exp \$
# http://www.bagley.org/~doug/shootout/
# with help from Paul Brannan

nl = nw = nc = 0
loop do
data = (STDIN.read(4096) or break) << (STDIN.gets || "")
nc += data.length
nl += data.count("\n")
((data.strip! || data).tr!("\n", " ") || data).squeeze!
nw += data.count(" ") + 1
end
puts "#{nl} #{nw} #{nc}"
```
Echo Client/Server
```#!/usr/local/bin/ruby
# -*- mode: ruby -*-
# \$Id: echo.ruby,v 1.3 2001/05/08 08:08:41 doug Exp \$
# http://www.bagley.org/~doug/shootout/

require "socket"

DATA = "Hello there sailor\n"

def echo_client(n, port)
sock = TCPsocket.open('127.0.0.1', port)
n.times do
sock.write(DATA)
if ans != DATA then
raise sprintf("client: \"%s\" \"%s\"", DATA, ans)
end
end
sock.close
end

def echo_server(n)
ssock = TCPserver.open('127.0.0.1', 0)
if pid = fork then
# parent is server
csock = ssock.accept
n = 0
while str = csock.gets
n += csock.write(str)
end
Process.wait
printf "server processed %d bytes\n", n
else
# child is client
echo_client(n, port)
end
end

echo_server(Integer(ARGV.shift || 1))
```
Exception Mechanisms
```#!/usr/local/bin/ruby
# -*- mode: ruby -*-
# \$Id: except.ruby,v 1.3 2000/10/07 08:41:43 doug Exp \$
# http://www.bagley.org/~doug/shootout/

\$HI = 0
\$LO = 0
NUM = Integer(ARGV[0] || 1)

class Lo_Exception < Exception
def initialize(num)
@value = num
return self
end
end

class Hi_Exception < Exception
def initialize(num)
@value = num
return self
end
end

def some_function(num)
begin
hi_function(num)
rescue
print "We shouldn't get here, exception is: #{\$!.type}\n"
end
end

def hi_function(num)
begin
lo_function(num)
rescue Hi_Exception
\$HI = \$HI + 1
end
end

def lo_function(num)
begin
blowup(num)
rescue Lo_Exception
\$LO = \$LO + 1
end
end

def blowup(num)
if num % 2 == 0
raise Lo_Exception.new(num)
else
raise Hi_Exception.new(num)
end
end

for iter in 1 .. NUM
some_function(iter)
end
print "Exceptions: HI=", \$HI, " / LO=", \$LO, "\n"
```
Fibonacci Numbers
```#!/usr/local/bin/ruby
# -*- mode: ruby -*-
# \$Id: fibo.ruby,v 1.2 2000/12/24 19:10:50 doug Exp \$
# http://www.bagley.org/~doug/shootout/

def fib(n)
if n < 2 then
1
else
fib(n-2) + fib(n-1)
end
end

N = Integer(ARGV.shift || 1)
puts fib(N)

```
Hash (Associative Array) Access
```#!/usr/local/bin/ruby
# -*- mode: ruby -*-
# \$Id: hash.ruby,v 1.2 2001/05/16 15:54:34 doug Exp \$
# http://www.bagley.org/~doug/shootout/

n = Integer(ARGV.shift || 1)

X = {}
for i in 1 .. n
X[sprintf("%x", i)] = 1
end

c = 0
(n).step(1,-1) do |i|
if (X.has_key?(i.to_s)) then
c += 1
end
end

puts c
```
Hashes, Part II
```#!/usr/local/bin/ruby
# -*- mode: ruby -*-
# \$Id: hash2.ruby,v 1.2 2001/05/16 16:17:08 doug Exp \$
# http://www.bagley.org/~doug/shootout/

n = Integer(ARGV.shift || 1)

hash1 = {}
for i in 0 .. 9999
hash1["foo_" << i.to_s] = i
end

hash2 = Hash.new(0)
n.times do
for k in hash1.keys
hash2[k] += hash1[k]
end
end

printf "%d %d %d %d\n",
hash1["foo_1"], hash1["foo_9999"], hash2["foo_1"], hash2["foo_9999"]
```
Heapsort
```#!/usr/local/bin/ruby
# -*- mode: ruby -*-
# \$Id: heapsort.ruby,v 1.7 2001/05/08 02:46:59 doug Exp \$
# http://www.bagley.org/~doug/shootout/

IM = 139968
IA =   3877
IC =  29573

\$last = 42.0
def gen_random (max) (max * (\$last = (\$last * IA + IC) % IM)) / IM end

def heapsort(n, ra)
j = i = rra = 0
l = (n >> 1) + 1
ir = n

while (1) do
if (l > 1) then
rra = ra[(l -= 1)]
else
rra = ra[ir]
ra[ir] = ra[1]
if ((ir -= 1) == 1) then
ra[1] = rra
return
end
end
i = l
j = l << 1
while (j <= ir) do
if ((j < ir) and (ra[j] < ra[j+1])) then
j += 1
end
if (rra < ra[j]) then
ra[i] = ra[j]
j += (i = j)
else
j = ir + 1
end
end
ra[i] = rra
end
end

N = Integer(ARGV.shift || 1)
ary = []
for i in 1 .. N
ary[i] = gen_random(1.0)
end

heapsort(N, ary)

printf "%.10f\n", ary[N]
```
Hello World
```#!/usr/local/bin/ruby
# -*- mode: ruby -*-
# \$Id: hello.ruby,v 1.1 2001/06/17 22:00:34 doug Exp \$
# http://www.bagley.org/~doug/shootout/

puts "hello world"
```
List Operations
```#!/usr/local/bin/ruby
# -*- mode: ruby -*-
# \$Id: lists.ruby,v 1.5 2000/11/27 03:39:25 doug Exp \$
# http://www.bagley.org/~doug/shootout/

NUM = Integer(ARGV.shift || 1)

SIZE = 10000

def test_lists()
# create a list of integers (Li1) from 1 to SIZE
li1 = (1..SIZE).to_a
# copy the list to li2 (not by individual items)
li2 = li1.dup
# remove each individual item from left side of li2 and
# append to right side of li3 (preserving order)
li3 = Array.new
while (not li2.empty?)
li3.push(li2.shift)
end
# li2 must now be empty
# remove each individual item from right side of li3 and
# append to right side of li2 (reversing list)
while (not li3.empty?)
li2.push(li3.pop)
end
# li3 must now be empty
# reverse li1 in place
li1.reverse!
# check that first item is now SIZE
if li1[0] != SIZE then
p "not SIZE"
return(0)
end
# compare li1 and li2 for equality
if li1 != li2 then
return(0)
end
# return the length of the list
return(li1.length)
end

for iter in 1 .. NUM
result = test_lists()
end
print result, "\n"
```
Matrix Multiplication
```#!/usr/local/bin/ruby
# -*- mode: ruby -*-
# \$Id: matrix.ruby,v 1.3 2001/05/16 16:38:55 doug Exp \$
# http://www.bagley.org/~doug/shootout/

n = Integer(ARGV.shift || 1)

size = 30

def mkmatrix(rows, cols)
count = 1
mx = Array.new(rows)
for i in 0 .. (rows - 1)
row = Array.new(cols, 0)
for j in 0 .. (cols - 1)
row[j] = count
count += 1
end
mx[i] = row
end
mx
end

def mmult(rows, cols, m1, m2)
m3 = Array.new(rows)
for i in 0 .. (rows - 1)
row = Array.new(cols, 0)
for j in 0 .. (cols - 1)
val = 0
for k in 0 .. (cols - 1)
val += m1[i][k] * m2[k][j]
end
row[j] = val
end
m3[i] = row
end
m3
end

m1 = mkmatrix(size, size)
m2 = mkmatrix(size, size)
mm = Array.new
n.times do
mm = mmult(size, size, m1, m2)
end
puts "#{mm[0][0]} #{mm[2][3]} #{mm[3][2]} #{mm[4][4]}"
```
Method Calls
```#!/usr/local/bin/ruby
# -*- mode: ruby -*-
# \$Id: methcall.ruby,v 1.2 2000/12/24 22:04:51 doug Exp \$
# http://www.bagley.org/~doug/shootout/

class Toggle
def initialize(start_state)
@bool = start_state
self
end
def value()
@bool
end
def activate()
@bool = !@bool
self
end
end

class NthToggle < Toggle
def initialize(start_state, max_counter)
super(start_state)
@count_max = max_counter
@counter = 0
self
end
def activate()
@counter += 1
if (@counter >= @count_max) then
@bool = !@bool
@counter = 0
end
self
end
end

def main()
n = Integer(ARGV.shift || 1)

val = 1
toggle = Toggle.new(val)
n.times do
val = toggle.activate().value()
end
if val then puts "true" else puts "false" end

val = 1
ntoggle = NthToggle.new(val, 3)
n.times do
val = ntoggle.activate().value()
end
if val then puts "true" else puts "false" end
end

main()

```
Nested Loops
```#!/usr/local/bin/ruby
# -*- mode: ruby -*-
# \$Id: nestedloop.ruby,v 1.2 2001/02/15 01:09:35 doug Exp \$
# http://www.bagley.org/~doug/shootout/
# from Avi Bryant

n = Integer(ARGV.shift || 1)
x = 0
n.times do
n.times do
n.times do
n.times do
n.times do
n.times do
x += 1
end
end
end
end
end
end
puts x
```
Object Instantiation
```#!/usr/local/bin/ruby
# -*- mode: ruby -*-
# \$Id: objinst.ruby,v 1.2 2000/12/24 22:04:57 doug Exp \$
# http://www.bagley.org/~doug/shootout/

class Toggle
def initialize(start_state)
@bool = start_state
self
end
def value()
@bool
end
def activate()
@bool = !@bool
self
end
end

class NthToggle < Toggle
def initialize(start_state, max_counter)
super(start_state)
@count_max = max_counter
@counter = 0
self
end
def activate()
@counter += 1
if (@counter >= @count_max) then
@bool = !@bool
@counter = 0
end
self
end
end

def main()
n = Integer(ARGV.shift || 1)

toggle = Toggle.new(1)
5.times do
if toggle.activate().value() then puts "true" else puts "false" end
end
n.times do
toggle = Toggle.new(1)
end

puts

ntoggle = NthToggle.new(1, 3)
8.times do
if ntoggle.activate().value() then puts "true" else puts "false" end
end
n.times do
ntoggle = NthToggle.new(1, 3)
end
end

main()

```
```#!/usr/local/bin/ruby
# -*- mode: ruby -*-
# \$Id: prodcons.ruby,v 1.2 2000/12/20 04:33:20 doug Exp \$
# http://www.bagley.org/~doug/shootout/

def main(n)
mutex = Mutex.new
access = ConditionVariable.new
count = data = consumed = produced = 0
i = 0
loop do
mutex.synchronize {
while count == 0 do access.wait(mutex) end
i = data
count = 0
access.signal
}
consumed += 1
if i == n then break end
end
end
for i in 1 .. n do
mutex.synchronize {
while count == 1 do access.wait(mutex) end
data = i
count = 1
access.signal
}
produced += 1
end
end
producer.join
consumer.join
puts "#{produced} #{consumed}"
end

main(Integer(ARGV.shift || 1))
```
Random Number Generator
```#!/usr/local/bin/ruby
# -*- mode: ruby -*-
# \$Id: random.ruby,v 1.13 2001/05/08 06:35:57 doug Exp \$
# http://www.bagley.org/~doug/shootout/

IM = 139968
IA = 3877
IC = 29573

\$last = 42.0
def gen_random (max) (max * (\$last = (\$last * IA + IC) % IM)) / IM end

N = Integer(ARGV.shift || 1)
result = 0
N.times do
result = gen_random(100.0)
end
printf "%.9f\n", result
```
Regular Expression Matching
```#!/usr/local/bin/ruby
# -*- mode: ruby -*-
# \$Id: regexmatch.ruby,v 1.11 2001/07/02 04:26:31 doug Exp \$
# http://www.bagley.org/~doug/shootout/

re = Regexp.new(
'(?:^|[^\d\(])' +            # must be preceeded by non-digit
'(?:\((\d\d\d)\)|(\d\d\d))' +    # match 1 or 2: area code is 3 digits
'[ ]' +                # area code followed by one space
'(\d\d\d)' +            # match 3: prefix of 3 digits
'[ -]' +                # separator is either space or dash
'(\d\d\d\d)' +            # match 4: last 4 digits
'\D'                # must be followed by a non-digit
)

NUM = Integer(ARGV[0] || 1)

count = m = line = iter = 0
for iter in 1..NUM
for line in phones
if m = re.match(line)
m1 = m[1];
if m1 == ""
m1 = m[2];
end
num = '(' + m1 + ') ' + m[3] + '-' + m[4];
if iter == NUM
count += 1
puts "#{count}: #{num}"
end
end
end
end
```
Reverse a File
```#!/usr/local/bin/ruby
# -*- mode: ruby -*-
# \$Id: reversefile.ruby,v 1.2 2000/11/27 03:39:26 doug Exp \$
# http://www.bagley.org/~doug/shootout/

```
Sieve of Erathostenes
```#!/usr/local/bin/ruby
# -*- mode: ruby -*-
# \$Id: sieve.ruby,v 1.12 2001/05/06 04:37:45 doug Exp \$
# http://www.bagley.org/~doug/shootout/

NUM = Integer(ARGV.shift || 1)

count = i = j = 0
flags0 = Array.new(8192,1)

NUM.times do
count = 0
flags = flags0.dup
for i in 2 .. 8192
next unless flags[i]
# remove all multiples of prime: i
(i*i).step(8192, i) do |j|
flags[j] = nil
end
count = count + 1
end
end

print "Count: ", count, "\n"

```
Spell Checker
```#!/usr/local/bin/ruby
# -*- mode: ruby -*-
# \$Id: spellcheck.ruby,v 1.6 2001/01/23 01:30:42 doug Exp \$
# http://www.bagley.org/~doug/shootout/

dict = Hash.new
file = open("Usr.Dict.Words")
while file.gets()
dict[\$_.chomp!] = 1
end
file.close()

count = word = 0
while STDIN.gets()
unless dict.has_key? \$_.chomp!
puts \$_
end
end
```
Statistical Moments
```#!/usr/local/bin/ruby
# -*- mode: ruby -*-
# \$Id: moments.ruby,v 1.5 2001/01/05 01:35:56 doug Exp \$
# http://www.bagley.org/~doug/shootout/

# throw away unused parameter sent by benchmark framework
ARGV.shift()

sum = 0.0
nums = []
num = nil
deviation = nil

num = Float(line)
nums << num
sum += num
}
n = nums.length()
mean = sum/n;
average_deviation = 0
standard_deviation = 0
variance = 0
skew = 0
kurtosis = 0

nums.each{|num|
deviation = num - mean
average_deviation += deviation.abs()
variance += deviation**2;
skew += deviation**3;
kurtosis += deviation**4
}
average_deviation /= n
variance /= (n - 1)
standard_deviation = Math.sqrt(variance)

if (variance > 0.0)
skew /= (n * variance * standard_deviation)
kurtosis = kurtosis/(n * variance * variance) - 3.0
end

nums.sort()
mid = n / 2

if (n % 2) == 0
median = (nums[mid] + nums[mid-1])/2
else
median = nums[mid]
end

printf("n:                  %d\n", n)
printf("median:             %f\n", median)
printf("mean:               %f\n", mean)
printf("average_deviation:  %f\n", average_deviation)
printf("standard_deviation: %f\n", standard_deviation)
printf("variance:           %f\n", variance)
printf("skew:               %f\n", skew)
printf("kurtosis:           %f\n", kurtosis)
```
String Concatenation
```#!/usr/local/bin/ruby
# -*- mode: ruby -*-
# \$Id: strcat.ruby,v 1.2 2000/12/23 15:52:44 doug Exp \$
# http://www.bagley.org/~doug/shootout/

# Benedikt Rosenau suggested using
#   str << "hello\n"
# which is orders of magnitude faster than:
#   str += "hello\n"

n = Integer(ARGV.shift || 1)

str = ''
for i in 1 .. n
str << "hello\n"
end
puts str.length
```
Sum a Column of Integers
```#!/usr/local/bin/ruby
# -*- mode: ruby -*-
# \$Id: sumcol.ruby,v 1.4 2001/01/04 20:09:24 doug Exp \$
# http://www.bagley.org/~doug/shootout/
# from: Mathieu Bouchard

count = 0
while STDIN.gets()
count += \$_.to_i
end
puts count
```
Word Frequency Count
```#!/usr/local/bin/ruby
# -*- mode: ruby -*-
# \$Id: wordfreq.ruby,v 1.9 2001/05/16 23:46:40 doug Exp \$
# http://www.bagley.org/~doug/shootout/

freq = Hash.new(0)
loop {
data = (STDIN.read(4095) or break) << (STDIN.gets || "")
for word in data.downcase.tr_s('^A-Za-z',' ').split(' ')
freq[word] += 1
end
}
freq.delete("")

lines = Array.new
freq.each{|w,c| lines << sprintf("%7d\t%s\n", c, w) }
print lines.sort.reverse
```