Brute force method, Translation of: Tcl
KnapsackItem = Struct.new(:volume, :weight, :value)
panacea = KnapsackItem.new(0.025, 0.3, 3000)
ichor   = KnapsackItem.new(0.015, 0.2, 1800)
gold    = KnapsackItem.new(0.002, 2.0, 2500)
maximum = KnapsackItem.new(0.25,  25,  0)

max_items = {}
for item in [panacea, ichor, gold]
  max_items[item] = [(maximum.volume/item.volume).to_i, (maximum.weight/item.weight).to_i].min
end

maxval = 0
solutions = []

0.upto(max_items[ichor]) do |i|
  0.upto(max_items[panacea]) do |p|
    0.upto(max_items[gold]) do |g|
      break if i*ichor.weight + p*panacea.weight + g*gold.weight > maximum.weight
      break if i*ichor.volume + p*panacea.volume + g*gold.volume > maximum.volume
      val = i*ichor.value + p*panacea.value + g*gold.value
      if val > maxval
        maxval = val
        solutions = [[i, p, g]]
      elsif val == maxval
        solutions << [i, p, g]
      end
    end
  end
end

puts "The maximal solution has value #{maxval}"
solutions.each do |i, p, g|
  printf "  ichor=%2d, panacea=%2d, gold=%2d -- weight:%.1f, volume=%.3f\n",
    i, p, g,
    i*ichor.weight + p*panacea.weight + g*gold.weight,
    i*ichor.volume + p*panacea.volume + g*gold.volume
end

determine the maximum value of items that a traveler can carry in his knapsack, given the weight and volume constraints. The items include vials of panacea, ampules of ichor, and bars of gold. The code calculates the optimal quantity of each item to maximize the total value, considering that only whole units of any item can be taken.


(1..10).each do |i|
  print i
  break if i == 10
  print ", "
end
puts

puts (1..10).join(", ")

generates a comma-separated list from 1 to 10 using separate output statements for the number and the comma within a loop. In the final iteration, only part of the loop body is executed. This is achieved using idiomatic Ruby.


require 'tsort'
class Hash
  include TSort
  alias tsort_each_node each_key
  def tsort_each_child(node, &block)
    fetch(node).each(&block)
  end
end

depends = {}
DATA.each do |line|
  key, *libs = line.split
  depends[key] = libs
  libs.each {|lib| depends[lib] ||= []}
end

begin
  p depends.tsort
  depends["dw01"] << "dw04"
  p depends.tsort
rescue TSort::Cyclic => e
  puts "\ncycle detected: #{e}"
end

__END__
des_system_lib   std synopsys std_cell_lib des_system_lib dw02 dw01 ramlib ieee
dw01             ieee dw01 dware gtech
dw02             ieee dw02 dware
dw03             std synopsys dware dw03 dw02 dw01 ieee gtech
dw04             dw04 ieee dw01 dware gtech
dw05             dw05 ieee dware
dw06             dw06 ieee dware
dw07             ieee dware
dware            ieee dware
gtech            ieee gtech
ramlib           std ieee
std_cell_lib     ieee std_cell_lib
synopsys

The code implements a function to determine a valid compile order of VHDL libraries based on their dependencies. It handles self-dependencies and flags any un-orderable dependencies. The function uses topological sorting, specifically Kahn's 1962 algorithm or depth-first search, to order the libraries. It assumes library names are single words and that items mentioned only as dependents have no dependents of their own. The function uses the TSort module from the Ruby standard library.


p 'abcd'.start_with?('ab')  #returns true
p 'abcd'.end_with?('ab')    #returns false
p 'abab'.include?('bb')     #returns false
p 'abab'.include?('ab')     #returns true
p 'abab'['bb']              #returns nil
p 'abab'['ab']              #returns "ab"
p 'abab'.index('bb')        #returns nil
p 'abab'.index('ab')        #returns 0
p 'abab'.index('ab', 1)     #returns 2
p 'abab'.rindex('ab')       #returns 2

The code checks if a given string starts with, contains, or ends with a second string. It also prints the location of the match and handles multiple occurrences of the second string within the first string.


def four_squares(low, high, unique=true, show=unique)
  f = -> (a,b,c,d,e,f,g) {[a+b, b+c+d, d+e+f, f+g].uniq.size == 1}
  if unique
    uniq = "unique"
    solutions = [*low..high].permutation(7).select{|ary| f.call(*ary)}
  else
    uniq = "non-unique"
    solutions = [*low..high].repeated_permutation(7).select{|ary| f.call(*ary)}
  end
  if show
    puts " " + [*"a".."g"].join("  ")
    solutions.each{|ary| p ary}
  end
  puts "#{solutions.size} #{uniq} solutions in #{low} to #{high}"
  puts
end

[[1,7], [3,9]].each do |low, high|
  four_squares(low, high)
end
four_squares(0, 9, false)

The code finds all possible solutions for a 4-squares puzzle where each square sums up to the same total. It operates under two conditions: each letter representing a unique value between 1-7 and 3-9, and each letter representing a non-unique value between 0-9. The code also counts the number of non-unique solutions.


Library: Shoes
Sample display of Ruby solution
Shoes.app(:width=>205, :height => 228, :title => "A Clock") do
  def draw_ray(width, start, stop, ratio)
    angle = Math::PI * 2 * ratio - Math::PI/2
    strokewidth width
    cos = Math::cos(angle)
    sin = Math::sin(angle)
    line 101+cos*start, 101+sin*start, 101+cos*stop, 101+sin*stop
  end

  def update
    t = Time.now
    @time.text = t.strftime("%H:%M:%S")
    h, m, s = (t.hour % 12).to_f, t.min.to_f, t.sec.to_f
    s += t.to_f - t.to_i  # add the fractional seconds

    @hands.clear do
      draw_ray(3, 0, 70, (h + m/60)/12)
      draw_ray(2, 0, 90, (m + s/60)/60)
      draw_ray(1, 0, 95, s/60)
    end
  end

  # a place for the text display
  @time = para(:align=>"center", :family => "monospace")

  # draw the clock face
  stack(:width=>203, :height=>203) do
    strokewidth 1
    fill gradient(deepskyblue, aqua)
    oval 1, 1, 200
    fill black
    oval 98, 98, 6
    # draw the minute indicators
    0.upto(59) {|m| draw_ray(1, (m % 5 == 0 ? 96 : 98), 100, m.to_f/60)}
  end.move(0,23)

  # the drawing area for the hands
  @hands = stack(:width=>203, :height=>203) {}.move(0,23)

  animate(5) {update}
end

Berlin-Uhr clock
Shoes.app(:title => "Berlin-Uhr Clock", :width => 209, :height => 300) do
  background lightgrey

  Red = rgb(255, 20, 20)
  Yellow = rgb(173, 255, 47)
  Green = rgb(154, 205, 50)
  Gray = rgb(128, 128, 128)

  @time = para(:align => "center")
  stack do
    fill Gray
    stroke black
    strokewidth 2
    @seconds = oval 75, 3, 50
    @hrs_a  =  4.times.collect {|i| rect   51*i,  56, 48, 30, 4}
    @hrs_b  =  4.times.collect {|i| rect   51*i,  89, 48, 30, 4}
    @mins_a = 11.times.collect {|i| rect 2+18*i, 122, 15, 30, 4}
    @mins_b =  4.times.collect {|i| rect   51*i, 155, 48, 30, 4}
    # some decoration
    fill white
    stroke darkslategray
    rect -10, -30, 75, 70, 10
    rect 140, -30, 75, 70, 10
    rect -13, 192, 105, 100, 10
    rect 110, 192, 105, 100, 10
  end.move(3,20)

  animate(1) do
    now = Time.now
    @time.text = now.strftime("%H:%M:%S")
    @seconds.style(:fill => now.sec.even? ? Green : Gray)
    a, b = now.hour.divmod(5)
    4.times {|i| @hrs_a[i].style(:fill => i < a ? Red : Gray)}
    4.times {|i| @hrs_b[i].style(:fill => i < b ? Red : Gray)}
    a, b = now.min.divmod(5)
    11.times {|i| @mins_a[i].style(:fill => i < a ? (i%3==2 ? Red : Yellow) : Gray)}
    4.times  {|i| @mins_b[i].style(:fill => i < b ? Yellow : Gray)}
  end

  keypress do |key|
    case key
    when :control_q, "\x11" then exit
    end
  end
end

Library: RubyGems
Library: JRubyArt

def setup
  sketch_title 'Clock'
  stroke 255
  font = create_font 'NimbusRoman-Regular', 20
  text_font font
end

def draw
  background 0
  fill 80
  no_stroke
  clock_x = lambda do |val, adj, length|
    DegLut.cos((val * adj).to_i - 90) * length + width / 2
  end
  clock_y = lambda do |val, adj, length|
    DegLut.sin((val * adj).to_i - 90) * length + height / 2
  end
  ellipse 100, 100, 160, 160
  stroke 220
  stroke_weight 6
  t = Time.now
  line(100, 100, clock_x.call(t.hour % 12 + (t.min / 60.0), 30, 50),
    clock_y.call(t.hour % 12 + (t.min / 60.0), 30, 50))
  stroke_weight 3
  line(100, 100, clock_x.call(t.min + (t.sec / 60.0), 6, 60),
    clock_y.call(t.min + (t.sec / 60.0), 6, 60))
  stroke 255, 0, 0
  stroke_weight 1
  line(100, 100, clock_x.call(t.sec, 6, 72), clock_y.call(t.sec, 6, 72))
  # Draw the minute ticks
  stroke_weight 2
  stroke 255
  (0..360).step(6) do |a|
    x = 100 + DegLut.cos(a) * 72
    y = 100 + DegLut.sin(a) * 72
    point x, y
  end
  fill 200
  text t.strftime('%H:%M:%S'), 50, 200
end

def settings
  size 200, 220
  smooth 8
end

implement a visual time-keeping device, which can be of any type but must show the passage of seconds. The display must update every second and cycle periodically. The time displayed should be in sync with the system clock. The code avoids unnecessary system resource usage and maintains simplicity and clarity. An example of a Berlin-Uhr clock implemented in JRubyArt is provided.


loadup.rb is the program loader.
# loadup.rb - run UPPERCASE RUBY program

class Object
  alias lowercase_method_missing method_missing

  # Allow UPPERCASE method calls.
  def method_missing(sym, *args, &block)
    str = sym.to_s
    if str == (down = str.downcase)
      lowercase_method_missing sym, *args, &block
    else
      send down, *args, &block
    end
  end

  # RESCUE an exception without the 'rescue' keyword.
  def RESCUE(_BEGIN, _CLASS, _RESCUE)
    begin _BEGIN.CALL
    rescue _CLASS
      _RESCUE.CALL; end
  end
end

_PROGRAM = ARGV.SHIFT
_PROGRAM || ABORT("USAGE: #{$0} PROGRAM.RB ARGS...")
LOAD($0 = _PROGRAM)

CAL.RB is an UPPERCASE RUBY translation of Calendar#Ruby.
Works with: Ruby version 1.8.7
# CAL.RB - CALENDAR
REQUIRE 'DATE'.DOWNCASE

# FIND CLASSES.
OBJECT = [].CLASS.SUPERCLASS
DATE = OBJECT.CONST_GET('DATE'.DOWNCASE.CAPITALIZE)

# CREATES A CALENDAR OF _YEAR_. RETURNS THIS CALENDAR AS A MULTI-LINE
# STRING FIT TO _COLUMNS_.
OBJECT.SEND(:DEFINE_METHOD, :CAL) {|_YEAR, _COLUMNS|

  # START AT JANUARY 1.
  #
  # DATE::ENGLAND MARKS THE SWITCH FROM JULIAN CALENDAR TO GREGORIAN
  # CALENDAR AT 1752 SEPTEMBER 14. THIS REMOVES SEPTEMBER 3 TO 13 FROM
  # YEAR 1752. (BY FORTUNE, IT KEEPS JANUARY 1.)
  #
  _DATE = DATE.NEW(_YEAR, 1, 1, DATE::ENGLAND)

  # COLLECT CALENDARS OF ALL 12 MONTHS.
  _MONTHS = (1..12).COLLECT {|_MONTH|
    _ROWS = [DATE::MONTHNAMES[_MONTH].UPCASE.CENTER(20),
             "SU MO TU WE TH FR SA"]

    # MAKE ARRAY OF 42 DAYS, STARTING WITH SUNDAY.
    _DAYS = []
    _DATE.WDAY.TIMES { _DAYS.PUSH "  " }
    CATCH(:BREAK) {
      LOOP {
        (_DATE.MONTH == _MONTH) || THROW(:BREAK)
        _DAYS.PUSH("%2D".DOWNCASE % _DATE.MDAY)
        _DATE += 1 }}
    (42 - _DAYS.LENGTH).TIMES { _DAYS.PUSH "  " }

    _DAYS.EACH_SLICE(7) {|_WEEK| _ROWS.PUSH(_WEEK.JOIN " ") }
    _ROWS }

  # CALCULATE MONTHS PER ROW (MPR).
  #  1. DIVIDE COLUMNS BY 22 COLUMNS PER MONTH, ROUNDED DOWN. (PRETEND
  #     TO HAVE 2 EXTRA COLUMNS; LAST MONTH USES ONLY 20 COLUMNS.)
  #  2. DECREASE MPR IF 12 MONTHS WOULD FIT IN THE SAME MONTHS PER
  #     COLUMN (MPC). FOR EXAMPLE, IF WE CAN FIT 5 MPR AND 3 MPC, THEN
  #     WE USE 4 MPR AND 3 MPC.
  _MPR = (_COLUMNS + 2).DIV 22
  _MPR = 12.DIV((12 + _MPR - 1).DIV _MPR)

  # USE 20 COLUMNS PER MONTH + 2 SPACES BETWEEN MONTHS.
  _WIDTH = _MPR * 22 - 2

  # JOIN MONTHS INTO CALENDAR.
  _ROWS = ["[SNOOPY]".CENTER(_WIDTH), "#{_YEAR}".CENTER(_WIDTH)]
  _MONTHS.EACH_SLICE(_MPR) {|_SLICE|
    _SLICE[0].EACH_INDEX {|_I|
      _ROWS.PUSH(_SLICE.MAP {|_A| _A[_I]}.JOIN "  ") }}
  _ROWS.JOIN("\012") }

(ARGV.LENGTH == 1) || ABORT("USAGE: #{$0} YEAR")

# GUESS WIDTH OF TERMINAL.
#  1. OBEY ENVIRONMENT VARIABLE COLUMNS.
#  2. TRY TO REQUIRE 'IO/CONSOLE' FROM RUBY 1.9.3.
#  3. TRY TO RUN `TPUT CO`.
#  4. ASSUME 80 COLUMNS.
LOADERROR = OBJECT.CONST_GET('LOAD'.DOWNCASE.CAPITALIZE +
                             'ERROR'.DOWNCASE.CAPITALIZE)
STANDARDERROR = OBJECT.CONST_GET('STANDARD'.DOWNCASE.CAPITALIZE +
                                 'ERROR'.DOWNCASE.CAPITALIZE)
_INTEGER = 'INTEGER'.DOWNCASE.CAPITALIZE
_TPUT_CO = 'TPUT CO'.DOWNCASE
_COLUMNS = RESCUE(PROC {SEND(_INTEGER, ENV["COLUMNS"] || "")},
                  STANDARDERROR,
                  PROC {
                    RESCUE(PROC {
                             REQUIRE 'IO/CONSOLE'.DOWNCASE
                             IO.CONSOLE.WINSIZE[1]
                           }, LOADERROR,
                           PROC {
                             RESCUE(PROC {
                                      SEND(_INTEGER, `#{_TPUT_CO}`)
                                    }, STANDARDERROR,
                                    PROC {80}) }) })

PUTS CAL(ARGV[0].TO_I, _COLUMNS)

A local variable must start with a lowercase letter or an underscore, so we have many leading underscores (_YEAR, _COLUMN, _DATE and so on).
We form blocks with curly braces { ... }, never with lowercase keywords do ... end.
OBJECT = [].CLASS.SUPERCLASS finds the superclass of the class of the empty array; this is the Object class! Class#CONST_GET finds some other classes.
Class#DEFINE_METHOD defines a new method, Object#CAL, without a def keyword.
Kernel#LOOP, Kernel#THROW, Kernel#CATCH and operator || act like a while loop without a while keyword.
$ ruby loadup.rb CAL.RB 1969
                                                             [SNOOPY]
                                                               1969
      JANUARY               FEBRUARY               MARCH                 APRIL                  MAY                   JUNE
SU MO TU WE TH FR SA  SU MO TU WE TH FR SA  SU MO TU WE TH FR SA  SU MO TU WE TH FR SA  SU MO TU WE TH FR SA  SU MO TU WE TH FR SA
          1  2  3  4                     1                     1         1  2  3  4  5               1  2  3   1  2  3  4  5  6  7
 5  6  7  8  9 10 11   2  3  4  5  6  7  8   2  3  4  5  6  7  8   6  7  8  9 10 11 12   4  5  6  7  8  9 10   8  9 10 11 12 13 14
12 13 14 15 16 17 18   9 10 11 12 13 14 15   9 10 11 12 13 14 15  13 14 15 16 17 18 19  11 12 13 14 15 16 17  15 16 17 18 19 20 21
19 20 21 22 23 24 25  16 17 18 19 20 21 22  16 17 18 19 20 21 22  20 21 22 23 24 25 26  18 19 20 21 22 23 24  22 23 24 25 26 27 28
26 27 28 29 30 31     23 24 25 26 27 28     23 24 25 26 27 28 29  27 28 29 30           25 26 27 28 29 30 31  29 30
                                            30 31
        JULY                 AUGUST              SEPTEMBER              OCTOBER               NOVEMBER              DECEMBER
SU MO TU WE TH FR SA  SU MO TU WE TH FR SA  SU MO TU WE TH FR SA  SU MO TU WE TH FR SA  SU MO TU WE TH FR SA  SU MO TU WE TH FR SA
       1  2  3  4  5                  1  2      1  2  3  4  5  6            1  2  3  4                     1      1  2  3  4  5  6
 6  7  8  9 10 11 12   3  4  5  6  7  8  9   7  8  9 10 11 12 13   5  6  7  8  9 10 11   2  3  4  5  6  7  8   7  8  9 10 11 12 13
13 14 15 16 17 18 19  10 11 12 13 14 15 16  14 15 16 17 18 19 20  12 13 14 15 16 17 18   9 10 11 12 13 14 15  14 15 16 17 18 19 20
20 21 22 23 24 25 26  17 18 19 20 21 22 23  21 22 23 24 25 26 27  19 20 21 22 23 24 25  16 17 18 19 20 21 22  21 22 23 24 25 26 27
27 28 29 30 31        24 25 26 27 28 29 30  28 29 30              26 27 28 29 30 31     23 24 25 26 27 28 29  28 29 30 31
                      31                                                                30

The code provides an algorithm for a calendar task, written entirely in uppercase, as per the requirements of "real" programmers from the 1960s era. It formats the calendar to fit a page that is 132 characters wide. The code is inspired by the articles "Real Programmers Don't Use PASCAL" and "Real programmers think in UPPERCASE". It also takes into account the practicality of programming in uppercase for those with hearing and sight difficulties. The code does not include Snoopy generation but instead outputs a placeholder. It is written in uppercase Ruby, using a custom program loader that responds to unknown method calls by calling their lowercase equivalents and defines Object#RESCUE to replace the 'rescue' keyword.


Translation of: Java
class PythagoranTriplesCounter
  def initialize(limit)
    @limit = limit
    @total = 0
    @primitives = 0
    generate_triples(3, 4, 5)
  end
  attr_reader :total, :primitives

  private
  def generate_triples(a, b, c)
    perim = a + b + c
    return if perim > @limit

    @primitives += 1
    @total += @limit / perim

    generate_triples( a-2*b+2*c, 2*a-b+2*c, 2*a-2*b+3*c)
    generate_triples( a+2*b+2*c, 2*a+b+2*c, 2*a+2*b+3*c)
    generate_triples(-a+2*b+2*c,-2*a+b+2*c,-2*a+2*b+3*c)
  end
end

perim = 10
while perim <= 100_000_000
  c = PythagoranTriplesCounter.new perim
  p [perim, c.total, c.primitives]
  perim *= 10
end

[10, 0, 0]
[100, 17, 7]
[1000, 325, 70]
[10000, 4858, 703]
[100000, 64741, 7026]
[1000000, 808950, 70229]
[10000000, 9706567, 702309]
[100000000, 113236940, 7023027]

determine the number of Pythagorean and primitive Pythagorean triples with a perimeter no larger than a given limit, and handle large perimeter values up to 100,000,000.


Works with: Ruby version 1.8.5
Library: Ruby/Tk
 require 'tk'

 window = TkRoot::new()
 window::mainloop()

Library: GTK
 require 'gtk2'

 window = Gtk::Window.new.show
 Gtk.main

Library: Shoes
Shoes.app {}

"Creates an empty GUI window that can respond to close requests."


def letter_frequency(file)
  letters = 'a' .. 'z'
  File.read(file) .
       split(//) .
       group_by {|letter| letter.downcase} .
       select   {|key, val| letters.include? key} .
       collect  {|key, val| [key, val.length]}
end

letter_frequency(ARGV[0]).sort_by {|key, val| -val}.each {|pair| p pair}

$ ruby letterFrequency.rb letterFrequency.rb
["e", 34]
["l", 20]
["t", 17]
["r", 14]
["a", 12]
["y", 9]
["c", 8]
["i", 7]
["v", 6]
["n", 6]
["f", 6]
["s", 6]
["d", 5]
["p", 5]
["k", 5]
["u", 4]
["o", 4]
["g", 3]
["b", 2]
["h", 2]
["q", 2]
["z", 1]
["w", 1]
Ruby 2.0[edit]
def letter_frequency(file)
  freq = Hash.new(0)
  file.each_char.lazy.grep(/[[:alpha:]]/).map(&:upcase).each_with_object(freq) do |char, freq_map|
    freq_map[char] += 1
  end
end

letter_frequency(ARGF).sort.each do |letter, frequency|
  puts "#{letter}: #{frequency}"
end

$ ruby letter_frequency.rb /usr/share/dict/words
A: 64439
B: 15526
C: 31872
D: 28531
E: 88833
F: 10675
G: 22712
H: 19320
I: 66986
J: 1948
K: 8409
L: 41107
M: 22508
N: 57144
O: 48944
P: 22274
Q: 1524
R: 57347
S: 90113
T: 53006
U: 26118
V: 7989
W: 7530
X: 2124
Y: 12652
Z: 3281
Å: 1
á: 10
â: 6
ä: 7
å: 3
ç: 5
è: 28
é: 144
ê: 6
í: 2
ñ: 8
ó: 8
ô: 2
ö: 16
û: 3
ü: 12

Ruby 2.7[edit]

p File.open("/usr/share/dict/words","r").each_char.tally

open a text file and count the frequency of each letter. It can count all characters including punctuation or only letters from A to Z. The code is optimized for large files using lazy enumerables introduced in Ruby 2.0. It also works with unicode text and utilizes the "tally" feature introduced in Ruby 2.7 for enumerables.


class ListNode
  attr_accessor :value, :succ

  def initialize(value, succ=nil)
    self.value = value
    self.succ = succ
  end

  def each(&b)
    yield self
    succ.each(&b) if succ
  end

  include Enumerable

  def self.from_array(ary)
    head = self.new(ary[0], nil)
    prev = head
    ary[1..-1].each do |val|
      node = self.new(val, nil)
      prev.succ = node
      prev = node
    end
    head
  end
end

list = ListNode.from_array([1,2,3,4])

define a data structure for a singly-linked list element. This element contains a data member for storing a numeric value and a mutable link to the next element in the list.


Library: Shoes
Shoes.app(:title => "Fractal Tree", :width => 600, :height => 600) do
  background "#fff"
  stroke "#000"
  @deg_to_rad = Math::PI / 180.0

  def drawTree(x1, y1, angle, depth)
    if depth != 0
      x2 = x1 + (Math.cos(angle * @deg_to_rad) * depth * 10.0).to_i
      y2 = y1 + (Math.sin(angle * @deg_to_rad) * depth * 10.0).to_i

      line x1, y1, x2, y2

      drawTree(x2, y2, angle - 20, depth - 1)
      drawTree(x2, y2, angle + 20, depth - 1)
    end
  end

  drawTree(300,550,-90,9)
end

generate and draw a fractal tree by first drawing the trunk, then splitting the trunk at the end by a certain angle to form two branches, and repeating this process until a desired level of branching is reached.


class Integer
  def factors() (1..self).select { |n| (self % n).zero? } end
end
p 45.factors
[1, 3, 5, 9, 15, 45]

class Integer
  def factors
    1.upto(Integer.sqrt(self)).select {|i| (self % i).zero?}.inject([]) do |f, i|
      f << self/i unless i == self/i
      f << i
    end.sort
  end
end
[45, 53, 64].each {|n| puts "#{n} : #{n.factors}"}

calculate the factors of a given positive integer. The factors are the positive integers that can divide the input number without leaving a remainder. The code does not handle the cases of zero or negative integers. It also notes that every prime number has two factors: 1 and itself. The code optimizes the process by only looping up to the square root of the input number.


Works with: Ruby version 1.9.3+
J2justifier = {Left: :ljust, Right: :rjust, Center: :center}

=begin
Justify columns of textual tabular input where the record separator is the newline
and the field separator is a 'dollar' character.
justification can be Symbol; (:Left, :Right, or :Center).

Return the justified output as a string
=end
def aligner(infile, justification = :Left)
  fieldsbyrow = infile.map {|line| line.strip.split('$')}
  # pad to same number of fields per record
  maxfields = fieldsbyrow.map(&:length).max
  fieldsbyrow.map! {|row| row + ['']*(maxfields - row.length)}
  # calculate max fieldwidth per column
  colwidths = fieldsbyrow.transpose.map {|column|
    column.map(&:length).max
  }
  # pad fields in columns to colwidth with spaces
  justifier = J2justifier[justification]
  fieldsbyrow.map {|row|
    row.zip(colwidths).map {|field, width|
      field.send(justifier, width)
    }.join(" ")
  }.join("\n")
end

require 'stringio'

textinfile = <<END
Given$a$text$file$of$many$lines,$where$fields$within$a$line$
are$delineated$by$a$single$'dollar'$character,$write$a$program
that$aligns$each$column$of$fields$by$ensuring$that$words$in$each$
column$are$separated$by$at$least$one$space.
Further,$allow$for$each$word$in$a$column$to$be$either$left$
justified,$right$justified,$or$center$justified$within$its$column.
END

for align in [:Left, :Right, :Center]
  infile = StringIO.new(textinfile)
  puts "\n# %s Column-aligned output:" % align
  puts aligner(infile, align)
end

The code reads a text file with lines separated by a dollar character. It aligns each column of fields by ensuring at least one space between words in each column. It also allows each word in a column to be left, right, or center justified. The minimum space between columns is computed from the text, not hard-coded. Trailing dollar characters or consecutive spaces at the end of lines do not affect the alignment. The output is suitable for viewing in a mono-spaced font on a plain text editor or basic terminal.


X, Y, Z = 6, 2, 3
DIR = {"-" => [1,0], "|" => [0,1], "/" => [1,1]}

def cuboid(nx, ny, nz)
  puts "cuboid %d %d %d:" % [nx, ny, nz]
  x, y, z = X*nx, Y*ny, Z*nz
  area = Array.new(y+z+1){" " * (x+y+1)}
  draw_line = lambda do |n, sx, sy, c|
    dx, dy = DIR[c]
    (n+1).times do |i|
      xi, yi = sx+i*dx, sy+i*dy
      area[yi][xi] = (area[yi][xi]==" " ? c : "+")
    end
  end
  nz    .times {|i| draw_line[x,     0,   Z*i, "-"]}
  (ny+1).times {|i| draw_line[x,   Y*i, z+Y*i, "-"]}
  nx    .times {|i| draw_line[z,   X*i,     0, "|"]}
  (ny+1).times {|i| draw_line[z, x+Y*i,   Y*i, "|"]}
  nz    .times {|i| draw_line[y,     x,   Z*i, "/"]}
  (nx+1).times {|i| draw_line[y,   X*i,     z, "/"]}
  puts area.reverse
end

cuboid(2, 3, 4)
cuboid(1, 1, 1)
cuboid(6, 2, 1)
cuboid(2, 4, 1)

generate a graphical or ASCII art representation of a cuboid with dimensions 2x3x4, ensuring three faces are visible, and allowing for either static or rotational projection.


Library: RubyGems
require 'rubygems'
require 'net/ldap'
ldap = Net::LDAP.new(:host => 'ldap.example.com', :base => 'o=companyname')
ldap.authenticate('bind_dn', 'bind_pass')

establish a connection to an Active Directory or Lightweight Directory Access Protocol server using the Ruby LDAP package Net::LDAP.


# Returns a copy of _s_ with rot13 encoding.
def rot13(s)
  s.tr('A-Za-z', 'N-ZA-Mn-za-m')
end

# Perform rot13 on files from command line, or standard input.
while line = ARGF.gets
  print rot13(line)
end

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz

NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm

The code implements a rot-13 function that replaces every letter of the ASCII alphabet with the letter which is 13 characters away in the 26 letter alphabet. It works on both upper and lower case letters, preserves case, and passes all non-alphabetic characters without alteration. The function can be wrapped in a utility program to perform a line-by-line rot-13 encoding of every line of input from each file listed on its command line or act as a filter on its standard input. It can be used to obfuscate text to prevent casual reading of spoiler or potentially offensive material.


Person = Struct.new(:name,:value) do
  def to_s; "name:#{name}, value:#{value}" end
end

list = [Person.new("Joe",3),
        Person.new("Bill",4),
        Person.new("Alice",20),
        Person.new("Harry",3)]
puts list.sort_by{|x|x.name}
puts
puts list.sort_by(&:value)

sort an array of composite structures, specifically name-value pairs, by the key name using a custom comparator.


for

Range#each

for i in 1..5
  for j in 1..i
    print "*"
  end
  puts
end

(1..5).each do |i|
  (1..i).each do |j|
    print "*"
  end
  puts
end

Integer#upto

Integer#times

Kernel#loop

1.upto(5) do |i|
  1.upto(i) do |j|
    print "*"
  end
  puts
end

5.times do |i|
  # i goes from 0 to 4
  (i+1).times do
    print "*"
  end
  puts
end

i = 1
loop do
  j = 1
  loop do
    print "*"
    break if (j += 1) > i
  end
  puts
  break if (i += 1) > 5
end

puts (1..5).map { |i| "*" * i }

The code demonstrates the use of nested 'for' loops in Ruby, where the number of iterations of the inner loop is controlled by the outer loop. It prints a pattern of asterisks, where each line has one more asterisk than the previous line. The code can be written in three different ways using Range#each, and can also be simplified to one line using Integer#upto, String#*, and Enumerable#map.


Hash literals[edit]

{:name => 'Zeus', :planet => 'Jupiter'}

{name: 'Zeus', planet: 'Jupiter'}

{1 => 'two', three: 4}

{}
Customizing the default value[edit]

hash = {}
hash[666] = 'devil'
hash[777]  # => nil
hash[666]  # => 'devil'

hash = Hash.new('unknown key')
hash[666] = 'devil'
hash[777]  # => 'unknown key'
hash[666]  # => 'devil'

hash = Hash.new { |h, k| "unknown key #{k}" }
hash[666] = 'devil'
hash[777]  # => 'unknown key 777'
hash[666]  # => 'devil'

hash = Hash.new { |h, k| h[k] = "key #{k} was added at #{Time.now}" }
hash[777]  # => 'key 777 was added at Sun Apr 03 13:49:57 -0700 2011'
hash[555]  # => 'key 555 was added at Sun Apr 03 13:50:01 -0700 2011'
hash[777]  # => 'key 777 was added at Sun Apr 03 13:49:57 -0700 2011'

- Creates an associative array or hash
- Demonstrates literal syntax for Hash objects in Ruby
- Shows how to create a Hash with symbols as keys
- Provides shorthand for symbol keys
- Illustrates creation of a Hash with keys and values of different types
- Creates an empty Hash
- Constructs a Hash object that returns nil for unknown keys
- Builds a Hash object that returns 'unknown key' for unknown keys
- Creates a Hash object that returns a custom message with the key for unknown keys
- Adds a timestamped entry to the hash when an unknown key is first encountered.


module LCG
  module Common
    # The original seed of this generator.
    attr_reader :seed

    # Creates a linear congruential generator with the given _seed_.
    def initialize(seed)
      @seed = @r = seed
    end
  end

  # LCG::Berkeley generates 31-bit integers using the same formula
  # as BSD rand().
  class Berkeley
    include Common
    def rand
      @r = (1103515245 * @r + 12345) & 0x7fff_ffff
    end
  end

  # LCG::Microsoft generates 15-bit integers using the same formula
  # as rand() from the Microsoft C Runtime.
  class Microsoft
    include Common
    def rand
      @r = (214013 * @r + 2531011) & 0x7fff_ffff
      @r >> 16
    end
  end
end

lcg = LCG::Berkeley.new(1)
p (1..5).map {lcg.rand}
# prints [1103527590, 377401575, 662824084, 1147902781, 2035015474]

lcg = LCG::Microsoft.new(1)
p (1..5).map {lcg.rand}
# prints [41, 18467, 6334, 26500, 19169]

The code replicates two historic random number generators, the rand() function from BSD libc and the rand() function from the Microsoft C Runtime (MSCVRT.DLL). It uses the linear congruential generator formula to generate a sequence of random numbers. The code also allows for the creation of multiple instances of LCG::Berkeley or LCG::Microsoft, each keeping the original seed and the current state. The .new method initializes a seed, the #rand method returns the next random number, and the #seed method returns the original seed.


class ListNode
  def insert_after(search_value, new_value)
    if search_value == value
      self.succ = self.class.new(new_value, succ)
    elsif self.succ.nil?
      raise StandardError, "value #{search_value} not found in list"
    else
      self.succ.insert_after(search_value, new_value)
    end
  end
end

list = ListNode.new(:a, ListNode.new(:b))
list.insert_after(:a, :c)

"Defines a method to insert an element into a singly-linked list after a specified element. Specifically, it inserts element C into a list of elements A->B, after element A."


def halve(x) = x/2
def double(x) = x*2

# iterative
def ethiopian_multiply(a, b)
  product = 0
  while a >= 1
    p [a, b, a.even? ? "STRIKE" : "KEEP"] if $DEBUG
    product += b unless a.even?
    a = halve(a)
    b = double(b)
  end
  product
end

# recursive
def rec_ethiopian_multiply(a, b)
  return 0 if a < 1
  p [a, b, a.even? ? "STRIKE" : "KEEP"] if $DEBUG
  (a.even? ? 0 : b) + rec_ethiopian_multiply(halve(a), double(b))
end

$DEBUG = true   # $DEBUG also set to true if "-d" option given
a, b = 20, 5
puts "#{a} * #{b} = #{ethiopian_multiply(a,b)}"; puts

The code defines three functions to perform Ethiopian multiplication. The first function halves an integer, the second function doubles an integer, and the third function checks if an integer is even. These functions are used to create a fourth function that performs Ethiopian multiplication, which involves repeatedly halving and doubling two numbers, discarding rows where the halved number is even, and summing the remaining doubled numbers.


Translation of: Tcl
Works with: Ruby version 2.1
class TwentyFourGame
  EXPRESSIONS = [
    '((%dr %s %dr) %s %dr) %s %dr',
    '(%dr %s (%dr %s %dr)) %s %dr',
    '(%dr %s %dr) %s (%dr %s %dr)',
    '%dr %s ((%dr %s %dr) %s %dr)',
    '%dr %s (%dr %s (%dr %s %dr))',
  ]

  OPERATORS = [:+, :-, :*, :/].repeated_permutation(3).to_a

  def self.solve(digits)
    solutions = []
    perms = digits.permutation.to_a.uniq
    perms.product(OPERATORS, EXPRESSIONS) do |(a,b,c,d), (op1,op2,op3), expr|
      # evaluate using rational arithmetic
      text = expr % [a, op1, b, op2, c, op3, d]
      value = eval(text)  rescue next                 # catch division by zero
      solutions << text.delete("r")  if value == 24
    end
    solutions
  end
end

# validate user input
digits = ARGV.map do |arg|
  begin
    Integer(arg)
  rescue ArgumentError
    raise "error: not an integer: '#{arg}'"
  end
end
digits.size == 4 or raise "error: need 4 digits, only have #{digits.size}"

solutions = TwentyFourGame.solve(digits)
if solutions.empty?
  puts "no solutions"
else
  puts "found #{solutions.size} solutions, including #{solutions.first}"
  puts solutions.sort
end

The code accepts four digits, either from user input or randomly generated, and calculates arithmetic expressions following the 24 game rules. It also displays examples of the solutions it generates.


With large n, the recursion can overflow the call stack and raise a SystemStackError. So factorial_recursive(10000) might fail.
MRI does not optimize tail recursion. So factorial_tail_recursive(10000) might also fail.
# Recursive
def factorial_recursive(n)
  n.zero? ? 1 : n * factorial_recursive(n - 1)
end

# Tail-recursive
def factorial_tail_recursive(n, prod = 1)
  n.zero? ? prod : factorial_tail_recursive(n - 1, prod * n)
end

# Iterative with Range#each
def factorial_iterative(n)
  (2...n).each { |i| n *= i }
  n.zero? ? 1 : n
end

# Iterative with Range#inject
def factorial_inject(n)
  (1..n).inject(1){ |prod, i| prod * i }
end

# Iterative with Range#reduce, requires Ruby 1.8.7
def factorial_reduce(n)
  (2..n).reduce(1, :*)
end

require 'benchmark'

n = 400
m = 10000

Benchmark.bm(16) do |b|
  b.report('recursive:')       {m.times {factorial_recursive(n)}}
  b.report('tail recursive:')  {m.times {factorial_tail_recursive(n)}}
  b.report('iterative:')       {m.times {factorial_iterative(n)}}
  b.report('inject:')          {m.times {factorial_inject(n)}}
  b.report('reduce:')          {m.times {factorial_reduce(n)}}
end

The code implements a function that calculates the factorial of a given number, either iteratively or recursively. The function may optionally handle errors for negative input numbers. Performance may vary depending on the Ruby implementation used.


Works with: Ruby version 1.8.7+
def generate_word(len)
  [*"1".."9"].shuffle.first(len)        # [*"1".."9"].sample(len)  ver 1.9+
end

def get_guess(len)
  loop do
    print "Enter a guess: "
    guess = gets.strip
    err = case
          when guess.match(/[^1-9]/)             ; "digits only"
          when guess.length != len               ; "exactly #{len} digits"
          when guess.split("").uniq.length != len; "digits must be unique"
          else return guess.split("")
          end
    puts "the word must be #{len} unique digits between 1 and 9 (#{err}). Try again."
  end
end

def score(word, guess)
  bulls = cows = 0
  guess.each_with_index do |num, idx|
    if word[idx] == num
      bulls += 1
    elsif word.include? num
      cows += 1
    end
  end
  [bulls, cows]
end

word_length = 4
puts "I have chosen a number with #{word_length} unique digits from 1 to 9."
word = generate_word(word_length)
count = 0
loop do
  guess = get_guess(word_length)
  count += 1
  break if word == guess
  puts "that guess has %d bulls and %d cows" % score(word, guess)
end
puts "you guessed correctly in #{count} tries."

Works with: Ruby version 2.0+
size = 4
secret = [*'1' .. '9'].sample(size)
guess = nil

i=0
loop do
  i+=1
  loop do
    print "Guess #{i}: "
    guess = gets.chomp.chars
    exit if guess.empty?

    break if guess.size == size and
             guess.all? { |x| ('1'..'9').include? x } and
             guess.uniq.size == size

    puts "Problem, try again. You need to enter #{size} unique digits from 1 to 9"
  end

  if guess == secret
    puts "Congratulations you guessed correctly in #{i} attempts"
    break
  end

  bulls = cows = 0
  size.times do |j|
    if guess[j] == secret[j]
      bulls += 1
    elsif secret.include? guess[j]
      cows += 1
    end
  end

  puts "Bulls: #{bulls}; Cows: #{cows}"
end

The code generates a unique four-digit random number from 1 to 9, prompts the user for guesses, rejects malformed guesses, and calculates a score based on the match between the guess and the random number. The game ends when the guess matches the random number. The score is calculated by assigning one bull for each digit that matches the random number in the correct position and one cow for each digit that is present in the random number but in the wrong position. Inspired by Python and Tcl.


Array.new(1000) { 1 + Math.sqrt(-2 * Math.log(rand)) * Math.cos(2 * Math::PI * rand) }

generate a collection of 1000 normally distributed pseudo-random numbers with a mean of 1.0 and a standard deviation of 0.5.


irb(main):001:0> require 'matrix'
=> true
irb(main):002:0> Vector[1, 3, -5].inner_product Vector[4, -2, -1]
=> 3

class Array
  def dot_product(other)
    raise "not the same size!" if self.length != other.length
    zip(other).sum {|a, b| a*b}
  end
end

p [1, 3, -5].dot_product [4, -2, -1]   # => 3

The code computes the dot product of two vectors of the same length by multiplying corresponding elements and summing the results. It can handle vectors of arbitrary length. The vectors for the example provided are [1, 3, -5] and [4, -2, -1]. The code may also use the 'matrix' library and call Vector#inner_product to compute the dot product.


stream = $stdin
stream.each do |line|
  # process line
end

# Create an array of lengths of every line.
ary = stream.map {|line| line.chomp.length}

The code reads data from a text stream either word-by-word or line-by-line until there is no more data. It uses Ruby's IO objects and their methods like IO#each or IO#each_line for iteration, and Enumerable#map for looping through lines. The amount of data in the stream is unknown.


Library: REXML
require("rexml/document")
include REXML
(doc = Document.new) << XMLDecl.new
root = doc.add_element('root')
element = root.add_element('element')
element.add_text('Some text here')

# save to a string
# (the first argument to write() needs an object that understands "<<")
serialized = String.new
doc.write(serialized, 4)
puts serialized

<?xml version='1.0'?>
<root>
    <element>
        Some text here
    </element>
</root>

Create a simple DOM and serialize it into a specific XML format.


version 1.9+t = Time.now

# textual
puts t        # => 2013-12-27 18:00:23 +0900

# epoch time
puts t.to_i   # => 1388134823

# epoch time with fractional seconds
puts t.to_f   # => 1388134823.9801579

# epoch time as a rational (more precision):
puts Time.now.to_r  # 1424900671883862959/1000000000

the system time in a specified unit. This can be used for debugging, network information, random number seeds, or program performance. The time is retrieved either by a system command or a built-in language function. It is related to the task of date formatting and retrieving system time.


Sedol_char = "0123456789BCDFGHJKLMNPQRSTVWXYZ"
Sedolweight = [1,3,1,7,3,9]

def char2value(c)
  raise ArgumentError, "Invalid char #{c}" unless Sedol_char.include?(c)
  c.to_i(36)
end

def checksum(sedol)
  raise ArgumentError, "Invalid length" unless sedol.size == Sedolweight.size
  sum = sedol.chars.zip(Sedolweight).sum{|ch, weight| char2value(ch) * weight }
  ((10 - (sum % 10)) % 10).to_s
end

data = %w(710889
          B0YBKJ
          406566
          B0YBLH
          228276
          B0YBKL
          557910
          B0YBKR
          585284
          B0YBKT
          B00030
          C0000
          1234567
          00000A)

data.each do |sedol|
  print "%-8s " % sedol
  begin
    puts sedol + checksum(sedol)
  rescue => e
    p e
  end
end

The code takes a list of 6-digit SEDOLs as input, calculates the checksum digit for each SEDOL, and appends it to the end of the respective SEDOL. It also validates the input to ensure it contains only valid characters for a SEDOL string.


"Code to draw a sphere, either graphically or in ASCII art, with static or rotational projection capabilities."


class Integer
  def ordinalize
    num = self.abs
    ordinal = if (11..13).include?(num % 100)
      "th"
    else
      case num % 10
        when 1; "st"
        when 2; "nd"
        when 3; "rd"
        else    "th"
      end
    end
    "#{self}#{ordinal}"
  end
end

[(0..25),(250..265),(1000..1025)].each{|r| puts r.map(&:ordinalize).join(", "); puts}

The code is a function that accepts an integer (0 or greater) as an input and returns a string representation of the number with an ordinal suffix. The function also demonstrates its output for specific ranges: 0-25, 250-265, and 1000-1025. The use of apostrophes in the output is optional.


"She was a soul stripper. She took my heart!".delete("aei")  # => "Sh ws  soul strppr. Sh took my hrt!"

"Function to remove specific characters from a given string"


def general_fizzbuzz(text)
  num, *nword = text.split
  num = num.to_i
  dict = nword.each_slice(2).map{|n,word| [n.to_i,word]}
  (1..num).each do |i|
    str = dict.map{|n,word| word if i%n==0}.join
    puts str.empty? ? i : str
  end
end

text = <<EOS
20
3 Fizz
5 Buzz
7 Baxx
EOS

general_fizzbuzz(text)

implement a generalized version of FizzBuzz that takes a maximum number and a list of factor-word pairs as inputs from the user. The code prints numbers from 1 to the maximum number, replacing multiples of each factor with the corresponding word. For numbers that are multiples of multiple factors, the associated words are printed in ascending order of their factors.


str = "llo world"
str.prepend("He")
p str #=> "Hello world"

create a string variable, prepend it with another string literal, and display the content of the variable. If possible, the task should be accomplished without referring to the variable twice in one expression.


Library: Shoes
Point = Struct.new(:x, :y)
Line = Struct.new(:start, :stop)

Shoes.app(:width => 800, :height => 600, :resizable => false) do

  def split_segments(n)
    dir = 1
    @segments = @segments.inject([]) do |new, l|
      a, b, c, d = l.start.x, l.start.y, l.stop.x, l.stop.y

      mid_x = a + (c-a)/2.0 - (d-b)/2.0*dir
      mid_y = b + (d-b)/2.0 + (c-a)/2.0*dir
      mid_p = Point.new(mid_x, mid_y)

      dir *= -1
      new << Line.new(l.start, mid_p)
      new << Line.new(mid_p, l.stop)
    end
  end

  @segments = [Line.new(Point.new(200,200), Point.new(600,200))]
  15.times do |n|
    info "calculating frame #{n}"
    split_segments(n)
  end

  stack do
    @segments.each do |l|
      line l.start.x, l.start.y, l.stop.x, l.stop.y
    end
  end
end

Library: RubyGems
Library: JRubyArt
LEN = 3
GEN = 14
attr_reader :angle

def setup
  sketch_title 'Heighway Dragon'
  background(0, 0, 255)
  translate(170, 170)
  stroke(255)
  @angle = 90.radians
  turn_left(GEN)
end

def draw_line
  line(0, 0, 0, -LEN)
  translate(0, -LEN)
end

def turn_right(gen)
  return draw_line if gen.zero?

  turn_left(gen - 1)
  rotate(angle)
  turn_right(gen - 1)
end

def turn_left(gen)
  return draw_line if gen.zero?

  turn_left(gen - 1)
  rotate(-angle)
  turn_right(gen - 1)
end

def settings
  size(700, 600)
end

Library: RubyGems
Library: JRubyArt
Library: cf3ruby

require 'cf3'

INV_SQRT = 1 / Math.sqrt(2)

def setup_the_dragon
  @dragon = ContextFree.define do
    shape :start do
      dragon alpha: 1
    end

    shape :dragon do
      square hue: 0, brightness: 0, saturation: 1, alpha: 0.02
      split do
        dragon size: INV_SQRT, rotation: -45, x: 0.25, y: 0.25
        rewind
        dragon size: INV_SQRT, rotation: 135, x: 0.25, y: 0.25
        rewind
      end
    end
  end
end

def settings
  size 800, 500
end

def setup
  sketch_title 'Heighway Dragon'
  setup_the_dragon
  draw_it
end

def draw_it
  background 255
  @dragon.render :start, size: width * 0.8, stop_size: 2,
                         start_x: width / 3, start_y: height / 3.5
end

The code generates a dragon curve fractal, which can be displayed directly or written to an image file. It uses various algorithms to achieve this, including recursive methods, successive approximation, iterative methods, and absolute direction calculation. The code also includes functionality to calculate absolute X,Y coordinates of a point and to test whether a given X,Y point or segment is on the curve. The dragon curve can be generated as a Lindenmayer system of expansions, and the code can limit the curve drawn to a certain number of points. The code is also capable of drawing other curves defined by L-systems.


n = rand(1..10)
puts 'Guess the number: '
puts 'Wrong! Guess again: ' until gets.to_i == n
puts 'Well guessed!'

"Implement a number guessing game where the computer selects a number between 1 and 10. The player is repeatedly prompted to guess the number until the correct number is guessed, upon which a 'Well guessed!' message is displayed and the program terminates. A conditional loop is used to facilitate repeated guessing."


generate a sequence of all lower case ASCII characters from a to z. This is done in a reliable coding style suitable for large programs, using strong typing if available. The code avoids manual enumeration of characters to prevent bugs. It also demonstrates how to access a similar sequence from the standard library if it exists.


[5,50,9000].each do |n|
  puts "%b" % n
end

for n in [5,50,9000]
  puts n.to_s(2)
end

"Output: The code takes a non-negative integer as input and converts it into its binary representation. It uses built-in radix functions or a user-defined function to achieve this. The binary output is displayed with no leading zeros, whitespace, radix, or sign markers. Each binary number is followed by a newline."


Works with: Ruby version 2.6.6
Library: gtk3
require 'gtk3'

Width, Height = 320, 240
PosX, PosY = 100, 100

window = Gtk::Window.new
window.set_default_size(Width, Height)
window.title = 'Draw a pixel'

window.signal_connect(:draw) do |widget, context|
  context.set_antialias(Cairo::Antialias::NONE)
  # paint out bg with white
  # context.set_source_rgb(1.0, 1.0, 1.0)
  # context.paint(1.0)
  # draw a rectangle
  context.set_source_rgb(1.0, 0.0, 0.0)
  context.fill do
    context.rectangle(PosX, PosY, 1, 1)
  end
end

window.signal_connect(:destroy) { Gtk.main_quit }

window.show
Gtk.main

"Creates a 320x240 window and draws a single red pixel at position (100, 100)."


fullname = favouritefruit = ""
needspeeling = seedsremoved = false
otherfamily = []

IO.foreach("config.file") do |line|
  line.chomp!
  key, value = line.split(nil, 2)
  case key
  when /^([#;]|$)/; # ignore line
  when "FULLNAME"; fullname = value
  when "FAVOURITEFRUIT"; favouritefruit = value
  when "NEEDSPEELING"; needspeeling = true
  when "SEEDSREMOVED"; seedsremoved = true
  when "OTHERFAMILY"; otherfamily = value.split(",").map(&:strip)
  when /^./; puts "#{key}: unknown key"
  end
end

puts "fullname       = #{fullname}"
puts "favouritefruit = #{favouritefruit}"
puts "needspeeling   = #{needspeeling}"
puts "seedsremoved   = #{seedsremoved}"
otherfamily.each_with_index do |name, i|
  puts "otherfamily(#{i+1}) = #{name}"
end

read a configuration file and set variables based on the contents. It ignores lines starting with a hash or semicolon and blank lines. It sets variables 'fullname', 'favouritefruit', 'needspeeling', and 'seedsremoved' based on the file entries. It also stores multiple parameters from the 'otherfamily' entry into an array.


include Math

Radius = 6372.8  # rough radius of the Earth, in kilometers

def spherical_distance(start_coords, end_coords)
  lat1, long1 = deg2rad *start_coords
  lat2, long2 = deg2rad *end_coords
  2 * Radius * asin(sqrt(sin((lat2-lat1)/2)**2 + cos(lat1) * cos(lat2) * sin((long2 - long1)/2)**2))
end

def deg2rad(lat, long)
  [lat * PI / 180, long * PI / 180]
end

bna = [36.12, -86.67]
lax = [33.94, -118.4]

puts "%.1f" % spherical_distance(bna, lax)

implement the Haversine formula to calculate the great-circle distance between Nashville International Airport and Los Angeles International Airport. The codes use either the authalic radius (6371.0 km) or the average great-circle radius (6372.8 km) for the earth, with the latter being recommended for more accurate results.


require 'open-uri'

print open("http://rosettacode.org") {|f| f.read}

require 'fileutils'
require 'open-uri'

open("http://rosettacode.org/") {|f| FileUtils.copy_stream(f, $stdout)}

"Code accesses a URL's content and prints it to the console using FileUtils.copy_stream for large content."


 def luhn_valid?(str)
   str.scan(/\d/).reverse            #using str.to_i.digits fails for cases with leading zeros
      .each_slice(2)
      .sum { |i, k = 0| i.to_i + ((k.to_i)*2).digits.sum }
      .modulo(10).zero?
 end

["49927398716", "49927398717", "1234567812345678", "1234567812345670"].map{ |i| luhn_valid?(i) }

The code validates credit card numbers using the Luhn test. It first reverses the order of the digits in the number. Then, it calculates the sum of every other odd digit (s1) and the sum of the doubled even digits (s2). If the sum of s1 and s2 ends in zero, the number is a valid credit card number. The code tests this functionality on four different numbers.


n = (ARGV[0] || 41).to_i
k = (ARGV[1] || 3).to_i

prisoners = (0...n).to_a
prisoners.rotate!(k-1).shift  while prisoners.length > 1
puts prisoners.first

- Determine the final survivor in the Josephus problem given any number of prisoners (n) and a step count (k).
- Calculate the position of any prisoner in the killing sequence.
- Provide an option to save a certain number of prisoners (m).
- The numbering of prisoners can start from either 0 or 1.
- The complexity of the solution is O(kn) for the complete killing sequence and O(m) for finding the m-th prisoner to die.


The code takes a string or a character as input and repeats it a specified number of times. For example, if the input is "ha" and 5, the output will be "hahahahaha". Similarly, if the input is "*" and 5, the output will be "*****".


str = "I am a string"
p "Ends with 'string'" if str =~ /string$/
p "Does not start with 'You'" unless str =~ /^You/

str.sub(/ a /, ' another ') #=> "I am another string"
# Or:
str[/ a /] = ' another '    #=> "another"
str                         #=> "I am another string"

str.gsub(/\bam\b/) { |match| match.upcase } #=> "I AM a string"

- Matches a string with a regular expression
- Replaces a part of the string using a regular expression
- Tests the substitution
- Performs substitution using a block


puts 'Enter x and y'
x = gets.to_i  # to check errors, use x=Integer(gets)
y = gets.to_i

puts "Sum: #{x+y}",
     "Difference: #{x-y}",
     "Product: #{x*y}",
     "Quotient: #{x/y}",       # truncates towards negative infinity
     "Quotient: #{x.fdiv(y)}", # float
     "Remainder: #{x%y}",      # same sign as second operand
     "Exponentiation: #{x**y}",
     "Quotient: %d with Remainder: %d" % x.divmod(y)

take two integers as input from the user and display their sum, difference, product, integer quotient, remainder, and exponentiation. The code also indicates the rounding direction for the quotient and the sign of the remainder. It does not include error handling. A bonus feature is the inclusion of the `divmod` operator example.


def countSubstrings str, subStr
  str.scan(subStr).length
end

p countSubstrings "the three truths", "th"      #=> 3
p countSubstrings "ababababab", "abab"          #=> 2

The code defines a function to count the number of non-overlapping occurrences of a specific substring within a given string. The function takes two arguments, the main string and the substring to search for. It returns an integer representing the count of the non-overlapping occurrences. The function does not count overlapping substrings and matches from left-to-right or right-to-left for the highest number of non-overlapping matches.


version 1[edit]
def move(num_disks, start=0, target=1, using=2)
  if num_disks == 1
   @towers[target] << @towers[start].pop
    puts "Move disk from #{start} to #{target} : #{@towers}"
  else
    move(num_disks-1, start, using, target)
    move(1,           start, target, using)
    move(num_disks-1, using, target, start)
  end
end

n = 5
@towers = [[*1..n].reverse, [], []]
move(n)

"Implement a recursive solution to solve the Towers of Hanoi problem."


Translation of: Tcl
Works with: Ruby version 1.8.7+
class Integer
  # binomial coefficient: n C k
  def choose(k)
    # n!/(n-k)!
    pTop = (self-k+1 .. self).inject(1, &:*)
    # k!
    pBottom = (2 .. k).inject(1, &:*)
    pTop / pBottom
  end
end

p 5.choose(3)
p 60.choose(30)

10
118264581564861424

def c n, r
  (0...r).inject(1) do |m,i| (m * (n - i)) / (i + 1) end
end
Ruby's Arrays have a combination method which result in a (lazy) enumerator. This Enumerator has a "size" method, which returns the size of the enumerator, or nil if it can’t be calculated lazily. (Since Ruby 2.0)
(1..60).to_a.combination(30).size  #=> 118264581564861424

The code calculates any binomial coefficient using the given formula. It is able to output the binomial coefficient of 5 choose 3, which equals to 10. It also handles tasks related to combinations and permutations, both with and without replacement.


Translation of: Java

class Array
  def shellsort!
    inc = length / 2
    while inc != 0
      inc.step(length-1) do |i|
        el = self[i]
        while i >= inc and self[i - inc] > el
          self[i] = self[i - inc]
          i -= inc
        end
        self[i] = el
      end
      inc = (inc == 2 ? 1 : (inc * 5.0 / 11).to_i)
    end
    self
  end
end

data = [22, 7, 2, -5, 8, 4]
data.shellsort!
p data # [-5, 2, 4, 7, 8, 22]

implement the Shell sort algorithm to sort an array of elements. This method, invented by Donald Shell, uses a diminishing increment sequence for interleaved insertion sorts. The increment size is reduced after each pass until it reaches 1, at which point the data is almost sorted. The sequence can be any as long as it ends in 1, with a geometric increment sequence of ratio 2.2 shown to work well. The method sorts in place, so a copy should be made if the original list needs to be preserved.


class RGBColour
  def to_grayscale
    luminosity = Integer(0.2126*@red + 0.7152*@green + 0.0722*@blue)
    self.class.new(luminosity, luminosity, luminosity)
  end
end

class Pixmap
  def to_grayscale
    gray = self.class.new(@width, @height)
    @width.times do |x|
      @height.times do |y|
        gray[x,y] = self[x,y].to_grayscale
      end
    end
    gray
  end
end

The code extends the basic bitmap storage to support grayscale images. It defines two operations for converting a color image to a grayscale image and vice versa. The conversion uses the CIE recommended formula for luminance calculation. It also ensures that rounding errors in floating-point arithmetic do not cause run-time issues or distort results when the calculated luminance is stored as an unsigned integer.


Translation of: Tcl
Library: Ruby/Tk
require 'tk'
$str = TkVariable.new("Hello World! ")
$dir = :right

def animate
  $str.value = shift_char($str.value, $dir)
  $root.after(125) {animate}
end

def shift_char(str, dir)
  case dir
  when :right then str[-1,1] + str[0..-2]
  when :left  then str[1..-1] + str[0,1]
  end
end

$root = TkRoot.new("title" => "Basic Animation")

TkLabel.new($root) do
  textvariable $str
  font "Courier 14"
  pack {side 'top'}
  bind("ButtonPress-1") {$dir = {:right=>:left,:left=>:right}[$dir]}
end

animate
Tk.mainloop

Library: Shoes
Shoes.app do
  @direction = 1
  @label = para "Hello World! ", :family => 'monospace'

  click {|button, left, top| @direction *= -1 if button == 1}

  animate(8) do |f|
    t = @label.text
    @label.text = @direction > 0 ? t[-1] + t[0..-2] : t[1..-1] + t[0]
  end
end

Create a GUI animation where the string "Hello World! " appears to rotate right by periodically moving the last letter to the front. The direction of rotation reverses when the user clicks on the text.


while

until

val = 0
begin
   val += 1
   puts val
end while val % 6 != 0

val = 0
begin
   val += 1
   puts val
end until val % 6 == 0

break unless

break if

val = 0
loop do
   val += 1
   puts val
   break unless val %6 != 0
end

val = 0
loop do
   val += 1
   puts val
   break if val %6 == 0
end

The code initializes a value at 0 and enters a loop which continues until the value modulo 6 is not 0. In each iteration, the value is incremented by 1 and printed. The loop is guaranteed to execute at least once. This behavior is attributed to the while statement modifier on a begin...end statement. The code prints the numbers 1 through 6.


Byte Length[edit]
"J̲o̲s̲é̲".bytesize
Character Length[edit]
"J̲o̲s̲é̲".chars.length
Grapheme Length[edit]
"J̲o̲s̲é̲".grapheme_clusters.length
Code Set Independence[edit]

To run these programs, you must convert them to different encodings.

If you use Emacs: Paste each program into Emacs. The magic comment, like -*- coding: iso-8859-1 -*-, will tell Emacs to save with that encoding.
If your text editor saves UTF-8: Convert the file before running it. For example:$ ruby -pe '$_.encode!("iso-8859-1", "utf-8")' scratch.rb | ruby

Works with: Ruby version 1.9

Program

Output

# -*- coding: iso-8859-1 -*-
s = "møøse"
puts "Byte length: %d" % s.bytesize
puts "Character length: %d" % s.length

Byte length: 5
Character length: 5

# -*- coding: utf-8 -*-
s = "møøse"
puts "Byte length: %d" % s.bytesize
puts "Character length: %d" % s.length

Byte length: 7
Character length: 5

# -*- coding: gb18030 -*-
s = "møøse"
puts "Byte length: %d" % s.bytesize
puts "Character length: %d" % s.length

Byte length: 11
Character length: 5

Ruby 1.8[edit]

/./n uses no multibyte encoding.
/./e uses EUC-JP.
/./s uses Shift-JIS or Windows-31J.
/./u uses UTF-8.

# -*- coding: utf-8 -*-

class String
  # Define String#bytesize for Ruby 1.8.6.
  unless method_defined?(:bytesize)
    alias bytesize length
  end
end

s = "文字化け"
puts "Byte length: %d" % s.bytesize
puts "Character length: %d" % s.gsub(/./u, ' ').size

determine the character and byte length of a string, considering different encodings such as UTF-8 and UTF-16. It handles Unicode code points correctly, distinguishing between actual character counts and code unit counts. It also provides the string length in graphemes if the language supports it. The code is compatible with different versions of Ruby and can count UTF-8 characters in a string.


require 'securerandom'
SecureRandom.random_number(1 << 32)

#or specifying SecureRandom as the desired RNG:
p (1..10).to_a.sample(3, random: SecureRandom) # =>[1, 4, 5]

demonstrate how to generate a random 32-bit number using the system's built-in mechanism, such as /dev/urandom in Unix. If available, the 'securerandom' library introduced in Ruby 1.8.7 is used, which attempts to generate random numbers by loading OpenSSL, opening /dev/urandom, or calling CryptGenRandom.


puts "knight"[1..-1]   # strip first character
puts "socks"[0..-2]    # strip last character
puts "socks".chop      # alternate way to strip last character
puts "brooms"[1..-2]   # strip both first and last characters
puts "与今令"[1..-2]    # => 今

The code demonstrates how to remove the first, last, and both the first and last characters from a string. It works with any valid Unicode code point in UTF-8 or UTF-16, referencing logical characters, not code units. It doesn't necessarily support all Unicode characters for other encodings like 8-bit ASCII or EUC-JP.


def main
  puts "first instance"
  sleep 20
  puts :done
end

if $0 == __FILE__
  if File.new(__FILE__).flock(File::LOCK_EX | File::LOCK_NB)
    main
  else
    raise "another instance of this program is running"
  end
end

__END__

check if a single instance of an application is running, display a message and exit if another instance is found, using file locking on the program file.


Works with: Ruby version 2.0+
def read_matrix(data)
  lines = data.lines
  9.times.collect { |i| 9.times.collect { |j| lines[i][j].to_i } }
end

def permissible(matrix, i, j)
  ok = [nil, *1..9]
  check = ->(x,y) { ok[matrix[x][y]] = nil  if matrix[x][y].nonzero? }
  # Same as another in the column isn't permissible...
  9.times { |x| check[x, j] }
  # Same as another in the row isn't permissible...
  9.times { |y| check[i, y] }
  # Same as another in the 3x3 block isn't permissible...
  xary = [ *(x = (i / 3) * 3) .. x + 2 ]        #=> [0,1,2], [3,4,5] or [6,7,8]
  yary = [ *(y = (j / 3) * 3) .. y + 2 ]
  xary.product(yary).each { |x, y| check[x, y] }
  # Gathering only permitted one
  ok.compact
end

def deep_copy_sudoku(matrix)
  matrix.collect { |row| row.dup }
end

def solve_sudoku(matrix)
  loop do
    options = []
    9.times do |i|
      9.times do |j|
        next if matrix[i][j].nonzero?
        p = permissible(matrix, i, j)
        # If nothing is permissible, there is no solution at this level.
        return if p.empty?              # return nil
        options << [i, j, p]
      end
    end
    # If the matrix is complete, we have a solution...
    return matrix if options.empty?

    i, j, permissible = options.min_by { |x| x.last.length }

    # If there is an option with only one solution, set it and re-check permissibility
    if permissible.length == 1
      matrix[i][j] = permissible[0]
      next
    end

    # We have two or more choices. We need to search both...
    permissible.each do |v|
      mtmp = deep_copy_sudoku(matrix)
      mtmp[i][j] = v
      ret = solve_sudoku(mtmp)
      return ret if ret
    end

    # We did an exhaustive search on this branch and nothing worked out.
    return
  end
end

def print_matrix(matrix)
  puts "Impossible" or return  unless matrix

  border = "+-----+-----+-----+"
  9.times do |i|
    puts border if i%3 == 0
    9.times do |j|
      print j%3 == 0 ? "|" : " "
      print matrix[i][j] == 0 ? "." : matrix[i][j]
    end
    puts "|"
  end
  puts border
end

data = <<EOS
394__267_
___3__4__
5__69__2_
_45___9__
6_______7
__7___58_
_1__67__8
__9__8___
_264__735
EOS

matrix = read_matrix(data)
print_matrix(matrix)
puts
print_matrix(solve_sudoku(matrix))

"Implement a Sudoku solver that takes a partially filled 9x9 grid and outputs the completed grid in a human-readable format, using backtracking algorithm."


Translation of: Tcl
class Array
  def knuth_shuffle!
    j = length
    i = 0
    while j > 1
      r = i + rand(j)
      self[i], self[r] = self[r], self[i]
      i += 1
      j -= 1
    end
    self
  end
end

r = Hash.new(0)
100_000.times do |i|
  a = [1,2,3].knuth_shuffle!
  r[a] += 1
end

r.keys.sort.each {|a| puts "#{a.inspect} => #{r[a]}"}

[1, 2, 3] => 16572
[1, 3, 2] => 16610
[2, 1, 3] => 16633
[2, 3, 1] => 16714
[3, 1, 2] => 16838
[3, 2, 1] => 16633

class Array
  def knuth_shuffle!
    (length - 1).downto(1) do |i|
      j = rand(i + 1)
      self[i], self[j] = self[j], self[i]
    end
    self
  end
end

implement the Knuth shuffle algorithm, which randomly shuffles the elements of an array. The algorithm modifies the input array in-place or returns the shuffled items as a new array, depending on the programming language. The algorithm can also be modified to iterate from left to right if needed.


require 'date'

def last_friday(year, month)
  # Last day of month: Date.new interprets a negative number as a relative month/day from the end of year/month.
  d = Date.new(year, month, -1)
  d -= (d.wday - 5) % 7  # Subtract days after Friday.
end

year = Integer(ARGV.shift)
(1..12).each {|month| puts last_friday(year, month)}

The code takes a year as input and returns the dates of the last Fridays of each month for that year. It calculates this by either using the expression (d.wday - 5) % 7 to count days after Friday, or by getting the last day of the month and going back day by day until it reaches a Friday.


"Display the string 'Goodbye, World!' without appending a newline at the end."


Library: Ruby/Tk
require 'tk'

def main
  root = TkRoot.new
  l1 = TkLabel.new(root, "text" => "input a string")
  e1 = TkEntry.new(root)
  l2 = TkLabel.new(root, "text" => "input the number 75000")
  e2 = TkEntry.new(root) do
    validate "focusout"
    validatecommand lambda {e2.value.to_i == 75_000}
    invalidcommand  lambda {focus_number_entry(e2)}
  end
  ok = TkButton.new(root) do
    text "OK"
    command lambda {validate_input(e1, e2)}
  end
  Tk.grid(l1, e1)
  Tk.grid(l2, e2)
  Tk.grid("x",ok, "sticky" => "w")
  Tk.mainloop
end

def validate_input(text_entry, number_entry)
  if number_entry.value.to_i != 75_000
    focus_number_entry(number_entry)
  else
    puts %Q{You entered: "#{text_entry.value}" and "#{number_entry.value}"}
    root.destroy
  end
end

def focus_number_entry(widget)
  widget \
    .configure("background" => "red", "foreground" => "white") \
    .selection_range(0, "end") \
    .focus
end

main

Library: Shoes
Shoes.app do
  string = ask('Enter a string:')
  begin
    number = ask('Enter the number 75000:')
  end while number.to_i != 75000
  para %Q{you entered the string "#{string}" and the number #{number}}
end

"Implement a graphical user interface to accept a string and the integer 75000 as input, and validate the input number to ensure it is exactly 75000."


class String
  ALFABET = ("A".."Z").to_a

  def caesar_cipher(num)
    self.tr(ALFABET.join, ALFABET.rotate(num).join)
  end

end

#demo:
encypted  = "THEYBROKEOURCIPHEREVERYONECANREADTHIS".caesar_cipher(3)
decrypted = encypted.caesar_cipher(-3)

implement both encoding and decoding functions of a Caesar cipher. The cipher rotates the alphabet letters based on a key ranging from 1 to 25, replacing each letter with the corresponding next letter in the alphabet. The codes also handle cases of wrapping from Z to A. The codes illustrate that Caesar cipher provides minimal security as it is vulnerable to frequency analysis and brute force attacks. The codes also demonstrate that Caesar cipher is identical to Vigenère cipher with a key length of 1 and to Rot-13 with a key of 13.


irb(main):001:0> 12.lcm 18
=> 36

def gcd(m, n)
  m, n = n, m % n until n.zero?
  m.abs
end

def lcm(*args)
  args.inject(1) do |m, n|
    return 0 if n.zero?
    (m * n).abs / gcd(m, n)
  end
end

p lcm 12, 18, 22
p lcm 15, 14, -6, 10, 21

The code calculates the least common multiple (LCM) of two integers, m and n. The LCM is the smallest positive integer that is a multiple of both m and n. If either m or n is zero, the LCM is zero. The code can calculate the LCM by iterating all multiples of m until finding one that is also a multiple of n, or by using the formula lcm(m, n) = |m x n| / gcd(m, n), where gcd is the greatest common divisor. The code can also find the LCM by merging the prime decompositions of m and n.


Following pseudocode[edit]
#!/usr/bin/env ruby

def check_cusip(cusip)
  abort('CUSIP must be 9 characters') if cusip.size != 9

  sum = 0
  cusip.split('').each_with_index do |char, i|
    next if i == cusip.size - 1
    case
    when char.scan(/\D/).empty?
      v = char.to_i
    when char.scan(/\D/).any?
      pos = char.upcase.ord - 'A'.ord + 1
      v = pos + 9
    when char == '*'
      v = 36
    when char == '@'
      v = 37
    when char == '#'
      v = 38
    end

    v *= 2 unless (i % 2).zero?
    sum += (v/10).to_i + (v % 10)
  end

  check = (10 - (sum % 10)) % 10
  return 'VALID' if check.to_s == cusip.split('').last
  'INVALID'
end

CUSIPs = %w[
  037833100 17275R102 38259P508 594918104 68389X106 68389X105
]

CUSIPs.each do |cusip|
  puts "#{cusip}: #{check_cusip(cusip)}"
end

037833100: VALID
17275R102: VALID
38259P508: VALID
594918104: VALID
68389X106: INVALID
68389X105: VALID

More concise[edit]

TABLE = ("0".."9").chain("A".."Z", %w(* @ #)).zip(0..).to_h

def valid_CUSIP?(str)
  sum = str[0..-2].chars.each_slice(2).sum do |c1,c2|
    TABLE[c1].divmod(10).sum + (TABLE[c2]*2).divmod(10).sum
  end
  str[-1].to_i == (10 - (sum % 10)) % 10
end

CUSIPs = %w(037833100 17275R102 38259P508 594918104 68389X106 68389X105)
CUSIPs.each{|cusip| puts "#{cusip}: #{valid_CUSIP? cusip}"}

The code validates the last digit (check digit) of a CUSIP code, which is a nine-character alphanumeric code identifying North American financial securities. It uses a specific algorithm to calculate the check digit from the first 8 characters of the CUSIP code and compares it with the actual last digit. The algorithm handles digits, letters, and special characters differently. The code is written in Ruby and requires a version > 2.5 due to the usage of methods like chain, to_h, sum, and infinite Range syntax (0..).


# We assume that a Fixnum occupies one machine word.
# Fixnum#size returns bytes (1 byte = 8 bits).
word_size = 42.size * 8
puts "Word size: #{word_size} bits"

# Array#pack knows the native byte order. We pack 1 as a 16-bit integer,
# then unpack bytes: [0, 1] is big endian, [1, 0] is little endian.
bytes = [1].pack('S').unpack('C*')
byte_order = (bytes[0] == 0 ? 'big' : 'little') + ' endian'
puts "Byte order: #{byte_order}"

determine and print the word size and endianness of the host machine. It takes into account the differences in Fixnum size between MRI and JRuby implementations of Ruby. In MRI, Fixnum size is equivalent to a native machine word, while in JRuby, it is always 64 bits. The code also ensures correct native byte order in JRuby by using java.nio.ByteOrder.nativeOrder().


By using the API[edit]
Works with: Ruby version 1.8.7

require 'rosettacode'

langs = []
RosettaCode.category_members("Programming Languages") {|lang| langs << lang}

# API has trouble with long titles= values.
# To prevent skipping languages, use short slices of 20 titles.
langcount = {}
langs.each_slice(20) do |sublist|
  url = RosettaCode.get_api_url({
    "action" => "query",
    "prop" => "categoryinfo",
    "format" => "xml",
    "titles" => sublist.join("|"),
  })

  doc = REXML::Document.new open(url)
  REXML::XPath.each(doc, "//page") do |page|
    lang = page.attribute("title").value
    info = REXML::XPath.first(page, "categoryinfo")
    langcount[lang] = info.nil? ? 0 : info.attribute("pages").value.to_i
  end
end

puts Time.now
puts "There are #{langcount.length} languages"
puts "the top 25:"
langcount.sort_by {|key,val| val}.reverse[0,25].each_with_index do |(lang, count), i|
  puts "#{i+1}. #{count} - #{lang.sub(/Category:/, '')}"
end

Results:
2010-07-08 14:52:46 -0500
There are 306 languages
the top 25:
1. 399 - Tcl
2. 370 - Python
3. 352 - Ruby
4. 338 - J
5. 337 - C
6. 333 - PicoLisp
7. 322 - OCaml
8. 322 - Haskell
9. 299 - Perl
10. 299 - AutoHotkey
11. 288 - Common Lisp
12. 280 - Java
13. 275 - Ada
14. 270 - D
15. 267 - Oz
16. 253 - R
17. 252 - PureBasic
18. 245 - E
19. 243 - C++
20. 241 - C sharp
21. 239 - ALGOL 68
22. 236 - JavaScript
23. 221 - Forth
24. 207 - Clojure
25. 201 - Fortran

The code sorts and ranks the most popular computer programming languages based on the number of members in Rosetta Code categories. It uses either web scraping or API methods to access the data. The code also has the option to filter incorrect results. It handles more than 500 categories by using the RC API to retrieve the categories and count the members of each. The code utilizes the RosettaCode module from Count programming examples#Ruby.


for i in collection do
  puts i
end

collection.each do |i|
  puts i
end

utilize a "for each" loop or another type of loop to iterate through and print each element of a collection in order. It also demonstrates the use of different versions of "each" that are dependent on the class, such as String#each_char, Array#each_index, Hash#each_key, etc.


"Tokenizes a string by commas into an array, and displays the words to the user separated by a period, including a trailing period."


40902.gcd(24140)  # => 34

def gcd(u, v)
  u, v = u.abs, v.abs
  while v > 0
    u, v = v, u % v
  end
  u
end

implement the gcd method to find the greatest common divisor (GCD), also known as greatest common factor (gcf) and greatest common measure, of two integers. This method is related to the task of finding the least common multiple. More information can be found in the MathWorld and Wikipedia entries for greatest common divisor.


require 'socket'
server = TCPServer.new(12321)

while (connection = server.accept)
  Thread.new(connection) do |conn|
    port, host = conn.peeraddr[1,2]
    client = "#{host}:#{port}"
    puts "#{client} is connected"
    begin
      loop do
        line = conn.readline
        puts "#{client} says: #{line}"
        conn.puts(line)
      end
    rescue EOFError
      conn.close
      puts "#{client} has disconnected"
    end
  end
end

Works with: Ruby version 1.9.2
require 'socket'

Socket.tcp_server_loop(12321) do |conn, addr|
  Thread.new do
    client = "#{addr.ip_address}:#{addr.ip_port}"
    puts "#{client} is connected"
    begin
      loop do
        line = conn.readline
        puts "#{client} says: #{line}"
        conn.puts(line)
      end
    rescue EOFError
      conn.close
      puts "#{client} has disconnected"
    end
  end
end

The code implements an echo server that runs on TCP port 12321, accepting and echoing back complete lines from multiple simultaneous connections, primarily from localhost. It handles multiple clients using multi-threading or multi-processing and continues to respond to other clients even if one client sends a partial line or stops reading responses. Connection information is logged to standard output. The server is created using the Socket.tcp_server_loop method introduced in Ruby 1.9.2.


def is_numeric?(s)
  begin
    Float(s)
  rescue
    false # not numeric
  else
    true # numeric
  end
end

def is_numeric?(s)
    !!Float(s) rescue false
end

def is_numeric?(s)
    !!Float(s, exception: false)
end

strings = %w(0 0.0 -123 abc 0x10 0xABC 123a -123e3 0.1E-5 50e)
strings.each do |str|
  puts "%9p => %s" % [str, is_numeric?(str)]
end

"Create a function that checks if a given string can be considered as a numeric value, including floating point and negative numbers, in the syntax used by the language for numeric literals or numbers converted from strings. Note that since Ruby 2.6, `rescue` is not needed by adding `exception: false` to return `nil` instead."


require 'net/https'
require 'uri'
require 'pp'

uri = URI.parse('https://sourceforge.net')
http = Net::HTTP.new(uri.host,uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

http.start do
  content = http.get(uri)
  p [content.code, content.message]
  pp content.to_hash
  puts content.body
end

["302", "Found"]
{"location"=>["http://sourceforge.net/"],
 "content-type"=>["text/html; charset=UTF-8"],
 "connection"=>["close"],
 "server"=>["nginx/0.7.60"],
 "date"=>["Sun, 30 Aug 2009 20:20:07 GMT"],
 "content-length"=>["229"],
 "set-cookie"=>
  ["sf.consume=89f65c6fadd222338b2f3de6f8e8a17b2c8f67c2gAJ9cQEoVQhfZXhwaXJlc3ECY2RhdGV0aW1lCmRhdGV0aW1lCnEDVQoH9gETAw4HAAAAhVJxBFUDX2lkcQVVIDEyOWI2MmVkOWMwMWYxYWZiYzE5Y2JhYzcwZDMxYTE4cQZVDl9hY2Nlc3NlZF90aW1lcQdHQdKmt73UN21VDl9jcmVhdGlvbl90aW1lcQhHQdKmt73UN2V1Lg==; expires=Tue, 19-Jan-2038 03:14:07 GMT; Path=/"]}

  <title>302 Found</title>

302 Found

  The resource was found at http://sourceforge.net/;
you should be redirected automatically.

send a GET request to the URL "https://www.w3.org/" and print the result to the console. The code checks the host certificate for validity and does not include authentication. It uses the Net::HTTP object for the request, which is set to use SSL before the session starts.


Translation of: Go
Point = Struct.new(:x,:y) do
  def to_s; "(#{x}, #{y})" end
end

def sutherland_hodgman(subjectPolygon, clipPolygon)
  # These inner functions reduce the argument passing to
  # "inside" and "intersection".
  cp1, cp2, s, e = nil
  inside = proc do |p|
    (cp2.x-cp1.x)*(p.y-cp1.y) > (cp2.y-cp1.y)*(p.x-cp1.x)
  end
  intersection = proc do
    dcx, dcy = cp1.x-cp2.x, cp1.y-cp2.y
    dpx, dpy = s.x-e.x, s.y-e.y
    n1 = cp1.x*cp2.y - cp1.y*cp2.x
    n2 = s.x*e.y - s.y*e.x
    n3 = 1.0 / (dcx*dpy - dcy*dpx)
    Point[(n1*dpx - n2*dcx) * n3, (n1*dpy - n2*dcy) * n3]
  end

  outputList = subjectPolygon
  cp1 = clipPolygon.last
  for cp2 in clipPolygon
    inputList = outputList
    outputList = []
    s = inputList.last
    for e in inputList
      if inside[e]
        outputList << intersection[] unless inside[s]
        outputList << e
      elsif inside[s]
        outputList << intersection[]
      end
      s = e
    end
    cp1 = cp2
  end
  outputList
end

subjectPolygon = [[50, 150], [200, 50], [350, 150], [350, 300],
                  [250, 300], [200, 250], [150, 350], [100, 250],
                  [100, 200]].collect{|pnt| Point[*pnt]}

clipPolygon = [[100, 100], [300, 100], [300, 300], [100, 300]].collect{|pnt| Point[*pnt]}

puts sutherland_hodgman(subjectPolygon, clipPolygon)

implement the Sutherland-Hodgman polygon clipping algorithm. The code takes a closed polygon and a rectangle as inputs, clips the polygon by the rectangle, and outputs the sequence of points that define the resulting clipped polygon. For extra credit, the code also displays all three polygons on a graphical surface, using different colors for each polygon and filling the resulting polygon. The orientation of the display can be either north-west or south-west.


ar = "44 Solomon
42 Jason
42 Errol
41 Garry
41 Bernard
41 Barry
39 Stephen".lines.map{|line| line.split}
grouped = ar.group_by{|pair| pair.shift.to_i}
s_rnk = 1
m_rnk = o_rnk = 0
puts "stand.\tmod.\tdense\tord.\tfract."

grouped.each.with_index(1) do |(score, names), d_rnk|
  m_rnk += names.flatten!.size
  f_rnk = (s_rnk + m_rnk)/2.0
  names.each do |name|
    o_rnk += 1
    puts "#{s_rnk}\t#{m_rnk}\t#{d_rnk}\t#{o_rnk}\t#{f_rnk.to_s.sub(".0","")}\t#{score} #{name}"
  end
  s_rnk += names.size
end

"Implement functions for five different ranking methods: Standard, Modified, Dense, Ordinal, and Fractional. Each function takes an ordered list of competition scores and applies the respective ranking method. The Standard method shares the first ordinal number for ties, the Modified method shares the last ordinal number for ties, the Dense method shares the next available integer for ties, the Ordinal method assigns the next available integer without special treatment for ties, and the Fractional method shares the mean of the ordinal numbers for ties."


radians = Math::PI / 4
degrees = 45.0

def deg2rad(d)
  d * Math::PI / 180
end

def rad2deg(r)
  r * 180 / Math::PI
end

#sine
puts "#{Math.sin(radians)} #{Math.sin(deg2rad(degrees))}"
#cosine
puts "#{Math.cos(radians)} #{Math.cos(deg2rad(degrees))}"
#tangent
puts "#{Math.tan(radians)} #{Math.tan(deg2rad(degrees))}"
#arcsine
arcsin = Math.asin(Math.sin(radians))
puts "#{arcsin} #{rad2deg(arcsin)}"
#arccosine
arccos = Math.acos(Math.cos(radians))
puts "#{arccos} #{rad2deg(arccos)}"
#arctangent
arctan = Math.atan(Math.tan(radians))
puts "#{arctan} #{rad2deg(arctan)}"

demonstrate the usage of trigonometric functions including sine, cosine, tangent and their inverses in a specific programming language. The functions are applied to the same angle in both radians and degrees. For non-inverse functions, the same angle is used for each radian/degree pair. For inverse functions, the same number is converted to radians and degrees. If the language lacks certain trigonometric functions, they are manually calculated using known approximations or identities. The codes also handle conversion between radians and degrees and provide the option to increase precision of the results using BigDecimal class.


Translation of: Python
# Item struct to represent each item in the problem
Struct.new('Item', :name, :weight, :value, :count)

$items = [
  Struct::Item.new('map', 9, 150, 1),
  Struct::Item.new('compass', 13, 35, 1),
  Struct::Item.new('water', 153, 200, 3),
  Struct::Item.new('sandwich', 50, 60, 2),
  Struct::Item.new('glucose', 15, 60, 2),
  Struct::Item.new('tin', 68, 45, 3),
  Struct::Item.new('banana', 27, 60, 3),
  Struct::Item.new('apple', 39, 40, 3),
  Struct::Item.new('cheese', 23, 30, 1),
  Struct::Item.new('beer', 52, 10, 3),
  Struct::Item.new('suntan cream', 11, 70, 1),
  Struct::Item.new('camera', 32, 30, 1),
  Struct::Item.new('t-shirt', 24, 15, 2),
  Struct::Item.new('trousers', 48, 10, 2),
  Struct::Item.new('umbrella', 73, 40, 1),
  Struct::Item.new('w-trousers', 42, 70, 1),
  Struct::Item.new('w-overcoat', 43, 75, 1),
  Struct::Item.new('note-case', 22, 80, 1),
  Struct::Item.new('sunglasses', 7, 20, 1),
  Struct::Item.new('towel', 18, 12, 2),
  Struct::Item.new('socks', 4, 50, 1),
  Struct::Item.new('book', 30, 10, 2)
]

def choose_item(weight, id, cache)
  return 0, [] if id < 0

  k = [weight, id]
  return cache[k] unless cache[k].nil?
  value = $items[id].value
  best_v = 0
  best_list = []
  ($items[id].count+1).times do |i|
    wlim = weight - i * $items[id].weight
    break if wlim < 0
    val, taken = choose_item(wlim, id - 1, cache)
    if val + i * value > best_v
      best_v = val + i * value
      best_list = taken + [i]
    end
  end
  cache[k] = [best_v, best_list]
  return [best_v, best_list]
end

val, list = choose_item(400, $items.length - 1, {})
w = 0
list.each_with_index do |cnt, i|
  if cnt > 0
    print "#{cnt} #{$items[i].name}\n"
    w += $items[i][1] * cnt
  end
end

p "Total weight: #{w}, Value: #{val}"

The code determines the optimal combination of items a tourist can carry in his knapsack, given a maximum weight limit of 4 kg. It selects items based on their importance value and weight, ensuring the total weight does not exceed the limit and the total value is maximized. The code considers the quantity available of each item and only allows whole units to be selected.


t1 = Time.now

catch :done do
  Signal.trap('INT') do
    Signal.trap('INT', 'DEFAULT') # reset to default
    throw :done
  end
  n = 0
  loop do
    sleep(0.5)
    n += 1
    puts n
  end
end

tdelt = Time.now - t1
puts 'Program has run for %5.3f seconds.' % tdelt

an integer every half second. It handles SIGINT or SIGQUIT signals to stop outputting integers, display the program's runtime in seconds, and then terminate the program.


"Code to increment a numerical string using the succ method"


require 'abbrev'

dirs = %w( /home/user1/tmp/coverage/test /home/user1/tmp/covert/operator /home/user1/tmp/coven/members )

common_prefix = dirs.abbrev.keys.min_by {|key| key.length}.chop  # => "/home/user1/tmp/cove"
common_directory = common_prefix.sub(%r{/[^/]*$}, '')            # => "/home/user1/tmp"

separator = '/'
path0, *paths = dirs.collect {|dir| dir.split(separator)}
uncommon_idx = path0.zip(*paths).index {|dirnames| dirnames.uniq.length > 1}
uncommon_idx = path0.length  unless uncommon_idx                # if uncommon_idx==nil
common_directory = path0[0...uncommon_idx].join(separator)      # => "/home/user1/tmp"

def common_directory_path(dirs, separator='/')
  dir1, dir2 = dirs.minmax.map{|dir| dir.split(separator)}
  dir1.zip(dir2).take_while{|dn1,dn2| dn1==dn2}.map(&:first).join(separator)
end

p common_directory_path(dirs)           #=> "/home/user1/tmp"

"Create a function to find and return the common directory path from a set of given directory paths using a specified directory separator character. The function also includes a test case using '/' as the directory separator and three specific directory paths. The function does not return the longest common string, but the valid directory path. If a pre-existing function in the language can perform this task, it should be mentioned. The function also uses the abbrev module to calculate and return a hash of unambiguous abbreviations for the given strings."


implement the Sattolo cycle algorithm which shuffles an array ensuring each element ends up in a new position. The algorithm works by iterating from the last index to the first, selecting a random index within the range, and swapping the elements at these two indices. The algorithm modifies the input array in-place, but can be adjusted to return a new array or iterate from left to right if necessary. The key distinction from the Knuth shuffle is the range from which the random index is selected.


Works with: Ruby version 1.8
require 'soap/wsdlDriver'

wsdl = SOAP::WSDLDriverFactory.new("http://example.com/soap/wsdl")
soap = wsdl.create_rpc_driver

response1 = soap.soapFunc(:elementName => "value")
puts response1.soapFuncReturn

response2 = soap.anotherSoapFunc(:aNumber => 42)
puts response2.anotherSoapFuncReturn

The code establishes a SOAP client to access and call the functions soapFunc() and anotherSoapFunc() from the WSDL located at http://example.com/soap/wsdl. Note, the task and corresponding code may require further clarification.


def median(ary)
  return nil if ary.empty?
  mid, rem = ary.length.divmod(2)
  if rem == 0
    ary.sort[mid-1,2].inject(:+) / 2.0
  else
    ary.sort[mid]
  end
end

p median([])                        # => nil
p median([5,3,4])                   # => 4
p median([5,4,2,3])                 # => 3.5
p median([3,4,1,-8.4,7.2,4,1,1.2])  # => 2.1

def median(aray)
    srtd = aray.sort
    alen = srtd.length
    (srtd[(alen-1)/2] + srtd[alen/2]) / 2.0
end

The code calculates the median value of a vector of floating-point numbers, handling the case of even number of elements by returning the average of the two middle values. It uses the selection algorithm for efficiency. It also includes tasks for calculating various statistical measures including mean, median, mode, and standard deviation, both in a moving and cumulative manner.


1.upto(100) do |n|
  print "Fizz" if a = (n % 3).zero?
  print "Buzz" if b = (n % 5).zero?
  print n unless (a || b)
  puts
end

(1..100).each do |n|
  puts if (n % 15).zero?
    "FizzBuzz"
  elsif (n % 5).zero?
    "Buzz"
  elsif (n % 3).zero?
    "Fizz"
  else
    n
  end
end

class Enumerator::Lazy
  def filter_map
    Lazy.new(self) do |holder, *values|
      result = yield *values
      holder << result if result
    end
  end
end

class Fizz
  def initialize(head, tail)
    @list = (head..Float::INFINITY).lazy.filter_map{|i| i if i % 3 == 0}.first(tail)
  end

  def fizz?(num)
    search = @list
    search.include?(num)
  end

  def drop(num)
    list = @list
    list.delete(num)
  end

  def to_a
    @list.to_a
  end
end

class Buzz
  def initialize(head, tail)
    @list = (head..Float::INFINITY).lazy.filter_map{|i| i if i % 5 == 0}.first(tail)
  end

  def buzz?(num)
    search = @list
    search.include?(num)
  end

  def drop(num)
    list = @list
    list.delete(num)
  end

  def to_a
    @list.to_a
  end
end

class FizzBuzz
  def initialize(head, tail)
    @list = (head..Float::INFINITY).lazy.filter_map{|i| i if i % 15 == 0}.first(tail)
  end

  def fizzbuzz?(num)
    search = @list
    search.include?(num)
  end

  def to_a
    @list.to_a
  end

  def drop(num)
    list = @list
    list.delete(num)
  end
end
stopper = 100
@fizz = Fizz.new(1,100)
@buzz = Buzz.new(1,100)
@fizzbuzz = FizzBuzz.new(1,100)
def min(v, n)
  if v == 1
    puts "Fizz: #{n}"
    @fizz::drop(n)
  elsif v == 2
    puts "Buzz: #{n}"
    @buzz::drop(n)
  else
    puts "FizzBuzz: #{n}"
    @fizzbuzz::drop(n)
  end
end
(@fizz.to_a & @fizzbuzz.to_a).map{|d| @fizz::drop(d)}
(@buzz.to_a & @fizzbuzz.to_a).map{|d| @buzz::drop(d)}
while @fizz.to_a.min < stopper or @buzz.to_a.min < stopper or @fizzbuzz.to_a.min < stopper
  f, b, fb = @fizz.to_a.min, @buzz.to_a.min, @fizzbuzz.to_a.min
  min(1,f)  if f < fb and f < b
  min(2,b)  if b < f and b < fb
  min(0,fb) if fb < b and fb < f
end

(1..100).each do |n|
  v = "#{"Fizz" if n % 3 == 0}#{"Buzz" if n % 5 == 0}"
  puts v.empty? ? n : v
end

1.upto(100) { |n| puts "#{'Fizz' if n % 3 == 0}#{'Buzz' if n % 5 == 0}#{n if n % 3 != 0 && n % 5 != 0}" }

1.upto 100 do |n|
  r = ''
  r << 'Fizz' if n % 3 == 0
  r << 'Buzz' if n % 5 == 0
  r << n.to_s if r.empty?
  puts r
end

1.upto(100) { |i| puts "#{[:Fizz][i%3]}#{[:Buzz][i%5]}"[/.+/] || i }

1.upto(100){|i|puts'FizzBuzz '[n=i**4%-15,n+13]||i}

f = [nil, nil, :Fizz].cycle
b = [nil, nil, nil, nil, :Buzz].cycle
(1..100).each do |i|
  puts "#{f.next}#{b.next}"[/.+/] || i
end

seq = *0..100
{Fizz:3, Buzz:5, FizzBuzz:15}.each{|k,n| n.step(100,n){|i|seq[i]=k}}
puts seq.drop(1)

class Integer
  def fizzbuzz
    v = "#{"Fizz" if self % 3 == 0}#{"Buzz" if self % 5 == 0}"
    v.empty? ? self : v
  end
end

puts *(1..100).map(&:fizzbuzz)

fizzbuzz = ->(i) do
  (i%15).zero? and next "FizzBuzz"
  (i%3).zero?  and next "Fizz"
  (i%5).zero?  and next "Buzz"
  i
end

puts (1..100).map(&fizzbuzz).join("\n")

1.upto(100) do |n|
  puts case [(n % 3).zero?, (n % 5).zero?]
       in true, false
         "Fizz"
       in false, true
         "Buzz"
       in true, true
         "FizzBuzz"
       else
         n
       end
end

print integers from 1 to 100. For multiples of three, it prints 'Fizz', for multiples of five, it prints 'Buzz', and for multiples of both three and five, it prints 'FizzBuzz'. It also includes functionality to grab the first n fizz/buzz/fizzbuzz numbers in a list with a user defined function, starting at a specified number. Various solutions are presented including the use of string interpolation, append, Enumerable#cycle, and Ruby 3's Pattern Matching.


require 'complex'

def mandelbrot(a)
  Array.new(50).inject(0) { |z,c| z*z + a }
end

(1.0).step(-1,-0.05) do |y|
  (-2.0).step(0.5,0.0315) do |x|
    print mandelbrot(Complex(x,y)).abs < 2 ? '*' : ' '
  end
  puts
end
Translation of: Tcl

# frozen_string_literal: true

require_relative 'raster_graphics'

class RGBColour
  def self.mandel_colour(i)
    self.new( 16*(i % 15), 32*(i % 7), 8*(i % 31) )
  end
end

class Pixmap
  def self.mandelbrot(width, height)
    mandel = Pixmap.new(width,height)
    pb = ProgressBar.new(width) if $DEBUG
    width.times do |x|
      height.times do |y|
        x_ish = Float(x - width*11/15) / (width/3)
        y_ish = Float(y - height/2) / (height*3/10)
        mandel[x,y] = RGBColour.mandel_colour(mandel_iters(x_ish, y_ish))
      end
      pb.update(x) if $DEBUG
    end
    pb.close if $DEBUG
    mandel
  end

  def self.mandel_iters(cx,cy)
    x = y = 0.0
    count = 0
    while Math.hypot(x,y) < 2 and count < 255
      x, y = (x**2 - y**2 + cx), (2*x*y + cy)
      count += 1
    end
    count
  end
end

Pixmap.mandelbrot(300,300).save('mandel.ppm')
Library: RubyGems
Library: JRubyArt

# frozen_string_literal: true

def setup
  sketch_title 'Mandelbrot'
  load_pixels
  no_loop
end

def draw
  grid(900, 600) do |x, y|
    const = Complex(
      map1d(x, (0...900), (-3..1.5)), map1d(y, (0...600), (-1.5..1.5))
    )
    pixels[x + y * 900] = color(
      constrained_map(mandel(const, 20), (5..20), (255..0))
    )
  end
  update_pixels
end

def mandel(z, max)
  score = 0
  const = z
  while score < max
    # z = z^2 + c
    z *= z
    z += const
    break if z.abs > 2

    score += 1
  end
  score
end

def settings
  size(900, 600)
end

generate and draw the Mandelbrot set using various algorithms and functions. The code also prints an 80-character by 41-line depiction of the set. It utilizes Raster graphics operations in Ruby and JRubyArt, a port of processing to Ruby.


arr = [1,2,3,4,5]     # or ary = *1..5, or ary = (1..5).to_a
p sum = arr.inject(0) { |sum, item| sum + item }
# => 15
p product = arr.inject(1) { |prod, element| prod * element }
# => 120
Works with: Ruby version 1.8.7
arr = [1,2,3,4,5]
p sum = arr.inject(0, :+)         #=> 15
p product = arr.inject(1, :*)     #=> 120

# If you do not explicitly specify an initial value for memo,
# then the first element of collection is used as the initial value of memo.
p sum = arr.inject(:+)            #=> 15
p product = arr.inject(:*)        #=> 120

arr = []
p arr.inject(0, :+)               #=> 0
p arr.inject(1, :*)               #=> 1
p arr.inject(:+)                  #=> nil
p arr.inject(:*)                  #=> nil

Works with: Ruby version 1.9.3
arr = [1,2,3,4,5]
p sum = arr.sum                   #=> 15
p [].sum                          #=> 0

Computes the sum and product of an array of integers, returning the initial value for empty arrays and nil if no initial value is provided. The code uses the Enumerable#reduce method, which is an alias of Enumerable#inject.


The code determines if a given year is a leap year in the Gregorian calendar, using the 'leap?' method, which is also referred to as 'gregorian_leap?'. There is also a 'julian_leap?' method available.


(1..7).to_a.permutation(3){|p| puts p.join if p.first.even? && p.sum == 12 }

all possible combinations of unique numbers between 1 and 7 (inclusive) for three different departments (police, sanitation, fire) that add up to 12, with the police department number being an even number.


original = "hello"
reference = original          # copies reference
copy1 = original.dup          # instance of original.class
copy2 = String.new(original)  # instance of String

original << " world!"         # append
p reference                   #=> "hello world!"
p copy1                       #=> "hello"
p copy2                       #=> "hello"

original = "hello".freeze     # prevents further modifications
copy1 = original.dup          # copies contents (without status)
copy2 = original.clone        # copies contents (with status)
p copy1.frozen?               #=> false
p copy1 << " world!"          #=> "hello world!"
p copy2.frozen?               #=> true
p copy2 << " world!"          #=> can't modify frozen String (RuntimeError)

demonstrate how to copy a string in Ruby, differentiating between copying the string content and creating an additional reference to the existing string using the Object#clone method.


define two mutually recursive functions to compute the Hofstadter Female and Male sequences. The Female function is defined as F(n) = n - M(F(n-1)) for n > 0 and F(0) = 1. The Male function is defined as M(n) = n - F(M(n-1)) for n > 0 and M(0) = 0. In Ruby, the Male function doesn't need to be pre-declared to be used in the Female function, but it must be defined before the Female function calls it.


%w(north east south west).sample   # => "west"
(1..100).to_a.sample(2)            # => [17, 79]

demonstrate how to select a random element from a list.


require 'cgi'
puts CGI.unescape("http%3A%2F%2Ffoo%20bar%2F")
# => "http://foo bar/"

Works with: Ruby version 1.9.2
require 'uri'
puts URI.decode_www_form_component("http%3A%2F%2Ffoo%20bar%2F")
# => "http://foo bar/"

provide a function to convert URL-encoded strings back to their original unencoded form. The function uses methods like CGI.unescape or URI.decode_www_form_component, which also convert "+" to " ". It handles various test cases including converting encoded URLs like "http%3A%2F%2Ffoo%20bar%2F" back to "http://foo bar/". Note that URI.unescape is obsolete since Ruby 1.9.2 due to issues with URI.escape.


class Array
  def binary_search(val, low=0, high=(length - 1))
    return nil if high < low
    mid = (low + high) >> 1
    case val <=> self[mid]
      when -1
        binary_search(val, low, mid - 1)
      when 1
        binary_search(val, mid + 1, high)
      else mid
    end
  end
end

ary = [0,1,4,5,6,7,8,9,12,26,45,67,78,90,98,123,211,234,456,769,865,2345,3215,14345,24324]

[0,42,45,24324,99999].each do |val|
  i = ary.binary_search(val)
  if i
    puts "found #{val} at index #{i}: #{ary[i]}"
  else
    puts "#{val} not found in array"
  end
end

class Array
  def binary_search_iterative(val)
    low, high = 0, length - 1
    while low <= high
      mid = (low + high) >> 1
      case val <=> self[mid]
        when 1
          low = mid + 1
        when -1
          high = mid - 1
        else
          return mid
      end
    end
    nil
  end
end

ary = [0,1,4,5,6,7,8,9,12,26,45,67,78,90,98,123,211,234,456,769,865,2345,3215,14345,24324]

[0,42,45,24324,99999].each do |val|
  i = ary.binary_search_iterative(val)
  if i
    puts "found #{val} at index #{i}: #{ary[i]}"
  else
    puts "#{val} not found in array"
  end
end

The code implements a binary search algorithm on a sorted integer array. It takes as input the starting and ending points of a range, and a "secret value". The algorithm divides the range into halves, and continues to narrow down the search until the secret value is found. The search can be implemented either recursively or iteratively. The code also handles multiple values equal to the given value and indicates whether the element was found or not. It also prints the index of the found number. The code also includes a fix for potential overflow bugs.


#! /usr/bin/env ruby
p ARGV
 myprog a -h b c
 => ["a","-h","b","c"]

The code retrieves the list of command-line arguments provided to the program and prints them when run directly. It uses the constant Object::ARGV to access these arguments. It also includes an example of how to use the command line arguments with the program. Furthermore, it provides references for understanding the program name and parsing command line arguments intelligently.