Uncontrolled looping and function Skipping in C++? - c++

I am trying to read two user inputted numbers from a keypad onto a discovery board. I have the code working for reading the first number in but for some reason when it hits the same Keypad(); function for the second time it doesn't appear to be calling the function up to allow an input instead it skips over the scan and prints the lines under it and if you press the button to start over it is random where the program picks up, any ideas what could be causing this. I am compiling on mbeds online Ide. below is the code as well.
#include <iostream>
#include "mbed.h"
DigitalIn columns[3] = {PB_6, PB_7, PD_0}; // Columns for digital input
DigitalOut rows[4] = {PA_5, PA_1, PA_2, PA_3}; // rows for digital output
DigitalIn startButton(USER_BUTTON);
DigitalOut led1(LED1); // reference LED
int numpad[4][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {-2, 0, -1}}; // keypad
int Total();
int Keypad();
int c = 0;
int Read;
int Num1 = 0;
int SelectOp();
int Oper;
int main() {
while (1) {
if (startButton == 1) {
printf("%s\n\rInput First Number\n\r");
wait(.5);
Keypad();
int First = Num1;
Num1 = 0;
printf("%s\n\r Your first number is ");
printf("%i", First);
printf("%s\n\r Input your second number\n\r");
wait(.5);
Keypad(); // this seems to be getting skipped
int Second = Num1;
Num1 = 0;
printf("%s\n\r Your Second number is ");
printf("%i", Second);
printf("%s\n\rSelect Operator: 1(+), 2(-), 3(*), 4(/)");
Keypad();
Oper = Num1;
}
}
}
int Keypad() {
columns[0].mode(PullUp);
columns[1].mode(PullUp);
columns[2].mode(PullUp);
while (1) {
if (Read == -1) {
return Num1;
}
for (int i = 0; i < 4; i++) {
rows[0] = 1;
rows[1] = 1;
rows[2] = 1;
rows[3] = 1;
rows[i] = 0;
wait(0.01);
for (int j = 0; j < 3; j++) {
if (columns[j] == 0) {
Read = numpad[i][j];
Total();
c++;
if (c == 5) {
c = 0;
}
wait(0.005);
while (columns[j] == 0)
;
}
}
}
}
}
int Total() {
if (Read >= 0) {
Num1 *= 10;
Num1 += Read;
printf("%i\n\r", Num1);
} else {
return Num1;
}
return Num1;
}

When Read is set to -1 during the first loop through Keypad(), it's still -1 when you enter Keypad() again, thus returning instantly.
Using some space to echo #Scheff on the importance of scoping variables according to their expected lifetimes and thus minimizing global variables wherever possible.

Related

what changes should i have to do to in my cpp code to get correct output?

//Question
/*There are N seats in a row. You are given a string S with length N; for each valid i, the i-th character of S is '0' if the i-th seat is empty or '1' if there is someone sitting in that seat.
Two people are friends if they are sitting next to each other. Two friends are always part of the same group of friends. Can you find the total number of groups?
Input
The first line of the input contains a single integer T denoting the number of test cases. The description of T test cases follows.
The first and only line of each test case contains a single string S.
Output
For each test case, print a single line containing one integer ― the number of groups.*/
// my code
#include <iostream>
#include <string>
using namespace std;
int main() {
int t;
cin>>t;
int n=1e6;
for(int i=0;i<t;i++){
string g1;
cin>>g1;
int group;
group = 0;
for(int j=0;j<g1.length();j++){
if(g1[j] == '1'){
for(int h=1;h<n;h++){
if(g1[j+h] == '1'){
h++;
}else{
break;
}
group++;
}
} else{
continue;
}
}
cout<<group<<endl;
}
return 0;}
Example Input
4
000
010
101
01011011011110
Example Output
0
1
2
4
//my output
0
0
0
9
Based on sample output, you suppose to count '1's between zeros, which is the number of groups you have. Here is your implementation with small correction to do that.
#include <iostream>
#include <string>
using namespace std;
int main() {
int t;
cin >> t;
// int n = 1e6; --> not used
for (int i = 0; i < t; i++) {
string g1;
cin >> g1;
int group;
group = 0;
for (size_t j = 0; j < g1.length(); j++) {
if (g1[j] == '1') {
group++;
//skip all '1' before the first '0'
while (g1[j] == '1' && j < g1.length())
j++;
}
else {
continue;
}
}
cout << group << endl;
}
return 0;
}
// my code
#include <iostream>
#include <string>
using namespace std;
int main() {
int t;
cin >> t;
// you don't need n variable
// it is appropriate to use the length of the string instead
// it also will remove one warning for initialization
int n = 1e6;
for (int i = 0; i < t; i++) {
string g1;
cin >> g1;
int group; // you can use int group = 0; avoiding the statement below
group = 0;
// size_t stringLength = g1.length();
for (int j = 0; j < g1.length(); j++) {
if (g1[j] == '1') {
group++; // you need to add it here to starts counting
// better this way -> for (size_t h = 1; h < stringLength; h++)
for (int h = 1; h < n; h++) { // h < n && (j+h)<stringLength
if (g1[j + h] == '1') {
// you increasing h value twice - first in for statement, second here
// instead, you need to set j to j+h value
//h++;
// you just "moving" through the string till next'0'
j = j + h;
}
else {
break;
}
// this will increase group count for each next '1' in the string
// this is why you got 9 for the last string in your's example
//group++;
}
}
// this is not needed
//else {
// continue;
//}
}
cout << group << endl;
}
return 0;
}

How to get the longest sequence of prime numbers from an array in c++

I'm trying to get the longest(largest) sequence of consecutive prime numbers from an array..
On first test with 10 elements in the array works , but when i tried with 15 elements like: 3, 5, 7, 8, 9, 11, 13, 17, 19, 20, 23, 29, 31, 37, 41 it spit out 4, which is incorrect.
#include <iostream>
using namespace std;
int main()
{
int bar[100];
int x, j = 0;
int maxseq = 0;
int longestseqstart = 0;
cout << "How big is the array? =";
cin >> x;
for (int i = 0; i < x; i++) {
cout << "bar[" << i << "]=";
cin >> bar[i];
}
for (int i = 1; i < x - 1; i = j) {
int startseq = i;
int seq = 0;
j = i + 1;
bool prim = true;
int a = bar[i];
for (int d = 2; d <= a / 2; d++) {
if (a % d == 0) {
prim = false;
}
}
while (j < x && prim) {
seq++;
if (seq > maxseq) {
maxseq = seq;
longestseqstart = i;
}
int a = bar[j];
for (int d = 2; d <= a / 2; d++) {
if (a % d == 0) {
prim = false;
}
}
j++;
}
}
cout << "The longest sequence is: ";
cout << maxseq;
return 0;
}
I would write the program the following way
#include <iostream>
#include <iterator>
#include <algorithm>
bool is_prime( unsigned int n )
{
bool prime = n % 2 == 0 ? n == 2 : n != 1;
for ( unsigned int i = 3; prime && i <= n / i; i += 2 )
{
prime = n % i != 0;
}
return prime;
}
int main()
{
unsigned int a[] = { 3, 5, 7, 8, 9, 11, 13, 17, 19, 20, 23, 29, 31, 37, 41 };
const size_t N = sizeof( a ) / sizeof( *a );
size_t maxseq = 0;
for ( auto current = std::find_if( a, a + N, is_prime );
current != a + N;
current = std::find_if( current, a + N, is_prime ) )
{
auto first = current;
current = std::find_if_not( current, a + N, is_prime );
size_t n = std::distance( first, current );
if ( maxseq < n ) maxseq = n;
}
std::cout << "The longest sequence is: " << maxseq << '\n';
return 0;
}
The program output is
The longest sequence is: 5
I did not use generic functions std::begin( a ) and std::end( a ) because in your program the array can contain less actual elements than the array dimension.
If you do not know yet standard C++ algorithms then the program can be defined the following way
#include <iostream>
bool is_prime( unsigned int n )
{
bool prime = n % 2 == 0 ? n == 2 : n != 1;
for ( unsigned int i = 3; prime && i <= n / i; i += 2 )
{
prime = n % i != 0;
}
return prime;
}
int main()
{
unsigned int a[] = { 3, 5, 7, 8, 9, 11, 13, 17, 19, 20, 23, 29, 31, 37, 41 };
const size_t N = sizeof( a ) / sizeof( *a );
size_t maxseq = 0;
size_t n = 0;
for ( size_t i = 0; i < N; i++ )
{
bool prime = a[i] % 2 == 0 ? a[i] == 2 : a[i] != 1;
for ( unsigned int j = 3; prime && j <= a[i] / j; j += 2 )
{
prime = a[i] % j != 0;
}
if ( prime )
{
if ( maxseq < ++n ) maxseq = n;
}
else
{
n = 0;
}
}
std::cout << "The longest sequence is: " << maxseq << '\n';
return 0;
}
The program output is the same as above
The longest sequence is: 5
As for your program then this loop
for (int i = 1; i < x - 1; i = j) {
skips the first element of the array that is bar[0].
And due to this statement
j = i + 1;
the calculated value of seq one less than it should be because you do not take into account that bar[i] is already prime.
Set initially seq equal to 1.
int seq = 1;
Moreover you incorrectly are determining prime numbers. For example according to your algorithm 1 is prime.
You are checking twice for prime numbers and you are using a nested loop. That's not necessary. It's enough to read all numbers, check each number, increment the count if it's a prime number and store the maximum sequence length.
#include <iostream>
#include <vector>
using namespace std;
bool isPrime(int a) {
bool prim = true;
for (int d = 2; d*d <= a; ++d) {
if (a % d == 0) {
prim = false;
}
}
return prim;
}
int main()
{
int x;
int longestseqstart = 0;
cout << "How big is the array? =";
cin >> x;
std::vector<int> bar(x);
for (int i = 0; i < x; i++) {
cout << "bar[" << i << "]=";
cin >> bar[i];
}
unsigned int count = 0;
unsigned int maxseq = 0;
for (const auto &el : bar) {
if (isPrime(el)) {
++count;
if (count > maxseq) maxseq = count;
} else count = 0;
}
cout << "The longest sequence is: ";
cout << maxseq;
return 0;
}
Of course you can avoid the usage of std::vector and functions with
#include <iostream>
using namespace std;
int main()
{
int x;
int longestseqstart = 0;
cout << "How big is the array? =";
cin >> x;
int bar[100];
for (int i = 0; i < x; i++) {
cout << "bar[" << i << "]=";
cin >> bar[i];
}
unsigned int count = 0;
unsigned int maxseq = 0;
for (unsigned int i = 0; i < x; ++i) {
int a = bar[i];
bool prim = true;
for (int d = 2; d*d <= a; ++d) {
if (a % d == 0) {
prim = false;
}
}
if (prim) {
++count;
if (count > maxseq) maxseq = count;
} else count = 0;
}
cout << "The longest sequence is: ";
cout << maxseq;
return 0;
}
The algorithm looks basically OK. The issue is mostly one of organization: the way the inner loop block is set up means that a run of primes will be short by 1 because the longest sequence is only updated at the beginning of the inner loop, missing the final prime.
A couple of minimal failing examples are:
How big is the array? =1
bar[0]=13
The longest sequence is: 0
How big is the array? =2
bar[0]=5
bar[1]=6
The longest sequence is: 0
Note that there's a repeated prime check in two places. This should not be. If we move all of the prime logic into the loop and test for a new longest sequence only after finishing the entire run, we'll have a clear, accurate algorithm:
#include <iostream>
int is_prime(int n) {
for (int i = 2; i <= n / 2; i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
int main() {
int nums[100];
int n;
std::cout << "How big is the array? =";
std::cin >> n;
for (int i = 0; i < n; i++) {
std::cout << "nums[" << i << "]=";
std::cin >> nums[i];
}
int longest = 0;
for (int i = 0, start = 0; i < n; i++) {
for (start = i; i < n && is_prime(nums[i]); i++);
longest = std::max(longest, i - start);
}
std::cout << "The longest sequence is: " << longest;
return 0;
}
In this rewrite I...
avoided using namespace std;.
removed unnecessary/confusing variables.
used clear variable names (bar should only be used in example code when the name doesn't matter).
moved is_prime to its own function.
But there are outstanding issues with this code. It should...
use a vector instead of an array. As it stands, it's vulnerable to a buffer overflow attack should the user specify an array length > 100.
use a faster method of finding primes. We only need to check up to the square root of the number and can skip a lot of numbers such as even numbers after 2. I suspect this is incidental to this exercise but it's worth mentioning.
move the longest_prime_sequence to a separate function (and possibly user input gathering as well).
Convert the array to a Boolean array and find longest length. Try this snippet(not optimized):
bool is_prime(int n) {
for (int i = 2; i < n; i++) {
if (n%i == 0) return false;
}
return true;
}
int main() {
//Input
unsigned int bar[15] = { 3, 5, 7, 8, 9, 11, 13, 17, 19, 20, 23, 29, 31, 37, 41 };
// Convert input to boolean array
bool boo[15];
for (int i = 0; i < 15; i++) {
boo[i] = is_prime(bar[i]);
}
//Check the longest boolean array
int longest = 0;
for (int i = 0; i < 15; i++) {
int count = 0;
while (boo[i + count] && (i+ count) <15) {
count++;
}
if (longest < count) longest = count;
}
//Output
cout << longest;
return 0;
}

Check whether all the pairs in an array are divisible by k

Given an array of integers and a number k, write a function that returns true if given array can be divided into pairs such that sum of every pair is divisible by k.
This code is producing correct results for all test cases except one I cannot find the glitch in it.
#include <bits/stdc++.h>
using namespace std;
int main() {
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
int arr[n];
for (int i = 0; i < n; i++) {
cin >> arr[i];
}
int k;
cin >> k;
int flag[n] = {0};
int p = 0;
int q = 0;
if (n % 2 != 0) {
cout << "False" << endl;
} else {
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
if ((arr[i] + arr[j]) % k == 0 && flag[j] == 0) {
p = 1;
flag[j] = 1;
}
}
if (p == 0) {
q = 1;
cout << "False" << endl;
break;
}
}
if (q == 0) {
cout << "True" << endl;
}
}
}
return 0;
}
One of the big sources of bugs in code is messy code. So how do we clean up code? We modularize it. This means breaking up the code so that each portion of the code does one job well. Let's see what that looks like.
Function to check if something is divisible by k:
bool isDivisible(int number, int divisor) {
return number % divisor == 0;
}
Function to check all pairs:
The logic is as follows:
Take the first number in the list; call in n0.
For every remaining number n1, check if that plus the first number is divisible by k
When we find n1 such that n0 + n1 is divisible by k,
a. If the remaining numbers left over can also be split into divisible pairs, return true
b. Otherwise, continue searching
4.If we've searched through all the numbers, return false.
bool pairsDivisible(int* nums, int count, int k) {
if(count == 0) return true;
if(count % 2 != 0) return false; // count must be even
// 1.
int n0 = nums[0];
// 2.
for(int i = 1; i < count; i++) {
int n1 = nums[i];
// 3.
if(isDivisible(n0 + n1, k)) {
// Move the ith number so it's now nums[1]
std::swap(nums[1], nums[i]);
if(pairsDivisible(nums + 2, count - 2, k)) {
return true; // 3.a
} else {
// Reset the array
std::swap(nums[1], nums[i]);
}
}
}
return false;
}

Memset with assignment

I have a problem : "Multiple test (t test), each test prints all strings with length N and contains exactly H numbers 1."
Here is my code:
#include <iostream>
#include <memory.h>
using namespace std;
typedef long long LL;
LL t,N,H;
LL arr[1000];
bool used[1000];
LL num = 0;
void show(){
LL number = 0;
for (LL u = 0; u<1000; u++)
{
if (arr[u]==2)
{
number++;
}
}
if (number==H)
{
for (LL v = 0; v<1000; v++)
{
if (arr[v])
{
cout << arr[v] - 1;
}
}
cout << "\n";
}
}
void backtrack (LL pos){
if (pos==N+1)
{
num = 0;
show();
return;
}
if (!used[pos])
{
for (LL j = 1; j<=2; j++)
{
if (j==2)
{
if (num==H)
{
break;
}
else
{
num++;
}
}
arr[pos] = j;
used[pos] = true;
backtrack(pos+1);
used[pos] = false;
}
}
}
int main(){
ios::sync_with_stdio(false);
cin >> t;
for (LL i = 0; i<t; i++)
{
cin >> N >> H;
//memset(arr, sizeof(arr), 0);
for (LL cv = 0; cv<1000; cv++)
{
arr[cv] = 0;
}
backtrack(1);
if (i<t-1)
{
cout << "\n";
}
}
return 0;
}
I had trouble with using "memset(arr, sizeof(arr), 0);" - it returned wrong answer. But with the same test, when I used for-loop to assign all elements in array "arr" equal to 0, it returned correct answer.
My test is:
2
4 2
3 1
I am asking to know the difference between memset and for-loop (using for assignment). Thanks.
memset takes three arguments.The first is the pointer to the block of memory to fill (your arr), the second is the value to set, and the third the number of bytes to fill. Here's the documentation for memset, if you want to go deeper.
In your code I read
memset(arr, sizeof(arr), 0)
That reads as "fill 0 bytes with the value of sizeof". You've only given the wrong arguments, it sould be:
memset(arr, 0, sizeof(arr))
memset's second argument should be value and third is size. Use this:
memset(arr, 0, sizeof(arr) );
See this for details.

Checking for validity in 2d array

so i am creating a sudoku validity checker program in C++. the program takes in a csv file with an already completed sudoku board. the program is supposed to read the file line by line and put the numbers into a 2d array (which it's doing just fine). i'm getting stuck on the checking whether or not there are any duplicate numbers in a row (i assume that if i can get this working then the columns should be fairly similar). i know how the algorithm is supposed to work in my head but i just can't seem to get it into code.
Algorithm:
1) look at each row and check for numbers 1 through 9 making sure that they only appear once (if at all)
2) if a duplicate is found (which means that some number is missing) tell the user at what row and column the error was found.
3) otherwise move on to the next row and do it again
i think that it's supposed to be a for loop running this but it's been a long time since i've coded in C++ and nothing on the internet has been very helpful to me.
Any help is appreciated.
Here is my code so far:
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <thread>
using namespace std;
int *board[9];
int row, col;
void printBoard();
void is_row_ok();
int main()
{
for (int i = 0; i < 9; ++i)
{
board[i] = new int[9];
}
printBoard();
is_row_ok();
cout << endl;
return 0;
}
void printBoard()
{
string line;
string val;
ifstream myFile("Testfile1.txt");
for (int row = 0; row < 9; ++row)
{
string line;
getline(myFile, line);
if (!myFile.good())
break;
stringstream iss(line);
cout << endl;
for (int col = 0; col < 9; ++col)
{
string val;
getline(iss, val, ',');
if (!iss.good())
break;
stringstream convertor(val);
convertor >> board[row][col];
cout << board[row][col] << " ";
}
}
cout << endl;
cout << endl;
}
void is_row_ok()
{
bool found = false;
int i, j;
for (int i = 0; i < 10; ++i) //<------ edit starts here
{
int counter = 0;
for (int j = 0; j < 9; ++j)
{
if(board[row][j] == i)
{
cout << "Before " << counter << endl;
counter++;
cout << counter << endl;
}
if(counter > 1)
break;
}
}
}
The easiest way I can think of is 2 loops (one inside of another): 1 gets you through numbers 1 to 9 and the other goes through the elements of the row. Small tip with code.
for(int i=1;i<10;i++){
int counter =0;
for(int j=0;j<9;j++){
if(board[row][j] ==i)counter ++;
}
if(counter >1) break; //here you check that there´s only one number on the row.
}
Of course, there are other ways to do it, this one is quite basic and slow.
-------------------------------------EDIT-------------------------------------------
Your function should be bool in order to know if there´s repeated number or not.
bool is_row_ok(vector<vector<int> board)//I suggest you use vectors instead of arrays.
{
//i and j are declared on for, there´s no need to declare them again.
for (int i = 0; i < 10; ++i)
{
int counter = 0;
for (int j = 0; j < 9; ++j)
{
if(board[row][j] == i)counter++;
if(counter > 1)return false;
}
}
return true;
}
Now you call this function on main. If function returns true, everything is ok, if it returns false, you have a repeated number.
int main(){
if(is_row_ok(board)cout<<"No number repeated"<<endl;
else cout << "Number repeated"<<endl;
return 0;
}
I think the easiest way is to use std::sort + std::unique as unique returns iterator to the new end of range.
#include <algorithm>
using namespace std;
int main()
{
int n[15] = { 1, 5, 4, 3, 6, 7, 5, 5, 5, 4, 2, 3, 9, 8, 9 };
int* end = n + 15;
sort(n, n + 15);
bool has_no_duplicates = (unique(n, n + 15) == end);
return 0;
}
This is just an example but you should get the idea.