I'm new to programming, can someone take two minutes to explain this statement for me? how can I write it like this :
if (condition) {...} else {...}
if (myFunction(i == 8? (j + 1): j, (j + 1) % 9))
{
return true;
}
The function is called with two arguments. First one uses a ternary operator to check if i (the index) is 8; if so, increment j, else leave j as is.
Second argument increments j by 1, it uses primary expression operator around j+1 because arithmetic + has lower precedence than modulus (%) http://www.swansontec.com/sopc.html. If j is 1 and we increment by 1, then 2 % 9 is 2, since the modulo operation returns the remainder. This assumes C style syntax.
int arg1 = i == 8 ? (j + 1) : j;
int arg2 = (j + 1) % 9;
if (myFunction(arg1,arg2))
{
return true;
}
else
{
return false;
}
Related
I am learning Dafny, attempting to write a specification for the hamming weight problem, aka the number of 1 bits in a number. I believe I have gotten the specification correct, but it still doesn't verify. For speed of verification I limited it to 8 bit numbers;
problem definition: https://leetcode.com/problems/number-of-1-bits/
function method twoPow(x: bv16): bv16
requires 0 <= x <= 16
{
1 << x
}
function method oneMask(n: bv16): bv16
requires 0 <= n <= 16
ensures oneMask(n) == twoPow(n)-1
{
twoPow(n)-1
}
function countOneBits(n:bv8): bv8 {
if n == 0 then 0 else (n & 1) + countOneBits(n >> 1)
}
method hammingWeight(n: bv8) returns (count: bv8 )
ensures count == countOneBits(n)
{
count := 0;
var i := 0;
var n' := n;
assert oneMask(8) as bv8 == 255; //passes
while i < 8
invariant 0 <= i <= 8
invariant n' == n >> i
invariant count == countOneBits(n & oneMask(i) as bv8);
{
count := count + n' & 1;
n' := n' >> 1;
i := i + 1;
}
}
I have written the same code in javascript to test the behavior and example the invariant values before and after the loop. I don't seen any problems.
function twoPow(x) {
return 1 << x;
}
function oneMask(n) {
return twoPow(n)-1;
}
function countOneBits(n) {
return n === 0 ? 0 : (n & 1) + countOneBits(n >> 1)
}
function hammingWeight(n) {
if(n < 0 || n > 256) throw new Error("out of range")
console.log(`n: ${n} also ${n.toString(2)}`)
let count = 0;
let i = 0;
let nprime = n;
console.log("beforeloop",`i: ${i}`, `n' = ${nprime}`, `count: ${count}`, `oneMask: ${oneMask(i)}`, `cb: ${countOneBits(n & oneMask(i))}`)
console.log("invariants", i >= 0 && i <= 8, nprime == n >> i, count == countOneBits(n & oneMask(i)));
while (i < 8) {
console.log("");
console.log('before',`i: ${i}`, `n' = ${nprime}`, `count: ${count}`, `oneMask: ${oneMask(i)}`, `cb: ${countOneBits(n & oneMask(i))}`)
console.log("invariants", i >= 0 && i <= 8, nprime == n >> i, count == countOneBits(n & oneMask(i)));
count += nprime & 1;
nprime = nprime >> 1;
i++;
console.log('Afterloop',`i: ${i}`, `n' = ${nprime}`, `count: ${count}`, `oneMask: ${oneMask(i)}`, `cb: ${countOneBits(n & oneMask(i))}`)
console.log("invariants", i >= 0 && i <= 8, nprime == n >> i, count == countOneBits(n & oneMask(i)));
}
return count;
};
hammingWeight(128);
All invariants evaluate as true. I must be missing something. it says invariant count == countOneBits(n & oneMask(i) as bv8); might not be maintained by the loop. Running the javascript shows that they are all true. Is it due to the cast of oneMask to bv8?
edit:
I replaced the mask function with one that didn't require casting and that still not resolve the problem.
function method oneMaskOr(n: bv8): bv8
requires 0 <= n <= 8
ensures oneMaskOr(n) as bv16 == oneMask(n as bv16)
{
if n == 0 then 0 else (1 << (n-1)) | oneMaskOr(n-1)
}
One interesting thing I found is that it shows me a counter example where it has reached the end of the loop and the final bit of the input variable n is set, so values 128 or greater. But when I add an assertion above the loop that value equals the count at the end of the loop it then shows me the another value of n.
assert 1 == countOneBits(128 & OneMaskOr(8)); //counterexample -> 192
assert 2 == countOneBits(192 & OneMaskOr(8)); //counterexample -> 160
So it seems like it isn't evaluating the loop invariant after the end of loop? I thought the whole point of the invariants was to evaluate after the end of loop.
Edit 2:
I figured it out, apparently adding the explicit decreases clause to the while loop fixed it. I don't get it though. I thought Dafny could figure this out.
while i < 8
invariant 0 <= i <= 8
invariant n' == n >> i
invariant count == countOneBits(n & oneMask(i) as bv8);
decreases 8 - i
{
I see one line in the docs for loop termination saying
If the decreases clause of a loop specifies *, then no termination check will be performed. Use of this feature is sound only with respect to partial correctness.
So is if the decreases clause is missing does it default to *?
After playing around, I did find a version which passes though it required reworking countOneBits() so that its recursion followed the order of iteration:
function countOneBits(n:bv8, i: int, j:int): bv8
requires i ≥ 0 ∧ i ≤ j ∧ j ≤ 8
decreases 8-i {
if i == j then 0
else (n&1) + countOneBits(n >> 1, i+1, j)
}
method hammingWeight(n: bv8) returns (count: bv8 )
ensures count == countOneBits(n,0,8)
{
count ≔ 0;
var i ≔ 0;
var n' ≔ n;
//
assert count == countOneBits(n,0,i);
//
while i < 8
invariant 0 ≤ i ≤ 8;
invariant n' == n >> i;
invariant count == countOneBits(n,0,i);
{
count ≔ (n' & 1) + count;
n' ≔ n' >> 1;
i ≔ i + 1;
}
}
The intuition here is that countOneBits(n,i,j) returns the number of 1 bits between i (inclusive) and j (exclusive). This then reflects what the loop is doing as we increase i.
i am trying to write a program that searches through a movie script using two different string searching algorithms. However the Warning C26451: Arithmetic overflow using operator '+' on a 4 byte value then casting the result to 8 byte value keeps on coming up in the calculate hash part of the rabin karp, is there anyway to fix this? Any help would be greatly appreciated.
#define d 256
Position rabinkarp(const string& pat, const string& text) {
int M = pat.size();
int N = text.size();
int i, j;
int p = 0; // hash value for pattern
int t = 0; // hash value for txt
int h = 1;
int q = 101;
// The value of h would be "pow(d, M-1)%q"
for (i = 0; i < M - 1; i++)
h = (h * d) % q;
// Calculate the hash value of pattern and first
// window of text
for (i = 0; i < M; i++)
{
p = (d * p + pat[i]) % q;
t = (d * t + text[i]) % q;
}
// Slide the pattern over text one by one
for (i = 0; i <= N - M; i++)
{
// Check the hash values of current window of text
// and pattern. If the hash values match then only
// check for characters on by one
if (p == t)
{
/* Check for characters one by one */
for (j = 0; j < M; j++)
{
if (text[i + j] != pat[j])
break;
}
// if p == t and pat[0...M-1] = txt[i, i+1, ...i+M-1]
if (j == M)
return i;
}
// Calculate hash value for next window of text: Remove
// leading digit, add trailing digit
if (i < N - M)
{
t = (d * (t - text[i] * h) + text[i + M]) % q;// <---- warning is here
[i + M
// We might get negative value of t, converting it
// to positive
if (t < 0)
t = (t + q);
}
}
return -1;
}
context for the error
You're adding two int which is 4 bytes in your case, whereas std::string::size_type is probably 8 bytes in your case. Said conversion happens when you do:
text[i + M]
Which is a call to std::string::operator[] taking a std::string::size_type as parameter.
Use std::string::size_type, which is usually the same as size_t.
gcc does not give any warning for that, even with -Wall -Wextra -pedantic, so I guess you activated really every warning you can, or something similar
I need to create a recursive function that counts the 2 and 6 from the number a user inputs.
For example if the user enters 26827 the count is 3.
It works with certain numbers and certain numbers it doesn't. Can someone please modify my function making sure its recursive and using very basic C++ language as I have used. Thank you! (I believe something is wrong with return type.)
int count(int n) {
static int count = 0;
if (n == 2 || n == 6) count++;
if ((n % 10 == 2) || (n % 10 == 6)) {
count++;
count(num / 10);
}
else return count;
}
One liner for fun.
int f(int n) {
return n == 0 ? 0 : (n%10==2 || n%10==6) + f(n/10);
}
int count(int n) {
if(n <= 0) return 0; // Base Condition
int countDig = 0; // Initalizing Count of digits
if(n % 10 == 2 || n % 10 == 6) // Checking whether the LSB is 2 or 6
countDig ++; // If it is then incrementing the countDig
countDig += count(n / 10); // Calling the recurive function by sending the number except its LSB
//And incrementing counter according to it
return countDig; // Returning the final count
}
you don't need to have a static value counter. It can be easily done as above. Please refer to comments given. Second the error in your code is you only calling the recursion if the LSB is 2 or 6. The recursion should be put outside the if condition in your code. Why are you using num variable. I think it should be n
You don't need statics
This should work (note return c + count(n / 10) line. That's the main recursion here)
int count(int n)
{
int c = 0;
if(n % 10 == 2 || n % 10 == 6)
c = 1;
if(n < 10)
return c;
return c + count(n / 10);
}
If you want to make it with recursion , another procedure you can apply using string manipulation.
PseudoCode:
Function ( int n):
1. Make n as a string. ( Convert Number to string)
2. Collect the first character (char C) of the string and remove the character from the string.
3. Make the main string again as a number n. ( Convert String to Number).
4. Check the character C , which is number 2 or 6 or not, count it with a flag.
5. Enter base case for which the recursion will stop.
6. return the number n , inside the Function (n) for recursion.
What is the correct syntax to use a while loop that exits when a boolean is true.
I'm not sure if this is works right:
while (CheckPalindrome(a, reverse) == false)
{
CalcPalindrome(a, reverse);
n = a;
while (n != 0)
{
remainder = n % 10; //Finds the 1's digit of n
reverse = reverse * 10 + remainder;
n /= 10;
}
CheckPalindrome(a, reverse);
}
You only need to call CheckPalindrome() once, and that's in while(CheckPalindrome())
Also, the proper syntax is while(!CheckPalindrome())
So your optimized code would be:
while (!CheckPalindrome(a, reverse))
{
n = a;
while (n != 0)
{
remainder = n % 10; //Finds the 1's digit of n
reverse = reverse * 10 + remainder;
n /= 10;
}
}
I'm not sure what that inner while loop is supposed to do, but that's the proper syntax for breaking from a while loop when a function returns false
I have a method which looks like this:
bool Perfect(int num) {
int sum = 0;
for (int i = 1; i < num; i++)
{
num%i == 0 ? sum += i : continue;
}
return sum == num ? true : false;
}
I'm trying to combine here ? operator with continue operator...
So logically if the statement here is false in this line:
num%i == 0 ? sum += i : continue;
I will just skip the iteration or do nothing?
If I do it like this the compiler reports an error like:
expected an expression
And in case like this:
num%i == 0 ? sum += i
It says:
Expected a ':'
Is there any way to use continue with ? operator or just simply avoid false case somehow ???
bool Perfect(int num) {
int sum = 0;
for (int i = 1; i < num; i++)
{
if(num % i == 0)
sum += i;
}
return sum == num;
}
Use an if statement. No need of continue since you have no other statement after sum += i.
C++ and C have both statements and expressions (notice that an assignment or a function call is an expression, and that expressions are statements). They are different syntactic (and semantical) things.
You could have coded (but this is weird style as a statement reduced to a ?: conditional expression) inside your for loop:
(num%i == 0) ? (sum += i) : 0;
(when num%i is non-zero, that evaluates to 0 which has no significant side effect; BTW that last occurrence of 0 could be 1234 or any constant integral expression)
Some programming languages (notably Scheme, read SICP) have only expressions (and no statements).
The ternary ?: operator applies to expressions and gives an expression (so can't be used for statements).
Conditional statements use the if keyword. In your case it is much more readable (because you are using sum += i only for its side effect) and an if statement is here easier to understand.
You can't use a ternary operator in this way. You would normally use it for assigning a value to a variable based on an expression being true or false. Eg.
int j, i,
j = (i == 2) ? 5: 10;
If i is equal to 2 then j is given the value of 5 else if i is not equal to 2 then j is given the value of 10.