diff --git a/app/controllers/main_controller.rb b/app/controllers/main_controller.rb --- a/app/controllers/main_controller.rb +++ b/app/controllers/main_controller.rb @@ -176,6 +176,37 @@ :locals => {:announcement_effect => true}) end + # actions for Code Jom + def new_input + problem = Problem.find(params[:id]) + user = User.find(session[:user_id]) + if user.can_request_new_test_pair_for? problem + assignment = user.get_new_test_pair_assignment_for problem + assignment.save + + send_data(assignment.test_pair.input, + { :filename => "#{problem.name}-#{assignment.request_number}.in", + :type => 'text/plain' }) + else + flash[:notice] = 'You cannot request new input now.' + redirect_to :action => 'list' + end + end + + def download + problem = Problem.find(params[:id]) + user = User.find(session[:user_id]) + recent_assignment = user.get_recent_test_pair_assignment_for problem + if recent_assignment != nil + send_data(recent_assignment.test_pair.input, + { :filename => "#{problem.name}-#{recent_assignment.request_number}.in", + :type => 'text/plain' }) + else + flash[:notice] = 'You have not request for any input data for this problem.' + redirect_to :action => 'list' + end + end + protected def prepare_announcements(recent=nil) diff --git a/app/models/problem.rb b/app/models/problem.rb --- a/app/models/problem.rb +++ b/app/models/problem.rb @@ -10,6 +10,21 @@ DEFAULT_TIME_LIMIT = 1 DEFAULT_MEMORY_LIMIT = 32 + def test_pair_count + @test_pair_count ||= test_pairs.size + end + + def uses_random_test_pair? + test_pair_count != 0 + end + + def random_test_pair(forbidden_numbers=nil) + begin + test_num = 1 + rand(test_pair_count) + end while forbidden_numbers!=nil and forbidden_numbers.include? test_num + test_pairs.find_by_number test_num + end + def self.find_available_problems find(:all, :conditions => {:available => true}, :order => "date_added DESC") end diff --git a/app/models/test_pair.rb b/app/models/test_pair.rb --- a/app/models/test_pair.rb +++ b/app/models/test_pair.rb @@ -1,3 +1,9 @@ +# TestPair stores an input-solution pair for a problem. This is used +# in a certain "test-pair"-type problem for the CodeJom competition +# which follows the Google Code Jam format, i.e., a participant only +# submits a solution to a single random input that the participant +# requested. This input-solution pair is a TestPair. + class TestPair < ActiveRecord::Base - belongs_to :problem + belongs_to :problem end diff --git a/app/models/test_pair_assignment.rb b/app/models/test_pair_assignment.rb new file mode 100644 --- /dev/null +++ b/app/models/test_pair_assignment.rb @@ -0,0 +1,5 @@ +class TestPairAssignment < ActiveRecord::Base + belongs_to :user + belongs_to :test_pair + belongs_to :problem +end diff --git a/app/models/user.rb b/app/models/user.rb --- a/app/models/user.rb +++ b/app/models/user.rb @@ -16,6 +16,8 @@ :foreign_key => "receiver_id", :order => 'created_at DESC' + has_many :test_pair_assignments, :dependent => :delete_all + belongs_to :site belongs_to :country @@ -67,6 +69,48 @@ self.roles.detect {|r| r.name == 'admin' } end + # These are methods related to test pairs + + def get_test_pair_assignments_for(problem) + test_pair_assignments.find_all { |a| a.problem_id == problem.id } + end + + def get_recent_test_pair_assignment_for(problem) + assignments = get_test_pair_assignments_for problem + if assignments.length == 0 + return nil + else + recent = assignments[0] + assignments.each do |a| + recent = a if a.request_number > recent.request_number + end + return recent + end + end + + def can_request_new_test_pair_for?(problem) + recent = get_recent_test_pair_assignment_for problem + return (recent == nil or recent.submitted) + end + + def get_new_test_pair_assignment_for(problem) + previous_assignment_numbers = + get_test_pair_assignments_for(problem).collect {|a| a.test_pair_number } + test_pair = problem.random_test_pair(previous_assignment_numbers) + if test_pair + assignment = TestPairAssignment.new(:user => self, + :problem => problem, + :test_pair => test_pair, + :test_pair_number => test_pair.number, + :request_number => + previous_assignment_numbers.length + 1, + :submitted => false) + return assignment + else + return nil + end + end + def email_for_editing if self.email==nil "(unknown)" diff --git a/app/views/main/_problem.html.erb b/app/views/main/_problem.html.erb --- a/app/views/main/_problem.html.erb +++ b/app/views/main/_problem.html.erb @@ -10,9 +10,17 @@ <%= @prob_submissions[problem_counter][:count] %> - <%= render :partial => 'submission_short', - :locals => { - :submission => @prob_submissions[problem_counter][:submission], - :problem_name => problem.name }%> + + <% form_tag "new_input/#{problem.id}", :method => :post do -%> + + <% end -%> + <% form_tag "download/#{problem.id}", :method => :post do -%> + + <% end -%> + <% form_tag "submit_solution/#{problem.id}", :method => :post do -%> + + + <% end -%> + diff --git a/db/migrate/20100118160800_add_number_to_test_pair.rb b/db/migrate/20100118160800_add_number_to_test_pair.rb new file mode 100644 --- /dev/null +++ b/db/migrate/20100118160800_add_number_to_test_pair.rb @@ -0,0 +1,9 @@ +class AddNumberToTestPair < ActiveRecord::Migration + def self.up + add_column 'test_pairs', 'number', :integer + end + + def self.down + remove_column 'test_pairs', 'number' + end +end diff --git a/db/migrate/20100118162000_create_test_pair_assignments.rb b/db/migrate/20100118162000_create_test_pair_assignments.rb new file mode 100644 --- /dev/null +++ b/db/migrate/20100118162000_create_test_pair_assignments.rb @@ -0,0 +1,16 @@ +class CreateTestPairAssignments < ActiveRecord::Migration + def self.up + create_table :test_pair_assignments do |t| + t.integer "user_id" + t.integer "problem_id" + t.integer "test_pair_id" + t.integer "test_pair_number" + t.integer "request_number" + t.timestamps + end + end + + def self.down + drop_table :test_pair_assignments + end +end diff --git a/db/migrate/20100118174404_add_submitted_to_test_pair_assignment.rb b/db/migrate/20100118174404_add_submitted_to_test_pair_assignment.rb new file mode 100644 --- /dev/null +++ b/db/migrate/20100118174404_add_submitted_to_test_pair_assignment.rb @@ -0,0 +1,9 @@ +class AddSubmittedToTestPairAssignment < ActiveRecord::Migration + def self.up + add_column 'test_pair_assignments', 'submitted', :boolean + end + + def self.down + remove_column 'test_pair_assignments', 'submitted' + end +end diff --git a/db/schema.rb b/db/schema.rb --- a/db/schema.rb +++ b/db/schema.rb @@ -9,7 +9,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20100113094740) do +ActiveRecord::Schema.define(:version => 20100118174404) do create_table "announcements", :force => true do |t| t.string "author" @@ -155,12 +155,24 @@ t.datetime "updated_at" end + create_table "test_pair_assignments", :force => true do |t| + t.integer "user_id" + t.integer "problem_id" + t.integer "test_pair_id" + t.integer "test_pair_number" + t.integer "request_number" + t.datetime "created_at" + t.datetime "updated_at" + t.boolean "submitted" + end + create_table "test_pairs", :force => true do |t| t.integer "problem_id" t.text "input" t.text "solution" t.datetime "created_at" t.datetime "updated_at" + t.integer "number" end create_table "test_requests", :force => true do |t| diff --git a/lib/testdata_importer.rb b/lib/testdata_importer.rb --- a/lib/testdata_importer.rb +++ b/lib/testdata_importer.rb @@ -99,8 +99,11 @@ break if not FileTest.exists? sol_filename + puts "#{dirname}" + test_pair = TestPair.new(:input => open(in_filename).read, :solution => open(sol_filename).read, + :number => test_num, :problem => @problem) break if not test_pair.save diff --git a/test/fixtures/test_pair_assignments.yml b/test/fixtures/test_pair_assignments.yml new file mode 100644 --- /dev/null +++ b/test/fixtures/test_pair_assignments.yml @@ -0,0 +1,7 @@ +# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html + +# one: +# column: value +# +# two: +# column: value diff --git a/test/unit/test_pair_assignment_test.rb b/test/unit/test_pair_assignment_test.rb new file mode 100644 --- /dev/null +++ b/test/unit/test_pair_assignment_test.rb @@ -0,0 +1,8 @@ +require 'test_helper' + +class TestPairAssignmentTest < ActiveSupport::TestCase + # Replace this with your real tests. + test "the truth" do + assert true + end +end