-
-
Notifications
You must be signed in to change notification settings - Fork 520
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[alphametics] Warn about long running tests in the common test data. #469
Changes from 1 commit
5f4917d
336a911
ea2ad66
a270ac3
6286608
3ded5e9
a5dbabe
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
3 | ||
4 |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,63 +3,72 @@ | |
require 'minitest/autorun' | ||
require_relative 'alphametics' | ||
|
||
# Test data version: | ||
# 8d8589f | ||
# Test data version: c1cb73f | ||
class AlphameticsTest < Minitest::Test | ||
def test_solve_short_puzzle | ||
|
||
def test_puzzle_with_three_letters | ||
# skip | ||
expect = { | ||
'I' => 1, 'B' => 9, 'L' => 0 | ||
} | ||
actual = Alphametics.new.solve('I + BB == ILL') | ||
assert_equal(expect, actual) | ||
input = 'I + BB == ILL' | ||
expected = { 'B' => 9, 'I' => 1, 'L' => 0 } | ||
assert_equal expected, Alphametics.solve(input) | ||
end | ||
|
||
# This test has been commented out due its long runtime. | ||
# def test_solve_long_puzzle | ||
# skip | ||
# expect = { | ||
# 'S' => 9, 'E' => 5, 'N' => 6, 'D' => 7, | ||
# 'M' => 1, 'O' => 0, 'R' => 8, 'Y' => 2 | ||
# } | ||
# actual = Alphametics.new.solve('SEND + MORE == MONEY') | ||
# assert_equal(expect, actual) | ||
# end | ||
|
||
def test_solution_must_have_unique_value_for_each_letter | ||
skip | ||
expect = nil | ||
actual = Alphametics.new.solve('A == B') | ||
assert_equal(expect, actual) | ||
input = 'A == B' | ||
expected = {} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Invalid solutions now expect an empty hash rather than a |
||
assert_equal expected, Alphametics.solve(input) | ||
end | ||
|
||
def test_leading_zero_solution_is_invalid | ||
skip | ||
expect = nil | ||
actual = Alphametics.new.solve('ACA + DD == BD') | ||
assert_equal(expect, actual) | ||
input = 'ACA + DD == BD' | ||
expected = {} | ||
assert_equal expected, Alphametics.solve(input) | ||
end | ||
|
||
def test_puzzle_with_four_letters | ||
skip | ||
input = 'AS + A == MOM' | ||
expected = { 'A' => 9, 'M' => 1, 'O' => 0, 'S' => 2 } | ||
assert_equal expected, Alphametics.solve(input) | ||
end | ||
|
||
def test_solve_puzzle_with_four_words | ||
def test_puzzle_with_six_letters | ||
skip | ||
expect = { | ||
'E' => 4, 'G' => 2, 'H' => 5, 'I' => 0, | ||
'L' => 1, 'S' => 9, 'T' => 7 | ||
} | ||
actual = Alphametics.new.solve('HE + SEES + THE == LIGHT') | ||
assert_equal(expect, actual) | ||
input = 'NO + NO + TOO == LATE' | ||
expected = { 'A' => 0, 'E' => 2, 'L' => 1, 'N' => 7, | ||
'O' => 4, 'T' => 9 } | ||
assert_equal expected, Alphametics.solve(input) | ||
end | ||
|
||
# This test has been commented out due its long runtime. | ||
# def test_solve_puzzle_with_many_words | ||
def test_puzzle_with_seven_letters | ||
skip | ||
input = 'HE + SEES + THE == LIGHT' | ||
expected = { 'E' => 4, 'G' => 2, 'H' => 5, 'I' => 0, | ||
'L' => 1, 'S' => 9, 'T' => 7 } | ||
assert_equal expected, Alphametics.solve(input) | ||
end | ||
|
||
# These tests have been commented out due their long runtime. If you are | ||
# interested in optimsing your solution for speed these are a good tests to | ||
# try. | ||
# | ||
# def test_puzzle_with_eight_letters | ||
# skip | ||
# input = 'SEND + MORE == MONEY' | ||
# expected = { 'D' => 7, 'E' => 5, 'M' => 1, 'N' => 6, | ||
# 'O' => 0, 'R' => 8, 'S' => 9, 'Y' => 2 } | ||
# assert_equal expected, Alphametics.solve(input) | ||
# end | ||
|
||
# def test_puzzle_with_ten_letters | ||
# skip | ||
# expect = { | ||
# 'A' => 5, 'D' => 3, 'E' => 4, 'F' => 7, | ||
# 'G' => 8, 'N' => 0, 'O' => 2, 'R' => 1, | ||
# 'S' => 6, 'T' => 9 | ||
# } | ||
# actual = Alphametics.new.solve('AND + A + STRONG + OFFENSE + AS + A + GOOD = DEFENSE') | ||
# assert_equal(expect, actual) | ||
# input = 'AND + A + STRONG + OFFENSE + AS + A + GOOD = DEFENSE' | ||
# expected = { 'A' => 5, 'D' => 3, 'E' => 4, 'F' => 7, | ||
# 'G' => 8, 'N' => 0, 'O' => 2, 'R' => 1, | ||
# 'S' => 6, 'T' => 9 } | ||
# assert_equal expected, Alphametics.solve(input) | ||
# end | ||
|
||
# Problems in exercism evolve over time, as we find better ways to ask | ||
|
@@ -81,6 +90,6 @@ def test_solve_puzzle_with_four_words | |
|
||
def test_bookkeeping | ||
skip | ||
assert_equal 3, BookKeeping::VERSION | ||
assert_equal 4, BookKeeping::VERSION | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,16 +3,37 @@ gem 'minitest', '>= 5.0.0' | |
require 'minitest/autorun' | ||
require_relative 'alphametics' | ||
|
||
# Test data version: | ||
# <%= sha1 %> | ||
class AlphameticsTest < Minitest::Test<% test_cases.each do |test_case| %> | ||
# Test data version: <%= sha1 %> | ||
class AlphameticsTest < Minitest::Test | ||
<% test_cases.each do |test_case| %> | ||
def <%= test_case.test_name %> | ||
<%= test_case.skipped %> | ||
expect = <%= test_case.expect %> | ||
actual = <%= test_case.work_load %> | ||
assert_equal(expect, actual) | ||
input = <%= test_case.input %> | ||
expected = <%= test_case.expect %> | ||
<%= test_case.workload %> | ||
end | ||
<% end %> | ||
# These tests have been commented out due their long runtime. If you are | ||
# interested in optimsing your solution for speed these are a good tests to | ||
# try. | ||
# | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The 'long' tests are ignored by the test case generator but are hardcoded here for reference. |
||
# def test_puzzle_with_eight_letters | ||
# skip | ||
# input = 'SEND + MORE == MONEY' | ||
# expected = { 'D' => 7, 'E' => 5, 'M' => 1, 'N' => 6, | ||
# 'O' => 0, 'R' => 8, 'S' => 9, 'Y' => 2 } | ||
# assert_equal expected, Alphametics.solve(input) | ||
# end | ||
|
||
# def test_puzzle_with_ten_letters | ||
# skip | ||
# input = 'AND + A + STRONG + OFFENSE + AS + A + GOOD = DEFENSE' | ||
# expected = { 'A' => 5, 'D' => 3, 'E' => 4, 'F' => 7, | ||
# 'G' => 8, 'N' => 0, 'O' => 2, 'R' => 1, | ||
# 'S' => 6, 'T' => 9 } | ||
# assert_equal expected, Alphametics.solve(input) | ||
# end | ||
|
||
<%= IO.read(XRUBY_LIB + '/bookkeeping.md') %> | ||
def test_bookkeeping | ||
skip | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,35 +1,54 @@ | ||
class AlphameticsCase < OpenStruct | ||
PAIRS_PER_LINE = 4 | ||
SPACE = ->(num) { ' ' * num } | ||
|
||
def test_name | ||
"test_#{description.tr(' ', '_')}" | ||
end | ||
|
||
def work_load | ||
"Alphametics.new.solve('#{puzzle}')" | ||
def skipped | ||
index.zero? ? '# skip' : 'skip' | ||
end | ||
|
||
def input | ||
"'#{puzzle}'" | ||
end | ||
|
||
def expect | ||
return 'nil' if expected.nil? | ||
expected_values | ||
expected.nil? ? {} : expected_values | ||
end | ||
|
||
def workload | ||
'assert_equal expected, Alphametics.solve(input)' | ||
end | ||
|
||
private | ||
|
||
def expected_values | ||
"{\n" << expected.each_slice(PAIRS_PER_LINE).map do |pairs| | ||
'%s'.prepend(SPACE[6]) % | ||
pairs.map { |k, v| "'#{k}' => #{v}" }.join(', ') | ||
end.join(",\n") << "\n }" | ||
"{ #{indent(expected_values_as_lines,17)} }" | ||
end | ||
|
||
def skipped | ||
index.zero? ? '# skip' : 'skip' | ||
def expected_values_as_lines | ||
lines = expected_values_as_strings.each_slice(4).map { |line| line.join(', ') } | ||
add_trailing_comma(lines) | ||
end | ||
|
||
def expected_values_as_strings | ||
expected.sort.map { |(key,value)| "'#{key}' => #{value}" } | ||
end | ||
|
||
def add_trailing_comma(lines) | ||
lines[0...-1].map { |line| "#{line}," }.push(lines.last) | ||
end | ||
|
||
def indent(string, spaces) | ||
string.join("\n" + ' ' * spaces) | ||
end | ||
end | ||
|
||
AlphameticsCases = proc do |data| | ||
JSON.parse(data)['solve']['cases'].map.with_index do |row, i| | ||
testcases = JSON.parse(data)['solve']['cases'].map.with_index do |row, i| | ||
row = row.merge('index' => i) | ||
AlphameticsCase.new(row) | ||
end | ||
|
||
# The example algorithm takes a long time to solve these. | ||
testcases.reject { |testcase| (testcase.expected||{}).size > 7 } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Test cases are ignored based on how many letters there are in the expected output. |
||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was:
Alphametics.new.solve(input)
Now:
Alphametics.solve(input)
Instantiating an object is unnecessary, so it now uses a
instanceclass method.Edit: It's NOT using an instance method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the final test,
'AND + A + STRONG + OFFENSE + AS + A + GOOD = DEFENSE'
, the=
should be==
. Also, in the commentary,optimsing
should beoptimising
.