I am currently working on writing a method that adds two polynomials (given by 2 text files) together. So for example:
4.0x^5 + -2.0x^3 + 2.0x + 3.0
&
8.0x^4 + 4.0x^3 + -3.0x + 9.0
would result in: 4.0x^5 + 8.0x^4 + 2.0x^3 - 1.0x + 12
Currently, my method creates a new polynomial object, but only adds the terms in which there is a degree match. So my output looks like this:
2.0x^3 - 1.0x + 12
It is missing the first two terms, because the degrees don't match up. Here is my code (important: Polynomial is initially constructed by Node poly = null; -- so the variable poly is a node that points to the front of the Linked List of the polynomial):
public Polynomial add(Polynomial p) {
Polynomial answer = new Polynomial();
for (Node firstPoly = poly; firstPoly != null; firstPoly = firstPoly.next){
for (Node secondPoly = p.poly; secondPoly != null; secondPoly = secondPoly.next){
if (firstPoly.term.degree == secondPoly.term.degree){
answer = addToRear(answer, (firstPoly.term.coeff + secondPoly.term.coeff), firstPoly.term.degree, null);
if (answer.poly.term.coeff == 0){
answer.poly = null;
}
}
}
}
return answer;
}
I'm not asking anyone to solve this for me, but does anyone have any idea what I would do next to make sure the non-matching degrees get added? I've been trying to work it out on paper, but nothing is working out for various reasons. Here is the addToRear method just in case it'll be useful to you guys.
private Polynomial addToRear(Polynomial p, float coeff, int degree, Node next){
if (p.poly == null){
p.poly = new Node(coeff, degree, null);
return p;
}
for (Node temp = p.poly; temp != null; temp = temp.next){
if (temp.next == null){
temp.next = new Node(coeff, degree, null);
return p;
}
}
return p;
}
Thank you.
It's probably easier to ensure that a polynomial data structure includes all powers, including those with zero multipliers. In other words, the polynomial 2.0x3 - 1.0x + 12 would be represented as the collection:
pwr 0 1 2 3
---- ---- ---- ----
{ 12.0, 1.0, 0.0, 2.0 }
Unless you're talking about large numbers of polynomials and massive powers for the high-end terms, the non-sparseness of this solution should be mostly irrelevant.
As you can see, I've also changed the order so that the x0 (constant) term is first in the list since, assuming your polynomials don't have negative powers, this will also ease the adding effort. This is because the matching powers will then have matching indexes in the collection.
So, to add together the two polynomials:
4.0x5 - 2.0x3 + 2.0x + 3.08.0x4 + 4.0x3 - 3.0x + 9.0
that would be akin to:
pwr 0 1 2 3 4 5
---- ---- ---- ---- ---- ----
{ 3.0, 2.0, 0.0, -2.0, 0.0, 4.0 }
+ { 9.0, -3.0, 0.0, 4.0, 8.0 }
----------------------------------------
= { 12.0, -1.0, 0.0, 2.0, 8.0, 4.0 }
which gives, as desired (ignoring zero multipliers when outputting)
4.0x5 + 8.0x4 + 2.0x3 - 1.0x + 12.0
If, for some reason, you must work on sparse linked lists, then it depends on whether the terms are sorted based on the power.
If they're not, you will generally have to use an algorithm like:
set poly3 to empty
# Process all in poly1, including those in poly2.
foreach term1 in poly1:
find term2 in poly2 with matching power
if none:
add (term1.coeff, term1.power) to poly3
else:
add (term1.coeff + term2.coeff, term1.power) to poly3
# Process all in poly2, but NOT in poly1.
foreach term2 in poly2:
find term1 in poly1 with matching power
if none:
add (term2.coeff, term2.power) to poly3
This will first add all powers in the first polynomial, including those that have an entry in the second.
It will then add those in the second that don't have a corresponding term in the first. That way, all terms are added correctly.
If the terms are sorted, you can make it a little more efficient by processing the lists in parallel (similar to a merge algorithm), at each stage getting the term from the list with the highest unprocessed power, something like:
set poly3 to empty
set term1 to poly1.head
set term2 to poly2.head
# Process both until at least one runs out.
while term1 != null and term2 != null:
if term1.power == term2.power:
add (term1.coeff + term2.coeff, term1.power) to poly3
term1 = term1.next
term2 = term2.next
elif term1.power > term2.power:
add (term1.coeff, term1.power) to poly3
term1 = term1.next
else:
add (term2.coeff, term2.power) to poly3
term2 = term2.next
# Process remaining single list, if any.
while term1 != null:
add (term1.coeff, term1.power) to poly3
term1 = term1.next
while term2 != null:
add (term2.coeff, term2.power) to poly3
term2 = term2.next
As a proof of concept, here's some Python code which does the sorted variant. The bulk of the code is turning a string into a "list" (actually a power-sparse array) and printing out the resultant polynomial. The meat of the solution is in the main line, starting at poly3 = []:
poly1 = '4.0x^5 - 2.0x^3 + 2.0x + 3.0'
poly2 = '8.0x^4 + 4.0x^3 + -3.0x + 9.0'
# Makes component extraction from array easier.
coeff = 0
power = 1
def baseline(s):
# Remove spaces, normalise to all '+'.
check = s + ' '
result = s
while result != check:
check = result
result = result.replace(' ','');
result = result.replace('-','+-')
result = result.replace('++','+')
# Create array of terms.
result = result.split('+')
# Make each term a coefficient/power pair.
for i in range(len(result)):
result[i] = result[i].split('^')
if len(result[i]) == 1 and result[i][coeff].endswith('x'):
result[i].append('1')
if len(result[i]) == 1 and not result[i][coeff].endswith('x'):
result[i].append('0')
if result[i][coeff].endswith('x'):
result[i][coeff] = result[i][coeff][:-1]
result[i][coeff] = float(result[i][coeff])
result[i][power] = int(result[i][power])
return result
def polyprint(s,p):
print()
print(s, p, end=':\n ')
if len(p) > 0:
print(p[0][coeff],end='')
if p[0][power] == 1:
print('x',end='')
elif p[0][power] > 1:
print('x^%d' % (p[0][power]),end='')
for i in range(1,len(p)):
if p[i][coeff] < 0:
print(' -',-p[i][coeff],end='')
else:
print(' +',p[i][coeff],end='')
if p[i][power] == 1:
print('x',end='')
elif p[i][power] > 1:
print('x^%d' % (p[i][power]),end='')
print()
# Turn polynomials into sparse (based on powers) array.
poly1 = baseline(poly1)
poly2 = baseline(poly2)
polyprint('poly1',poly1)
polyprint('poly2',poly2)
# Add them as per sorted algorithm.
poly3 = []
idx1 = 0
idx2 = 0
while idx1 < len(poly1) and idx2 < len(poly2):
if poly1[idx1][power] == poly2[idx2][power]:
if poly1[idx1][coeff] != poly2[idx2][coeff]:
poly3.append([poly1[idx1][coeff] + poly2[idx2][coeff], poly1[idx1][power]])
idx1 += 1
idx2 += 1
continue
if poly1[idx1][power] > poly2[idx2][power]:
poly3.append([poly1[idx1][coeff], poly1[idx1][power]])
idx1 += 1
continue
poly3.append([poly2[idx2][coeff], poly2[idx2][power]])
idx2 += 1
while idx1 < len(poly1):
poly3.append([poly1[idx1][coeff], poly1[idx1][power]])
idx1 += 1
while idx2 < len(poly2):
poly3.append([poly2[idx2][coeff], poly2[idx2][power]])
idx2 += 1
polyprint('poly3',poly3)
Take the maximum degree of either polynomial, and set all missing terms to zero. That is, x^2 = 0x^3 + 1x^2 + 0x^1 + 0x^0. (As a side note, a real implementation for numeric computing would represent polynomials in nested form, to minimize the loss of precision from adding after multiplication.)
Related
I'm working on an implementation of the Karatsuba algorithm of multiplying numbers, but unlike most implementations using Strings as the primary data structure instead of BigNumbers or longs. I've written a recursive solution to the problem that appears to work for all n < 6, but for some reason it fails to work for odd ns greater than 6, despite all of the base cases working. Here's the karatsuba part of the program, with a few prints left behind from debugging. All of the methods used in this should work as intended, I tested them thoroughly. For a value factor1 = "180" and factor2 = "109", the correct result is outputted. For a value factor1 = "1111" and factor2 = "1111" the correct result is outputted. For a factor1 = "2348711" and factor2 = "8579294" the program outputs "20358060808034" when it should output "20150282190034". I've tried backtracing the logic, and I can't find where exactly it goes wrong. If anyone has any insight as to where something may not work, any help is appreciated.
public static String multiply(String factor1, String factor2) {
// base case of length = 1
System.out.println("Factor1 " + factor1 + " factor2 " + factor2);
if (factor1.length() == 1 && factor2.length() == 1) {
return smallNumberMultiplication(factor1, factor2);
} else if (factor1.length() == 1 && factor2.length() == 2) { //these conditions needed for odd-size #s
return smallNumberMultiplication(factor1, factor2); // max iteration = 10
} else if (factor1.length() == 2 && factor2.length() == 1) {
return smallNumberMultiplication(factor2, factor1); // max iteration = 10
}
// check which factor is smaller, find the index at which the value is split
int numberLength = factor1.length();
int middleIndex = numberLength / 2;
// Find the power to which 10 is raised such that it follows Karatsuba's algorithm for ac
int powerValue = numberLength + numberLength % 2;
// divide both numbers into two parts bounded by middleIndex place
String[] tempSplitString = splitString(factor1, middleIndex);
String f1Large = tempSplitString[0], f1Small = tempSplitString[1];
tempSplitString = splitString(factor2, middleIndex);
String f2Large = tempSplitString[0], f2Small = tempSplitString[1];
String multiplyHighestNumbers, multiplySmallestNumbers, multiplyMiddleNumbers;
// large factor1 * large factor2
multiplyHighestNumbers = multiply(f1Large, f2Large);
// Multiply (f1Large + f1Small)*(f2Large + f2Small)
multiplyMiddleNumbers = multiply(addTwoValues(f1Large, f1Small), addTwoValues(f2Large, f2Small));
// small factor1 * small factor2
multiplySmallestNumbers = multiply(f1Small, f2Small);
// add trailing zeros to values (multiply by 10^powerValue)
String finalHighestNumber = addTrailingZeros(multiplyHighestNumbers, powerValue);
String finalMiddleNumber = addTrailingZeros(
subtractTwoValues(subtractTwoValues(multiplyMiddleNumbers, multiplyHighestNumbers),
multiplySmallestNumbers),
powerValue / 2);
String finalSmallestNumber = multiplySmallestNumbers;
// add each part together
return removeLeadingZeros(addTwoValues(addTwoValues(finalHighestNumber, finalMiddleNumber), finalSmallestNumber));
}
I noticed two problems:
using different values for splitting (middleIndex) and shifting (powerValue) (needlessly implemented by tacking on zeroes).
For productHighParts("multiplyHighestNumbers") to be closer in length to the other products, use (factor1.length() + factor2.length()) / 4 (half the average length of both factors).
this length has to be the length of the less significant part in splitString(), not the leading part.
(Note that the first two controlled statements can be combined:
if (factor1.length() <= 1 && factor2.length() <= 2).)
I have an array of operations and a target number.
The operations could be
+ 3
- 3
* 4
/ 2
I want to find out how close I can get to the target number by using those operations.
I start from 0 and I need to iterate through the operations in that order, and I can choose to either use the operation or not use it.
So if the target number is 13, I can use + 3 and * 4 to get 12 which is the closest I can get to the target number 13.
I guess I need to compute all possible combinations (I guess the number of calculations is thus 2^n where n is the number of operations).
I have tried to do this in java with
import java.util.*;
public class Instruction {
public static void main(String[] args) {
// create scanner
Scanner sc = new Scanner(System.in);
// number of instructions
int N = sc.nextInt();
// target number
int K = sc.nextInt();
//
String[] instructions = new String[N];
// N instructions follow
for (int i=0; i<N; i++) {
//
instructions[i] = sc.nextLine();
}
//
System.out.println(search(instructions, 0, N, 0, K, 0, K));
}
public static int search(String[] instructions, int index, int length, int progressSoFar, int targetNumber, int bestTarget, int bestDistance) {
//
for (int i=index; i<length; i++) {
// get operator
char operator = instructions[i].charAt(0);
// get number
int number = Integer.parseInt(instructions[i].split("\\s+")[1]);
//
if (operator == '+') {
progressSoFar += number;
} else if (operator == '*') {
progressSoFar *= number;
} else if (operator == '-') {
progressSoFar -= number;
} else if (operator == '/') {
progressSoFar /= number;
}
//
int distance = Math.abs(targetNumber - progressSoFar);
// if the absolute distance between progress so far
// and the target number is less than what we have
// previously accomplished, we update best distance
if (distance < bestDistance) {
bestTarget = progressSoFar;
bestDistance = distance;
}
//
if (true) {
return bestTarget;
} else {
return search(instructions, index + 1, length, progressSoFar, targetNumber, bestTarget, bestDistance);
}
}
}
}
It doesn't work yet, but I guess I'm a little closer to solving my problem. I just don't know how to end my recursion.
But maybe I don't use recursion, but should instead just list all combinations. I just don't know how to do this.
If I, for instance, have 3 operations and I want to compute all combinations, I get the 2^3 combinations
111
110
101
011
000
001
010
100
where 1 indicates that the operation is used and 0 indicates that it is not used.
It should be rather simple to do this and then choose which combination gave the best result (the number closest to the target number), but I don't know how to do this in java.
In pseudocode, you could try brute-force back-tracking, as in:
// ops: list of ops that have not yet been tried out
// target: goal result
// currentOps: list of ops used so far
// best: reference to the best result achieved so far (can be altered; use
// an int[1], for example)
// opsForBest: list of ops used to achieve best result so far
test(ops, target, currentOps, best, opsForBest)
if ops is now empty,
current = evaluate(currentOps)
if current is closer to target than best,
best = current
opsForBest = a copy of currentOps
otherwise,
// try including next op
with the next operator in ops,
test(opsAfterNext, target,
currentOps concatenated with next, best, opsForBest)
// try *not* including next op
test(opsAfterNext, target, currentOps, best, opsForBest)
This is guaranteed to find the best answer. However, it will repeat many operations once and again. You can save some time by avoiding repeat calculations, which can be achieved using a cache of "how does this subexpression evaluate". When you include the cache, you enter the realm of "dynamic programming" (= reusing earlier results in later computation).
Edit: adding a more OO-ish variant
Variant returning the best result, and avoiding the use of that best[] array-of-one. Requires the use of an auxiliary class Answer with fields ops and result.
// ops: list of ops that have not yet been tried out
// target: goal result
// currentOps: list of ops used so far
Answer test(ops, target, currentOps, opsForBest)
if ops is now empty,
return new Answer(currentOps, evaluate(currentOps))
otherwise,
// try including next op
with the next operator in ops,
Answer withOp = test(opsAfterNext, target,
currentOps concatenated with next, best, opsForBest)
// try *not* including next op
Answer withoutOp = test(opsAfterNext, target,
currentOps, best, opsForBest)
if withOp.result closer to target than withoutOp.target,
return withOp
else
return withoutOp
Dynamic programming
If the target value is t, and there are n operations in the list, and the largest absolute value you can create by combining some subsequence of them is k, and the absolute value of the product of all values that appear as an operand of a division operation is d, then there's a simple O(dkn)-time and -space dynamic programming algorithm that determines whether it's possible to compute the value i using some subset of the first j operations and stores this answer (a single bit) in dp[i][j]:
dp[i][j] = dp[i][j-1] || dp[invOp(i, j)][j-1]
where invOp(i, j) computes the inverse of the jth operation on the value i. Note that if the jth operation is a multiplication by, say, x, and i is not divisible by x, then the operation is considered to have no inverse, and the term dp[invOp(i, j)][j-1] is deemed to evaluate to false. All other operations have unique inverses.
To avoid loss-of-precision problems with floating point code, first multiply the original target value t, as well as all operands to addition and subtraction operations, by d. This ensures that any division operation / x we encounter will only ever be applied to a value that is known to be divisible by x. We will essentially be working throughout with integer multiples of 1/d.
Because some operations (namely subtractions and divisions) require solving subproblems for higher target values, we cannot in general calculate dp[i][j] in a bottom-up way. Instead we can use memoisation of the top-down recursion, starting at the (scaled) target value t*d and working outwards in steps of 1 in each direction.
C++ implementation
I've implemented this in C++ at https://ideone.com/hU1Rpq. The "interesting" part is canReach(i, j); the functions preceding this are just plumbing to handle the memoisation table. Specify the inputs on stdin with the target value first, then a space-separated list of operations in which operators immediately preceed their operand values, e.g.
10 +8 +11 /2
or
10 +4000 +5500 /1000
The second example, which should give the same answer (9.5) as the first, seems to be around the ideone (and my) memory limits, although this could be extended somewhat by using long long int instead of int and a 2-bit table for _m[][][] instead of wasting a full byte on each entry.
Exponential worst-case time and space complexity
Note that in general, dk or even just k by itself could be exponential in the size of the input: e.g. if there is an addition, followed by n-1 multiplication operations, each of which involves a number larger than 1. It's not too difficult to compute k exactly via a different DP that simply looks for the largest and smallest numbers reachable using the first i operations for all 1 <= i <= n, but all we really need is an upper bound, and it's easy enough to get a (somewhat loose) one: simply discard the signs of all multiplication operands, convert all - operations to + operations, and then perform all multiplication and addition operations (i.e., ignoring divisions).
There are other optimisations that could be applied, for example dividing through by any common factor.
Here's a Java 8 example, using memoization. I wonder if annealing can be applied...
public class Tester {
public static interface Operation {
public int doOperation(int cur);
}
static Operation ops[] = { // lambdas for the opertions
(x -> x + 3),
(x -> x - 3),
(x -> x * 4),
(x -> x / 2),
};
private static int getTarget(){
return 2;
}
public static void main (String args[]){
int map[];
int val = 0;
int MAX_BITMASK = (1 << ops.length) - 1;//means ops.length < 31 [int overflow]
map = new int[MAX_BITMASK];
map[0] = val;
final int target = getTarget();// To get rid of dead code warning
int closest = val, delta = target < 0? -target: target;
int bestSeq = 0;
if (0 == target) {
System.out.println("Winning sequence: Do nothing");
}
int lastBitMask = 0, opIndex = 0;
int i = 0;
for (i = 1; i < MAX_BITMASK; i++){// brute force algo
val = map[i & lastBitMask]; // get prev memoized value
val = ops[opIndex].doOperation(val); // compute
map[i] = val; //add new memo
//the rest just logic to find the closest
// except the last part
int d = val - target;
d = d < 0? -d: d;
if (d < delta) {
bestSeq = i;
closest = val;
delta = d;
}
if (val == target){ // no point to continue
break;
}
//advance memo mask 0b001 to 0b011 to 0b111, etc.
// as well as the computing operation.
if ((i & (i + 1)) == 0){ // check for 2^n -1
lastBitMask = (lastBitMask << 1) + 1;
opIndex++;
}
}
System.out.println("Winning sequence: " + bestSeq);
System.out.println("Closest to \'" + target + "\' is: " + closest);
}
}
Worth noting, the "winning sequence" is the bit representation (displayed as decimal) of what was used and what wasn't, as the OP has done in the question.
For Those of you coming from Java 7, this is what I was referencing for lambdas: Lambda Expressionsin GUI Applications. So if you're constrained to 7, you can still make this work quite easily.
I have the methods that do both the multiplication and addition, but I'm just not able to get my head around them. Both of them are from external websites and not my own:
public static void bitwiseMultiply(int n1, int n2) {
int a = n1, b = n2, result=0;
while (b != 0) // Iterate the loop till b==0
{
if ((b & 01) != 0) // Logical ANDing of the value of b with 01
{
result = result + a; // Update the result with the new value of a.
}
a <<= 1; // Left shifting the value contained in 'a' by 1.
b >>= 1; // Right shifting the value contained in 'b' by 1.
}
System.out.println(result);
}
public static void bitwiseAdd(int n1, int n2) {
int x = n1, y = n2;
int xor, and, temp;
and = x & y;
xor = x ^ y;
while (and != 0) {
and <<= 1;
temp = xor ^ and;
and &= xor;
xor = temp;
}
System.out.println(xor);
}
I tried doing a step-by-step debug, but it really didn't make much sense to me, though it works.
What I'm possibly looking for is to try and understand how this works (the mathematical basis perhaps?).
Edit: This is not homework, I'm just trying to learn bitwise operations in Java.
Let's begin by looking the multiplication code. The idea is actually pretty clever. Suppose that you have n1 and n2 written in binary. Then you can think of n1 as a sum of powers of two: n2 = c30 230 + c29 229 + ... + c1 21 + c0 20, where each ci is either 0 or 1. Then you can think of the product n1 n2 as
n1 n2 =
n1 (c30 230 + c29 229 + ... + c1 21 + c0 20) =
n1 c30 230 + n1 c29 229 + ... + n1 c1 21 + n1 c0 20
This is a bit dense, but the idea is that the product of the two numbers is given by the first number multiplied by the powers of two making up the second number, times the value of the binary digits of the second number.
The question now is whether we can compute the terms of this sum without doing any actual multiplications. In order to do so, we're going to need to be able to read the binary digits of n2. Fortunately, we can do this using shifts. In particular, suppose we start off with n2 and then just look at the last bit. That's c0. If we then shift the value down one position, then the last bit is c0, etc. More generally, after shifting the value of n2 down by i positions, the lowest bit will be ci. To read the very last bit, we can just bitwise AND the value with the number 1. This has a binary representation that's zero everywhere except the last digit. Since 0 AND n = 0 for any n, this clears all the topmost bits. Moreover, since 0 AND 1 = 0 and 1 AND 1 = 1, this operation preserves the last bit of the number.
Okay - we now know that we can read the values of ci; so what? Well, the good news is that we also can compute the values of the series n1 2i in a similar fashion. In particular, consider the sequence of values n1 << 0, n1 << 1, etc. Any time you do a left bit-shift, it's equivalent to multiplying by a power of two. This means that we now have all the components we need to compute the above sum. Here's your original source code, commented with what's going on:
public static void bitwiseMultiply(int n1, int n2) {
/* This value will hold n1 * 2^i for varying values of i. It will
* start off holding n1 * 2^0 = n1, and after each iteration will
* be updated to hold the next term in the sequence.
*/
int a = n1;
/* This value will be used to read the individual bits out of n2.
* We'll use the shifting trick to read the bits and will maintain
* the invariant that after i iterations, b is equal to n2 >> i.
*/
int b = n2;
/* This value will hold the sum of the terms so far. */
int result = 0;
/* Continuously loop over more and more bits of n2 until we've
* consumed the last of them. Since after i iterations of the
* loop b = n2 >> i, this only reaches zero once we've used up
* all the bits of the original value of n2.
*/
while (b != 0)
{
/* Using the bitwise AND trick, determine whether the ith
* bit of b is a zero or one. If it's a zero, then the
* current term in our sum is zero and we don't do anything.
* Otherwise, then we should add n1 * 2^i.
*/
if ((b & 1) != 0)
{
/* Recall that a = n1 * 2^i at this point, so we're adding
* in the next term in the sum.
*/
result = result + a;
}
/* To maintain that a = n1 * 2^i after i iterations, scale it
* by a factor of two by left shifting one position.
*/
a <<= 1;
/* To maintain that b = n2 >> i after i iterations, shift it
* one spot over.
*/
b >>>= 1;
}
System.out.println(result);
}
Hope this helps!
It looks like your problem is not java, but just calculating with binary numbers. Start of simple:
(all numbers binary:)
0 + 0 = 0 # 0 xor 0 = 0
0 + 1 = 1 # 0 xor 1 = 1
1 + 0 = 1 # 1 xor 0 = 1
1 + 1 = 10 # 1 xor 1 = 0 ( read 1 + 1 = 10 as 1 + 1 = 0 and 1 carry)
Ok... You see that you can add two one digit numbers using the xor operation. With an and you can now find out whether you have a "carry" bit, which is very similar to adding numbers with pen&paper. (Up to this point you have something called a Half-Adder). When you add the next two bits, then you also need to add the carry bit to those two digits. Taking this into account you can get a Full-Adder. You can read about the concepts of Half-Adders and Full-Adders on Wikipedia:
http://en.wikipedia.org/wiki/Adder_(electronics)
And many more places on the web.
I hope that gives you a start.
With multiplication it is very similar by the way. Just remember how you did multiplying with pen&paper in elementary school. Thats what is happening here. Just that it's happening with binary numbers and not with decimal numbers.
EXPLANATION OF THE bitwiseAdd METHOD:
I know this question was asked a while back but since no complete answer has been given regarding how the bitwiseAdd method works here is one.
The key to understanding the logic encapsulated in bitwiseAdd is found in the relationship between addition operations and xor and and bitwise operations. That relationship is defined by the following equation (see appendix 1 for a numeric example of this equation):
x + y = 2 * (x&y)+(x^y) (1.1)
Or more simply:
x + y = 2 * and + xor (1.2)
with
and = x & y
xor = x ^ y
You might have noticed something familiar in this equation: the and and xor variables are the same as those defined at the beginning of bitwiseAdd. There is also a multiplication by two, which in bitwiseAdd is done at the beginning of the while loop. But I will come back to that later.
Let me also make a quick side note about the '&' bitwise operator before we proceed further. This operator basically "captures" the intersection of the bit sequences against which it is applied. For example, 9 & 13 = 1001 & 1101 = 1001 (=9). You can see from this result that only those bits common to both bit sequences are copied to the result. It derives from this that when two bit sequences have no common bit, the result of applying '&' on them yields 0. This has an important consequence on the addition-bitwise relationship which shall become clear soon
Now the problem we have is that equation 1.2 uses the '+' operator whereas bitwiseAdd doesn't (it only uses '^', '&' and '<<'). So how do we make the '+' in equation 1.2 somehow disappear? Answer: by 'forcing' the and expression to return 0. And the way we do that is by using recursion.
To demonstrate this I am going to recurse equation 1.2 one time (this step might be a bit challenging at first but if needed there's a detailed step by step result in appendix 2):
x + y = 2*(2*and & xor) + (2*and ^ xor) (1.3)
Or more simply:
x + y = 2 * and[1] + xor[1] (1.4)
with
and[1] = 2*and & xor,
xor[1] = 2*and ^ xor,
[1] meaning 'recursed one time'
There's a couple of interesting things to note here. First you noticed how the concept of recursion sounds close to that of a loop, like the one found in bitwiseAdd in fact. This connection becomes even more obvious when you consider what and[1] and xor[1] are: they are the same expressions as the and and xor expressions defined INSIDE the while loop in bitwiseAdd. We also note that a pattern emerges: equation 1.4 looks exactly like equation 1.2!
As a result of this, doing further recursions is a breeze, if one keeps the recursive notation. Here we recurse equation 1.2 two more times:
x + y = 2 * and[2] + xor[2]
x + y = 2 * and[3] + xor[3]
This should now highlight the role of the 'temp' variable found in bitwiseAdd: temp allows to pass from one recursion level to the next.
We also notice the multiplication by two in all those equations. As mentioned earlier this multiplication is done at the begin of the while loop in bitwiseAdd using the and <<= 1 statement. This multiplication has a consequence on the next recursion stage since the bits in and[i] are different from those in the and[i] of the previous stage (and if you recall the little side note I made earlier about the '&' operator you probably see where this is going now).
The general form of equation 1.4 now becomes:
x + y = 2 * and[x] + xor[x] (1.5)
with x the nth recursion
FINALY:
So when does this recursion business end exactly?
Answer: it ends when the intersection between the two bit sequences in the and[x] expression of equation 1.5 returns 0. The equivalent of this in bitwiseAdd happens when the while loop condition becomes false. At this point equation 1.5 becomes:
x + y = xor[x] (1.6)
And that explains why in bitwiseAdd we only return xor at the end!
And we are done! A pretty clever piece of code this bitwiseAdd I must say :)
I hope this helped
APPENDIX:
1) A numeric example of equation 1.1
equation 1.1 says:
x + y = 2(x&y)+(x^y) (1.1)
To verify this statement one can take a simple example, say adding 9 and 13 together. The steps are shown below (the bitwise representations are in parenthesis):
We have
x = 9 (1001)
y = 13 (1101)
And
x + y = 9 + 13 = 22
x & y = 9 & 13 = 9 (1001 & 1101 = 1001)
x ^ y = 9^13 = 4 (1001 ^ 1101 = 0100)
pluging that back into equation 1.1 we find:
9 + 13 = 2 * 9 + 4 = 22 et voila!
2) Demonstrating the first recursion step
The first recursion equation in the presentation (equation 1.3) says that
if
x + y = 2 * and + xor (equation 1.2)
then
x + y = 2*(2*and & xor) + (2*and ^ xor) (equation 1.3)
To get to this result, we simply took the 2* and + xor part of equation 1.2 above and applied the addition/bitwise operands relationship given by equation 1.1 to it. This is demonstrated as follow:
if
x + y = 2(x&y) + (x^y) (equation 1.1)
then
[2(x&y)] + (x^y) = 2 ([2(x&y)] & (x^y)) + ([2(x&y)] ^ (x^y))
(left side of equation 1.1) (after applying the addition/bitwise operands relationship)
Simplifying this with the definitions of the and and xor variables of equation 1.2 gives equation 1.3's result:
[2(x&y)] + (x^y) = 2*(2*and & xor) + (2*and ^ xor)
with
and = x&y
xor = x^y
And using that same simplification gives equation 1.4's result:
2*(2*and & xor) + (2*and ^ xor) = 2*and[1] + xor[1]
with
and[1] = 2*and & xor
xor[1] = 2*and ^ xor
[1] meaning 'recursed one time'
Here is another approach for Multiplication
/**
* Multiplication of binary numbers without using '*' operator
* uses bitwise Shifting/Anding
*
* #param n1
* #param n2
*/
public static void multiply(int n1, int n2) {
int temp, i = 0, result = 0;
while (n2 != 0) {
if ((n2 & 1) == 1) {
temp = n1;
// result += (temp>>=(1/i)); // To do it only using Right shift
result += (temp<<=i); // Left shift (temp * 2^i)
}
n2 >>= 1; // Right shift n2 by 1.
i++;
}
System.out.println(result);
}
I need to find combination of combination in JAVA.
I have for instance 6 students in class. Out of them, I need to create combination of 4 people in group, and for each group I can choose an intimate group of 2.
I have to make sure that there are no doubles (order does not matter).! and need to print the 4 people group.
However, this is the hard part:
So defining students with numbers:
If I print out 1234 as one of the combinations, I can't print out1256 as well, since 12 appears both in 1234 and in 1256.
How can I write it in Java?
EDITED
output of ([1,2,3,4,5],3,2) will be:
Combinations without repetition (n=5, r=3)
{1,2,3} {1,2,4} {1,2,5} {1,3,4} {1,3,5} {1,4,5} {2,3,4} {2,3,5} {2,4,5} {3,4,5}
deleting repeating groups of 2 elements, will leave me only:
{1,2,3} {1,4,5} (i deleted groups that have combinations of 12,13,23,45,14,15 since they already appear in the first two that I have found.
Ok, here's the simple emulation of the process you described. But I use binary numbers to present set, it makes manipulations easier. For example, number 19 is 10011 in binary form: it means students 0, 3 and 4 are selected (there're 1's in those positions).
A little helper first.
// return all subsets of 'set', having size 'subsetSize'
Set<Integer> allSubsets(int set, int subsetSize) {
Set<Integer> result = new HashSet<Integer>();
if (subsetSize == 0) {
result.add(0);
return result;
}
if (set == 0) {
return result;
}
// check if 1st element is present
if (set % 2 == 1) {
// use 1st element, one less element to collect
for (Integer i : allSubsets(set / 2, subsetSize - 1)) {
result.add(i * 2 + 1);
}
}
// not use 1st element
for (Integer i : allSubsets(set / 2, subsetSize)) {
result.add(i * 2);
}
return result;
}
And main program. Suggestions are welcome.
int N = 5;
int M = 3;
int Z = 2;
List<Integer> result = new ArrayList<Integer>();
// get all groups of M elements from 'wholeSet'
int wholeSet = (1 << N) - 1;
for (int s : allSubsets(wholeSet, M)) {
// Check all subsets of 'Z' elements from set 's'
boolean valid = true;
for (int t : allSubsets(s, Z)) {
// check if this Z-element subset already was used
for (int past : result) {
// check if 't' is subset of 'past' set
if ((past|t) == past) {
valid = false;
break;
}
}
if (!valid) {
break;
}
}
if (valid) {
// none of Z-element subsets of 's' were used before
result.add(s);
}
}
But it may require improvements (like memoization) for big inputs. But for now, since you don't say what kind of input you expect, I assume this is good enough.
Imagine you have a Student object with an equals comparing their Primarykey. In your example, student 1 will return 1, 2 will return 2 and so on.
Put them all in the set, this will ensure that there will be no double.
Iterate though the set by 4 then by 2 and will return you your desired result.
How can you write the following statement in the given languages?
a(0) = 1
a_(n+1) = 1 - 1 / ( a_n + 3)
I need to find the smallest value of n when a_n -> 0.732050....
My attempt in Mathematica
a[(x+1)_] = 1 - 1/(a[x_] + 3)
The problem is apparently in this a[(x+1)_].
However, I do not know how to do it iteratively in Mathematica.
Mathematica
a[0] = 1;
a[n_] := a[n] = 1 - 1/(a[n-1] + 3)
(Note the memoization trick.)
Also, a[n] converges (very quickly) to sqrt(3)-1:
Solve[x == 1 - 1/(x+3), x]
Python, simplest:
def a(n):
if n == 0: return 1
return 1 - 1 / float(a(n-1) + 3)
# limit is sqrt(3) - 1
limit = 3.0 ** 0.5 - 1.0
# get 9 digits' precision
i = 0
while abs(a(i) - limit) > 1.0e-9:
i += 1
print i
This emits 8, suggesting that optimizations such as recursion elimination or memoizing are likely not warranted.
Of course normally we'd want to get the limit numerically rather than analytically, so the normal way to loop would be rather different -- and best encapsulated in a higher-order function...:
# get a function's limit numerically
def limit(f, eps=1.0e-11):
previous_value = f(0)
next_value = f(1)
i = 2
while abs(next_value - previous_value) > eps:
previous_value = next_value
next_value = f(i)
i += 1
return next_value
Nontrivial looping logic is usually best encapsulated in a generator:
def next_prev(f):
previous_value = f(0)
i = 1
while True:
next_value = f(i)
yield next_value, previous_value
i += 1
previous_value = next_value
with the help of this generator, the limit HOF becomes much simpler:
def limit(f, eps=1.0e-11):
for next_value, previous_value in next_prev(f):
if abs(next_value - previous_value) < eps:
return next_value
Note how useful the separation is: next_prev embodies the concept of "get the next and previous value of the function", limit just deals with "when should the loop terminate".
Last but not least, itertools often offers a good alternative to generators, letting you encapsulate finicky iteration logic in speedy ways (though it does take some getting used to...;-):
import itertools
def next_prev(f):
values = itertools.imap(f, itertools.count())
prv, nxt = itertools.tee(values)
nxt.next()
return itertools.izip(prv, nxt)
Java
double A = 1;
int n = 0;
while (true) {
System.out.println(n + " " + A);
A = 1 - 1 / (A + 3);
n++;
}
Python
A = 1.0
n = 0
while 1:
print n, A
A = 1 - 1 / (A + 3)
n += 1
Mathematica:
a[0] := 1
a[k_] := 1 - 1/(a[k - 1] + 3)
I substituted k = n + 1 because that makes the expression simpler. The result is equivalent.
Python
next = lambda x: 1.0 - (1.0 / (float(x) + 3.0))
last, z, count = -1, 0.0, 0
while last != z:
print count, z
last, z, count = z, next(z), count+1
I try to avoid writing "while True" or such if I can avoid it. Almost certainly no code that I write will loop forever. In this case, it ran sixteen times for me. Sixteen is a lot less than ℵ-null.
A one-liner in Mathematica which gives a list of exact elements of your sequence:
In[66]:= NestWhileList[1 - 1/(#1 + 3) &, 1,
RealExponent[Subtract[##]] > -8 &, 2]
Out[66]= {1, 3/4, 11/15, 41/56, 153/209, 571/780, 2131/2911, \
7953/10864, 29681/40545}
The difference between the last two elements is less than 10^-8. It thus have taken 8 iterations:
In[67]:= Length[%]
Out[67]= 9