Skip to content
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

Implement Sher Lock and Cost Problem. #5169

Closed
wants to merge 12 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package com.thealgorithms.datastructures.graphs;

import java.util.ArrayList;
import java.util.List;

public final class MultistageGraph {

private MultistageGraph() {
}
private int k; // number of partitions (k > 2)

// Adjacency list to store edges between different stages
public List<List<Integer>> adjacencyList;

public MultistageGraph(int k) {
this.k = k;
this.adjacencyList = new ArrayList<>();

// Initialize the adjacency list with empty lists for each stage
for (int i = 0; i < k; i++) {
adjacencyList.add(new ArrayList<>());
}
}

public void addEdge(int fromStage, int toStage) throws IllegalArgumentException {
if (!isValidStageNumber(fromStage)) {
throw new IllegalArgumentException("Invalid stage number: " + fromStage);
}

if (!isValidStageNumber(toStage)) {
throw new IllegalArgumentException("Invalid stage number: " + toStage);
}

// Check if the edge exists between the given stages, and add it if not
if (adjacencyList.get(fromStage - 1).contains(toStage)) {
System.out.println("Edge already exists between stage " + fromStage + " and stage " + toStage);
} else {
adjacencyList.get(fromStage - 1).add(toStage);
System.out.println("Added edge between stage " + fromStage + " and stage " + toStage);
}
}

private boolean isValidStageNumber(int stage) {
return (stage >= 1 && stage <= k);
}

public void printGraph() {
System.out.println("Multistage Graph:");

for (int i = 0; i < k; i++) {
System.out.print(i + " -> ");

for (Integer adjacentStage : adjacencyList.get(i)) {
if (!adjacentStage.equals(i)) {
System.out.println(" -> " + adjacentStage);
}
}
}
}

public static void main(String[] args) {
MultistageGraph graph = new MultistageGraph(4); // Create a multistage graph with k = 4 partitions

try {
graph.addEdge(1, 2);
graph.addEdge(1, 3);
graph.addEdge(2, 3);
graph.printGraph();
} catch (IllegalArgumentException e) {
System.out.println("Error: " + e.getMessage());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/**
* This class contains a method to solve the Sherlock and Cost problem using dynamic programming.
* The problem is to find the maximum possible sum of absolute differences between adjacent elements in an array.
*
* @author gowtham sankar gunasekaran
*/

package com.thealgorithms.dynamicprogramming;

import java.util.List;

public final class SherLockAndCost {
private SherLockAndCost() {
}

/**
* This method takes a list of integers as input and returns the maximum possible sum of absolute differences between adjacent elements in the array.
*
* @param list the input list of integers
* @return the maximum possible sum of absolute differences between adjacent elements in the array
* <p></p>
* Approach:
* I can use dynamic programming to solve this problem efficiently. Let’s break down the approach:
* <p>
* 1.) Initialize two arrays: dp[i][0] and dp[i][1]. These arrays will store the maximum sum of absolute differences for the first i elements of the input array.
* 2.) Iterate through the input array from left to right:
* Update dp[i][0] and dp[i][1] based on the previous values and the current element.
* 3.) The final answer is the maximum value between dp[N-1][0] and dp[N-1][1].
* 4.) The time complexity of this method is O(N), where N is the length of the input list.
*/
public static int sherlockAndCostProblem(List<Integer> list) {

if (list == null || list.isEmpty()) {
return 0;
}

int N = list.size();
int[][] dp = new int[N][2];
dp[0][0] = 0;
dp[0][1] = 0;

for (int i = 1; i < N; i++) {
int curr = list.get(i);
int prev = list.get(i - 1);

dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prev - 1);
dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] + curr - 1);
}

return Math.max(dp[N - 1][0], dp[N - 1][1]);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.thealgorithms.datastructures.graphs;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.Arrays;
import java.util.List;
import org.junit.jupiter.api.Test;

public class MultistageGraphTest {

@Test
public void testAddEdge_invalidFromStage() {
MultistageGraph graph = new MultistageGraph(3);

assertThrows(IllegalArgumentException.class, () -> graph.addEdge(0, 2));
}

@Test
public void testAddEdge_invalidToStage() {
MultistageGraph graph = new MultistageGraph(3);

assertThrows(IllegalArgumentException.class, () -> graph.addEdge(1, 4));
}

@Test
public void testAddEdge_edgeAlreadyExists() {
MultistageGraph graph = new MultistageGraph(3);

graph.addEdge(1, 2);
graph.addEdge(1, 2); // Attempt to add the same edge again

List<Integer> expectedAdjacentStages = Arrays.asList(2);
assertEquals(expectedAdjacentStages, graph.adjacencyList.get(0));
}

@Test
public void testAddEdge_printsSuccessMessage() {
MultistageGraph graph = new MultistageGraph(3);

// Capture the standard output stream
ByteArrayOutputStream outputStreamCaptor = new ByteArrayOutputStream();
System.setOut(new PrintStream(outputStreamCaptor));

graph.addEdge(1, 2);

String expectedOutput = "Added edge between stage 1 and stage 2\r\n";
assertEquals(expectedOutput, outputStreamCaptor.toString());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.thealgorithms.dynamicprogramming;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

import java.util.Arrays;
import java.util.List;
import org.junit.jupiter.api.Test;

public class SherLockAndCostTest {

@Test
public void testPositiveIntegers() {
List<Integer> inputList = Arrays.asList(1, 2, 3, 4, 5);
int result = SherLockAndCost.sherlockAndCostProblem(inputList);
assertEquals(8, result);
}

@Test
public void testNegativeInteger() {
List<Integer> list = Arrays.asList(-1, -2, -3, -4, -5);
int result = SherLockAndCost.sherlockAndCostProblem(list);
assertEquals(0, result);
}

@Test
public void testMixedElements() {
List<Integer> list = Arrays.asList(-1, 1);
int result = SherLockAndCost.sherlockAndCostProblem(list);
assertEquals(0, result);
}

@Test
public void testEdge() {
List<Integer> list = Arrays.asList(-1, 2, 3, 4, 5);
int result = SherLockAndCost.sherlockAndCostProblem(list);
assertEquals(8, result);
}

@Test
public void testNullElements() {
List<Integer> list = Arrays.asList(null, null, null, null);
assertThrows(NullPointerException.class, () -> SherLockAndCost.sherlockAndCostProblem(list));
}

@Test
public void testEmptyList() {
List<Integer> list = Arrays.asList();
int result = SherLockAndCost.sherlockAndCostProblem(list);
assertEquals(0, result);
}

@Test
public void testSingleFList() {
List<Integer> list = Arrays.asList(500);
int result = SherLockAndCost.sherlockAndCostProblem(list);
assertEquals(0, result);
}
}
Loading