Why is my memoized calculation failing? - algorithm

I am trying to turn a two dimensional recursion problem into a dynamic programming problem. But the results are different.
Here is the code:
import edu.princeton.cs.algs4.*;
import java.util.Arrays;
public class Test {
public static double binomial(int N, int k, double p) {
if(N == 0 && k == 0) return 1.0;
if(N < 0 || k < 0) return 0.0;
return (1 - p)*binomial(N-1, k, p) + p*binomial(N-1, k-1, p);
}
public static double binomialm(int N, int k, double p) {
if(N < 0 || k < 0) return 0.0;
double[][] memory = new double[N+1][k+1];
memory[0][0] = 1.0;
memory[1][0] = 1 - p;
memory[0][1] = 0.0;
for(int i = 1; i <= N; i++) {
for(int j = 1; j <= k; j++) {
memory[i][j] = (1 - p)*memory[i-1][j] + p*memory[i-1][j-1];
}
}
return memory[N][k];
}
static public void main(String args[]) {
long stime, stime1, etime, etime1;
double r, r1;
stime = System.currentTimeMillis();
r = binomial(10, 5, 0.25);
etime = System.currentTimeMillis();
System.out.println("Regular binomial: result = " + r + ", time = " + (etime - stime));
stime1 = System.currentTimeMillis();
r1 = binomialm(10, 5, 0.25);
etime1 = System.currentTimeMillis();
System.out.println("Memoized binomial: result = " + r1 + ", time = " + (etime1 - stime1));
}
}
I really cannot figure out why the results are different. Here they are:
Regular binomial: result = 0.058399200439453125, time = 0
Memoized binomial: result = 0.045421600341796875, time = 0
Is there some floating point magic that I am missing?

In your memoized version, your inner loop starts from j = 1. Therefore, the values for (2,0), (3,0), (4,0), ... are never changed, they are all still 0.0 from the creation of the double array. They are supposed to be 1.0, -1.0, 1.0, ...
for(int i = 1; i <= N; i++) {
memory[i][0] = (1 - p)*memory[i-1][0];
for(int j = 1; j <= k; j++) {
memory[i][j] = (1 - p)*memory[i-1][j] + p*memory[i-1][j-1];
}
}

Related

time complexity of expected cost of optimal BST

import java.util.Scanner;
public class Main {
public static int optimalBst(int[] keys, int[] p, int[] q) {
int n = keys.length;
int[][] w = new int[n + 1][n + 1];
int[][] cost = new int[n + 1][n + 1];
for (int i = 0; i <= n; i++) {
w[i][i] = q[i];
cost[i][i] = 0;
}
for (int i = 1; i <= n; i++) {
int j = i - 1;
w[j][i] = w[j][i - 1] + p[i] + q[i];
cost[j][i] = w[j][i];
}
// sum of probabilities
for (int gap = 2; gap <= n; gap++) {
int i = 0;
int j = i + gap;
while (i <= n) {
int k = i;
while (j <= n) {
if (i != j) {
if (w[k][j] == 0) {
w[k][j] = w[k][j - 1] + p[j] + q[j];
}
}
j = j + 1;
k = k + 1;
}
i = i + 1;
}
}
// expected cost of optimal BST
for (int gap = 2; gap <= n; gap++) {
int i = 0;
int j = i + gap;
while (i <= n) {
int k = i;
while (j <= n) {
if (i != j) {
if (cost[k][j] == 9999) {
for (int r = k + 1; r < j; r++) {
int c = cost[k][j];
cost[k][j] = cost[k][r - 1] + cost[r][j] + w[k][j];
if (cost[k][j] > c) {
cost[k][j] = c;
}
}
}
}
j = j + 1;
k = k + 1;
}
i = i + 1;
}
}
return cost[0][n];
}
public static void main(String[] args) {
int[] keys = {10, 20, 30, 40};
int[] probSuccess = {0, 3, 3, 1, 1};
int[] probFailure = {2, 3, 1, 1, 1};
System.out.println("Cost of Optimal BST is: " + optimalBst(keys, probSuccess, probFailure));
}
}
I am trying to figure out what is the time complexity of above program. I am confused would the TC=O(n^3) or TC =O(n^4). In the for loop below the comment expected cost of optimal BST , we can find 2 nested while loops and 1 for loop with range(k+1 to j) inside a for loop whose range is from 2 to n+1. My confusion is whether the loop with range (k+1 to j) runs O(n) times or O(1) times.
Please help me to figure this out and also if anyone has better program for expected cost of optimal BST with successful and unsuccessful probabilities.

Finding number of pairs, product of whose indices is divisible by another number X

Given an array and some value X, find the number of pairs such that i < j , a[i] = a[j] and (i * j) % X == 0
Array size <= 10^5
I am thinking of this problem for a while but only could come up with the brute force solution(by checking all pairs) which will obviously time-out [O(N^2) time complexity]
Any better approach?
First of all, store separate search structures for each distinct A[i] as we iterate.
i * j = k * X
i = k * X / j
Let X / j be some fraction. Since i is an integer, k would be of the form m * least_common_multiple(X, j) / X, where m is natural.
Example 1: j = 20, X = 60:
lcm(60, 20) = 60
matching `i`s would be of the form:
(m * 60 / 60) * 60 / 20
=> m * q, where q = 3
Example 2: j = 6, X = 2:
lcm(2, 6) = 6
matching `i`s would be of the form:
(m * 6 / 2) * 2 / 6
=> m * q, where q = 1
Next, I would consider how to efficiently query the number of multiples of a number in a sorted list of arbitrary naturals. One way is to hash the frequency of divisors of each i we add to the search structure of A[i]. But first consider i as j and add to the result the count of divisors q that already exist in the hash map.
JavaScript code with brute force testing at the end:
function gcd(a, b){
return b ? gcd(b, a % b) : a;
}
function getQ(X, j){
return X / gcd(X, j);
}
function addDivisors(n, map){
let m = 1;
while (m*m <= n){
if (n % m == 0){
map[m] = -~map[m];
const l = n / m;
if (l != m)
map[l] = -~map[l];
}
m += 1;
}
}
function f(A, X){
const Ais = {};
let result = 0;
for (let j=1; j<A.length; j++){
if (A[j] == A[0])
result += 1;
// Search
if (Ais.hasOwnProperty(A[j])){
const q = getQ(X, j);
result += Ais[A[j]][q] || 0;
// Initialise this value's
// search structure
} else {
Ais[A[j]] = {};
}
// Add divisors for j
addDivisors(j, Ais[A[j]]);
}
return result;
}
function bruteForce(A, X){
let result = 0;
for (let j=1; j<A.length; j++){
for (let i=0; i<j; i++){
if (A[i] == A[j] && (i*j % X) == 0)
result += 1;
}
}
return result;
}
var numTests = 1000;
var n = 100;
var m = 50;
var x = 100;
for (let i=0; i<numTests; i++){
const A = [];
for (let j=0; j<n; j++)
A.push(Math.ceil(Math.random() * m));
const X = Math.ceil(Math.random() * x);
const _brute = bruteForce(A, X);
const _f = f(A, X);
if (_brute != _f){
console.log("Mismatch!");
console.log(X, JSON.stringify(A));
console.log(_brute, _f);
break;
}
}
console.log("Done testing.")
Just in case If someone needed the java version of this answer - https://stackoverflow.com/a/69690416/19325755 explanation has been provided in that answer.
I spent lot of time in understanding the javascript code so I thought the people who are comfortable with java can refer this for better understanding.
import java.util.HashMap;
public class ThisProblem {
public static void main(String[] args) {
int t = 1000;
int n = 100;
int m = 50;
int x = 100;
for(int i = 0; i<t; i++) {
int[] A = new int[n];
for(int j = 0; j<n; j++) {
A[j] = ((int)Math.random()*m)+1;
}
int X = ((int)Math.random()*x)+1;
int optR = createMaps(A, X);
int brute = bruteForce(A, X);
if(optR != brute) {
System.out.println("Wrong Answer");
break;
}
}
System.out.println("Test Completed");
}
public static int bruteForce(int[] A, int X) {
int result = 0;
int n = A.length;
for(int i = 1; i<n; i++) {
for(int j = 0; j<i; j++) {
if(A[i] == A[j] && (i*j)%X == 0)
result++;
}
}
return result;
}
public static int gcd(int a, int b) {
return b==0 ? a : gcd(b, a%b);
}
public static int getQ(int X, int j) {
return X/gcd(X, j);
}
public static void addDivisors(int n, HashMap<Integer, Integer> map) {
int m = 1;
while(m*m <= n) {
if(n%m == 0) {
map.put(m, map.getOrDefault(m, 0)+1);
int l = n/m;
if(l != m) {
map.put(l, map.getOrDefault(l, 0)+1);
}
}
m++;
}
}
public static int createMaps(int[] A, int X) {
int result = 0;
HashMap<Integer, HashMap<Integer, Integer>> contentsOfA = new HashMap<>();
int n = A.length;
for(int i = 1; i<n; i++) {
if(A[i] == A[0])
result++;
if(contentsOfA.containsKey(A[i])) {
int q = getQ(X, i);
result += contentsOfA.get(A[i]).getOrDefault(q, 0);
} else {
contentsOfA.put(A[i], new HashMap<>());
}
addDivisors(i, contentsOfA.get(A[i]));
}
return result;
}
}

Probability of stay in matrix

You are given a matrix of order (M x N). You can move in 4 directions: left, top, right and bottom. You are given initial position (x, y) and number of steps which you can move from the given location. While moving if you go out of the matrix, you are disqualified from the game. What is the probability that you are not disqualified?
I solved the question in the following two ways:
Way 1. Find out total ways say T1 in which you will be inside the matrix and find out total ways T2 in which you will be out of the matrix. Then return T1 / (T1 + T2) as the result.
Way 2. Use the fact that probability of reaching your neighbor is: 1/4 as you can move only in 4 directions from the given position and calculate the result.
But the two approaches are giving different results in many scenarios.
Please find my code below and do let me know where I am mistaken or if there is fault in the approaches.
public class ProbabilityOfStay {
private int[] x = {0, 1, 0, -1};
private int[] y = {-1, 0, 1, 0};
private int ROW;
private int COL;
private int xPos;
private int yPos;
private int steps ;
int[][][] stayDP = null;
int[][][] nonStayDP = null;
float[][][] sp = null;
public ProbabilityOfStay(int R, int C, int x, int y, int steps)
{
this.ROW = R;
this.COL = C;
this.xPos = x;
this.yPos = y;
this.steps = steps;
stayDP = new int[ROW][COL][steps];
nonStayDP = new int[ROW][COL][steps];
sp = new float[ROW][COL][steps];
this.initializeInt(stayDP, -1);
this.initializeInt(nonStayDP, -1);
this.initializeF(sp, -1);
}
private void initializeInt(int[][][] M, int d)
{
for(int i = 0; i < ROW; i++)
{
for(int j = 0; j < COL; j++)
{
for(int k = 0; k < steps; k++)
M[i][j][k] = d;
}
}
}
private void initializeF(float[][][] M, int d)
{
for(int i = 0; i < ROW; i++)
{
for(int j = 0; j < COL; j++)
{
for(int k = 0; k < steps; k++)
M[i][j][k] = d;
}
}
}
private int getTotalStayPath()
{
int p = getStayPaths(xPos, yPos, steps);
return p;
}
private int getStayPaths(int xp, int yp, int s)
{
if(xp < 0 || xp >= ROW || yp < 0 || yp >= COL)
return 0;
if(s == 0)
return 1;
if(stayDP[xp][yp][s-1] != -1)
return stayDP[xp][yp][s-1];
int ans = 0;
for(int i = 0; i < x.length; i++)
{
ans += getStayPaths(xp + x[i], yp + y[i], s-1);
}
return (stayDP[xp][yp][s-1] = ans);
}
private int getTotalNonStayPath()
{
int p = getNonStayPaths(xPos, yPos, steps);
return p;
}
private int getNonStayPaths(int xp, int yp, int s)
{
if(xp < 0 || xp >= ROW || yp < 0 || yp >= COL)
return 1;
if(s == 0)
return 0;
if(nonStayDP[xp][yp][s-1] != -1)
return nonStayDP[xp][yp][s-1];
int ans = 0;
for(int i = 0; i < x.length; i++)
{
ans += getNonStayPaths(xp + x[i], yp + y[i], s - 1);
}
return (nonStayDP[xp][yp][s-1] = ans);
}
private float getStayProbabilityM()
{
float p = getProbability(xPos, yPos, steps);
return p;
}
private float getProbability(int xp, int yp, int s)
{
if(xp < 0 || xp >= ROW || yp < 0 || yp >= COL)
return 0;
if(s == 0)
return 1;
if(sp[xp][yp][s-1] != -1)
return sp[xp][yp][s-1];
float ans = 0.0f;
for(int i = 0; i < x.length; i++)
{
ans += (getProbability(xp + x[i], yp + y[i], s-1)) / 4.0;
}
return (sp[xp][yp][s-1] = ans);
}
public static void main(String[] args)
{
int ROW = 7, COL = 7, x = 3, y = 5, steps = 3; //(x, y) is your position in the matrix.
ProbabilityOfStay pos = new ProbabilityOfStay(ROW, COL, x, y, steps);
int totalStayPaths = pos.getTotalStayPath(); //number of ways in which you can stay in the matrix.
int totalNonStayPaths = pos.getTotalNonStayPath(); ////number of ways in which you can't stay in the matrix.
float stayingProbability = (totalStayPaths / (float)(totalStayPaths + totalNonStayPaths));
float sP_memorization = pos.getStayProbabilityM();
System.out.println("Total stay paths: " + totalStayPaths + ", total non-stay paths: " + totalNonStayPaths + ", Stay probability: " + stayingProbability);
System.out.println("Total probability memoriation: " + sP_memorization);
}
}
If I run the program it prints:
Total stay paths: 56, total non-stay paths: 5
However, this results in a total number of paths of 56+5=61.
There are 4 choices at each of 3 steps, so the total should be 4*4*4 = 64.
I think the issue is that you stop counting as soon as the path goes off the board. This means that the paths are not of equal probability so your calculation by dividing the number of paths is not valid.
If you change the computation to:
float stayingProbability = (totalStayPaths / (float)Math.pow(4,steps));
it prints matching answers.

Maximum product prefix string

The following is a demo question from a coding interview site called codility:
A prefix of a string S is any leading contiguous part of S. For example, "c" and "cod" are prefixes of the string "codility". For simplicity, we require prefixes to be non-empty.
The product of prefix P of string S is the number of occurrences of P multiplied by the length of P. More precisely, if prefix P consists of K characters and P occurs exactly T times in S, then the product equals K * T.
For example, S = "abababa" has the following prefixes:
"a", whose product equals 1 * 4 = 4,
"ab", whose product equals 2 * 3 = 6,
"aba", whose product equals 3 * 3 = 9,
"abab", whose product equals 4 * 2 = 8,
"ababa", whose product equals 5 * 2 = 10,
"ababab", whose product equals 6 * 1 = 6,
"abababa", whose product equals 7 * 1 = 7.
The longest prefix is identical to the original string. The goal is to choose such a prefix as maximizes the value of the product. In above example the maximal product is 10.
Below is my poor solution in Java requiring O(N^2) time. It is apparently possible to do this in O(N). I was thinking Kadanes algorithm. But I can't think of any way that I can encode some information at each step that lets me find the running max. Can any one think of an O(N) algorithm for this?
import java.util.HashMap;
class Solution {
public int solution(String S) {
int N = S.length();
if(N<1 || N>300000){
System.out.println("Invalid length");
return(-1);
}
HashMap<String,Integer> prefixes = new HashMap<String,Integer>();
for(int i=0; i<N; i++){
String keystr = "";
for(int j=i; j>=0; j--) {
keystr += S.charAt(j);
if(!prefixes.containsKey(keystr))
prefixes.put(keystr,keystr.length());
else{
int newval = prefixes.get(keystr)+keystr.length();
if(newval > 1000000000)return 1000000000;
prefixes.put(keystr,newval);
}
}
}
int maax1 = 0;
for(int val : prefixes.values())
if(val>maax1)
maax1 = val;
return maax1;
}
}
Here's a O(n log n) version based on suffix arrays. There are O(n) construction algorithms for suffix arrays, I just don't have the patience to code them.
Example output (this output isn't O(n), but it's only to show that we can indeed compute all the scores):
4*1 a
3*3 aba
2*5 ababa
1*7 abababa
3*2 ab
2*4 abab
1*6 ababab
Basically you have to reverse the string, and compute the suffix array (SA) and the longest common prefix (LCP).
Then you have traverse the SA array backwards looking for LCPs that match the entire suffix (prefix in the original string). If there's a match, increment the counter, otherwise reset it to 1. Each suffix (prefix) receive a "score" (SCR) that corresponds to the number of times it appears in the original string.
#include <iostream>
#include <cstring>
#include <string>
#define MAX 10050
using namespace std;
int RA[MAX], tempRA[MAX];
int SA[MAX], tempSA[MAX];
int C[MAX];
int Phi[MAX], PLCP[MAX], LCP[MAX];
int SCR[MAX];
void suffix_sort(int n, int k) {
memset(C, 0, sizeof C);
for (int i = 0; i < n; i++)
C[i + k < n ? RA[i + k] : 0]++;
int sum = 0;
for (int i = 0; i < max(256, n); i++) {
int t = C[i];
C[i] = sum;
sum += t;
}
for (int i = 0; i < n; i++)
tempSA[C[SA[i] + k < n ? RA[SA[i] + k] : 0]++] = SA[i];
memcpy(SA, tempSA, n*sizeof(int));
}
void suffix_array(string &s) {
int n = s.size();
for (int i = 0; i < n; i++)
RA[i] = s[i] - 1;
for (int i = 0; i < n; i++)
SA[i] = i;
for (int k = 1; k < n; k *= 2) {
suffix_sort(n, k);
suffix_sort(n, 0);
int r = tempRA[SA[0]] = 0;
for (int i = 1; i < n; i++) {
int s1 = SA[i], s2 = SA[i-1];
bool equal = true;
equal &= RA[s1] == RA[s2];
equal &= RA[s1+k] == RA[s2+k];
tempRA[SA[i]] = equal ? r : ++r;
}
memcpy(RA, tempRA, n*sizeof(int));
}
}
void lcp(string &s) {
int n = s.size();
Phi[SA[0]] = -1;
for (int i = 1; i < n; i++)
Phi[SA[i]] = SA[i-1];
int L = 0;
for (int i = 0; i < n; i++) {
if (Phi[i] == -1) {
PLCP[i] = 0;
continue;
}
while (s[i + L] == s[Phi[i] + L])
L++;
PLCP[i] = L;
L = max(L-1, 0);
}
for (int i = 1; i < n; i++)
LCP[i] = PLCP[SA[i]];
}
void score(string &s) {
SCR[s.size()-1] = 1;
int sum = 1;
for (int i=s.size()-2; i>=0; i--) {
if (LCP[i+1] < s.size()-SA[i]-1) {
sum = 1;
} else {
sum++;
}
SCR[i] = sum;
}
}
int main() {
string s = "abababa";
s = string(s.rbegin(), s.rend()) +".";
suffix_array(s);
lcp(s);
score(s);
for(int i=0; i<s.size(); i++) {
string ns = s.substr(SA[i], s.size()-SA[i]-1);
ns = string(ns.rbegin(), ns.rend());
cout << SCR[i] << "*" << ns.size() << " " << ns << endl;
}
}
Most of this code (specially the suffix array and LCP implementations) I have been using for some years in contests. This version in special I adapted from this one I wrote some years ago.
public class Main {
public static void main(String[] args) {
String input = "abababa";
String prefix;
int product;
int maxProduct = 0;
for (int i = 1; i <= input.length(); i++) {
prefix = input.substring(0, i);
String substr;
int occurs = 0;
for (int j = prefix.length(); j <= input.length(); j++) {
substr = input.substring(0, j);
if (substr.endsWith(prefix))
occurs++;
}
product = occurs*prefix.length();
System.out.println("product of " + prefix + " = " +
prefix.length() + " * " + occurs +" = " + product);
maxProduct = (product > maxProduct)?product:maxProduct;
}
System.out.println("maxProduct = " + maxProduct);
}
}
I was working on this challenge for more than 4 days , reading a lot of documentation, I found a solution with O(N) .
I got 81%, the idea is simple using a window slide.
def solution(s: String): Int = {
var max = s.length // length of the string
var i, j = 1 // start with i=j=1 ( is the beginning of the slide and j the end of the slide )
val len = s.length // the length of the string
val count = Array.ofDim[Int](len) // to store intermediate results
while (i < len - 1 || j < len) {
if (i < len && s(0) != s(i)) {
while (i < len && s(0) != s(i)) { // if the begin of the slide is different from
// the first letter of the string skip it
i = i + 1
}
}
j = i + 1
var k = 1
while (j < len && s(j).equals(s(k))) { // check for equality and update the array count
if (count(k) == 0) {
count(k) = 1
}
count(k) = count(k) + 1
max = math.max((k + 1) * count(k), max)
k = k + 1
j = j + 1
}
i = i + 1
}
max // return the max
}

Fast code to determine if any two subsets of columns have the same sum

For a given n and m I iterate over all n by m partial circulant matrices with entries that are either 0 or 1. I want to find if there is a matrix such that there are no two subsets of the columns that give the same sum. Here when we add columns we just do it elementwise. My current code uses constraint programming via ortools. However it is not as fast I would like. For n = 7 and m = 12 it takes over 3 minutes and for n = 10, m = 18 it doesn't terminate even though there are only 2^18 = 262144 different matrices to consider. Here is my code.
from scipy.linalg import circulant
import numpy as np
import itertools
from ortools.constraint_solver import pywrapcp as cs
n = 7
m = 12
def isdetecting(matrix):
X = np.array([solver.IntVar(values) for i in range(matrix.shape[1])])
X1 = X.tolist()
for row in matrix:
x = X[row].tolist()
solver.Add(solver.Sum(x) == 0)
db = solver.Phase(X1, solver.INT_VAR_DEFAULT, solver.INT_VALUE_DEFAULT)
solver.NewSearch(db)
count = 0
while (solver.NextSolution() and count < 2):
solution = [x.Value() for x in X1]
count += 1
solver.EndSearch()
if (count < 2):
return True
values = [-1,0,1]
solver = cs.Solver("scip")
for row in itertools.product([0,1],repeat = m):
M = np.array(circulant(row)[0:n], dtype=bool)
if isdetecting(M):
print M.astype(int)
break
Can this problem be solved fast enough so that n = 10, m = 18 can be solved?
One problem is that you are declaring the "solver" variable globally and it seems to confuse or-tools to reuse it many times. When moving it inside "isdetecting", then the (7,12) problem is solved much faster, in about 7 seconds (compared to 2:51 minutes for the original model). I haven't checked it for the larger problem, though.
Also, it might be good idea to test different labelings (instead of solver.INT_VAR_DEFAULT and solver.INT_VALUE_DEFAULT), though binary value tend to be not very sensitive to different labelings. See the code for another labeling.
def isdetecting(matrix):
solver = cs.Solver("scip") # <----
X = np.array([solver.IntVar(values) for i in range(matrix.shape[1])])
X1 = X.tolist()
for row in matrix:
x = X[row].tolist()
solver.Add(solver.Sum(x) == 0)
# db = solver.Phase(X1, solver.INT_VAR_DEFAULT, solver.INT_VALUE_DEFAULT)
db = solver.Phase(X1, solver.CHOOSE_FIRST_UNBOUND, solver.ASSIGN_CENTER_VALUE)
solver.NewSearch(db)
count = 0
while (solver.NextSolution() and count < 2):
solution = [x.Value() for x in X1]
count += 1
solver.EndSearch()
if (count < 2):
print "FOUND"
return True
Edit: Here are constraints to remove the all-0 solutions as mentioned in the comments. What I know of, it require a separate list. It now takes a little longer (10.4s vs 7s).
X1Abs = [solver.IntVar(values, 'X1Abs[%i]' % i) for i in range(X1_len)]
for i in range(X1_len):
solver.Add(X1Abs[i] == abs(X1[i]))
solver.Add(solver.Sum(X1Abs) > 0)
Something like this is what I had in mind. I'd estimate the running time for command line parameters 10 18 at less than 8 hours on my machine.
public class Search {
public static void main(String[] args) {
int n = Integer.parseInt(args[0]);
int m = Integer.parseInt(args[1]);
int row = search(n, m);
if (row >= 0) {
printRow(m, row);
}
}
private static int search(int n, int m) {
if (n < 0 || m < n || m >= 31 || powOverflows(m + 1, n)) {
throw new IllegalArgumentException();
}
long[] column = new long[m];
long[] sums = new long[1 << m];
int row = 1 << m;
while (row-- > 0) {
System.err.println(row);
for (int j = 0; j < m; j++) {
column[j] = 0;
for (int i = 0; i < n; i++) {
column[j] = (column[j] * (m + 1)) + ((row >> ((i + j) % m)) & 1);
}
}
for (int subset = 0; subset < (1 << m); subset++) {
long sum = 0;
for (int j = 0; j < m; j++) {
if (((subset >> j) & 1) == 1) {
sum += column[j];
}
}
sums[subset] = sum;
}
java.util.Arrays.sort(sums);
boolean duplicate = false;
for (int k = 1; k < (1 << m); k++) {
if (sums[k - 1] == sums[k]) {
duplicate = true;
break;
}
}
if (!duplicate) {
break;
}
}
return row;
}
private static boolean powOverflows(long b, int e) {
if (b <= 0 || e < 0) {
throw new IllegalArgumentException();
}
if (e == 0) {
return false;
}
long max = Long.MAX_VALUE;
while (e > 1) {
if (b > Integer.MAX_VALUE) {
return true;
}
if ((e & 1) == 1) {
max /= b;
}
b *= b;
e >>= 1;
}
return b > max;
}
private static void printRow(int m, int row) {
for (int j = 0; j < m; j++) {
System.out.print((row >> j) & 1);
}
System.out.println();
}
}

Resources