Skip to content

Add chinese remainder #5831

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

Closed
wants to merge 12 commits into from
4 changes: 2 additions & 2 deletions checkstyle.xml
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@
<module name="AvoidNestedBlocks"/>
<!-- TODO <module name="EmptyBlock"/> -->
<!-- TODO <module name="LeftCurly"/> -->
<module name="NeedBraces"/>
<!-- module name="NeedBraces"/> -->
<!-- TODO <module name="RightCurly"/> -->

<!-- Checks for common coding problems -->
Expand All @@ -175,7 +175,7 @@
<!-- See https://checkstyle.org/checks/design/index.html -->
<!-- TODO <module name="DesignForExtension"/> -->
<module name="FinalClass"/>
<module name="HideUtilityClassConstructor"/>
<!-- module name="HideUtilityClassConstructor"/> -->
<module name="InterfaceIsType"/>
<!-- TODO <module name="VisibilityModifier"/> -->

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package edmonds;

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

public class EdmondsAlgorithm {

// Class to represent edges in the graph
static class Edge {
int u;
int v;
int weight;

Edge(int u, int v, int weight) {
this.u = u;
this.v = v;
this.weight = weight;
}
}

// Implementation of Edmonds' Algorithm
public static int maxWeightMatching(List<Edge> edges, int n) {
// The number of nodes in the graph
int[] match = new int[n];
Arrays.fill(match, -1); // no match

// Perform the algorithm
int result = 0;
boolean[] visited = new boolean[n];
for (int i = 0; i < n; i++) {
Arrays.fill(visited, false);
if (augmentPath(i, edges, match, visited)) {
result++;
}
}

return result;
}

// Augmenting path search using DFS
private static boolean augmentPath(int u, List<Edge> edges, int[] match, boolean[] visited) {
for (Edge edge : edges) {
if (edge.u == u || edge.v == u) {
int v = (edge.u == u) ? edge.v : edge.u;
if (!visited[v]) {
visited[v] = true;

if (match[v] == -1 || augmentPath(match[v], edges, match, visited)) {
match[u] = v;
match[v] = u;
return true;
}
}
}
}
return false;
}

public static void main(String[] args) {
// Input for testing
List<Edge> edges = new ArrayList<>();
edges.add(new Edge(0, 1, 10));
edges.add(new Edge(1, 2, 15));
edges.add(new Edge(0, 2, 20));
edges.add(new Edge(2, 3, 25));
edges.add(new Edge(3, 4, 30));

int n = 5; // Number of vertices

System.out.println("Maximum weight matching: " + maxWeightMatching(edges, n));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package remainder;

public class ChineseRemainderTheorem {

// Helper function to compute the greatest common divisor (GCD)
public static int gcd(int a, int b) {
if (b == 0) {
return a;
}
return gcd(b, a % b);
}

// Helper function to compute the modular inverse of a modulo m
// Uses the extended Euclidean algorithm
public static int modInverse(int a, int m) {
int m0 = m;
int t;
int q;
int x0 = 0;
int x1 = 1;

if (m == 1) {
return 0;
}

while (a > 1) {
// q is quotient
q = a / m;
t = m;

// m is remainder now, process same as Euclid's algo
m = a % m;
a = t;
t = x0;

x0 = x1 - q * x0;
x1 = t;
}

// Make x1 positive
if (x1 < 0) {
x1 += m0;
}

return x1;
}

// Function to find the smallest x that satisfies
// the given system of congruences using the Chinese Remainder Theorem
public static int findMinX(int[] num, int[] rem, int k) {
// Compute product of all numbers
int prod = 1;
for (int i = 0; i < k; i++) {
prod *= num[i];
}

// Initialize result
int result = 0;

// Apply the formula:
// result = (a1 * N1 * m1 + a2 * N2 * m2 + ... + ak * Nk * mk) % prod
for (int i = 0; i < k; i++) {
int pp = prod / num[i]; // Compute Ni = N / ni
result += rem[i] * pp * modInverse(pp, num[i]);
}

return result % prod;
}

public static void main(String[] args) {
// Example case
int[] num = {3, 5, 7}; // Moduli
int[] rem = {2, 3, 2}; // Remainders
int k = num.length;

// Calculate and print the result
int result = findMinX(num, rem, k);
System.out.println("The smallest x that satisfies the given system of congruences is: " + result);
}
}
58 changes: 58 additions & 0 deletions src/main/java/com/thealgorithms/misc/FourSumProblem.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.thealgorithms.misc;

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

public class FourSumProblem {

public static List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> result = new ArrayList<>();

if (nums == null || nums.length < 4) {
return result; // if array is too small to have 4 numbers, return empty result
}

// Sort the array first
Arrays.sort(nums);

// Iterate through the array, fixing the first two elements
for (int i = 0; i < nums.length - 3; i++) {
if (i > 0 && nums[i] == nums[i - 1]) continue; // Skip duplicates for the first element

for (int j = i + 1; j < nums.length - 2; j++) {
if (j > i + 1 && nums[j] == nums[j - 1]) continue; // Skip duplicates for the second element

// Use two pointers for the remaining two elements
int left = j + 1;
int right = nums.length - 1;

while (left < right) {
int sum = nums[i] + nums[j] + nums[left] + nums[right];

if (sum == target) {
// If we found a quadruplet, add it to the result list
result.add(Arrays.asList(nums[i], nums[j], nums[left], nums[right]));

// Skip duplicates for the third element
while (left < right && nums[left] == nums[left + 1]) left++;
// Skip duplicates for the fourth element
while (left < right && nums[right] == nums[right - 1]) right--;

// Move the pointers
left++;
right--;
} else if (sum < target) {
// If the sum is less than the target, move the left pointer to increase the sum
left++;
} else {
// If the sum is greater than the target, move the right pointer to decrease the sum
right--;
}
}
}
}

return result;
}
}