Task-6
LRU Cache in Java
1. Aim:
To implement an LRU (Least Recently Used) Cache using Java, demonstrating
efficient memory management by removing the least recently accessed elements
when the cache reaches its capacity.
2. Algorithm:
1. Create an LRU Cache class using LinkedHashMap (or Doubly Linked List
with HashMap for manual implementation).
2. Define:
o Capacity: Maximum number of elements the cache can hold.
o Put(K, V): Inserts a key-value pair and removes the least recently used
item if full.
o Get(K): Fetches the value for a key and marks it as recently used.
3. Use LinkedHashMap with accessOrder = true to maintain access order.
4. Override removeEldestEntry() to automatically remove the least recently
used element.
3. Program:
import java.util.*;
class LRUCache {
class Node {
int key, value;
Node prev, next;
Node(int k, int v)
{
key = k; value = v; }
}
private final int capacity;
private final Map<Integer, Node> cache;
private final Node head, tail;
public LRUCache(int capacity) {
this.capacity = capacity;
this.cache = new HashMap<>();
this.head = new Node(0, 0);
this.tail = new Node(0, 0);
head.next = tail;
tail.prev = head;
}
private void remove(Node node) {
node.prev.next = node.next;
node.next.prev = node.prev;
}
private void insert(Node node) {
node.next = head.next;
node.prev = head;
head.next.prev = node;
head.next = node;
}
public int get(int key) {
if (!cache.containsKey(key)) return -1;
Node node = cache.get(key);
remove(node);
insert(node);
return node.value;
}
public void put(int key, int value) {
if (cache.containsKey(key))
remove(cache.get(key));
if (cache.size() >= capacity) {
cache.remove(tail.prev.key);
remove(tail.prev);
}
Node node = new Node(key, value);
insert(node);
cache.put(key, node);
}
public static void main(String[] args) {
LRUCache lru = new LRUCache(2); // Cache capacity = 2
lru.put(1, 1);
lru.put(2, 2);
System.out.println(lru.get(1)); // Expected Output: 1
lru.put(3, 3); // Removes key 2
System.out.println(lru.get(2)); // Expected Output: -1 (not found)
lru.put(4, 4); // Removes key 1
System.out.println(lru.get(1)); // Expected Output: -1 (not found)
System.out.println(lru.get(3)); // Expected Output: 3
System.out.println(lru.get(4)); // Expected Output: 4
}
}
Output:
1
-1
-1
3
4
Explanation:
1. LRUCache(2) → Creates an LRU Cache with a capacity of 2.
2. put(1, 1) → Inserts (1,1).
3. put(2, 2) → Inserts (2,2).
4. get(1) → Returns 1 because key 1 is present.
5. put(3, 3) → Cache is full; removes least recently used key 2, inserts (3,3).
6. get(2) → Returns -1 (key 2 was removed).
7. put(4, 4) → Cache is full; removes least recently used key 1, inserts (4,4).
8. get(1) → Returns -1 (key 1 was removed).
9. get(3) → Returns 3 (key 3 is present).
10. get(4) → Returns 4 (key 4 is present).
Descending Weights in Java
1. Aim:
To write a Java program that sorts an array of elements based on their descending weights, where
weight is defined as a function of divisibility by a given number k. Elements with higher
divisibility (higher weight) are sorted first, and elements with the same weight are sorted in
descending order.
2. Algorithm:
1. Input the array and the integer k (used to determine the weight of each element).
2. Calculate the weight of each element:
o Weight is determined by the number of times the element is divisible by k.
3. Sort the array:
o Elements with a higher weight appear first.
o If two elements have the same weight, they are sorted in descending order.
4. Print the sorted array.
Program:
import java.util.*;
class DescendingWeights {
// Custom comparator to sort based on weight and value
static class WeightComparator implements Comparator<Integer> {
int k;
WeightComparator(int k) {
this.k = k;
@Override
public int compare(Integer a, Integer b) {
int weightA = getWeight(a, k);
int weightB = getWeight(b, k);
// Sort by weight (descending)
if (weightA != weightB)
return Integer.compare(weightB, weightA);
// If same weight, sort by value (descending)
return Integer.compare(b, a);
private int getWeight(int num, int k) {
int count = 0;
while (num % k == 0 && num != 0) {
count++;
num /= k;
return count;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Input: array size
System.out.print("Enter the number of elements: ");
int n = scanner.nextInt();
int[] arr = new int[n];
// Input: array elements
System.out.println("Enter the elements: ");
for (int i = 0; i < n; i++) {
arr[i] = scanner.nextInt();
// Input: k value
System.out.print("Enter the value of k: ");
int k = scanner.nextInt();
// Convert to List for sorting
List<Integer> list = new ArrayList<>();
for (int num : arr) {
list.add(num);
// Sort using custom comparator
Collections.sort(list, new WeightComparator(k));
// Output sorted array
System.out.println("Sorted array based on descending weights:");
for (int num : list) {
System.out.print(num + " ");
}
Sample input
Enter the number of elements: 6
Enter the elements: 8 12 15 20 30 25
Enter the value of k: 5
Sample output:
Step-by-Step Calculation of Weights:
8 → Not divisible by 5, weight = 0.
12 → Not divisible by 5, weight = 0.
15 → Divisible by 5 once, weight = 1.
20 → Divisible by 5 once, weight = 1.
30 → Divisible by 5 once, weight = 1.
25 → Divisible by 5 twice, weight = 2.
Sorted Order (Based on Weight & Descending Order of Values):
1. 25 (Weight 2)
2. 30 (Weight 1)
3. 20 (Weight 1)
4. 15 (Weight 1)
5. 12 (Weight 0)
6. 8 (Weight 0)
Output:
Sorted array based on descending weights:
25 30 20 15 12 8
Let's verify other numbers for k = 5:
Number Division Steps Weight
25 25 → 5 → 1 2
30 30 → 6 (stops) 1
20 20 → 4 (stops) 1
15 15 → 3 (stops) 1
12 Not divisible by 5 0
8 Not divisible by 5 0
Dividing Apples in Java
This Java program solves the problem of distributing apples among students evenly, ensuring
fairness. If apples cannot be evenly divided, the program will indicate the remainder.
1. Aim
To develop a Java program that:
Takes the number of apples and students as input.
Determines how many apples each student gets.
Determines how many apples are left unallocated if the division is not perfect.
2. Algorithm
1. Input the number of apples (A) and students (S).
2. Check for edge cases:
o If the number of students is zero, print an error message (division by zero is not
possible).
3. Calculate division:
o Each student receives A / S apples (integer division).
o The remaining apples are determined by A % S.
4. Output the results:
o If no remainder, print "Each student gets X apples."
o If there’s a remainder, print "Each student gets X apples, and Y apples remain."
Program
import java.util.Scanner;
public class DivideApples {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Taking input for number of apples and students
System.out.print("Enter the number of apples: ");
int apples = scanner.nextInt();
System.out.print("Enter the number of students: ");
int students = scanner.nextInt();
// Handling division by zero case
if (students == 0) {
System.out.println("Error: Cannot divide apples among zero students.");
} else {
int applesPerStudent = apples / students; // Apples each student gets
int remainingApples = apples % students; // Leftover apples
// Output the results
System.out.println("Each student gets " + applesPerStudent + " apples.");
if (remainingApples > 0) {
System.out.println(remainingApples + " apples remain unallocated.");
scanner.close();
5. Sample Input & Output
Example 1: Even Distribution
Input:
Enter the number of apples: 20
Enter the number of students: 5
Output:
Each student gets 4 apples.
(20 apples are evenly divided among 5 students.)
Example 2: Uneven Distribution
Input:
Enter the number of apples: 23
Enter the number of students: 4
Output:
Each student gets 5 apples.
3 apples remain unallocated.
(Each student gets 5 apples, but 3 are left over.)
Example 3: Zero Students (Edge Case)
Input:
Enter the number of apples: 10
Enter the number of students: 0
Output:
Error: Cannot divide apples among zero students.
(Division by zero is not allowed.)