I was given a Codility test lately and I was wondering how can I negate -2 base numbers?
For example the array [1,0,0,1,1] represents 9 in base -2:
-2 bases:
1,-2,4,-8,16
1 + (-8) + 16 = 9
[1,0,0,1,1]
Negative 9 in base -2 is:
-2 bases:
1,-2,4,-8
1 + (-2) + -8 = -9
[1,1,0,1]
I'm in the dark regarding the question. There must be some intuitive solution for this. Do you have any hints?
In base −2, a 1 at position i means (−2)i.
So, a [1,1] in positions [i,i+1] means (−2)i + (−2)i+1 = (−2)i + (−2)(−2)i = (1 + −2)(−2)i = −(−2)i.
So you can negate any occurrence of a [1,0] by changing it to a [1,1], and vice versa.
Any other occurrences of 0, of course, can be left intact: −0 = 0.
So in your example, we split [1,0,0,1,1] into [{1,0}, {0}, {1,1}], negate each part to get [{1,1}, {0}, {1,0}], i.e., [1,1,0,1,0], and remove the unnecessary high 0, producing [1,1,0,1].
Let's try a few examples:
(16 -8 4 -2 1)
1 = 0 0 0 0 1
-1 = 0 0 0 1 1
2 = 0 0 1 1 0
-2 = 0 0 0 1 0
3 = 0 0 1 1 1
-3 = 0 1 1 0 1
4 = 0 0 1 0 0
-4 = 0 1 1 0 0
5 = 0 0 1 0 1
-5 = 0 1 1 1 1
We can try to define this mathematically:
Given input I(b) (where B is the bit number),
I = ∑(-2)bI(b) -- definition of base -2)
O = -I -- what we're trying to solve for
O = -∑(-2)bI(b) -- substitution
O = ∑-(-2)bI(b) -- distribution
-(-2)b = (-2)b + (-2)b+1
O = ∑((-2)b + (-2)b+1)I(b) -- substitution
O = ∑((-2)bI(b) + (-2)b+1I(b)) -- substitution
O = ∑(-2)bI(b) + ∑(-2)b+1I(b)
O(b) = I(b) + I(b-1)
Now, this leaves the possibility that O(b) is 0, 1, or 2, since I(b) is always 0 or 1.
If O(b) is a 2, that is a "carry", Let's look at a few examples of carries:
(16 -8 4 -2 1) (16 -8 4 -2 1)
1+1 = 0 0 0 0 2 = 0 0 1 1 0
-2-2 = 0 0 0 2 0 = 0 1 1 0 0
4+4 = 0 0 2 0 0 = 1 1 0 0 0
for each b, starting at 0, if O(b) >= 2, subtract 2 from O(b) and increment O(b+1) and O(b+2). Do this until you reach your maximum B.
Hopefully this explains it in enough detail.
Imagine you have a number A. Then -A = A - 2*A
Or -A = A + (-2)*A. Luckily you have base -2. And (-2)*A is equivalent to left shift by one digit. All you need now is just to implement A << 1 + A. Array shifting is easy. And then you need to implement binary addition with one small difference: each time you carry over a bit you need to multiply it by -1.
public int[] solution(int[] input)
{
var A = new int[input.Length + 1];
var B = new int[input.Length + 1];
input.CopyTo(B, 1);
input.CopyTo(A, 0);
return GetResult(A, B).ToArray();
}
public IEnumerable<int> GetResult(int[] A, int[] B)
{
var r = 0;
for (int i = 0; i < A.Length; i++)
{
var currentSum = A[i] + B[i] + r;
r = -currentSum / 2;
yield return currentSum % 2;
}
}
Sorry, but the example is in C#
Related
I am currently trying to make my chess engine faster, and am looking at implementing magic bitboards for my sliding piece attack generation. I am using a bitboard representation of the chessboard with the a1 square being the furthest right bit, and h8 being the furthest left. I am looking at this site:
https://rhysre.net/fast-chess-move-generation-with-magic-bitboards.html#:~:text=A%20bitboard%20is%20simply%20a,and%20bit%2063%20%3D%20h8)
Specifically the code snippet found towards the bottom of the page that reads:
U64 getBishopAttacksMagic(int square, U64 blockers) {
// Mask blockers to only include bits on diagonals
blockers &= BISHOP_MASKS[square];
// Generate the key using a multiplication and right shift
U64 key = (blockers * BISHOP_MAGICS[square]) >> (64 - BISHOP_INDEX_BITS[square]);
// Return the preinitialized attack set bitboard from the table
return BISHOP_TABLE[square][key];
}
I already have Shallow blues magic numbers(each number corresponding to a square), and I already have pre initialized attack masks for the bishop piece stored in a 64 length array(again each number corresponding to a square). So i know how to get the key. But how do I generate the last array which takes the key, "BISHOP_TABLE" array? I do not understand how to generate that 2d array given an attack mask and magic number for each square. Thank you for your help in advance.
For each square, you need to generate every permutation of blocking pieces inside the bishop mask. For example, using this mask for the square e4 (#28):
8 | 0 0 0 0 0 0 0 0
7 | 0 1 0 0 0 0 0 0
6 | 0 0 1 0 0 0 1 0
5 | 0 0 0 1 0 1 0 0
4 | 0 0 0 0 0 0 0 0
3 | 0 0 0 1 0 1 0 0
2 | 0 0 1 0 0 0 1 0
1 | 0 0 0 0 0 0 0 0
---------------
a b c d e f g h
since there are 9 set bits, there are 2^9 = 512 different patterns of blocking pieces. The permutation number 339 (as binary = 0b101010011) looks like this:
8 | 0 0 0 0 0 0 0 0
7 | 0 1 0 0 0 0 0 0
6 | 0 0 1 0 0 0 0 0
5 | 0 0 0 1 0 0 0 0
4 | 0 0 0 0 0 0 0 0
3 | 0 0 0 0 0 0 0 0
2 | 0 0 1 0 0 0 1 0
1 | 0 0 0 0 0 0 0 0
---------------
a b c d e f g h
Bits are read from right (lsb) to left (msb) in the number and are set in the mask from the a file to the h file, 1st rank to 8th. Permutation 0 is an empty board and 511 (0b111111111) is the full mask.
Here's a method that takes a permutation number along with the bishop mask and returns the corresponding blockers bitboard:
private static long blockersPermutation(int iteration, long mask) {
long blockers = 0;
while (iteration != 0) {
if ((iteration & 1) != 0) {
int shift = Long.numberOfTrailingZeros(mask);
blockers |= (1L << shift);
}
iteration >>>= 1;
mask &= (mask - 1); // used in Kernighan's bit count algorithm
// it pops out the least significant bit in the number
}
return blockers;
}
Using this we can calculate the keys with both the magic numbers and the blockers, and we can create their corresponding values, the attack masks.
For each permutation of blocking pieces, create the corresponding attack mask and store it in the table. Include the blocking pieces and the squares on the side of the board in the mask. The attack mask for the blockers #339 on square #28 is:
8 | 0 0 0 0 0 0 0 0
7 | 0 0 0 0 0 0 0 1
6 | 0 0 0 0 0 0 1 0
5 | 0 0 0 1 0 1 0 0
4 | 0 0 0 0 0 0 0 0
3 | 0 0 0 1 0 1 0 0
2 | 0 0 1 0 0 0 1 0
1 | 0 0 0 0 0 0 0 0
---------------
a b c d e f g h
Here's a Java method to initialize the 64 bishop lookup tables:
private final long[][] BISHOP_LOOKUP = new long[64][512];
private static int getFile(int square) {
return square % 8;
}
private static int getRank(int square) {
return square / 8;
}
private static int getSquare(int rank, int file) {
return rank * 8 + file;
}
// just like the code snippet, generates the key
private static int transform (long blockers, long magic, int shift) {
return (int) ((blockers * magic) >>> (64 - shift));
}
private void initBishopLookup() {
for (int square = 0; square < 64; square++) {
long mask = BISHOP_MASKS[square];
int permutationCount = (1 << Long.bitCount(mask));
for (int i = 0; i < permutationCount; i++) {
long blockers = blockersPermutation(i, mask);
long attacks = 0L;
int rank = getRank(square), r;
int file = getFile(square), f;
for (r = rank + 1, f = file + 1; r <= 7 && f <= 7; r++, f++) {
attacks |= (1L << getSquare(r, f));
if ((blockers & (1L << getSquare(r, f))) != 0) {
break;
}
}
for (r = rank - 1, f = file + 1; r >= 0 && f <= 7; r--, f++) {
attacks |= (1L << getSquare(r, f));
if ((blockers & (1L << getSquare(r, f))) != 0) {
break;
}
}
for (r = rank - 1, f = file - 1; r >= 0 && f >= 0; r--, f--) {
attacks |= (1L << getSquare(r, f));
if ((blockers & (1L << getSquare(r, f))) != 0) {
break;
}
}
for (r = rank + 1, f = file - 1; r <= 7 && f >= 0; r++, f--) {
attacks |= (1L << getSquare(r, f));
if ((blockers & (1L << getSquare(r, f))) != 0) {
break;
}
}
int key = transform(blockers, BISHOP_MAGICS[square], Long.bitCount(mask));
BISHOP_LOOKUP[square][key] = attacks;
}
}
}
This uses plain magic bitboards with fixed size lookup tables, all of length 512 when masks with less set bits could fit in less space. Like on square b1 the mask uses 5 bits on the diagonal and the table could fit in an array of length 2^5 = 32. We're wasting (512 - 32) * (8 bytes per 64 bits number) / 1024 bytes per Kio = 3.75Kio for this square. Plain magic bitboards take 2Mib of memory for rooks and 256Kib for bishops, using fancy magic bitboards can reduce the total to ~800Kib. It's not really needed though, 2.25Mib of memory is small.
I was given a task during an interview, where I was given a matrix, now I need to generate another matrix out of it using below formula:
Given matrix A[R][C], generate B[R][C]
val = 0;
for (i = 0; i ≤ xPosition; i += 1) {
for (j = 0; j ≤ yPosition; j += 1) {
val = val + a(i, j);
}
}
B(xPosition,yPosition) = val;
I have come up with below code:
public List<List<Integer>> generate(List<List<Integer>> A) {
List<List<Integer>> top = new ArrayList<>();
for (int i = 0; i < A.size(); i++) {
List<Integer> inner = new ArrayList<>();
for (int j = 0; j < A.get(0).size(); j++) {
inner.add(generateValue(A, i, j));
}
top.add(inner);
}
return top;
}
int generateValue(List<List<Integer>> A, int xPosition, int yPosition) {
int val = 0;
for (int i = 0; i <= xPosition; i++) {
for (int j = 0; j <= yPosition; j++) {
int value = A.get(i).get(j);
val += value;
}
}
return val;
}
Sample input :
1 2 3
4 5 6
Output :
1 3 6
5 12 21
How to improve the performance of this logic?
mathematicaly for your solution in array b,each element is related to it's previous one.
to improve your code / optimise it you need to see this relation.
so for every B[i][j] is related to it's previous element and value from the array A.
below is solution mathematically,
b[i][j] = b[i-1][j] + a[i][0]+a[i][1] + a[i][2]+...+a[i][y-1]
for so if you able to implement this, your code will pass all test cases
i am not a java dev, but if you want code, i can write it for you in python
The key is to think of this as a dynamic programming problem, assuming that we have already calculated B[x][y] for all 0 <= x < i, 0 <= y < j when we go to calculate B[i][j].
B[i][j] contains the sum of all elements in the submatrix of A that starts at 0, 0 and ends at i, j. Thus B[i-1][j] will contain the sum of the all the elements in this submatrix except the ones in the ith row. Similarly, B[i][j-1] will contain the sum of the all the elements in this submatrix except the ones in the jth column. Adding these two together, we get the sum of all the elements in the submatrix except for element A[i][j]. However, while doing this we count all the elements from 0, 0 to i-1, j-1 twice, and we have to subtract their sum (which is B[i-1][j-1]) once so that we only sum them up once in total. Then we add the missing element, A[i][j]. Hence
B[i][j] = B[i-1][j] + B[i][j-1] - B[i-1][j-1] + A[i][j]
This recursion can now be implemented as a O(RC) dynamic programming algorithm.
To help understand this further, consider the following figure representing the submatrix for which we have to find the sum of the elements. The figure is a matrix C[i][j], where the x, yth element is the number of times we have summed A[x][y]. In terms of C[i][j], our end goal (B[i][j]) is
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
B[i-1][j] corresponds to the matrix C[i-1][j], which is
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
0 0 0 0 0
B[i][j-1] corresponds to the matrix C[i][j-1], which is
1 1 1 1 0
1 1 1 1 0
1 1 1 1 0
1 1 1 1 0
B[i-1][j] + B[i][j-1] corresponds to the matrix C[i-1][j] + C[i][j-1], which is
2 2 2 2 1
2 2 2 2 1
2 2 2 2 1
1 1 1 1 0
B[i-1][j] + B[i][j-1] - B[i-1][j-1] corresponds to the matrix C[i-1][j] + C[i][j-1] - C[i-1][j-1], which is
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 0
Now B[i-1][j] + B[i][j-1] - B[i-1][j-1] + A[i][j] corresponds to
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
which is the same as B[i][j].
So let's say that I have an array of zeroes, where the number 1 occasionally occurs.
For example, let's say I have the following array:
0 1 1 0 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 0 1 1 0 0 1 0
The output I am trying to get is the following descriptions about the positions of the number 1:
Every 5th starting with 2
Every 11th starting with 3
Every 7th starting with 0
We can see that if we start with an array of zeroes:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Then we add a 1 every 5th number starting with 2:
0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0
Then we add a 1 every 11th number starting with 3:
0 1 1 0 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 0 0 1 0 0 1 0
Then we add a 1 every 7th number starting with 0:
0 1 1 0 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 0 1 1 0 0 1 0
We get the array that we started out with.
One obvious thing is that there is more than one set of instructions that result in this array. For example, instead of the third instruction Every 7th starting with 0, we could have stated the instruction Every 21st starting with 0, or Every 1000000th starting with 21. Therefore, an obvious solution for this problem is to find each location of 1, and make each instruction Every [large number]th starting with [a certain position of 1].
However, I am looking for an algorithm that can find the most optimal, or close to the most optimal, set of instructions that gives the locations of the 1's in the array.
Based on its applications and input, the discrete Fourier transform looks promising; however, since it gives a pair of numbers for each value in the array, this doesn't seem very efficient.
So, are there any algorithms out there (perhaps in the Fourier family?) that can help me do this?
Thank you!
EDIT - for clarification, I don't care about the length of the array. Feel free to pad it with zeroes to the nearest power of two, or anything else.
EDIT 2 - if needed, feel free to make a rule of removing a 1. For instance, Remove every 6th starting with 4 would also work.
The following program uses rules that have a start and an end. The rules are allowed to overlap, so that a 1 could be used in 2 or more rules. It would be very easy to modify the code if that isn't what you want.
If the number of 1s is small it should be very fast, but it won't scale well.
It isn't very "clever". All it does is aim to knock out as many ones at each stage as possible. This approach is not optimal but it should be very good in most cases. For example, if you start with
1 1 1 1 1 0 1 1 1 1 1
the first rule found is
Every 2th, starting at 1, ending at 11.
because it uses six ones. However, the best solution clearly needs only two rules involving five 1s. I think it would be very difficult to find an efficient algorithm that always finds the best answer.
public static void main(String[] args) {
rulesFor(0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0);
}
public static void rulesFor(int... arr) {
Set<Integer> allOnes = new HashSet<>();
for (int i = 0; i < arr.length; i++)
if (arr[i] == 1)
allOnes.add(i);
// Size 1 has to be done separately as the below code wouldn't work.
if (allOnes.size() == 1) {
int a = allOnes.iterator().next();
System.out.println("Every 1st, starting at " + (a + 1) + ", ending at " + (a + 1) + ".");
return;
}
Set<Integer> leftToRemove = new HashSet<>(allOnes);
while (!leftToRemove.isEmpty()) {
int low = -1;
int high = -1;
int d = -1;
int removeTotal = -1;
for (int a : leftToRemove) {
for (int b : allOnes) {
if (b == a)
continue;
int d2 = Math.abs(b - a);
int low2 = a;
int high2 = a;
int removeTotal2 = 1;
while (true) {
if (!allOnes.contains(low2 - d2))
break;
low2 -= d2;
if (leftToRemove.contains(low2))
removeTotal2++;
}
while (true) {
if (!allOnes.contains(high2 + d2))
break;
high2 += d2;
if (leftToRemove.contains(high2))
removeTotal2++;
}
if (removeTotal2 > removeTotal) {
low = low2;
high = high2;
removeTotal = removeTotal2;
d = d2;
}
}
}
System.out.println("Every " + d + "th, starting at " + (low + 1) + ", ending at " + (high + 1) + ".");
for (int i = low; i <= high; i += d)
leftToRemove.remove(i);
}
}
I have a file with some values in it:
11
8
0 0 1 0 0 0 0 0 1 0 0
0 0 0 1 0 0 0 1 0 0 0
0 0 1 1 1 1 1 1 1 0 0
0 1 1 0 1 1 1 0 1 1 0
1 1 1 1 1 1 1 1 1 1 1
1 0 1 1 1 1 1 1 1 0 1
1 0 1 0 0 0 0 0 1 0 1
0 0 0 1 1 0 1 1 0 0 0
I need to read those values into a 2D ArrayList. The fist two values (11 and 8) would be the number of rows and columns respectively. So here is the code:
Scanner scanner = new Scanner(file);
int x, y;
x = scanner.nextInt();
System.out.println(x + " has been read");
y = scanner.nextInt();
System.out.println(y + " has been read");
ArrayList<ArrayList<Boolean>> pixelMap;
pixelMap = new ArrayList<ArrayList<Boolean>>();
ArrayList<Boolean> buffer_line = new ArrayList<Boolean>();
Boolean buffer;
for (int i = 0; i < x; i++){
for (int j = 0; j < y; j++){
buffer = scanner.nextBoolean();
System.out.println(buffer + " has been read");
//buffer_line.add(buffer);
}
//pixelMap.add(buffer_line);
//buffer_line.clear();
}
The problem is - the program reads first two numbers successfully, and when it comes to boolean values, it throws InputMismatch exception on line
buffer = scanner.nextBoolean();
so I can't undersand why. 0 should be read next and it is boolean - so what's actually mismatching?
I also point out that if change buffer type to integer and then assign scanner.nextInt(), the program would read all the values properly, so in the output I would see all of them. So then of course, I can change ArrayList to Integer to make that work, but it would be semantically wrong as it would hold only boolean values.
Can anyone help me to find out the problem?
In your code you have this statement:
buffer = scanner.nextBoolean();
But I do not see boolean values true or false in the input file.
In Java, 0 and 1 are not treated as boolean values like in other languages such as C.
You need to read these values as int and then manually map them to boolean values.
Logic something like this:
int val = scanner.nextInt();
boolean buffer = (val == 1) ? true : false;
I have been trying to implement the following formula
the formula is as follows
summation(from i = 1 to i = K) (M choose i) * i! * StirlingNumberOfSeconfType(N,i)
for the constraints
1 ≤ N ≤ 1000
1 ≤ M ≤ 1000000
1 ≤ K ≤ 1000
but I am failing to get results for large inputs can anyone provide me an efficient implementation of the formula ?
You can try using a double (or a "long double" if you use C or C++ on gcc) to avoid failing for the larger results.
EDIT: Read the question more carefully
Efficient stirling 2nd numbers calculation (question title is misleading I know but read it): https://mathoverflow.net/questions/34151/simple-efficient-representation-of-stirling-numbers-of-the-first-kind
Use http://gmplib.org/ to avoid the overflows.
I recently implemented this using BigInteger. I have the methods as static as it is part of a utility class for my project, change them as you will.
explanations from here:
Stirling Numbers of the second kind
Binomial Coefficient
Rounding is carried out to remove inaccuracies from limitations of variables.
note: BigInteger should only be used if necessary. I am having to calculate the number of combinations possible in arrays of possible maximum long possible, hence I believe BigInteger is required for accuracies in my calculations. If you do not need this accuracy, switch to long.
Comments should explain the code:
/**
* calculates the sterling number of {n k}
*
* #param n
* #param k
* #return
*/
public static BigDecimal SterlingNumber(int n, int k) {
//return 1 or 0 for special cases
if(n == k){
return BigDecimal.ONE;
} else if(k == 0){
return BigDecimal.ZERO;
}
//calculate first coefficient
BigDecimal bdCoefficient = BigDecimal.ONE.divide(new BigDecimal(UtilityMath.factorial(k)), MathContext.DECIMAL64);
//define summation
BigInteger summation = BigInteger.ZERO;
for (int i = 0; i <= k; i++) {
//combination amount = binomial coefficient
BigInteger biCombinationAmount = UtilityMath.getCombinationAmount(k, i, false, false);
//biN = i^n
BigInteger biN = BigInteger.valueOf(i).pow(n);
//plus this calculation onto previous calculation. 1/k! * E(-1^(k-j) * (k, j) j^n)
summation = summation.add(BigInteger.valueOf(-1).pow(k - i).multiply(biCombinationAmount).multiply(biN));
}
return bdCoefficient.multiply(new BigDecimal(summation)).setScale(0, RoundingMode.UP);
}
/**
* get combinations amount where repetition(1:1) is not allowed; and Order
* does not matter (both 1:2 and 2:1 are the same). Otherwise known as
* Bionomial coefficient [1] .
*
* #param iPossibleObservations number of possible observations.
* #param iPatternLength length of each pattern (number of outcomes we are
* selecting. According to [1], if patternLength is 0 or the same as
* iPossibleObservations, this method will return 1
* #return the combination amount where repetition is not allowed and order
* is not taken into consideration.
* #see [1]http://en.wikipedia.org/wiki/Binomial_coefficient
*/
public static BigInteger getCombinationAmountNoRepNoOrder(int iPossibleObservations, int iPatternLength) {
if (iPatternLength == 0 || iPatternLength == iPossibleObservations) {
return BigInteger.ONE;
}
BigInteger biNumOfCombinations;
BigInteger biPossibleObservationsFactorial = factorial(iPossibleObservations);
BigInteger biPatternLengthFactorial = factorial(iPatternLength);
BigInteger biLastFactorial = factorial(iPossibleObservations - iPatternLength);
biNumOfCombinations = biPossibleObservationsFactorial.divide(biPatternLengthFactorial.multiply(biLastFactorial));
return biNumOfCombinations;
}
From this main
public static void main(String[] args) {
System.out.print("\t" + " ");
for (int i = 0; i <= 10; i++) {
System.out.print("\t" + i);
}
System.out.print("\n");
for (int i = 0; i <= 10; i++) {
System.out.print("\t" + i);
for (int j = 0; j <= 10; j++) {
int n = i;
int k = j;
if (k > i) {
System.out.print("\t0");
continue;
}
BigDecimal biSterling = UtilityMath.SterlingNumber(n, k);
System.out.print("\t" + biSterling.toPlainString());
}
System.out.print("\n");
}
}
I have output:
0 1 2 3 4 5 6 7 8 9 10
0 1 0 0 0 0 0 0 0 0 0 0
1 0 1 0 0 0 0 0 0 0 0 0
2 0 1 1 0 0 0 0 0 0 0 0
3 0 1 3 1 0 0 0 0 0 0 0
4 0 1 7 7 1 0 0 0 0 0 0
5 0 1 5 26 11 1 0 0 0 0 0
6 0 1 31 91 66 15 1 0 0 0 0
7 0 1 63 302 351 140 22 1 0 0 0
8 0 1 127 967 1702 1050 267 28 1 0 0
9 0 1 255 3026 7771 6951 2647 462 36 1 0
10 0 1 511 9331 34106 42525 22828 5880 750 451 1