Skip to content

Instantly share code, notes, and snippets.

@mejibyte
Forked from nhocki/val_lista.rb
Created December 23, 2011 00:15
Show Gist options
  • Save mejibyte/1512447 to your computer and use it in GitHub Desktop.
Save mejibyte/1512447 to your computer and use it in GitHub Desktop.
Validators for the training contest held on Dec. 22
#!/usr/bin/env ruby
require 'scanf'
if ARGV.size < 3
puts "Usage: #{__FILE__} <testdata.in> <program.out> <testdata.out>"
exit 1
end
def wrong_answer(reason)
STDOUT.puts "Wrong Answer: #{reason}"
exit 0
end
# File extension
class File
def read_int
x = self.scanf("%d")
wrong_answer("Expected an integer but got '#{self.readline.chomp rescue "EOF"}'") if x.size != 1
x.first
end
def read_char
x = self.scanf(" %c ")
wrong_answer("Expected a char but got '#{self.readline.chomp rescue "EOF"}'") if x.size != 1
x.first
end
end
class Checker
attr_accessor :in_file, :team_file, :ans_file, :prev, :_next
def initialize
self.in_file = File.open(ARGV[0])
self.team_file = File.open(ARGV[1])
self.ans_file = File.open(ARGV[2])
at_exit { self.close_files }
end
def close_files
in_file.close
team_file.close
ans_file.close
end
def erase x
@prev[ @_next[x] ] = @prev[x]
@_next[ @prev[x] ] = @_next[x]
end
def do_a x, y
erase(x)
@_next[x] = y
@prev[x] = @prev[y]
@_next[ @prev[y] ] = x
@prev[y] = x
end
def do_b x, y
erase(x)
@_next[x] = @_next[y]
@prev[x] = y
@prev[ @_next[y] ] = x
@_next[y] = x
end
def run
movs = team_file.read_int
movj = ans_file.read_int
wrong_answer "Wrong number of movements. Expected #{movj} and got #{movs}" if movs != movj
a = in_file.read_int
b = in_file.read_int
arr = (1..a).to_a
@prev = Array.new(a)
@_next = Array.new(a)
arr.each do |x|
@prev[x] = x - 1
@_next[x] = x + 1
end
b.times do |i|
move = in_file.read_char
from = in_file.read_int
to = in_file.read_int
if move == 'A'
do_a(from, to)
else
do_b(from, to)
end
end
first = prev.index(0)
cur = first
n = a
arr = []
while cur > 0 and cur < n + 1
arr << cur
cur = @_next[cur]
end
#### START READING THE ANSWER FROM THE TEAM
movs.times do |i|
move = team_file.read_char
from = team_file.read_int
to = team_file.read_int
if move == 'A'
do_a(from, to)
else
do_b(from, to)
end
end
first = prev.index(0)
cur = first
n = a
arr = []
while cur > 0 and cur < n + 1
arr << cur
cur = @_next[cur]
end
wrong_answer "The final array was not sorted" unless arr == arr.sort
exit 0
end
end
Checker.new.run
#!/usr/bin/env ruby
require 'scanf'
if ARGV.size < 3
puts "Usage: #{__FILE__} <testdata.in> <program.out> <testdata.out>"
exit 1
end
def wrong_answer(reason)
STDOUT.puts "Wrong Answer: #{reason}"
exit 0
end
# File extension
class File
def read_int
x = self.scanf("%d")
wrong_answer("Expected an integer but got '#{self.readline.chomp rescue "EOF"}'") if x.size != 1
x.first
end
def read_char
x = self.scanf(" %c ")
wrong_answer("Expected a char but got '#{self.readline.chomp rescue "EOF"}'") if x.size != 1
x.first
end
end
class Checker
attr_accessor :in_file, :team_file, :ans_file, :tanks
def initialize
self.in_file = File.open(ARGV[0])
self.team_file = File.open(ARGV[1])
self.ans_file = File.open(ARGV[2])
at_exit { self.close_files }
end
def close_files
in_file.close
team_file.close
ans_file.close
end
def valid?(tank, x, y)
@tanks.count{|b| b[0] != tank && b[1] == x && b[2] == y}.zero?
end
def check_tank!(label, tank)
wrong_answer "No such tank with label = '#{label}'" unless tank
end
def left label
tank = @tanks.select{|x| x[0] == label}.first
check_tank!(label, tank)
wrong_answer "Invalid move. Overlaps with other tank" unless valid?(tank[0], tank[1], tank[2] - 1)
@tanks[@tanks.index(tank)][2] -= 1
end
def right label
tank = @tanks.select{|x| x[0] == label}.first
check_tank!(label, tank)
wrong_answer "Invalid move. Overlaps with other tank" unless valid?(tank[0], tank[1], tank[2] + 1)
@tanks[@tanks.index(tank)][2] += 1
end
def up label
tank = @tanks.select{|x| x[0] == label}.first
check_tank!(label, tank)
wrong_answer "Invalid move. Overlaps with other tank" unless valid?(tank[0], tank[1] - 1, tank[2])
@tanks[@tanks.index(tank)][1] -= 1
end
def down label
tank = @tanks.select{|x| x[0] == label}.first
check_tank!(label, tank)
wrong_answer "Invalid move. Overlaps with other tank" unless valid?(tank[0], tank[1] + 1, tank[2])
@tanks[@tanks.index(tank)][1] += 1
end
def run
movs = team_file.read_int
movj = ans_file.read_int
wrong_answer "Wrong number of movements. Expected #{movj} and got #{movs}" if movs != movj
n = in_file.read_int
@tanks = []
# Each tank will be represented with a 3 dim. array as follows
# [label, row, column]
n.times do |i|
x = in_file.read_int
y = in_file.read_int
@tanks << [i+1, x, y]
end
#### TEAM OUTPUT
movs.times do |i|
tank = team_file.read_int
direc = team_file.read_char
case direc
when 'U'
up tank
when 'D'
down tank
when 'L'
left tank
when 'R'
right tank
end
end
n.times do |i|
wrong_answer "More than one tank on row #{i + 1}" unless @tanks.select{|x| x[1] == i+1}.count == 1
wrong_answer "More than one tank on column #{i + 1}" unless @tanks.select{|x| x[2] == i+1}.count == 1
end
exit 0
end
end
Checker.new.run
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment