#!/usr/bin/env ruby -w require "yaml" require "drb" $SAFE = 1 PORT = 61676 class DRbChallenger def self.host(challenges = nil) hosted_challenges = challenges || new DRb.start_service("druby://0.0.0.0:#{PORT}", hosted_challenges) puts "Now serving challenges on port #{PORT}..." hosted_challenges end def self.join(ip_address) DRb.start_service puts "Connecting to challenges on port #{PORT} at IP #{ip_address}..." challenges = DRbObject.new_with_uri("druby://#{ip_address}:#{PORT}") $stdout.extend(DRbUndumped) challenges.drb_stdout = $stdout challenges end def self.load(file_name = "regexp_challenge.yaml") File.open(file_name) { |file| YAML.load(file) } end def initialize @challenges = Array.new @solutions = Array.new @drb_stdout = nil end attr_writer :drb_stdout def io if caller.any? { |call| call =~ /\bdrb\b/ } @drb_stdout || $stdout else $stdout end end def challenge(input, output, note = nil) @challenges << [input, output, note] and nil end def challenges @challenges.each_with_index do |challenge, i| io.puts describe_challenge(challenge, i) end && nil end alias_method :inspect, :challenges def solve(challenge_number) answer = yield(@challenges[challenge_number][0]) #@challenges[challenge_number][0].send( method_call,*args ) if answer == @challenges[challenge_number][1] io.puts "Correct. Nice job." @solutions << @challenges.slice!(challenge_number) else io.puts "That is not a valid solution." io.puts "Expected output: #{@challenges[challenge_number][1].inspect}" io.puts " Your output: #{answer.inspect}" end && nil end def solutions @solutions.each_with_index do |solution, i| io.puts describe_challenge(solution, i, "Solution"). map { |line| line.sub(/^ /, "\\0\\0") } description = " Solution: #{solution[3]}(#{solution[4].inspect}" io.puts description + ")" end && nil end def save(file_name = "regexp_challenge.yaml") File.open(file_name, "w") { |file| YAML.dump(self, file) } end private def describe_challenge(challenge, number, title = "Challenge") description = [ "#{title} ##{number}:", " Input: #{challenge[0].inspect}", " Output: #{challenge[1].inspect}", ] unless challenge[2].nil? description << " Note: #{challenge[2].inspect}" end description end end