- 
          
 - 
                Notifications
    
You must be signed in to change notification settings  - Fork 738
 
Adding approach change #2859
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
Adding approach change #2859
Changes from 9 commits
e3cbf38
              4a7811f
              e8d2787
              6152c10
              5d398d0
              115a331
              d2c2451
              b3a98df
              e338ff2
              9438325
              fde837b
              7ec2960
              404de05
              1aa6d9c
              2fbec2a
              c1d07e5
              afee45a
              d9694fa
              7aa412e
              f3eb007
              0b5b6f2
              2df72c4
              2758bc3
              c0a46c6
              f76ad5d
              5db8204
              505a92d
              39f0e69
              2dea910
              4e0e5e0
              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 | 
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| { | ||
| "introduction": { | ||
| "authors": [ | ||
| "jagdish-15" | ||
| ] | ||
| }, | ||
| "approaches": [ | ||
| { | ||
| "uuid": "d0b615ca-3a02-4d66-ad10-e0c513062189", | ||
| "slug": "dynamic-programming", | ||
| "title": "Dynamic Programming Approach", | ||
| "blurb": "Use dynamic programming to find the most efficient change combination.", | ||
| "authors": [ | ||
| "jagdish-15" | ||
| ], | ||
| "contributors": [ | ||
| "kagoh" | ||
| ] | ||
| } | ||
| ] | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
| @@ -0,0 +1,86 @@ | ||||
| # Dynamic Programming Approach | ||||
| 
     | 
||||
| The **Dynamic Programming (DP)** approach is an efficient way to solve the problem of making change for a given total using a list of available coin denominations. It minimizes the number of coins needed by breaking down the problem into smaller subproblems and solving them progressively. | ||||
                
       | 
||||
| 
     | 
||||
| This approach ensures that we find the most efficient way to make change and handles edge cases where no solution exists. | ||||
| 
     | 
||||
| ## Explanation | ||||
| 
     | 
||||
| 1. **Initialize Coins Usage Tracker**: | ||||
| 
     | 
||||
| - We create a list `coinsUsed`, where each index `i` stores the most efficient combination of coins that sum up to the value `i`. | ||||
| - The list is initialized with an empty list at index `0`, as no coins are needed to achieve a total of zero. | ||||
| 
     | 
||||
| 2. **Iterative Dynamic Programming**: | ||||
| 
     | 
||||
| - For each value `i` from 1 to `grandTotal`, we explore all available coin denominations to find the best combination that can achieve the total `i`. | ||||
| - For each coin, we check if it can be part of the solution (i.e., if `coin <= i` and `coinsUsed[i - coin]` is a valid combination). | ||||
| - If so, we generate a new combination by adding the current coin to the solution for `i - coin`. We then compare the size of this new combination with the existing best combination and keep the one with fewer coins. | ||||
| 
     | 
||||
| 3. **Result**: | ||||
| 
     | 
||||
| - After processing all values up to `grandTotal`, the combination at `coinsUsed[grandTotal]` will represent the most efficient solution. | ||||
| - If no valid combination exists for `grandTotal`, an exception is thrown. | ||||
| 
     | 
||||
| ```java | ||||
| import java.util.List; | ||||
| import java.util.ArrayList; | ||||
| 
     | 
||||
| class ChangeCalculator { | ||||
| private final List<Integer> currencyCoins; | ||||
| 
     | 
||||
| ChangeCalculator(List<Integer> currencyCoins) { | ||||
| this.currencyCoins = currencyCoins; | ||||
| } | ||||
| 
     | 
||||
| List<Integer> computeMostEfficientChange(int grandTotal) { | ||||
| if (grandTotal < 0) | ||||
| throw new IllegalArgumentException("Negative totals are not allowed."); | ||||
| 
     | 
||||
| List<List<Integer>> coinsUsed = new ArrayList<>(grandTotal + 1); | ||||
| coinsUsed.add(new ArrayList<Integer>()); | ||||
| 
     | 
||||
| for (int i = 1; i <= grandTotal; i++) { | ||||
| List<Integer> bestCombination = null; | ||||
| for (int coin: currencyCoins) { | ||||
| if (coin <= i && coinsUsed.get(i - coin) != null) { | ||||
| List<Integer> currentCombination = new ArrayList<>(coinsUsed.get(i - coin)); | ||||
| currentCombination.add(0, coin); | ||||
| if (bestCombination == null || currentCombination.size() < bestCombination.size()) | ||||
| bestCombination = currentCombination; | ||||
| } | ||||
| } | ||||
| coinsUsed.add(bestCombination); | ||||
| } | ||||
| 
     | 
||||
| if (coinsUsed.get(grandTotal) == null) | ||||
| throw new IllegalArgumentException("The total " + grandTotal + " cannot be represented in the given currency."); | ||||
| 
     | 
||||
| return coinsUsed.get(grandTotal); | ||||
| } | ||||
| } | ||||
| ``` | ||||
| 
     | 
||||
| ## Key Points | ||||
                
       | 
||||
| ## Key Points | 
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.
Sure, I've removed this heading.
        
          
              
                Outdated
          
        
      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.
Suggest moving the points from the edge cases to be with your explanation as they are part of the implementation details. Idalso suggest separating them to follow the order of the code to make it easier to follow (i.e putting the point about checking if grandTotal is negative to the top and one about if no exact total to the bottom of the explanation).
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.
I've moved the first point to the start of the explanation as you suggested and removed the second point since it's already covered at the end, just before the 'Time Complexity' section.
        
          
              
                Outdated
          
        
      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.
Could you please remove this section on alternative approaches? This should just focus on the dynamic programming approach as this will become the dynamic programming page. Alternatively, we could move it to a Which approach to use? section in the introduction.md (similar to the isogram or robot name approaches), but we probably should briefly describe the Greedy Approach if we do (and we could possibly move the point about the efficiency there too).
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.
I have removed both the "Efficiency" and "Alternative Approach" sections entirely. I agree that it makes more sense to include these points in the introduction file under a section like "Which Approach to Use?" However, I believe this should be done only after we add another approach to compare. For now, with just a single approach, these sections are unnecessary.
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| class ChangeCalculator { | ||
| private final List<Integer> currencyCoins; | ||
| 
     | 
||
| ChangeCalculator(List<Integer> currencyCoins) { | ||
| this.currencyCoins = currencyCoins; | ||
| } | ||
| // computeMostEfficientChange method | ||
| } | 
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,26 @@ | ||||||
| # Introduction to Change Calculator | ||||||
                
       | 
||||||
| # Introduction to Change Calculator | |
| # Introduction | 
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.
Indeed!!
        
          
              
                Outdated
          
        
      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.
I don't think we need to repeat the exercise here. The other approaches generally have a "General guidance" section that talks about the "key things" to solve the exercise - things that all approaches are likely to have to. For example, in leap, it is as simple as knowing whether a year is divisible by 400, 100 and 4. For grains, its knowing that each square is doubled.
For Change, it could be that not all totals can be reached and somehow figuring out which ones can be reached and how.
| ## Problem Overview | |
| ## General guidance | 
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.
Sure, I've changed it.
        
          
              
                  jagdish-15 marked this conversation as resolved.
              
          
            Show resolved
            Hide resolved
        
              
          
              
                Outdated
          
        
      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.
The other approaches generally have a short listing of all the approaches here, with a link to the specific approach's page just underneath. For example, this would normally be a code listing for your dynamic programming approach followed by a link to the page generated from dynamic-programming/content.md (the URL would be https://exercism.org/tracks/java/exercises/change/approaches/dynamic-programming).
| ## Approach Overview | |
| ## Approach: Dynamic programming | 
        
          
              
                Outdated
          
        
      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 regards to the approach file link, there is a preference to use reference linking to make maintenance easier.
I also suggest changing the link text to "Dynamic Programming approach" as students will see a web page based on your content.md (and not the content.md "file").
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.
I agree, and I've made the changes accordingly.
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.
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.
I am sorry for the oversight.