Skip to content

Commit 8217e25

Browse files
committed
Merge branch 'update-tests-palindrome-calculator' of https://github.com/jagdish-15/java into update-tests-palindrome-calculator
Merging with origin
2 parents 1deaacb + a4af51f commit 8217e25

File tree

35 files changed

+563
-84
lines changed

35 files changed

+563
-84
lines changed

docs/TESTS.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,20 @@ Good luck! Have fun!
8181

8282
_(Don't worry about the tests failing, at first, this is how you begin each exercise.)_
8383

84+
If you get the following error:
85+
86+
```sh
87+
./gradlew: Permission denied
88+
```
89+
90+
Then the file is missing the execute permission. To fis this, run:
91+
92+
```sh
93+
chmod +x ./gradlew
94+
```
95+
96+
And now you should be able to run the previous command.
97+
8498
4. Solve the exercise. Find and work through the `instructions.append.md` guide ([view on GitHub][hello-world-tutorial]).
8599

86100
Good luck! Have fun!

exercises/concept/salary-calculator/.meta/src/reference/java/SalaryCalculator.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ public int bonusMultiplier(int productsSold) {
88
return productsSold < 20 ? 10 : 13;
99
}
1010

11-
public double bonusForProductsSold (int productsSold) {
11+
public double bonusForProductsSold(int productsSold) {
1212
return productsSold * bonusMultiplier(productsSold);
1313
}
1414

15-
public double finalSalary (int daysSkipped, int productsSold) {
15+
public double finalSalary(int daysSkipped, int productsSold) {
1616
double finalSalary = 1000.0 * salaryMultiplier(daysSkipped) + bonusForProductsSold(productsSold);
1717
return finalSalary > 2000.0 ? 2000.0 : finalSalary;
1818
}

exercises/practice/bob/.meta/config.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"austinlyons",
88
"c-thornton",
99
"FridaTveit",
10+
"jagdish-15",
1011
"jmrunkle",
1112
"jtigger",
1213
"kytrinyx",

exercises/practice/bob/.meta/tests.toml

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
1-
# This is an auto-generated file. Regular comments will be removed when this
2-
# file is regenerated. Regenerating will not touch any manually added keys,
3-
# so comments can be added in a "comment" key.
1+
# This is an auto-generated file.
2+
#
3+
# Regenerating this file via `configlet sync` will:
4+
# - Recreate every `description` key/value pair
5+
# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
6+
# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
7+
# - Preserve any other key/value pair
8+
#
9+
# As user-added comments (using the # character) will be removed when this file
10+
# is regenerated, comments can be added via a `comment` key.
411

512
[e162fead-606f-437a-a166-d051915cea8e]
613
description = "stating something"
@@ -64,6 +71,7 @@ description = "alternate silence"
6471

6572
[66953780-165b-4e7e-8ce3-4bcb80b6385a]
6673
description = "multiple line question"
74+
include = false
6775

6876
[5371ef75-d9ea-4103-bcfa-2da973ddec1b]
6977
description = "starting with whitespace"
@@ -76,3 +84,7 @@ description = "other whitespace"
7684

7785
[12983553-8601-46a8-92fa-fcaa3bc4a2a0]
7886
description = "non-question ending with whitespace"
87+
88+
[2c7278ac-f955-4eb4-bf8f-e33eb4116a15]
89+
description = "multiple line question"
90+
reimplements = "66953780-165b-4e7e-8ce3-4bcb80b6385a"

exercises/practice/bob/src/test/java/BobTest.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -152,13 +152,6 @@ public void alternateSilence() {
152152
.isEqualTo("Fine. Be that way!");
153153
}
154154

155-
@Disabled("Remove to run test")
156-
@Test
157-
public void multipleLineQuestion() {
158-
assertThat(bob.hey("\nDoes this cryogenic chamber make me look fat?\nNo."))
159-
.isEqualTo("Whatever.");
160-
}
161-
162155
@Disabled("Remove to run test")
163156
@Test
164157
public void startingWithWhitespace() {
@@ -187,4 +180,11 @@ public void nonQuestionEndingWithWhiteSpace() {
187180
.isEqualTo("Whatever.");
188181
}
189182

183+
@Disabled("Remove to run test")
184+
@Test
185+
public void multipleLineQuestion() {
186+
assertThat(bob.hey("\nDoes this cryogenic chamber make\n me look fat?"))
187+
.isEqualTo("Sure.");
188+
}
189+
190190
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"introduction": {
3+
"authors": [
4+
"jagdish-15"
5+
]
6+
},
7+
"approaches": [
8+
{
9+
"uuid": "d0b615ca-3a02-4d66-ad10-e0c513062189",
10+
"slug": "dynamic-programming",
11+
"title": "Dynamic Programming Approach",
12+
"blurb": "Use dynamic programming to find the most efficient change combination.",
13+
"authors": [
14+
"jagdish-15"
15+
],
16+
"contributors": [
17+
"kahgoh"
18+
]
19+
}
20+
]
21+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Dynamic Programming Approach
2+
3+
```java
4+
import java.util.List;
5+
import java.util.ArrayList;
6+
7+
class ChangeCalculator {
8+
private final List<Integer> currencyCoins;
9+
10+
ChangeCalculator(List<Integer> currencyCoins) {
11+
this.currencyCoins = currencyCoins;
12+
}
13+
14+
List<Integer> computeMostEfficientChange(int grandTotal) {
15+
if (grandTotal < 0)
16+
throw new IllegalArgumentException("Negative totals are not allowed.");
17+
18+
List<List<Integer>> coinsUsed = new ArrayList<>(grandTotal + 1);
19+
coinsUsed.add(new ArrayList<Integer>());
20+
21+
for (int i = 1; i <= grandTotal; i++) {
22+
List<Integer> bestCombination = null;
23+
for (int coin: currencyCoins) {
24+
if (coin <= i && coinsUsed.get(i - coin) != null) {
25+
List<Integer> currentCombination = new ArrayList<>(coinsUsed.get(i - coin));
26+
currentCombination.add(0, coin);
27+
if (bestCombination == null || currentCombination.size() < bestCombination.size())
28+
bestCombination = currentCombination;
29+
}
30+
}
31+
coinsUsed.add(bestCombination);
32+
}
33+
34+
if (coinsUsed.get(grandTotal) == null)
35+
throw new IllegalArgumentException("The total " + grandTotal + " cannot be represented in the given currency.");
36+
37+
return coinsUsed.get(grandTotal);
38+
}
39+
}
40+
```
41+
42+
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.
43+
It minimizes the number of coins needed by breaking down the problem into smaller subproblems and solving them progressively.
44+
45+
## Explanation
46+
47+
### Initialize Coins Usage Tracker
48+
49+
- If the `grandTotal` is negative, an exception is thrown immediately.
50+
- We create a list `coinsUsed`, where each index `i` stores the most efficient combination of coins that sum up to the value `i`.
51+
- The list is initialized with an empty list at index `0`, as no coins are needed to achieve a total of zero.
52+
53+
### Iterative Dynamic Programming
54+
55+
- 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`.
56+
- 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).
57+
- 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.
58+
59+
### Result
60+
61+
- After processing all values up to `grandTotal`, the combination at `coinsUsed[grandTotal]` will represent the most efficient solution.
62+
- If no valid combination exists for `grandTotal`, an exception is thrown.
63+
64+
## Time and Space Complexity
65+
66+
The time complexity of this approach is **O(n * m)**, where `n` is the `grandTotal` and `m` is the number of available coin denominations. This is because we iterate over all coin denominations for each amount up to `grandTotal`.
67+
68+
The space complexity is **O(n)** due to the list `coinsUsed`, which stores the most efficient coin combination for each total up to `grandTotal`.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
class ChangeCalculator {
2+
private final List<Integer> currencyCoins;
3+
4+
ChangeCalculator(List<Integer> currencyCoins) {
5+
this.currencyCoins = currencyCoins;
6+
}
7+
// computeMostEfficientChange method
8+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Introduction
2+
3+
There is an idiomatic approach to solving "Change."
4+
You can use [dynamic programming][dynamic-programming] to calculate the minimum number of coins required for a given total.
5+
6+
## General guidance
7+
8+
The key to solving "Change" is understanding that not all totals can be reached with the available coin denominations.
9+
The solution needs to figure out which totals can be achieved and how to combine the coins optimally.
10+
11+
## Approach: Dynamic Programming
12+
13+
```java
14+
import java.util.List;
15+
import java.util.ArrayList;
16+
17+
class ChangeCalculator {
18+
private final List<Integer> currencyCoins;
19+
20+
ChangeCalculator(List<Integer> currencyCoins) {
21+
this.currencyCoins = currencyCoins;
22+
}
23+
24+
List<Integer> computeMostEfficientChange(int grandTotal) {
25+
if (grandTotal < 0)
26+
throw new IllegalArgumentException("Negative totals are not allowed.");
27+
28+
List<List<Integer>> coinsUsed = new ArrayList<>(grandTotal + 1);
29+
coinsUsed.add(new ArrayList<Integer>());
30+
31+
for (int i = 1; i <= grandTotal; i++) {
32+
List<Integer> bestCombination = null;
33+
for (int coin: currencyCoins) {
34+
if (coin <= i && coinsUsed.get(i - coin) != null) {
35+
List<Integer> currentCombination = new ArrayList<>(coinsUsed.get(i - coin));
36+
currentCombination.add(0, coin);
37+
if (bestCombination == null || currentCombination.size() < bestCombination.size())
38+
bestCombination = currentCombination;
39+
}
40+
}
41+
coinsUsed.add(bestCombination);
42+
}
43+
44+
if (coinsUsed.get(grandTotal) == null)
45+
throw new IllegalArgumentException("The total " + grandTotal + " cannot be represented in the given currency.");
46+
47+
return coinsUsed.get(grandTotal);
48+
}
49+
}
50+
```
51+
52+
For a detailed look at the code and logic, see the full explanation in the [Dynamic Programming Approach][approach-dynamic-programming].
53+
54+
[approach-dynamic-programming]: https://exercism.org/tracks/java/exercises/change/approaches/dynamic-programming
55+
[dynamic-programming]: https://en.wikipedia.org/wiki/Dynamic_programming
Lines changed: 89 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,100 @@
11
# Instructions
22

3-
A complex number is a number in the form `a + b * i` where `a` and `b` are real and `i` satisfies `i^2 = -1`.
3+
A **complex number** is expressed in the form `z = a + b * i`, where:
44

5-
`a` is called the real part and `b` is called the imaginary part of `z`.
6-
The conjugate of the number `a + b * i` is the number `a - b * i`.
7-
The absolute value of a complex number `z = a + b * i` is a real number `|z| = sqrt(a^2 + b^2)`. The square of the absolute value `|z|^2` is the result of multiplication of `z` by its complex conjugate.
5+
- `a` is the **real part** (a real number),
86

9-
The sum/difference of two complex numbers involves adding/subtracting their real and imaginary parts separately:
10-
`(a + i * b) + (c + i * d) = (a + c) + (b + d) * i`,
11-
`(a + i * b) - (c + i * d) = (a - c) + (b - d) * i`.
7+
- `b` is the **imaginary part** (also a real number), and
128

13-
Multiplication result is by definition
14-
`(a + i * b) * (c + i * d) = (a * c - b * d) + (b * c + a * d) * i`.
9+
- `i` is the **imaginary unit** satisfying `i^2 = -1`.
1510

16-
The reciprocal of a non-zero complex number is
17-
`1 / (a + i * b) = a/(a^2 + b^2) - b/(a^2 + b^2) * i`.
11+
## Operations on Complex Numbers
1812

19-
Dividing a complex number `a + i * b` by another `c + i * d` gives:
20-
`(a + i * b) / (c + i * d) = (a * c + b * d)/(c^2 + d^2) + (b * c - a * d)/(c^2 + d^2) * i`.
13+
### Conjugate
2114

22-
Raising e to a complex exponent can be expressed as `e^(a + i * b) = e^a * e^(i * b)`, the last term of which is given by Euler's formula `e^(i * b) = cos(b) + i * sin(b)`.
15+
The conjugate of the complex number `z = a + b * i` is given by:
2316

24-
Implement the following operations:
17+
```text
18+
zc = a - b * i
19+
```
2520

26-
- addition, subtraction, multiplication and division of two complex numbers,
27-
- conjugate, absolute value, exponent of a given complex number.
21+
### Absolute Value
2822

29-
Assume the programming language you are using does not have an implementation of complex numbers.
23+
The absolute value (or modulus) of `z` is defined as:
24+
25+
```text
26+
|z| = sqrt(a^2 + b^2)
27+
```
28+
29+
The square of the absolute value is computed as the product of `z` and its conjugate `zc`:
30+
31+
```text
32+
|z|^2 = z * zc = a^2 + b^2
33+
```
34+
35+
### Addition
36+
37+
The sum of two complex numbers `z1 = a + b * i` and `z2 = c + d * i` is computed by adding their real and imaginary parts separately:
38+
39+
```text
40+
z1 + z2 = (a + b * i) + (c + d * i)
41+
= (a + c) + (b + d) * i
42+
```
43+
44+
### Subtraction
45+
46+
The difference of two complex numbers is obtained by subtracting their respective parts:
47+
48+
```text
49+
z1 - z2 = (a + b * i) - (c + d * i)
50+
= (a - c) + (b - d) * i
51+
```
52+
53+
### Multiplication
54+
55+
The product of two complex numbers is defined as:
56+
57+
```text
58+
z1 * z2 = (a + b * i) * (c + d * i)
59+
= (a * c - b * d) + (b * c + a * d) * i
60+
```
61+
62+
### Reciprocal
63+
64+
The reciprocal of a non-zero complex number is given by:
65+
66+
```text
67+
1 / z = 1 / (a + b * i)
68+
= a / (a^2 + b^2) - b / (a^2 + b^2) * i
69+
```
70+
71+
### Division
72+
73+
The division of one complex number by another is given by:
74+
75+
```text
76+
z1 / z2 = z1 * (1 / z2)
77+
= (a + b * i) / (c + d * i)
78+
= (a * c + b * d) / (c^2 + d^2) + (b * c - a * d) / (c^2 + d^2) * i
79+
```
80+
81+
### Exponentiation
82+
83+
Raising _e_ (the base of the natural logarithm) to a complex exponent can be expressed using Euler's formula:
84+
85+
```text
86+
e^(a + b * i) = e^a * e^(b * i)
87+
= e^a * (cos(b) + i * sin(b))
88+
```
89+
90+
## Implementation Requirements
91+
92+
Given that you should not use built-in support for complex numbers, implement the following operations:
93+
94+
- **addition** of two complex numbers
95+
- **subtraction** of two complex numbers
96+
- **multiplication** of two complex numbers
97+
- **division** of two complex numbers
98+
- **conjugate** of a complex number
99+
- **absolute value** of a complex number
100+
- **exponentiation** of _e_ (the base of the natural logarithm) to a complex number

0 commit comments

Comments
 (0)