I'm trying to understand the binary operators in C# or in general, in particular ^ - exclusive or.
For example:
Given an array of positive integers. All numbers occur even number of times except one number which occurs odd number of times. Find the number in O(n) time and constant space.
This can be done with ^ as follows: Do bitwise XOR of all the elements. Finally we get the number which has odd occurrences.
How does it work?
When I do:
int res = 2 ^ 3;
res = 1;
int res = 2 ^ 5;
res = 7;
int res = 2 ^ 10;
res = 8;
What's actually happening? What are the other bit magics? Any reference I can look up and learn more about them?
I know this is a rather old post but I wanted simplify the answer since I stumbled upon it while looking for something else.
XOR (eXclusive OR/either or), can be translated simply as toggle on/off.
Which will either exclude (if exists) or include (if nonexistent) the specified bits.
Using 4 bits (1111) we get 16 possible results from 0-15:
decimal | binary | bits (expanded)
0 | 0000 | 0
1 | 0001 | 1
2 | 0010 | 2
3 | 0011 | (1+2)
4 | 0100 | 4
5 | 0101 | (1+4)
6 | 0110 | (2+4)
7 | 0111 | (1+2+4)
8 | 1000 | 8
9 | 1001 | (1+8)
10 | 1010 | (2+8)
11 | 1011 | (1+2+8)
12 | 1100 | (4+8)
13 | 1101 | (1+4+8)
14 | 1110 | (2+4+8)
15 | 1111 | (1+2+4+8)
The decimal value to the left of the binary value, is the numeric value used in XOR and other bitwise operations, that represents the total value of associated bits. See Computer Number Format and Binary Number - Decimal for more details.
For example: 0011 are bits 1 and 2 as on, leaving bits 4 and 8 as off. Which is represented as the decimal value of 3 to signify the bits that are on, and displayed in an expanded form as 1+2.
As for what's going on with the logic behind XOR here are some examples
From the original post
2^3 = 1
2 is a member of 1+2 (3) remove 2 = 1
2^5 = 7
2 is not a member of 1+4 (5) add 2 = 1+2+4 (7)
2^10 = 8
2 is a member of 2+8 (10) remove 2 = 8
Further examples
1^3 = 2
1 is a member of 1+2 (3) remove 1 = 2
4^5 = 1
4 is a member of 1+4 (5) remove 4 = 1
4^4 = 0
4 is a member of itself remove 4 = 0
1^2^3 = 0Logic: ((1^2)^(1+2))
(1^2) 1 is not a member of 2 add 2 = 1+2 (3)
(3^3) 1 and 2 are members of 1+2 (3) remove 1+2 (3) = 0
1^1^0^1 = 1 Logic: (((1^1)^0)^1)
(1^1) 1 is a member of 1 remove 1 = 0
(0^0) 0 is a member of 0 remove 0 = 0
(0^1) 0 is not a member of 1 add 1 = 1
1^8^4 = 13 Logic: ((1^8)^4)
(1^8) 1 is not a member of 8 add 1 = 1+8 (9)
(9^4) 1 and 8 are not members of 4 add 1+8 = 1+4+8 (13)
4^13^10 = 3 Logic: ((4^(1+4+8))^(2+8))
(4^13) 4 is a member of 1+4+8 (13) remove 4 = 1+8 (9)
(9^10) 8 is a member of 2+8 (10) remove 8 = 2
1 is not a member of 2+8 (10) add 1 = 1+2 (3)
4^10^13 = 3 Logic: ((4^(2+8))^(1+4+8))
(4^10) 4 is not a member of 2+8 (10) add 4 = 2+4+8 (14)
(14^13) 4 and 8 are members of 1+4+8 (13) remove 4+8 = 1
2 is not a member of 1+4+8 (13) add 2 = 1+2 (3)
To see how it works, first you need to write both operands in binary, because bitwise operations work on individual bits.
Then you can apply the truth table for your particular operator. It acts on each pair of bits having the same position in the two operands (the same place value). So the leftmost bit (MSB) of A is combined with the MSB of B to produce the MSB of the result.
Example: 2^10:
0010 2
XOR 1010 8 + 2
----
1 xor(0, 1)
0 xor(0, 0)
0 xor(1, 1)
0 xor(0, 0)
----
= 1000 8
And the result is 8.
The other way to show this is to use the algebra of XOR; you do not need to know anything about individual bits.
For any numbers x, y, z:
XOR is commutative: x ^ y == y ^ x
XOR is associative: x ^ (y ^ z) == (x ^ y) ^ z
The identity is 0: x ^ 0 == x
Every element is its own inverse: x ^ x == 0
Given this, it is easy to prove the result stated. Consider a sequence:
a ^ b ^ c ^ d ...
Since XOR is commutative and associative, the order does not matter. So sort the elements.
Now any adjacent identical elements x ^ x can be replaced with 0 (self-inverse property). And any 0 can be removed (because it is the identity).
Repeat as long as possible. Any number that appears an even number of times has an integral number of pairs, so they all become 0 and disappear.
Eventually you are left with just one element, which is the one appearing an odd number of times. Every time it appears twice, those two disappear. Eventually you are left with one occurrence.
[update]
Note that this proof only requires certain assumptions about the operation. Specifically, suppose a set S with an operator . has the following properties:
Assocativity: x . (y . z) = (x . y) . z for any x, y, and z in S.
Identity: There exists a single element e such that e . x = x . e = x for all x in S.
Closure: For any x and y in S, x . y is also in S.
Self-inverse: For any x in S, x . x = e
As it turns out, we need not assume commutativity; we can prove it:
(x . y) . (x . y) = e (by self-inverse)
x . (y . x) . y = e (by associativity)
x . x . (y . x) . y . y = x . e . y (multiply both sides by x on the left and y on the right)
y . x = x . y (because x . x = y . y = e and the e's go away)
Now, I said that "you do not need to know anything about individual bits". I was thinking that any group satisfying these properties would be enough, and that such a group need not necessarily be isomorphic to the integers under XOR.
But #Steve Jessup proved me wrong in the comments. If you define scalar multiplication by {0,1} as:
0 * x = 0
1 * x = x
...then this structure satisfies all of the axioms of a vector space over the integers mod 2.
Thus any such structure is isomorphic to a set of vectors of bits under component-wise XOR.
This is based on the simple fact that XOR of a number with itself results Zero.
and XOR of a number with 0 results the number itself.
So, if we have an array = {5,8,12,5,12}.
5 is occurring 2 times.
8 is occurring 1 times.
12 is occurring 2 times.
We have to find the number occurring odd number of times. Clearly, 8 is the number.
We start with res=0 and XOR with all the elements of the array.
int res=0;
for(int i:array)
res = res ^ i;
1st Iteration: res = 0^5 = 5
2nd Iteration: res = 5^8
3rd Iteration: res = 5^8^12
4th Iteration: res = 5^8^12^5 = 0^8^12 = 8^12
5th Iteration: res = 8^12^12 = 8^0 = 8
The bitwise operators treat the bits inside an integer value as a tiny array of bits. Each of those bits is like a tiny bool value. When you use the bitwise exclusive or operator, one interpretation of what the operator does is:
for each bit in the first value, toggle the bit if the corresponding bit in the second value is set
The net effect is that a single bit starts out false and if the total number of "toggles" is even, it will still be false at the end. If the total number of "toggles" is odd, it will be true at the end.
Just think "tiny array of boolean values" and it will start to make sense.
The definition of the XOR (exclusive OR) operator, over bits, is that:
0 XOR 0 = 0
0 XOR 1 = 1
1 XOR 0 = 1
1 XOR 1 = 0
One of the ways to imagine it, is to say that the "1" on the right side changes the bit from the left side, and 0 on the right side doesn't change the bit on the left side. However, XOR is commutative, so the same is true if the sides are reversed.
As any number can be represented in binary form, any two numbers can be XOR-ed together.
To prove it being commutative, you can simply look at its definition, and see that for every combination of bits on either side, the result is the same if the sides are changed. To prove it being associative, you can simply run through all possible combinations of having 3 bits being XOR-ed to each other, and the result will stay the same no matter what the order is.
Now, as we proved the above, let's see what happens if we XOR the same number at itself. Since the operation works on individual bits, we can test it on just two numbers: 0 and 1.
0 XOR 0 = 0
1 XOR 1 = 0
So, if you XOR a number onto itself, you always get 0 (believe it or not, but that property of XOR has been used by compilers, when a 0 needs to be loaded into a CPU register. It's faster to perform a bit operation than to explicitly push 0 into a register. The compiler will just produce assembly code to XOR a register onto itself).
Now, if X XOR X is 0, and XOR is associative, and you need to find out what number hasn't repeated in a sequence of numbers where all other numbers have been repeated two (or any other odd number of times). If we had the repeating numbers together, they will XOR to 0. Anything that is XOR-ed with 0 will remain itself. So, out of XOR-ing such a sequence, you will end up being left with a number that doesn't repeat (or repeats an even number of times).
This has a lot of samples of various functionalities done by bit fiddling. Some of can be quite complex so beware.
What you need to do to understand the bit operations is, at least, this:
the input data, in binary form
a truth table that tells you how to "mix" the inputs to form the result
For XOR, the truth table is simple:
1^1 = 0
1^0 = 1
0^1 = 1
0^0 = 0
To obtain bit n in the result you apply the rule to bits n in the first and second inputs.
If you try to calculate 1^1^0^1 or any other combination, you will discover that the result is 1 if there is an odd number of 1's and 0 otherwise. You will also discover that any number XOR'ed with itself is 0 and that is doesn't matter in what order you do the calculations, e.g. 1^1^(0^1) = 1^(1^0)^1.
This means that when you XOR all the numbers in your list, the ones which are duplicates (or present an even number of times) will XOR to 0 and you will be left with just the one which is present an odd number of times.
As it is obvious from the name(bitwise), it operates between bits.
Let's see how it works,
for example, we have two numbers a=3 and b=4,
the binary representation of 3 is 011 and of 4 is 100, so basically xor of the same bits is 0 and for opposite bits, it is 1.
In the given example 3^4, where "^" is a xor symbol, will give us 111 whose decimal value will be 7.
for another example, if you've given an array in which every element occurs twice except one element & you've to find that element.
How can you do that? simple xor of the same numbers will always be 0 and the number which occur exactly once will be your output. because the output of any one number with 0 will be the same name number because the number will have set bits which zero don't have.
Related
I'm trying to tackle down a problem where the time limit is very low (1 second) and the number of cases is supposedly high.
You need to tell if a number is divisible by 3, but the problem is that you don't get the direct number, you get a number k, and then need to check if the concatenation of numbers from 1 to k (123...k) is divisible by 3.
Example input:
4 // The number of cases
2
6
15
130000000
Output:
YES // Because 12 is divisible by 3
YES // Because 123456 is divisible by 3
YES // Because 123456789101112131415 is divisible by 3
NO
I've found some topics about quickly checking the divisibility, but what most time takes I think is to build the number. There are cases where the initial number is as high as 130000000 (so the final is 1234...130000000) which I thinks overflows any numeric data type.
So, what am I missing here? Is there any way to know if something is divisible by 3 without concatenating the number? Any ideas?
PD: Someone also posted the triangular numbers formula which also is a correct solution and then deleted the answer, it was:
if ((1 + num) * num / 2) % 3 == 0 ? "YES" : "NO"
Every third number is divisible by three.
Every number divisible by three has a digit sum divisible by 3.
Every third number has a digit sum divisible by 3.
In between these, every third number has a digit sum congruent to 1 and then 2 mod 3.
Take a look:
n digit sum mod 3
0 0
1 1
2 2
3 0
4 1
5 2
6 0
...
10 1
11 2
12 0
...
19 1
20 2
21 0
...
Say we have a string of digits constructed as you describe, and the number we just added was divisible mod 3. When we append the next number's digits, we are appending digits whose sum is congruent to 1 mod 3, and when added to those in our number, we will get a combined digit sum congruent to 1 mod 3, so our answer for the next one will be "no". The next one will add a number with digit sum congruent to 2 mod 3, and this causes the total to become congruent to 0 again, so the answer here is "yes". Finally, adding the next number which must be divisible by 3 keeps the digit sum congruent to 0.
The takeaway?
if n is congruent to 0 modulo 3, then the answer is "yes"
if n is congruent to 1 modulo 3, then the answer is "no"
if n is congruent to 2 modulo 3, then the answer is "yes"
In particular, your example for n=15 is wrong; the digit string obtained represents a number that should be divisible by 3, and indeed it is (try it on a big enough calculator to verify).
All that is left is to find an implementation that is fast enough and handles all the required cases. If n is guaranteed to be under ~2 billion, then you are probably safe with something like
return (n % 3) != 1;
If n can be an arbitrarily large number, never fear; you can check whether the digit sum is congruent to 0 modulo 3 by adding up the digits in linear time. If not, you can add 1 from the number by coding addition like you do it by hand on paper and then check the result of that for divisibility by 3, again in linear time. So something like:
if (digit_sum_mod_3(n) == 0) return true;
else if (digit_sum_mod_3(add_one(n)) == 0) return false;
else return true;
Then you would have something like
digit_sum_mod_3(n[1...m])
sum = 0
for k = 1 to m do
sum = sum + n[k]
// keep sum from getting too big
if sum >= 18 then
sum = sum - 18
return sum % 3
add_one(n[1...m])
// work from right to left, assume big-endian
for k = m to 1 do
if n[k] < 9 then // don't need to carry
n[k] = n[k] + 1
break
else then // need to carry
n[k] = 0
if n[1] = 0 then // carried all the way to the front
n[1] = 1
n[m+1] = 0
return n
Any three consecutive numbers sum up to 0 == a + a + 1 + a + 2 mod 3.
The answer reduces to k%3 == 0, or 2k-1 % 3 == 0. The latter is equivalent to k%3 == 2, which leaves out k%3==1 which then simplifies further to k%3 != 1.
It is a known trick in mathematics that a number is divisible by three if the sum of its individual decimal digits is divisible by three.
Example:
2271
2+2+7+1 = 12
12 is divisible by 3, therefore so is 2271
Additionally, the sum of any three consecutive integers must be divisible by three. This is because:
((n)+(n+1)+(n+2))/3 = (3n+3)/3 = n+1 = integer
Therefore:
If k mod 3 == 0, then concatenation of 1 to k is divisible by three.
If k mod 3 == 1, then concatenation of 1 to k is not divisible by three.
If k mod 3 == 2, then it is a bit trickier. In this case, concatenation of 1 to k is divisible by three if the sum of k and the number before k (which evaluates to (k)+(k-1), which is 2k-1) is divisible by three.
Therefore, the final condition is:
(k mod 3 == 0) || ((k mod 3 == 2) && (2k-1 mod 3 == 0))
However, this can be even further simplified.
It turns out that k mod 3 can only equal 2 whenever 2k-1 mod 3 equals 0 and vice versa.
See simple graph below that shows cyclic pattern of this behavior.
Therefore, the formula can be further simplified just to:
(k mod 3 == 0) || (k mod 3 == 2)
Or, even more simply:
(k mod 3 != 1)
I realize answerer already provided this answer so I don't expect this to be the accepted answer, just giving a more thorough mathematical explanation.
A number is divisible by three if the sum of its digits is divisible by three (see here). Therefore, there is no need to "construct" your number, you need simply add the digits of the individual numbers. Thus for your 15 case, you do not need to "construct" 123456789101112131415, you just need to sum all of the digits in [1, 2, 3, 4, ... 14, 15].
This is simpler than it sounds because the problem only needs to check numbers of a very specific format: 12345789101112131415…k. You can use Gauss's method to quickly get the sum of the numbers 1 to k and then check if that sum is divisible by three using the usual methods. The code for that is:
'NO' if (k*(k+1)/2)%3 else 'YES'
If you look at the pattern that occurs as k increases (NO, YES, YES, NO, YES, YES, ...), you don't even need the multiplication or division. In short, all you need is:
'YES' if (k-1)%3 else 'NO'
Here is Python code which reads integers from a file and, if it wouldn't take too long also checks the answer the hard way so you can see that it is right. (Python numbers can be infinitely long, so you don't need to worry about overflow):
#!/usr/bin/python3
# Read integers from stdin, convert each int to a triangular number
# and output YES (or NO) if it is divisible by 3.
def sumgauss(x):
'''Return the sum from 1 to x using Gauss's shortcut'''
return (x*(x+1)/2)
def triangle(n):
'''Given an integer n, return a string with all the integers
from 1 to n concatenated. E.g., 15 -> 123456789101112131415'''
result=""
for t in range(1, k+1):
result+=str(t)
return result
import sys
for k in sys.stdin.readlines():
k=int(k)
print ( 'YES' if (k-1)%3 else 'NO', end='')
# If it wouldn't take too long, double check by trying it the hard way
if k<100000:
kstr=triangle(k)
print("\t// %s modulo 3 is %d" % (kstr, int(kstr)%3))
else:
print('\t// 123456789101112131415...%d%d%d modulo 3 is %d' %
tuple([k-2, k-1, k, sumgauss(k)%3]))
Speaking of Gauss's shortcut for summation, this problem seems a lot like a homework assignment. (Gauss invented it as a student when a teacher was trying to get the class out of his hair for a while by making them add up the numbers from 1 to 100.) If this is indeed a class assignment, please make sure the teacher knows to give the A to me and stackoverflow. Thanks!
Sample output:
$ cat data
2
6
15
130000000
130000001
$ ./k3.py < data
YES // 12 modulo 3 is 0
YES // 123456 modulo 3 is 0
YES // 123456789101112131415 modulo 3 is 0
NO // 123456789101112131415...129999998129999999130000000 modulo 3 is 1
YES // 123456789101112131415...129999999130000000130000001 modulo 3 is 0
The first 32 triangular numbers:
$ seq 32 | ./k3.py
NO // 1 modulo 3 is 1
YES // 12 modulo 3 is 0
YES // 123 modulo 3 is 0
NO // 1234 modulo 3 is 1
YES // 12345 modulo 3 is 0
YES // 123456 modulo 3 is 0
NO // 1234567 modulo 3 is 1
YES // 12345678 modulo 3 is 0
YES // 123456789 modulo 3 is 0
NO // 12345678910 modulo 3 is 1
YES // 1234567891011 modulo 3 is 0
YES // 123456789101112 modulo 3 is 0
NO // 12345678910111213 modulo 3 is 1
YES // 1234567891011121314 modulo 3 is 0
YES // 123456789101112131415 modulo 3 is 0
NO // 12345678910111213141516 modulo 3 is 1
YES // 1234567891011121314151617 modulo 3 is 0
YES // 123456789101112131415161718 modulo 3 is 0
NO // 12345678910111213141516171819 modulo 3 is 1
YES // 1234567891011121314151617181920 modulo 3 is 0
YES // 123456789101112131415161718192021 modulo 3 is 0
NO // 12345678910111213141516171819202122 modulo 3 is 1
YES // 1234567891011121314151617181920212223 modulo 3 is 0
YES // 123456789101112131415161718192021222324 modulo 3 is 0
NO // 12345678910111213141516171819202122232425 modulo 3 is 1
YES // 1234567891011121314151617181920212223242526 modulo 3 is 0
YES // 123456789101112131415161718192021222324252627 modulo 3 is 0
NO // 12345678910111213141516171819202122232425262728 modulo 3 is 1
YES // 1234567891011121314151617181920212223242526272829 modulo 3 is 0
YES // 123456789101112131415161718192021222324252627282930 modulo 3 is 0
NO // 12345678910111213141516171819202122232425262728293031 modulo 3 is 1
YES // 1234567891011121314151617181920212223242526272829303132 modulo 3 is 0
Actually the answer is pretty straight forward, if the sum of the digits divisible by three then the number is also divisible by 3.
string ans=(((1 + num) * num) / 2) % 3 == 0 ? "YES" : "NO";
according to the problem sum of digit can be considered as sum of numbers from 1 to n, sum=(n*(n+1))/2
*Make sure you divide the whole thing by 2
Another approach:
string ans=n % 3 !=1 ? "YES" : "NO";
You can prove that if n or n-2 is divisible by 3, then the sum up to n is divisible by 3 (e.g., in your case sum(1...8), sum(1..9), sum(1..11), etc.).
I am trying to fit 3 numbers inside 1 number.But numbers will be only between 0 and 11.So their (base) is 12.For example i have 7,5,2 numbers.I come up with something like this:
Three numbers into One number :
7x12=84
84x5=420
420+2=422
Now getting back Three numbers from One number :
422 MOD 12 = 2 (the third number)
422 - 2 = 420
420 / 12 = 35
And i understanded that 35 is multiplication of first and the second number (i.e 7 and 5)
And now i cant get that 7 and 5 anyone knows how could i ???
(I started typing this answer before the other one got posted, but this one is more specific to Arduino then the other one, so I'm leaving it)
The code
You can use bit shifting to get multiple small numbers into one big number, in code it would look like this:
int a, b, c;
//putting then together
int big = (a << 8) + (b << 4) + c;
//separating them again
a = (big >> 8) & 15;
b = (big >> 4) & 15;
c = big & 15;
This code only works when a, b and c are all in the range [0, 15] witch appears to be enough for you case.
How it works
The >> and << operators are the bitshift operators, in short a << n shifts every bit in a by n places to the left, this is equivalent to multiplying by 2^n. Similarly, a >> n shifts to to the right. An example:
11 << 3 == 120 //0000 1011 -> 0101 1000
The & operator performs a bitwise and on the two operands:
6 & 5 == 4 // 0110
// & 0101
//-> 0100
These two operators are combined to "pack" and "unpack" the three numbers. For the packing every small number is shifted a bit to the left and they are all added together. This is how the bits of big now look (there are 16 of them because ints in Arduino are 16 bits wide):
0000aaaabbbbcccc
When unpacking, the bits are shifted to the right again, and they are bitwise anded together with 15 to filter out any excess bits. This is what that last operation looks like to get b out again:
00000000aaaabbbb //big shifted 4 bits to the right
& 0000000000001111 //anded together with 15
-> 000000000000bbbb //gives the original number b
All is working exactly like in base 10 (or 16). Here after your corrected example.
Three numbers into One number :
7x12^2=1008
5*12^1=60
2*12^0=2
1008+60+2=1070
Now getting back Three numbers from One number :
1070 MOD 12 = 2 (the third number)
1070/12 = 89 (integer division) => 89 MOD 12 = 5
89 / 12 = 7
Note also that the maximum value will be 11*12*12+11*12+11=1727.
If this is really programming related, you will be using 16bits instead of 3*8 bits so sparing one byte. An easyer method not using base 12 would be fit each number into half a byte (better code efficiency and same transmission length):
7<<(4+4) + 5<<4 + 2 = 1874
1874 & 0x000F = 2
1874>>4 & 0x000F = 5
1874>>8 & 0x0F = 7
Because MOD(12) and division by 12 is much less efficient than working with powers of 2
you can use the principle of the positional notation to change from one or the other in any base
Treat yours numbers (n0,n1,...,nm) as a digit of a big number in the base B of your choosing so the new number is
N = n0*B^0 + n1*B^1 + ... + nm*B^m
to revert the process is also simple, while your number is greater than 0 find its modulo in respect to the base to get to get the first digit, then subtracts that digit and divide for the base, repeat until finish while saving each digit along the way
digit_list = []
while N > 0 do:
d = N mod B
N = (N - d) / B
digit_list.append( d )
then if N is N = n0*B^0 + n1*B^1 + ... + nm*B^m doing N mod B give you n0, then subtract it leaving you with n1*B^1 + ... + nm*B^m and divide by B to reduce the exponents of all B and that is the new N, N = n1*B^0 + ... + nm*B^(m-1) repetition of that give you all the digit you start with
here is a working example in python
def compact_num( num_list, base=12 ):
return sum( n*pow(base,i) for i,n in enumerate(num_list) )
def decompact_num( n, base=12):
if n==0:
return [0]
result = []
while n:
n,d = divmod(n,base)
result.append(d)
return result
example
>>> compact_num([2,5,7])
1070
>>> decompact_num(1070)
[2, 5, 7]
>>> compact_num([10,2],16)
42
>>> decompact_num(42,16)
[10, 2]
>>>
I want to write in Maple Taylor series for cosinus function. Here's my code:
better_cos := proc (x) options operator, arrow; sum((-1)^n*x^(2*n)/factorial(2*n), n = 0 .. 20) end proc;
better_cos(0) returns 0 instead of 1 (cos(0) == 1). It's probably because x^(2*n) return always 0 instead of 1. For example:
fun_sum := proc (x) options operator, arrow; sum(x^(2*n), n = 0 .. 0) end proc
return 0 for x == 1.
It's weird because 0^0 returns 1. Do you have any idea how can I correctly implement taylor series for cosinus?
You should be able to get what you want by using add instead of sum in your better_cos operator.
Using add is often more appropriate for adding up a finite number of terms of a numeric sequence, and also note that add has Maple's so-called special evaluation rules.
If you intend to take the sum of a fixed number of terms (ie. n from 0 to 20) then you should not write a procedure that computes the factorials for each input argument (ie. for each value of x). Instead, produce the truncated series just once, and then use unapply to produce an operator. This approach also happens to deal with your original problem, since the x^0 term becomes 1 because the symbol x is used.
You could also rearrange the polynomial (truncated series) so that it is in Horner form, to try and minimize arithmetic steps when evaluating subsequently at various numeric values of x.
For example, using 5 terms for brevity instead of 20 as you had it,
convert(add((-1)^n*x^(2*n)/factorial(2*n), n = 0 .. 5),horner);
/ 1 /1 / 1 / 1 1 2\ 2\ 2\ 2\ 2
1 + |- - + |-- + |- --- + |----- - ------- x | x | x | x | x
\ 2 \24 \ 720 \40320 3628800 / / / /
bc := unapply(%,x):
You can now apply the procedure bc as you wish, either with symbolic or numeric arguments.
expand(bc(x));
1 2 1 4 1 6 1 8 1 10
1 - - x + -- x - --- x + ----- x - ------- x
2 24 720 40320 3628800
bc(0);
1
bc(1.2);
0.3623577360
If you prefer to have your procedure better_cos take a pair of arguments, so that the number of terms is variable, then you could still consider using add to deal with your original problem. eg,
bc := (x,N)->add((-1)^n*x^(2*n)/(2*n)!, n = 0 .. N):
I suppose that this is a homework assignment, and that you realize that you could also use the existing system commands taylor or series to get the same results, ie.
convert(series(cos(x),x=0,10),polynom);
1 2 1 4 1 6 1 8
1 - - x + -- x - --- x + ----- x
2 24 720 40320
convert(taylor(cos(x),x=0,10),polynom);
1 2 1 4 1 6 1 8
1 - - x + -- x - --- x + ----- x
2 24 720 40320
Here's the Taylor series definition:
Don't start the loop with zero; initialize with one and start at two.
Factorial is inefficient, too.
This question already has answers here:
What does the caret (^) operator do?
(5 answers)
Closed 2 years ago.
What mathematical operation does XOR perform?
XOR is a binary operation, it stands for "exclusive or", that is to say the resulting bit evaluates to one if only exactly one of the bits is set.
This is its function table:
a | b | a ^ b
--|---|------
0 | 0 | 0
0 | 1 | 1
1 | 0 | 1
1 | 1 | 0
This operation is performed between every two corresponding bits of a number.
Example: 7 ^ 10
In binary: 0111 ^ 1010
0111
^ 1010
======
1101 = 13
Properties: The operation is commutative, associative and self-inverse.
It is also the same as addition modulo 2.
^ is the Python bitwise XOR operator. It is how you spell XOR in python:
>>> 0 ^ 0
0
>>> 0 ^ 1
1
>>> 1 ^ 0
1
>>> 1 ^ 1
0
XOR stands for exclusive OR. It is used in cryptography because it let's you 'flip' the bits using a mask in a reversable operation:
>>> 10 ^ 5
15
>>> 15 ^ 5
10
where 5 is the mask; (input XOR mask) XOR mask gives you the input again.
A little more information on XOR operation.
XOR a number with itself odd number of times the result is number
itself.
XOR a number even number of times with itself, the result is 0.
Also XOR with 0 is always the number itself.
One thing that other answers don't mention here is XOR with negative numbers -
a | b | a ^ b
----|-----|------
0 | 0 | 0
0 | 1 | 1
1 | 0 | 1
1 | 1 | 0
While you could easily understand how XOR will work using the above functional table, it doesn't tell how it will work on negative numbers.
How XOR works with Negative Numbers :
Since this question is also tagged as python, I will be answering it with that in mind. The XOR ( ^ ) is an logical operator that will return 1 when the bits are different and 0 elsewhere.
A negative number is stored in binary as two's complement. In 2's complement, The leftmost bit position is reserved for the sign of the value (positive or negative) and doesn't contribute towards the value of number.
In, Python, negative numbers are written with a leading one instead of a leading
zero. So if you are using only 8 bits for your two's-complement
numbers, then you treat patterns from 00000000 to 01111111 as the
whole numbers from 0 to 127, and reserve 1xxxxxxx for writing negative
numbers.
With that in mind, lets understand how XOR works on negative number with an example. Lets consider the expression - ( -5 ^ -3 ) .
The binary representation of -5 can be considered as 1000...101 and
Binary representation of -3 can be considered as 1000...011.
Here, ... denotes all 0s, the number of which depends on bits used for representation (32-bit, 64-bit, etc). The 1 at the MSB ( Most Significant Bit ) denotes that the number represented by the binary representation is negative. The XOR operation will be done on all bits as usual.
XOR Operation :
-5 : 10000101 |
^ |
-3 : 10000011 |
=================== |
Result : 00000110 = 6 |
________________________________|
∴ -5 ^ -3 = 6
Since, the MSB becomes 0 after the XOR operation, so the resultant number we get is a positive number. Similarly, for all negative numbers, we consider their representation in binary format using 2's complement (one of most commonly used) and do simple XOR on their binary representation.
The MSB bit of result will denote the sign and the rest of the bits will denote the value of the final result.
The following table could be useful in determining the sign of result.
a | b | a ^ b
------|-------|------
+ | + | +
+ | - | -
- | + | -
- | - | +
The basic rules of XOR remains same for negative XOR operations as well, but how the operation really works in negative numbers could be useful for someone someday 🙂.
Another application for XOR is in circuits. It is used to sum bits.
When you look at a truth table:
x | y | x^y
---|---|-----
0 | 0 | 0 // 0 plus 0 = 0
0 | 1 | 1 // 0 plus 1 = 1
1 | 0 | 1 // 1 plus 0 = 1
1 | 1 | 0 // 1 plus 1 = 0 ; binary math with 1 bit
You can notice that the result of XOR is x added with y, without keeping track of the carry bit, the carry bit is obtained from the AND between x and y.
x^y // is actually ~xy + ~yx
// Which is the (negated x ANDed with y) OR ( negated y ANDed with x ).
The (^) XOR operator generates 1 when it is applied on two different bits (0 and 1). It generates 0 when it is applied on two same bits (0 and 0 or 1 and 1).
I have the following pseudocode:
sum<-0
inc<-0
for i from 1-n
for j from 1 to i
sum<-sum+inc
inc<-inc+1
I am asked to find a closed formula. The hint is to use common summations. No matter how I look at it I cannot write this code in summation form. Can someone give me an idea of what the summations would look like or even a recursive formula?
Assuming the for i from 1-n means:
for i from 1 to n
A closed formula for that can be obtained through some numerical analysis. Let's examine the number of times through the loop for a couple of values of n (5 and 6).
The outer loop is always n times and the inner loop is whatever i is for each iteration, so for values of n, here are the iteration counts:
n count
= ===========================================
1 (1) = 1
2 (1),(12) = 3
3 (1),(12),(123) = 6
4 (1),(12),(123),(1234) = 10
5 (1),(12),(123),(1234),(12345) = 15
6 (1),(12),(123),(1234),(12345),(123456) = 21
The closed formula for these is best illustrated as follows:
n = 5: 5 + 4 + 3 + 2 + 1
| | | | |
| | V | |
| | 3 | | Formula is: (n+1)*((n-1)/2) + ((n+1)/2)
| +-> 6 <-+ | [outer pair sets] + [inner value]
+-----> 6 <-----+
--
15
This is a formula for all odd values of n. For even values, a similar method can be used:
n = 6: 6 + 5 + 4 + 3 + 2 + 1
| | | | | |
| | +-> 7 <-+ | | Formula is: (n+1)*(n/2)
| +-----> 7 <-----+ | [outer pair sets]
+---------> 7 <---------+
--
21
This tells you the number of iterations of the nested loop for each value of n (we'll call this x).
The calculation of the final value of sum is very similar. On the first iteration you add zero. On the second iteration, you add one. On the third iteration, you add two. That's pretty much exactly the same thing you had to do to figure out the number of iterations, only now it's based on x rather than n and it's 0+1+2+... rather than 1+2+3+..., meaning we can use exactly the same formula just by applying it to x-1 rather than x.
So we can use:
if n is odd:
x <- (n+1) * ((n-1)/2) + ((n+1)/2)
else:
x <- (n+1) * (n/2)
x <- x - 1
if x is odd:
sum <- (x+1) * ((x-1)/2) + ((x+1)/2)
else:
sum <- (x+1) * (x/2)
Checking this against the algorithm for the first few values on n:
n algorithm formula
- --------- -------
0 0 0
1 0 0
2 3 3
3 15 15
4 45 45
5 105 105
So, a perfect match, at least withing the sample space chosen. You could actually go further and turn that into a single formula based on n alone rather than working out an intermediate value, but I'll leave that as an exercise for the reader.
Hint: A C formula which works for both odd and even numbers is:
x <- ((n+1) * ((n-(n%2))/2)) + ((n%2) * ((n+1)/2))
(though still not tested for negative values of n - you should put a check for that before you use the formulaic version).
Innermost loop (let's just call i a fixed number):
inc is incremented i times.
sum has inc added to it i times. (i*(i-1)/2, right?)
If we assume that inc and sum start art value 0, then that's valid. If we assume that they start at some different value, let's call them k and l, then we know that inc will end up at value k+i. We know that sum will end up at l+k*i + i*(i-1)/2.
Now, i itself is going from 1 to n. Um... hum. Let me think about this a bit more.