This question already has answers here:
What is the result of % in Python?
(20 answers)
Closed 6 years ago.
for x in xrange(12):
if x % 2 == 1:
continue
print x
i know what it does, but the language doesn't make sense to me. In particular the second line is where i am lost.
if x % 2 == 1 means "if x modulo 2 equals 1".
Modulo (or mod) is the remainder after division. So, for example:
3 mod 2 = 1
12 mod 5 = 2
15 mod 6 = 3
For x mod 2, you're there's a remainder if and only iff x is odd. (Because all even numbers are divisible by two with 0 remainder.) Likewise, odd numbers will always have a remainder of 1.
So x % 2 == 1 returns true if x is odd.
Related
This question already has an answer here:
How to use arrayformula with formulas that do not seem to support arrayformulas?
(1 answer)
Closed 4 months ago.
Using an array formula I want to find the max value of each row of a range and get the resulting range to work with it further.
The problem occurs as soon as I add the MAX() statement since it does seem to behave strangely within an array formula. Even if you ad commands which will give you multiple values within the MAX() statement it does always only return one single value.
E.g. this will give you the ranges which I want to get the max of:
=ARRAYFORMULA(ADDRESS(ROW(E1:E11); COLUMN() + 1; 4) & ":" & ADDRESS(ROW(E1:E11); COLUMN() + 4; 4))
The result looks like the following:
F1:I1
F2:I2
F3:I3
F4:I4
F5:I5
F6:I6
F7:I7
F8:I8
F9:I9
F10:I10
F11:I11
If I now add INDIRECT() to make those to actual ranges and add MAX() it should return the max of each of those ranges since the array formula should go through the ROW(E1:11) as it did bevor. However, the result of this new formula
=ARRAYFORMULA(MAX(INDIRECT(ADDRESS(ROW(E1:E11); COLUMN() + 1; 4) & ":" & ADDRESS(ROW(E1:E11); COLUMN() + 4; 4))))
rather is one single value, the maximum of the first range.
I have even tried to bypass the problem by adding an IF() statement for the array formula to iterate through the rows. Doing so, it did give me a result for all 11 rows, however, the result always was the same (the max of the first row).
The new formula:
=ARRAYFORMULA(IF(ROW(E1:E11) = ROW(E1:E11); MAX(INDIRECT(ADDRESS(ROW(E1:E11); COLUMN() + 1; 4) & ":" & ADDRESS(ROW(E1:E11); COLUMN() + 4; 4))); ""))
The new result (left column are the results of the formula, trying to get the max of each row to its right):
10 7 10 4 1
10 10 8 1 2
10 4 5 9 4
10 10 10 2 2
10 10 10 5 10
10 10 6 9 5
10 4 5 7 3
10 6 9 4 7
10 5 5 7 3
10 9 2 3 10
10 10 3 9 10
=QUERY(TRANSPOSE(QUERY(TRANSPOSE(F1:I),
"select "®EXREPLACE(JOIN( , ARRAYFORMULA(IF(LEN(F1:F&G1:G&H1:H&I1:I),
"max(Col"&ROW(F1:F)-ROW(F1)+1&"),", ""))), ".\z", "")&"")),
"select Col2")
I realise that there are several topics already covering this. But my question is not regarding how to build such an algorithm, rather in finding what mistake I have made in my implementation that's causing a single test out of dozens to fail.
The challenge: supplied with a std::list<int> of random numbers, determine the last digit of x1 ^ (x2 ^ (x3 ^ (... ^ xn))). These numbers are large enough, or the lists long enough, that the result is astronomical and cannot be handled by traditional means.
My solution: I chose to use a modular arithmetic approach. In short, the last digit of these huge powers will be the same as that of a reduced power consisting of the first digit of the base (mod 10), raised to the last two digits of the exponent (mod 100). The units in a sequence of powers repeat in patterns of 4 at most, so we can use mod 4 to reduce the exponent, offset by 4 to avoid remainders of 0. At least, this is my understanding of it so far based on the following resources: brilliant / quora.
#include <list>
#include <cmath>
int last_digit(std::list<int> arr)
{
// Break conditions, extract last digit
if (arr.size() == 1) return arr.back() % 10;
if (arr.size() == 0) return 1;
// Extract the last 2 items in the list
std::list<int> power(std::prev(arr.end(), 2), arr.end());
arr.pop_back(); arr.pop_back();
// Treat them as the base and exponent for this recursion
long base = power.front(), exponent = power.back(), next;
// Calculate the current power
switch (exponent)
{
case 0: next = 1; break;
case 1: next = base % 100; break;
default: next = (long)std::pow(base % 10, exponent % 4 + 4) % 100;
}
if (base != 0 && next == 0) next = 100;
// Add it as the last item in the list
arr.push_back(next);
// Recursively deal with the next 2 items in the list
return last_digit(arr);
}
Random example: 123,232 694,027 140,249 ≡ 8
First recrusion: { 123'232, 694'027, 140'249 }
base: 694,027 mod 10 = 7
exponent: 140,249 mod 4 + 4 = 5
next: 75 = 16,807 mod 100 = 7
Second recursion: { 123'232, 7 }
base: 123,232 mod 10 = 2
exponent: 7 mod 4 + 4 = 7
next: 27 = 128 mod 100 = 28
Third recursion: { 28 }
return: 28 mod 10 = 8
The problem: this works for dozens of test cases (like the one above), but fails for 2 2 101 2 ≡ 6.
By hand:
1012 = 10,201
210,201 mod 4 = 0, + 4 = 4
24 = 16 // 6 -correct
Following the algorithm, however:
First recursion: { 2, 2, 101, 2 }
base: 101 mod 10 = 1
exponent: 2 mod 4 + 4 = 6
next: 16 = 1 mod 100 = 1
Second recursion: { 2, 2, 1 } (we can already see that the result is going to be 4)
exponent = 1, next = 2 mod 100 = 2
Third recursion: { 2, 2 }
base: 2 mod 10 = 2
exponent: 2 mod 4 + 4 = 6
next: 26 = 64 mod 100 = 64
Fourth recursion: { 64 }
return 64 mod 10 = 4 // -wrong
In a way, I see what's going on, but I'm not entirely sure why it's happening for this one specific case, and not for dozens of others. I admit I'm rather pushing the limits of my maths knowledge here, but I get the impression I'm just missing a tiny part of the puzzle.
I reckon this post is long and arduous enough as it is. If anyone has any insights into where I'm going wrong, I'd appreciate some pointers.
There's a lot of problems regarding the modulo of a really big number and a lot of the sol'ns back there was basically based on basic number theory. Fermat's Little Theorem, Chinese Remainder Theorem, and the Euler's Phi Function can all help you solve such problems. I recommend you to read "A Computational Introduction to Number Theory and Algebra" by Victor Shoup. It'll help you a lot to better simplify and approach number theory-related questions better. Here's the link for the book in case you'll browse this answer.
I have a question about prime numbers algorithm.
why in the following pseudo code i increases by 6 and not by 2 every iteration?
function is_prime(n)
if n ≤ 1
return false
else if n ≤ 3
return true
else if n mod 2 = 0 or n mod 3 = 0
return false
let i ← 5
while i * i ≤ n
if n mod i = 0 or n mod (i + 2) = 0
return false
i ← i + 6
return true
Thanks!
If it increased by 2 it would be testing almost everything twice, that wouldn't make any sense. So I assume you mean: how can it get away with not testing every odd number?
This is because every prime p greater than 3 is of the form 6n±1. Proof:
Consider the remainder r = p mod 6. Obviously r must be odd. Notice also that r cannot be 3, because then p would be divisible by 3, making it not a prime. This leaves only the possibilities 1 and 5, which correspond p being of the form 6n+1 or the form 6n-1 respectively.
The effect is that it avoid testing multiples of 3. Dividing by a multiple of 3 is redundant, because we already know that n is not a multiple of 3, so it cannot be the multiple of a multiple of 3 either.
The assignment in the loop body is i <- i + 6, not i <- i + 2. In the if statement the expression i + 2 just becomes a new value. There is no assignment operator in that expression.
The algorithm is based on the fact that prime numbers can be predicted using the formula 6k ± 1 and this does not apply on 2 and 3.
For instance
(6 * 1) - 1 = 5
(6 * 2) - 1 = 11
(6 * 3) - 1 = 17
The list goes on and on.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
Why do I get this output: 0 1 2 3 0 1 2 3 0 1 after running the code below? Doesn't the modulus operation finds the remainder after division of one number by another?
#include <iostream>
using namespace std;
int main ()
{
for (int i=0; i< 10; ++i)
cout << i % 4 << " ";
}
The answer is correct. '%' mean "reminder". The % operator is remainder operator. The A % B operator actually answer the question “If I divided A by B using integer arithmetic, what would the remainder be?”
dividend = quotient * divisor + remainder
0 % 4 = 0
1 % 4 = 1
2 % 4 = 2
3 % 4 = 3
4 % 4 = 0
5 % 4 = 1
.....
etc..
For negative number...
1 % (-4) = 1
(-2) % 4 = -2
(-3) % (-4) = -3
With a remainder operator, the sign of the result is the same as the sign of the dividend
you can read more at What's the difference between “mod” and “remainder”?
Yes, that's how modulus works. The output is correct.
0 % 4 = 0
1 % 4 = 1
2 % 4 = 2
3 % 4 = 3
4 % 4 = 0
5 % 4 = 1
...
Take the number, remove as many 4's as you can. Whatever is left over is the modulus.
It does.0 / 4 = 0 remainder 01 / 4 = 0 remainder 1and so on.
Modulus operator returns the remainder after dividing the first number with the second one.
0 % 4 = 0
1 % 4 = 1
2 % 4 = 2
3 % 4 = 3
4 % 4 = 0
5 % 4 = 1
6 % 4 = 2
7 % 4 = 3
8 % 4 = 0
9 % 4 = 1
How is this code working for multiple of 5
bool isMultipleof5(int n)
{
/* If n is a multiple of 5 then we make sure that last
digit of n is 0 */
if ( (n&1) == 1 )
n <<= 1;
float x = n;
x = ( (int)(x*0.1) )*10;
/* If last digit of n is 0 then n will be equal to (int)x */
if ( (int)x == n )
return true;
return false;
}
It first makes n divisable by 2.
Next, it checks if it is divisable by 10 by multiplying with 0.1 and again with 10. The idea that if it is divisable by 10, you will get back to the original, and only then.
So, if the modifies n is divisable by 10 - it is certainly divisable by 5 as well, and since modified n is always divisable by 2, if it is divisable by 5 it will be divisable by 10, and the algorithm works.
NOTE: This is very unsuggested and especially might break with large values due to floating point precision issues. using the % operator should be prefered: return (n % 5) == 0
This is how the code works with some examples.
if ( (n&1) == 1 ) //Checks if the number is odd
n <<= 1; //Multiplies the number by 2 if odd
x = ( (int)(x * 0.1) //Divides the number 10 then truncates any decimal places
* 10 ) //Multiplies it back by 10
if ( (int)x == n ) //If the floating point value equals the (semi) original value its divisible by 5
return true;
return false; //Other wise false
Example:
15 & 1 == 1 //15 is odd
15 <<= 1; //n is now 30
30 / 10 = 3;
3 * 10 = 30; //x is now 30
30 == 30 //15 is a multiple of 5
17 & 1 == 1 //17 is odd
17 <<= 1; //n is now 34
34 / 10 = 3.4;
((int)3.4 = 3) * 10 = 30; //x is now 30
30 != 34 //17 is not a multiple of 5.
As others said though just simply use the mod operator %.
This is how it works:
Double the number. Now anything ending in 5 will be divisible 10 (and also divisible by 5). n <<= 1; (the check for oddness is unnecessary (n&1) == 1)
Divide it by 10, and cast away the fractional part. (int)(x*0.1)
Multiply it by 10, so now we have the same number as in step 1 only if the number in step 1 was already divisible by 10.
The use of floating point to divide by 10 makes this algorithm dangerous and probably incorrect for large values.
Try this
bool isMultipleof5(int n)
{
return (n%5) == 0;
}
A simpler way would be
bool isMultipleof5(int n)
{
return 0 == ( n % 5 ) ;
}
#define IS_MULTIPLE_OF_5(n) (((n)%5) ? 0 : 1)
I'd agree that (n % 5) == 0 would be an ideal solution, but that wasn't really the question.
This code works because it first checks if the input is odd. If it is, it multiplies by two. Since all odd multiples of 5 end with a 5, multiplying by 2 gives a number that ends with 0.
Then it checks if the last digit is 0. This can only happen if it started as a 0 (i.e. was even, we didn't change it) or if it was odd and ended in a 5 (we multiplied by 2). So, if it ends in 0 then the input must have been divisible by 5.
I'd add that this is also an awkward way to check the value of the last digit. I'd suggest n % 10 == 0 instead, but like others mentioned... you could have just used n % 5 == 0 in the first place ;).