Skip to content

Commit a8093e2

Browse files
authored
Merge branch 'master' into master
2 parents 4bbb617 + ce4eb55 commit a8093e2

38 files changed

+1665
-687
lines changed

pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@
107107
<plugin>
108108
<groupId>org.apache.maven.plugins</groupId>
109109
<artifactId>maven-checkstyle-plugin</artifactId>
110-
<version>3.4.0</version>
110+
<version>3.5.0</version>
111111
<configuration>
112112
<configLocation>checkstyle.xml</configLocation>
113113
<consoleOutput>true</consoleOutput>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.thealgorithms.conversions;
2+
3+
public final class AffineConverter {
4+
private final double slope;
5+
private final double intercept;
6+
public AffineConverter(final double inSlope, final double inIntercept) {
7+
slope = inSlope;
8+
intercept = inIntercept;
9+
}
10+
11+
public double convert(final double inValue) {
12+
return slope * inValue + intercept;
13+
}
14+
15+
public AffineConverter invert() {
16+
assert slope != 0.0;
17+
return new AffineConverter(1.0 / slope, -intercept / slope);
18+
}
19+
20+
public AffineConverter compose(final AffineConverter other) {
21+
return new AffineConverter(slope * other.slope, slope * other.intercept + intercept);
22+
}
23+
}

src/main/java/com/thealgorithms/conversions/AnyBaseToDecimal.java

+28-32
Original file line numberDiff line numberDiff line change
@@ -3,54 +3,50 @@
33
/**
44
* @author Varun Upadhyay (<a href="https://github.com/varunu28">...</a>)
55
*/
6-
// Driver program
76
public final class AnyBaseToDecimal {
8-
private AnyBaseToDecimal() {
9-
}
7+
private static final int CHAR_OFFSET_FOR_DIGIT = '0';
8+
private static final int CHAR_OFFSET_FOR_UPPERCASE = 'A' - 10;
109

11-
public static void main(String[] args) {
12-
assert convertToDecimal("1010", 2) == Integer.valueOf("1010", 2);
13-
assert convertToDecimal("777", 8) == Integer.valueOf("777", 8);
14-
assert convertToDecimal("999", 10) == Integer.valueOf("999", 10);
15-
assert convertToDecimal("ABCDEF", 16) == Integer.valueOf("ABCDEF", 16);
16-
assert convertToDecimal("XYZ", 36) == Integer.valueOf("XYZ", 36);
10+
private AnyBaseToDecimal() {
1711
}
1812

1913
/**
20-
* Convert any radix to decimal number
14+
* Convert any radix to a decimal number.
2115
*
22-
* @param s the string to be convert
23-
* @param radix the radix
24-
* @return decimal of bits
25-
* @throws NumberFormatException if {@code bits} or {@code radix} is invalid
16+
* @param input the string to be converted
17+
* @param radix the radix (base) of the input string
18+
* @return the decimal equivalent of the input string
19+
* @throws NumberFormatException if the input string or radix is invalid
2620
*/
27-
public static int convertToDecimal(String s, int radix) {
28-
int num = 0;
29-
int pow = 1;
21+
public static int convertToDecimal(String input, int radix) {
22+
int result = 0;
23+
int power = 1;
3024

31-
for (int i = s.length() - 1; i >= 0; i--) {
32-
int digit = valOfChar(s.charAt(i));
25+
for (int i = input.length() - 1; i >= 0; i--) {
26+
int digit = valOfChar(input.charAt(i));
3327
if (digit >= radix) {
34-
throw new NumberFormatException("For input string " + s);
28+
throw new NumberFormatException("For input string: " + input);
3529
}
36-
num += valOfChar(s.charAt(i)) * pow;
37-
pow *= radix;
30+
result += digit * power;
31+
power *= radix;
3832
}
39-
return num;
33+
return result;
4034
}
4135

4236
/**
43-
* Convert character to integer
37+
* Convert a character to its integer value.
4438
*
45-
* @param c the character
46-
* @return represented digit of given character
47-
* @throws NumberFormatException if {@code ch} is not UpperCase or Digit
48-
* character.
39+
* @param character the character to be converted
40+
* @return the integer value represented by the character
41+
* @throws NumberFormatException if the character is not an uppercase letter or a digit
4942
*/
50-
public static int valOfChar(char c) {
51-
if (!(Character.isUpperCase(c) || Character.isDigit(c))) {
52-
throw new NumberFormatException("invalid character :" + c);
43+
private static int valOfChar(char character) {
44+
if (Character.isDigit(character)) {
45+
return character - CHAR_OFFSET_FOR_DIGIT;
46+
} else if (Character.isUpperCase(character)) {
47+
return character - CHAR_OFFSET_FOR_UPPERCASE;
48+
} else {
49+
throw new NumberFormatException("invalid character:" + character);
5350
}
54-
return Character.isDigit(c) ? c - '0' : c - 'A' + 10;
5551
}
5652
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.thealgorithms.conversions;
2+
3+
import static java.util.Map.entry;
4+
5+
import java.util.Map;
6+
import org.apache.commons.lang3.tuple.Pair;
7+
8+
public final class UnitConversions {
9+
private UnitConversions() {
10+
}
11+
12+
public static final UnitsConverter TEMPERATURE = new UnitsConverter(Map.ofEntries(entry(Pair.of("Kelvin", "Celsius"), new AffineConverter(1.0, -273.15)), entry(Pair.of("Celsius", "Fahrenheit"), new AffineConverter(9.0 / 5.0, 32.0)),
13+
entry(Pair.of("Réaumur", "Celsius"), new AffineConverter(5.0 / 4.0, 0.0)), entry(Pair.of("Delisle", "Celsius"), new AffineConverter(-2.0 / 3.0, 100.0)), entry(Pair.of("Rankine", "Kelvin"), new AffineConverter(5.0 / 9.0, 0.0))));
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package com.thealgorithms.conversions;
2+
3+
import java.util.HashMap;
4+
import java.util.HashSet;
5+
import java.util.Map;
6+
import java.util.Set;
7+
import org.apache.commons.lang3.tuple.Pair;
8+
9+
public final class UnitsConverter {
10+
private final Map<Pair<String, String>, AffineConverter> conversions;
11+
private final Set<String> units;
12+
13+
private static void putIfNeeded(Map<Pair<String, String>, AffineConverter> conversions, final String inputUnit, final String outputUnit, final AffineConverter converter) {
14+
if (!inputUnit.equals(outputUnit)) {
15+
final var key = Pair.of(inputUnit, outputUnit);
16+
conversions.putIfAbsent(key, converter);
17+
}
18+
}
19+
20+
private static Map<Pair<String, String>, AffineConverter> addInversions(final Map<Pair<String, String>, AffineConverter> knownConversions) {
21+
Map<Pair<String, String>, AffineConverter> res = new HashMap<Pair<String, String>, AffineConverter>();
22+
for (final var curConversion : knownConversions.entrySet()) {
23+
final var inputUnit = curConversion.getKey().getKey();
24+
final var outputUnit = curConversion.getKey().getValue();
25+
putIfNeeded(res, inputUnit, outputUnit, curConversion.getValue());
26+
putIfNeeded(res, outputUnit, inputUnit, curConversion.getValue().invert());
27+
}
28+
return res;
29+
}
30+
31+
private static Map<Pair<String, String>, AffineConverter> addCompositions(final Map<Pair<String, String>, AffineConverter> knownConversions) {
32+
Map<Pair<String, String>, AffineConverter> res = new HashMap<Pair<String, String>, AffineConverter>();
33+
for (final var first : knownConversions.entrySet()) {
34+
final var firstKey = first.getKey();
35+
putIfNeeded(res, firstKey.getKey(), firstKey.getValue(), first.getValue());
36+
for (final var second : knownConversions.entrySet()) {
37+
final var secondKey = second.getKey();
38+
if (firstKey.getValue().equals(secondKey.getKey())) {
39+
final var newConversion = second.getValue().compose(first.getValue());
40+
putIfNeeded(res, firstKey.getKey(), secondKey.getValue(), newConversion);
41+
}
42+
}
43+
}
44+
return res;
45+
}
46+
47+
private static Map<Pair<String, String>, AffineConverter> addAll(final Map<Pair<String, String>, AffineConverter> knownConversions) {
48+
final var res = addInversions(knownConversions);
49+
return addCompositions(res);
50+
}
51+
52+
private static Map<Pair<String, String>, AffineConverter> computeAllConversions(final Map<Pair<String, String>, AffineConverter> basicConversions) {
53+
var tmp = basicConversions;
54+
var res = addAll(tmp);
55+
while (res.size() != tmp.size()) {
56+
tmp = res;
57+
res = addAll(tmp);
58+
}
59+
return res;
60+
}
61+
62+
private static Set<String> extractUnits(final Map<Pair<String, String>, AffineConverter> conversions) {
63+
Set<String> res = new HashSet<>();
64+
for (final var conversion : conversions.entrySet()) {
65+
res.add(conversion.getKey().getKey());
66+
}
67+
return res;
68+
}
69+
70+
public UnitsConverter(final Map<Pair<String, String>, AffineConverter> basicConversions) {
71+
conversions = computeAllConversions(basicConversions);
72+
units = extractUnits(conversions);
73+
}
74+
75+
public double convert(final String inputUnit, final String outputUnit, final double value) {
76+
if (inputUnit.equals(outputUnit)) {
77+
throw new IllegalArgumentException("inputUnit must be different from outputUnit.");
78+
}
79+
final var conversionKey = Pair.of(inputUnit, outputUnit);
80+
return conversions.get(conversionKey).convert(value);
81+
}
82+
83+
public Set<String> availableUnits() {
84+
return units;
85+
}
86+
}

src/main/java/com/thealgorithms/datastructures/caches/LFUCache.java

+26-27
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@
1010
public class LFUCache<K, V> {
1111

1212
private class Node {
13-
14-
private K key;
13+
private final K key;
1514
private V value;
1615
private int frequency;
1716
private Node previous;
@@ -26,67 +25,67 @@ private class Node {
2625

2726
private Node head;
2827
private Node tail;
29-
private Map<K, Node> map = null;
30-
private Integer capacity;
28+
private final Map<K, Node> cache;
29+
private final int capacity;
3130
private static final int DEFAULT_CAPACITY = 100;
3231

3332
public LFUCache() {
34-
this.capacity = DEFAULT_CAPACITY;
33+
this(DEFAULT_CAPACITY);
3534
}
3635

37-
public LFUCache(Integer capacity) {
36+
public LFUCache(int capacity) {
37+
if (capacity <= 0) {
38+
throw new IllegalArgumentException("Capacity must be greater than zero.");
39+
}
3840
this.capacity = capacity;
39-
this.map = new HashMap<>();
41+
this.cache = new HashMap<>();
4042
}
4143

4244
/**
43-
* This method returns value present in the cache corresponding to the key passed as parameter
45+
* Retrieves the value for the given key from the cache. Increases the frequency of the node.
4446
*
45-
* @param <K> key for which value is to be retrieved
46-
* @returns <V> object corresponding to the key passed as parameter, returns null if <K> key is
47-
* not present in the cache
47+
* @param key The key to look up.
48+
* @return The value associated with the key, or null if the key is not present.
4849
*/
4950
public V get(K key) {
50-
if (this.map.get(key) == null) {
51+
Node node = cache.get(key);
52+
if (node == null) {
5153
return null;
5254
}
53-
54-
Node node = map.get(key);
5555
removeNode(node);
5656
node.frequency += 1;
5757
addNodeWithUpdatedFrequency(node);
58-
5958
return node.value;
6059
}
6160

6261
/**
63-
* This method stores <K> key and <V> value in the cache
62+
* Adds or updates a key-value pair in the cache. If the cache is full, the least frequently used item is evicted.
6463
*
65-
* @param <K> key which is to be stored in the cache
66-
* @param <V> value which is to be stored in the cache
64+
* @param key The key to insert or update.
65+
* @param value The value to insert or update.
6766
*/
6867
public void put(K key, V value) {
69-
if (map.containsKey(key)) {
70-
Node node = map.get(key);
68+
if (cache.containsKey(key)) {
69+
Node node = cache.get(key);
7170
node.value = value;
7271
node.frequency += 1;
7372
removeNode(node);
7473
addNodeWithUpdatedFrequency(node);
7574
} else {
76-
if (map.size() >= capacity) {
77-
map.remove(this.head.key);
75+
if (cache.size() >= capacity) {
76+
cache.remove(this.head.key);
7877
removeNode(head);
7978
}
8079
Node node = new Node(key, value, 1);
8180
addNodeWithUpdatedFrequency(node);
82-
map.put(key, node);
81+
cache.put(key, node);
8382
}
8483
}
8584

8685
/**
87-
* This method stores the node in the cache with updated frequency
86+
* Adds a node to the linked list in the correct position based on its frequency.
8887
*
89-
* @param Node node which is to be updated in the cache
88+
* @param node The node to add.
9089
*/
9190
private void addNodeWithUpdatedFrequency(Node node) {
9291
if (tail != null && head != null) {
@@ -123,9 +122,9 @@ private void addNodeWithUpdatedFrequency(Node node) {
123122
}
124123

125124
/**
126-
* This method removes node from the cache
125+
* Removes a node from the linked list.
127126
*
128-
* @param Node node which is to be removed in the cache
127+
* @param node The node to remove.
129128
*/
130129
private void removeNode(Node node) {
131130
if (node.previous != null) {

0 commit comments

Comments
 (0)