if "or pipes" (||) bug? - if-statement

I'm looping through my view's subviews (with a total of 10 subviews).
Before doing so, I declare a new int to be used as a counter.
I'm checking if the count isn't equal to a hard-coded value (!=):
int count = 0;
for (UIView *subview in self.view.subviews) {
count = count + 1;
if (count != 5) {
NSLog(#"Hello");
} else {
NSLog(#"World");
}
}
With this, NSLog(#"World"); is invoked when the count is equal to "5" (as expected):
Hello
Hello
Hello
Hello
World
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Now to the issue, if I add "or pipes" (||), NSLog(#"World"); is never invoked (if isn't validated).
int count = 0;
for (UIView *subview in self.view.subviews) {
count = count + 1;
if (count != 5 || count != 6) {
NSLog(#"Hello");
} else {
NSLog(#"World");
}
}
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Now this issue can ofc be fixed by changing the syntax, but my question is why isn't the if validated?
It should be noted, that changing the "not equal" (!=) to "is equal" (==) solves the issue.
Is this a bug, or have I missed something?

Your conditional is always true. Given count != 5 || count != 6, if count == 5 then the latter half is true; if count == 6 then the former half is true; and if count equals anything else, the statement is also true.
You may have meant to use && instead.

Related

Why is the dry run of finding prime number in a given range not working as expected?

n=int(input("Enter a number"))
for num in range(2,n+1):
for i in range(2,num):
if(num%i==0):
break
else:
print(num,end="")
Here is the dry run-:
https://imgur.com/a/8cyBulI
Everything is fine except for 2 where I am not getting 2 as output. What has gone wrong here? I don't understand what is gone wrong here?
2 mod 2 is 0, so your loop breaks.
Instead of checking if your number is divisible by every integer up to the number, try checking it only against the array of primes you have already found - this should be more efficient, and also give the output you are looking for :-)
EDIT:
Here is some code I wrote in JavaScript as an example of my suggestion:
let n = 5
let foundPrimes = []
for (let num = 2; num <= n; num++){
let divisible = false
for (let prime of foundPrimes){
if (num%prime == 0) {
divisible = true
break;
}
}
if (!divisible) {
foundPrimes.push(num)
}
}
console.log(foundPrimes)

Algorithm for permutations of given characters with repetition with conditions C++

So I need to make a program that lists all permutations.
There are 4 characters:
"1",
"2",
"R",
"T"
The conditions is that the "R" needs to have "1" before and after him so it sits like this 1-R-1
The "T" condition is that either "1" or "2" are after him so it sits like this T-1 or T-2
The max length should be 10
The output should be like this:
111
112
121
122
1R1
1T1
1T2
211
212
221
222
2T1
2T2
T11
T12
T21
T22
I have managed to figure out the permutations part but I just cannot make them work with the conditions
void displayPermutation(string permutation[], int length){
int i;
for (i=0;i<length;i++){
cout<<permutation[i];
}
cout << endl;
}
void getPermutations(string operatorBank[], int operatorCount,
string permutation[],int permutationLength, int curIndex){
int i;
//stop recursion condition
if(curIndex == permutationLength){
displayPermutation(permutation,permutationLength);
}
else{
for(i = 0; i < operatorCount; i++){
permutation[curIndex] = operatorBank[i];
getPermutations(operatorBank,operatorCount,permutation,
permutationLength,curIndex+1);
}
}
}
int main ()
{
int operatorCount = 4;
int permutationLength = 3;
string operatorBank[] = {"1","2","R","T"};
string permutation[] = {"","","",""}; //empty string
int curIndex = 0;
getPermutations(operatorBank,operatorCount,permutation,
permutationLength,curIndex);
return 0;
}
You got your terms a little mixed up. You're not talking about permutations[1] but about combinations[2].
As far as I can tell you already have the algorithm (recursive backtracking) you're just not checking if your solution is valid, by filtering the solution space. So you're generating all solutions without taking into account any constraint and you print a solution when you reached the permutationLength. At this step you can also check if the solution is valid by checking if it abides by the conditions. If it is you print it, if not you discard it.
Strategy for this would be:
Look for R and check if permutation[idx-1] is 1 and permutation[idx+1] is 1
Look for T and check if permutation[idx+1] is either 1 or 2.
You only print the solution if these conditions are met!
...
if(curIndex == permutationLength){
if (solutionValid()) {
displayPermutation(permutation,permutationLength);
}
}
...
https://mathworld.wolfram.com/Permutation.html
https://mathworld.wolfram.com/Combination.html
Do you mean a recursion like this?
function f(n, str=""){
if (!n)
return [str];
let result = [];
if (n >= 3)
result = result.concat(f(n - 3, str + "1R1"));
if (n >= 2)
result = result
.concat(f(n - 2, str + "T1"))
.concat(f(n - 2, str + "T2"));
return result
.concat(f(n - 1, str + "1"))
.concat(f(n - 1, str + "2"));
}
console.log(f(3));

String.split not counting the last empty elements

Look at the following 2 examples. How to make sure the 2nd one prints 4 as well?
String s="a|b|c|d"
println(s.split("\\|").length)
//prints 4
s="a|b||"​​​​​​​​​​​​
println(s.split("\\|").length)​
//prints 2
To keep the empty token, use split with limit = -1
println(s.split("\\|", -1).length)​
Split wont allow you to have null values when you iterate. So the following code will work.
int counter = 0;
for(int i = 0 ; i < s.length();i++)
{
if(s.charAt(i) == '|')
{
counter++;
}
}
System.out.println(counter);

Merge 2 files and sort them

I have 2 txt files where I have numbers > 0 and I have to combine and sort them. Also there cannot be 2 same values.
Here are values of files.
File1:
1
2
3
4
5
6
7
File2:
1
3
6
8
10
The output should look like this:
1
2
3
4
5
6
7
8
10
The code which I have so far:
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fr1,*fr2;
int fst, snd, p[256], i=0, n=0;
bool f1=true,f2=true;
fr1 = fopen("txt/cisla.txt","r");
fr2 = fopen("txt/cisla2.txt","r");
while(feof(fr1) == 0 && feof(fr2) == 0)
{
if (f1) fscanf(fr1, "%d", &fst);
if (f2) fscanf(fr2, "%d", &snd);
printf("%d - %d\n", fst, snd);
if (fst == snd)
{
f1 = true;
f2 = true;
p[i] = fst;
} else if (fst > snd)
{
p[i] = snd;
f1 = false;
f2 = true;
} else
{
f2 = false;
f1 = true;
p[i] = fst;
}
i++;
}
fclose(fr1);
fclose(fr2);
printf("\n\n\n");
for(int j = 0; j < i; j++)
{
printf("%d\n", p[j]);
}
return 0;
}
The result of this is:
1 - 1
2 - 3
3 - 3
4 - 6
5 - 6
6 - 6
7 - 8
1
2
3
4
5
6
7
The bottom part is the array. At top I am writing the values which are read. The thing is it seems to stop at the end of the first file but I want it to continue the second one even if the first one is at the end
The thing is it seems to stop at the end of the first file
That's because you told it to do so - the continuation condition that you have is that both feofs returned zero:
while(feof(fr1) == 0 && feof(fr2) == 0) {
...
}
I want it to continue the second one even if the first one is at the end
Add two more loops after the first one, to write out the "tail" of the file with the larger elements:
while(feof(fr1) == 0 && feof(fr2) == 0) {
... // Do the merge
}
while(feof(fr1) == 0) {
... // Read from fr1, and write to the output
}
while(feof(fr2) == 0) {
... // Read from fr2, and write to the output
}
Your while loop says to continue while BOTH files are not at the end; I think you want it to continue as long as EITHER is not at the end. Of course, you'd better be sure not to try and read from the one that IS at the end...
This small improvement could be of help.
while(feof(fr1) == 0 || feof(fr2) == 0)
{}
This is because you want to loop or read untill both the files are not completely read.
Btw, why can't you use some generic container..
Your question is tagged as C++, but the code presented doesn't look like it. It looks more like C.
It's much easier to accomplish what you're trying to do if you avoid reinventing the wheel and use the C++ standard library.
Here's a simple example of how to do it using std::vector and the standard library:
// Open file streams for reading.
std::ifstream fr1{"file1.txt"};
std::ifstream fr2{"file2.txt"};
// Read number tokens into a std::vector from both files.
std::vector<int> v{std::istream_iterator<int>{fr1}, std::istream_iterator<int>{}};
v.insert(std::begin(v), std::istream_iterator<int>{fr2}, std::istream_iterator<int>{});
// Sort the vector.
std::sort(std::begin(v), std::end(v));
// Remove consecutive duplicates (move them to back of vector).
auto end = std::unique(std::begin(v), std::end(v));
// Remove duplicate elements.
if (end != std::end(v)) {
v.erase(end, std::end(v));
}
// Output vector.
for (int i : v) {
std::cout << i << std::endl;
}
Look at this live example

C++ reading a sequence of integers

gooday programers. I have to design a C++ program that reads a sequence of positive integer values that ends with zero and find the length of the longest increasing subsequence in the given sequence. For example, for the following
sequence of integer numbers:
1 2 3 4 5 2 3 4 1 2 5 6 8 9 1 2 3 0
the program should return 6
i have written my code which seems correct but for some reason is always returning zero, could someone please help me with this problem.
Here is my code:
#include <iostream>
using namespace std;
int main()
{
int x = 1; // note x is initialised as one so it can enter the while loop
int y = 0;
int n = 0;
while (x != 0) // users can enter a zero at end of input to say they have entered all their numbers
{
cout << "Enter sequence of numbers(0 to end): ";
cin >> x;
if (x == (y + 1)) // <<<<< i think for some reason this if statement if never happening
{
n = n + 1;
y = x;
}
else
{
n = 0;
}
}
cout << "longest sequence is: " << n << endl;
return 0;
}
In your program, you have made some assumptions, you need to validate them first.
That the subsequence always starts at 1
That the subsequence always increments by 1
If those are correct assumptions, then here are some tweaks
Move the cout outside of the loop
The canonical way in C++ of testing whether an input operation from a stream has worked, is simply test the stream in operation, i.e. if (cin >> x) {...}
Given the above, you can re-write your while loop to read in x and test that x != 0
If both above conditions hold, enter the loop
Now given the above assumptions, your first check is correct, however in the event the check fails, remember that the new subsequence starts at the current input number (value x), so there is no sense is setting n to 0.
Either way, y must always be current value of x.
If you make the above logic changes to your code, it should work.
In the last loop, your n=0 is execute before x != 0 is check, so it'll always return n = 0. This should work.
if(x == 0) {
break;
} else if (x > y ) {
...
} else {
...
}
You also need to reset your y variable when you come to the end of a sequence.
If you just want a list of increasing numbers, then your "if" condition is only testing that x is equal to one more than y. Change the condition to:
if (x > y) {
and you should have more luck.
You always return 0, because the last number that you read and process is 0 and, of course, never make x == (y + 1) comes true, so the last statement that its always executed before exiting the loop its n=0
Hope helps!
this is wrong logically:
if (x == (y + 1)) // <<<<< i think for some reason this if statement if never happening
{
Should be
if(x >= (y+1))
{
I think that there are more than one problem, the first and most important that you might have not understood the problem correctly. By the common definition of longest increasing subsequence, the result to that input would not be 6 but rather 8.
The problem is much more complex than the simple loop you are trying to implement and it is usually tackled with Dynamic Programming techniques.
On your particular code, you are trying to count in the if the length of the sequence for which each element is exactly the successor of the last read element. But if the next element is not in the sequence you reset the length to 0 (else { n = 0; }), which is what is giving your result. You should be keeping a max value that never gets reset back to 0, something like adding in the if block: max = std::max( max, n ); (or in pure C: max = (n > max? n : max );. Then the result will be that max value.