|
|
class DSLNode
|
|
|
def DSLNode.scalar_attr(*names)
|
|
|
names.each do |name|
|
|
|
define_method name do |*a|
|
|
|
if a.length == 0
|
|
|
instance_variable_get( "@#{name}" )
|
|
|
else
|
|
|
instance_variable_set( "@#{name}", a[0] )
|
|
|
end
|
|
|
end
|
|
|
end
|
|
|
end
|
|
|
|
|
|
def DSLNode.array_attr(*names)
|
|
|
names.each do |name|
|
|
|
define_method name do |*a|
|
|
|
if a.length == 0
|
|
|
instance_variable_get( "@#{name}" )
|
|
|
else
|
|
|
instance_variable_set( "@#{name}", a )
|
|
|
end
|
|
|
end
|
|
|
end
|
|
|
end
|
|
|
end
|
|
|
|
|
|
class Problem < DSLNode
|
|
|
def initialize
|
|
|
@runs = []
|
|
|
@tests = []
|
|
|
end
|
|
|
|
|
|
def Problem.getter(name, plural_name, each_name)
|
|
|
eval "def get_#{name}(index) \n \
|
|
|
if defined?(@tests) and @tests[index] != nil \n \
|
|
|
if @tests[index].#{name} != nil \n \
|
|
|
return @tests[index].#{name} \n \
|
|
|
end \n \
|
|
|
end \n \
|
|
|
\n \
|
|
|
(1..@runs.length-1).each do |i| \n \
|
|
|
run = @runs[i] \n \
|
|
|
k = run.tests.index(index) \n \
|
|
|
if k == nil \n \
|
|
|
next \n \
|
|
|
end \n \
|
|
|
\n \
|
|
|
if run.#{plural_name} != nil && run.#{plural_name}[k] != nil \n \
|
|
|
return run.#{plural_name}[k] \n \
|
|
|
end \n \
|
|
|
\n \
|
|
|
if run.#{each_name} != nil \n \
|
|
|
return run.#{each_name} \n \
|
|
|
end \n \
|
|
|
end \n \
|
|
|
\n \
|
|
|
if @#{each_name} != nil \n \
|
|
|
return @#{each_name} \n \
|
|
|
else \n \
|
|
|
raise 'The problem is malformed (possibly in more than one way)!' \n \
|
|
|
end \n \
|
|
|
end"
|
|
|
end
|
|
|
|
|
|
scalar_attr :num_tests, :full_score, :score_each, :time_limit_each, :mem_limit_each
|
|
|
array_attr :runs, :tests
|
|
|
getter "score", "scores", "score_each"
|
|
|
getter "mem_limit", "mem_limits", "mem_limit_each"
|
|
|
getter "time_limit", "time_limits", "time_limit_each"
|
|
|
|
|
|
def run(index, &block)
|
|
|
new_run = Run.new
|
|
|
new_run.instance_eval &block
|
|
|
@runs[index] = new_run
|
|
|
end
|
|
|
|
|
|
def test(index, &block)
|
|
|
new_test = Test.new
|
|
|
new_test.instance_eval &block
|
|
|
@tests[index] = new_test
|
|
|
end
|
|
|
|
|
|
def read_test(index)
|
|
|
filename = ENV['PROBLEM_HOME'] + "/test_cases/#{index}/test.cfg"
|
|
|
if File.exists?(filename)
|
|
|
@tests[index] ||= Test.new
|
|
|
content = File.read(filename)
|
|
|
@tests[index].instance_eval content
|
|
|
end
|
|
|
end
|
|
|
|
|
|
def Problem.set_instance(prob)
|
|
|
@instance = prob
|
|
|
end
|
|
|
|
|
|
def Problem.get_instance
|
|
|
return @instance
|
|
|
end
|
|
|
|
|
|
def well_formed?
|
|
|
# Check if run 1 to run @runs.length are present.
|
|
|
(1..(@runs.length-1)).each do |i|
|
|
|
if @runs[i] == nil
|
|
|
puts "run #{i} is not present"
|
|
|
return false
|
|
|
end
|
|
|
end
|
|
|
|
|
|
# Check if all tests are in one and only one run.
|
|
|
test_present = []
|
|
|
(1..(@num_tests)).each do |i|
|
|
|
test_present[i] = false
|
|
|
end
|
|
|
(1..(@runs.length-1)).each do |j|
|
|
|
run = @runs[j]
|
|
|
run.tests.each do |t|
|
|
|
if test_present[t] == false
|
|
|
test_present[t] = true
|
|
|
else
|
|
|
puts "test #{t} is present in more than one run"
|
|
|
return false
|
|
|
end
|
|
|
end
|
|
|
end
|
|
|
(1..(@num_tests)).each do |i|
|
|
|
if test_present[i] == false
|
|
|
puts "test #{i} is not present"
|
|
|
return false
|
|
|
end
|
|
|
end
|
|
|
|
|
|
# Check if we can find the score, mem limit, and time limit for all tests.
|
|
|
(1..(@num_tests)).each do |i|
|
|
|
begin
|
|
|
get_score i
|
|
|
rescue
|
|
|
puts "cannot get score for test #{i}"
|
|
|
return false
|
|
|
end
|
|
|
|
|
|
begin
|
|
|
get_mem_limit i
|
|
|
rescue
|
|
|
puts "cannot get mem limit for test #{i}"
|
|
|
return false
|
|
|
end
|
|
|
|
|
|
begin
|
|
|
get_time_limit i
|
|
|
rescue
|
|
|
puts "cannot get time limit for test #{i}"
|
|
|
return false
|
|
|
end
|
|
|
end
|
|
|
|
|
|
return true
|
|
|
end
|
|
|
end
|
|
|
|
|
|
class Run < DSLNode
|
|
|
scalar_attr :score_each, :time_limit_each, :mem_limit_each
|
|
|
array_attr :tests, :scores, :time_limits, :mem_limits
|
|
|
end
|
|
|
|
|
|
class Test < DSLNode
|
|
|
scalar_attr :score, :time_limit, :mem_limit
|
|
|
end
|
|
|
|
|
|
def problem(&blk)
|
|
|
prob = Problem.new
|
|
|
prob.instance_eval &blk
|
|
|
Problem.set_instance prob
|
|
|
p = Problem.get_instance
|
|
|
(1..(p.num_tests)).each do |i|
|
|
|
p.read_test i
|
|
|
end
|
|
|
p.well_formed?
|
|
|
end
|
|
|
|