Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,12 @@
"difficulty": 1,
"topics": [
]
},
{
"slug": "tournament",
"difficulty": 1,
"topics": [
]
}
],
"deprecated": [
Expand Down
1 change: 1 addition & 0 deletions exercises/tournament/.version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1
54 changes: 54 additions & 0 deletions exercises/tournament/example.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
module BookKeeping
VERSION = 1
end

class Tournament
def self.tally(input)
teams = Hash.new { |h, k| h[k] = Hash.new { |h, k| h[k] = 0 } }

input.split("\n").each do |line|
team_one, team_two, result = line.split(';')

case result
when "win"
teams[team_one][:won] += 1
teams[team_two][:loss] += 1
when "loss"
teams[team_one][:loss] += 1
teams[team_two][:won] += 1
when "draw"
teams[team_one][:draw] += 1
teams[team_two][:draw] += 1
end
end

teams.keys.each do |team_name|
team = teams[team_name]
team[:matches] = team[:won] + team[:loss] + team[:draw]
team[:points] = team[:won] * 3 + team[:draw]
end

team_order =
teams
.to_a
.sort_by { |team| [-team[1][:points], team[0]] }
.map(&:first)

result = ['Team | MP | W | D | L | P']

team_order.each do |team_name|
stats = teams[team_name]

result << [
team_name.ljust(30),
stats[:matches],
stats[:won],
stats[:draw],
stats[:loss],
stats[:points]
].join(' | ')
end

result.join("\n") + "\n"
end
end
23 changes: 23 additions & 0 deletions exercises/tournament/example.tt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/usr/bin/env ruby
gem 'minitest', '>= 5.0.0'
require 'minitest/autorun'
require_relative 'tournament'

# Test data version:
# <%= sha1 %>
class TournamentTest < Minitest::Test
<% test_cases.each do |test_case| %>
def <%= test_case.test_name %>
<%= test_case.skipped %>
input = <%= test_case.input_text %>
actual = <%= test_case.workload %>
expected = <%= test_case.expect %>
assert_equal expected, actual
end
<% end %>
<%= IO.read(XRUBY_LIB + '/bookkeeping.md') %>
def test_bookkeeping
skip
assert_equal <%= version.next %>, BookKeeping::VERSION
end
end
92 changes: 92 additions & 0 deletions exercises/tournament/tournament_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#!/usr/bin/env ruby
gem 'minitest', '>= 5.0.0'
require 'minitest/autorun'
require_relative 'tournament'

# Test data version:
# 0a51cfc
class TournamentTest < Minitest::Test

def test_typical_input
# skip
input = <<-INPUT.gsub(/^ */, '')
Allegoric Alaskans;Blithering Badgers;win
Devastating Donkeys;Courageous Californians;draw
Devastating Donkeys;Allegoric Alaskans;win
Courageous Californians;Blithering Badgers;loss
Blithering Badgers;Devastating Donkeys;loss
Allegoric Alaskans;Courageous Californians;win
INPUT
actual = Tournament.tally(input)
expected = <<-TALLY.gsub(/^ */, '')
Team | MP | W | D | L | P
Devastating Donkeys | 3 | 2 | 1 | 0 | 7
Allegoric Alaskans | 3 | 2 | 0 | 1 | 6
Blithering Badgers | 3 | 1 | 0 | 2 | 3
Courageous Californians | 3 | 0 | 1 | 2 | 1
TALLY
assert_equal expected, actual
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider indenting and trimming the left hand side whitespace.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might work:
expected = <<-TALLY.gsub(/^ */,'')

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will only work if there is no internal indentation happening. True in this case, I think.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can confirm it works. Updated PR.

end

def test_incomplete_competition_not_all_pairs_have_played
skip
input = <<-INPUT.gsub(/^ */, '')
Allegoric Alaskans;Blithering Badgers;loss
Devastating Donkeys;Allegoric Alaskans;loss
Courageous Californians;Blithering Badgers;draw
Allegoric Alaskans;Courageous Californians;win
INPUT
actual = Tournament.tally(input)
expected = <<-TALLY.gsub(/^ */, '')
Team | MP | W | D | L | P
Allegoric Alaskans | 3 | 2 | 0 | 1 | 6
Blithering Badgers | 2 | 1 | 1 | 0 | 4
Courageous Californians | 2 | 0 | 1 | 1 | 1
Devastating Donkeys | 1 | 0 | 0 | 1 | 0
TALLY
assert_equal expected, actual
end

def test_ties_broken_alphabetically
skip
input = <<-INPUT.gsub(/^ */, '')
Courageous Californians;Devastating Donkeys;win
Allegoric Alaskans;Blithering Badgers;win
Devastating Donkeys;Allegoric Alaskans;loss
Courageous Californians;Blithering Badgers;win
Blithering Badgers;Devastating Donkeys;draw
Allegoric Alaskans;Courageous Californians;draw
INPUT
actual = Tournament.tally(input)
expected = <<-TALLY.gsub(/^ */, '')
Team | MP | W | D | L | P
Allegoric Alaskans | 3 | 2 | 1 | 0 | 7
Courageous Californians | 3 | 2 | 1 | 0 | 7
Blithering Badgers | 3 | 0 | 1 | 2 | 1
Devastating Donkeys | 3 | 0 | 1 | 2 | 1
TALLY
assert_equal expected, actual
end

# Problems in exercism evolve over time, as we find better ways to ask
# questions.
# The version number refers to the version of the problem you solved,
# not your solution.
#
# Define a constant named VERSION inside of the top level BookKeeping
# module, which may be placed near the end of your file.
#
# In your file, it will look like this:
#
# module BookKeeping
# VERSION = 1 # Where the version number matches the one in the test.
# end
#
# If you are curious, read more about constants on RubyDoc:
# http://ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/constants.html

def test_bookkeeping
skip
assert_equal 1, BookKeeping::VERSION
end
end
45 changes: 45 additions & 0 deletions lib/tournament_cases.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
class TournamentCase < OpenStruct
def test_name
"test_#{description.tr(' ', '_').tr('()', '')}"
end

def skipped
index.zero? ? '# skip' : 'skip'
end

def workload
'Tournament.tally(input)'
end

def expect
indented_heredoc(expected, 'TALLY')
end

def input_text
indented_heredoc(input, 'INPUT')
end

private

def indented_heredoc(string, delimiter)
[
"<<-#{delimiter}.gsub(/^ */, '')",
indent_lines(string),
indent_line(delimiter)
].join("\n")
end

def indent_lines(lines, indent = 3)
lines.map { |line| indent_line(line, indent) }.join("\n")
end

def indent_line(line, indent = 2)
' ' * indent * 2 + line
end
end

TournamentCases = proc do |data|
JSON.parse(data)['valid_inputs']['cases'].map.with_index do |row, i|
TournamentCase.new(row.merge('index' => i))
end
end