The Computer Language
Benchmarks Game

chameneos-redux Ruby JRuby program

source code

# The Computer Language Benchmarks Game
# http://benchmarksgame.alioth.debian.org/

#   contributed by Michael Barker
#   based on a Java contribution by Luzius Meisser
#   converted to C by dualamd
#   converted to Ruby by Eugene Pimenov

require 'thread'

COLORS     = [:blue, :red, :yellow, :invalid].freeze
COMPLIMENT = {
  :blue => {:blue => :blue, :red => :yellow, :yellow => :red}.freeze,
  :red => {:blue => :yellow, :red => :red, :yellow => :blue}.freeze,
  :yellow => {:blue => :red, :red => :blue, :yellow => :yellow}.freeze
}.freeze

$creature_id = 0

NUMBERS = %w{zero one two three four five six seven eight nine}.freeze

# convert integer to number string: 1234 -> "one two three four"
def format_number(num)
  out = []
  begin
    out << NUMBERS[num%10]
    num /= 10
  end while num > 0
  out.reverse.join(" ")
end

class MeetingPlace
  attr_reader :mutex
  attr_accessor :meetings_left, :first_creature

  def initialize(meetings)
    @mutex = Mutex.new
    @meetings_left = meetings
  end
end

class Creature
  attr_accessor :place, :thread, :count, :same_count, :color, :id, :two_met, :sameid

  def initialize(place, color)
    @place = place
    @count = @same_count = 0

    @id = ($creature_id += 1)
    @color = color
    @two_met = FALSE

    @thread = Thread.new do
      loop do
        if meet
          Thread.pass while @two_met == false

          @same_count += 1 if @sameid
          @count += 1
        else
          break
        end
      end
    end
  end

  def meet
    @place.mutex.lock

    if @place.meetings_left > 0
      if @place.first_creature
        first = @place.first_creature
        new_color = COMPLIMENT[@color][first.color]

        @sameid  = first.sameid  = @id == first.id
        @color   = first.color   = new_color
        @two_met = first.two_met = true

        @place.first_creature = nil
        @place.meetings_left -= 1
      else
        @two_met = false
        @place.first_creature = self
      end
      true
    else
      false
    end
  ensure
    @place.mutex.unlock
  end

  def result
    '' << @count.to_s << ' ' << format_number(@same_count)
  end
end

def run_game(n_meeting, colors)
  place = MeetingPlace.new(n_meeting)

  creatures = []
  colors.each do |color|
    print color, " "
    creatures << Creature.new(place, color)
  end
  puts

  # wait for them to meet
  creatures.each { |c| c.thread.join}

  total = 0
  # print meeting times of each creature
  creatures.each do |c|
    puts c.result
    total += c.count
  end

  # print total meeting times, should be equal n_meeting
  print ' ', format_number(total), "\n\n"
end

def print_colors_table
  [:blue, :red, :yellow].each do |c1|
    [:blue, :red, :yellow].each do |c2|
      puts "#{c1} + #{c2} -> #{COMPLIMENT[c1][c2]}"
    end
  end
end

n = (ARGV[0] || 600).to_i


print_colors_table
puts

run_game n, [:blue, :red, :yellow]
run_game n, [:blue, :red, :yellow, :red, :yellow, :blue, :red, :yellow, :red, :blue]
    

notes, command-line, and program output

NOTES:
64-bit Ubuntu quad core
jruby 9.1.13.0 (2.3.3) 2017-09-06 8e1c115 Java HotSpot(TM) 64-Bit Server VM 9+181 on 9+181 +jit [linux-x86_64]


Thu, 21 Sep 2017 22:03:16 GMT

MAKE:
mv chameneosredux.jruby chameneosredux.rb

0.03s to complete and log all make actions

COMMAND LINE:
/usr/local/src/jruby-9.1.13.0/bin/jruby -Xcompile.fastest=true -Xcompile.invokedynamic=true -J-server -J-Xmn512m -J-Xms2048m -J-Xmx2048m chameneosredux.rb 6000000

PROGRAM OUTPUT:
blue + blue -> blue
blue + red -> yellow
blue + yellow -> red
red + blue -> yellow
red + red -> red
red + yellow -> blue
yellow + blue -> red
yellow + red -> blue
yellow + yellow -> yellow

blue red yellow 
4137709 zero
3761342 zero
4100949 zero
 one two zero zero zero zero zero zero

blue red yellow red yellow blue red yellow red blue 
1205948 zero
1194635 zero
1184611 zero
1219441 zero
1198124 zero
1202226 zero
1187964 zero
1206191 zero
1199435 zero
1201425 zero
 one two zero zero zero zero zero zero


WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.jruby.util.io.FilenoUtil to method sun.nio.ch.SelChImpl.getFD()
WARNING: Please consider reporting this to the maintainers of org.jruby.util.io.FilenoUtil
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release