-
-
Notifications
You must be signed in to change notification settings - Fork 520
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #695 from adimasuhid/features/implement-change-exe…
…rcise change: Implement Change exercise
- Loading branch information
Showing
5 changed files
with
158 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
require 'generator/exercise_case' | ||
|
||
class ChangeCase < Generator::ExerciseCase | ||
|
||
def workload | ||
assert_equal { "Change.generate(#{coins}, #{target})" } | ||
end | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
module BookKeeping | ||
VERSION = 1 | ||
end | ||
|
||
class Change | ||
attr_reader :coins, :target | ||
|
||
def initialize(coins, target) | ||
@coins = coins.sort.reverse | ||
@target = target | ||
@total_change = [] | ||
end | ||
|
||
def generate | ||
return [] if target.zero? | ||
|
||
calculate_change(coins, [], target) | ||
|
||
total_change.any? ? total_change.sort : -1 | ||
end | ||
|
||
def self.generate(coins, target) | ||
new(coins, target).generate | ||
end | ||
|
||
private | ||
|
||
attr_accessor :total_change | ||
|
||
def calculate_change(current_coins, current_change, current_value) | ||
available_coins = current_coins.reject {|d| d > current_value } | ||
|
||
save_change(current_change) if current_value.zero? | ||
|
||
return if has_more_coins?(current_change) | ||
|
||
each_group(available_coins) do |coin, group| | ||
calculate_change(group, current_change + [coin], current_value - coin) | ||
end | ||
end | ||
|
||
def save_change(contents) | ||
return if has_more_coins?(contents) | ||
|
||
self.total_change = contents | ||
end | ||
|
||
def has_more_coins?(contents) | ||
total_change.any? && (total_change.length < contents.length) | ||
end | ||
|
||
def each_group(array) | ||
array.length.times do |n| | ||
yield(array[n], array[n..-1]) | ||
end | ||
end | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
require 'minitest/autorun' | ||
require_relative 'change' | ||
|
||
# Common test data version: 1.0.0 3d8b5b3 | ||
class ChangeTest < Minitest::Test | ||
def test_single_coin_change | ||
# skip | ||
assert_equal [25], Change.generate([1, 5, 10, 25, 100], 25) | ||
end | ||
|
||
def test_multiple_coin_change | ||
skip | ||
assert_equal [5, 10], Change.generate([1, 5, 10, 25, 100], 15) | ||
end | ||
|
||
def test_change_with_lilliputian_coins | ||
skip | ||
assert_equal [4, 4, 15], Change.generate([1, 4, 15, 20, 50], 23) | ||
end | ||
|
||
def test_change_with_lower_elbonia_coins | ||
skip | ||
assert_equal [21, 21, 21], Change.generate([1, 5, 10, 21, 25], 63) | ||
end | ||
|
||
def test_large_target_values | ||
skip | ||
assert_equal [2, 2, 5, 20, 20, 50, 100, 100, 100, 100, 100, 100, 100, 100, 100], Change.generate([1, 2, 5, 10, 20, 50, 100], 999) | ||
end | ||
|
||
def test_possible_change_without_unit_coins_available | ||
skip | ||
assert_equal [2, 2, 2, 5, 10], Change.generate([2, 5, 10, 20, 50], 21) | ||
end | ||
|
||
def test_no_coins_make_0_change | ||
skip | ||
assert_equal [], Change.generate([1, 5, 10, 21, 25], 0) | ||
end | ||
|
||
def test_error_testing_for_change_smaller_than_the_smallest_of_coins | ||
skip | ||
assert_equal -1, Change.generate([5, 10], 3) | ||
end | ||
|
||
def test_error_if_no_combination_can_add_up_to_target | ||
skip | ||
assert_equal -1, Change.generate([5, 10], 94) | ||
end | ||
|
||
def test_cannot_find_negative_change_values | ||
skip | ||
assert_equal -1, Change.generate([1, 2, 5], -5) | ||
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 |