Find minimum value different than zero given some conditions - c++

I've started learning C++ Sets and Iterators and I can't figure if I'm doing this correctly since I'm relatively new to programming.
I've created a Set of a struct with a custom comparator that puts the items in a decreasing order. Before receiving the input I don't know how many items my Set will contain. It can contain any number of items from 0 to 1000.
Here are the Setdefinitions:
typedef struct Pop {
int value_one; int node_value;
} Pop;
struct comparator {
bool operator() (const Pop& lhs, const Pop& rhs) const {
if (rhs.value_one == lhs.value_one) {
return lhs.node_value < rhs.node_value;
} else { return rhs.value_one < lhs.value_one;}
}
};
set<Pop, comparator> pop;
set<Pop>::iterator it;
And this is the algorithm. It should find a minimum value and print that value. If it does not find (the function do_some_work(...) returns 0), it should print "Zero work found!\n":
int minimum = (INT_MAX) / 2; int result;
int main(int argc, char** argv) {
//....
//After reading input and adding values to the SET gets to this part
Pop next;
Pop current;
for (it = pop.begin(); it != pop.end() && minimum != 1; it++) {
current = *it;
temp_it = it;
temp_it++;
if (temp_it != pop.end()) {
next = *temp_it;
// This function returns a integer value that can be any number from 0 to 5000.
// Besides this, it checks if the value found is less that the minimum (declared as global) and different of 0 and if so
// updates the minimum value. Even if the set as 1000 items and at the first iteration the value
// found is 1, minimum is updated with 1 and we should break out of the for loop.
result = do_some_work(current.node_value);
if (result > 0 && next.value_one < current.value_one) {
break;
}
} else {
result = do_some_work(current.node_value);
}
}
if (minimum != (INT_MAX) / 2) {
printf("%d\n", minimum);
} else {
printf("Zero work found!\n");
}
return 0;
}
Here are some possible outcomes.
If the Set is empty it should print Zero work found!
If the Set as one item and do_some_work(current.node_value) returns a value bigger than 0 it should printf("%d\n", minimum); or Zero work found! otherwise.
Imagine I have this Set (first position value_one and second position node_value:
4 2
3 6
3 7
3 8
3 10
2 34
If in the first iteration do_some_work(current.node_value) returns a value bigger than 0, since all other items value_one are smaller, it should break the loop, print the minimum and exit the program.
If in the first iteration do_some_work(current.node_value) returns 0, I advance in the Set and since there are 4 items with value_one as 3 I must analyze this 4 items because any of these can return a possible valid minimum value. If any of these updates the minimum value to 1, it should break the loop, print the minimum and exit the program.
In this case, the last item of the Set is only analysed if all other items return 0 or minimum value is set to 1.
For me this is both an algorithmic problem and a programming problem.
With this code, am I analysing all the possibilities and if minimum is 1, breaking the loop since if 1 is returned there's no need to check any other items?

Related

leetcode question 81 c++ returns wrong answer

question:
There is an integer array nums sorted in non-decreasing order (not necessarily with distinct values).
Before being passed to your function, nums is rotated at an unknown pivot index k (0 <= k < nums.length) such that the resulting array is [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]] (0-indexed). For example, [0,1,2,4,4,4,5,6,6,7] might be rotated at pivot index 5 and become [4,5,6,6,7,0,1,2,4,4].
Given the array nums after the rotation and an integer target, return true if target is in nums, or false if it is not in nums.
You must decrease the overall operation steps as much as possible.
class Solution {
public:
int search(vector<int>& nums, int target) {
int s=0;
vector<int> f(4999);
vector<int> x(4999);
int y=f.size()-1;
int z=x.size()-1;
for (int i=0;i<nums.size();i++){
for (int j=1;j<nums.size();j++){
if (i<=j){
f.push_back(nums[i]);
}else if (i>j){
f.push_back(nums[i]);
x.push_back(nums[j]);
for (int k=j;k<nums.size();k++)
x.push_back(nums[k]);
break;
}
}
}
if (target==x[0]||target==f[0]){
return true;
}
else if (target>f[0]){
while (s<=y){
int mid=0;
mid=(y+s)/2;
if (f[mid]>target){
y=mid-1;
}else if (f[mid]<target){
s=mid+1;
}else if (f[mid]==target){
return true;
}
}
return false;
}else if (target<f[0]){
while (s<=z){
int mid=0;
mid=(z+s)/2;
if (x[mid]>target){
z=mid-1;
}else if (x[mid]<target){
s=mid+1;
}else if (x[mid]==target){
return true;
}
}
return false;
}
else{
return false;
}return false;
}
};
input [2,5,6,0,0,1,2] target 2 returned false expected true
input [1] target 1 returned false expected true
input [1] target 0 returned true expected false
trying to stick to a binary search solution how can this work
help is appriciated thanks
To figure out why it's not working, you can walk through one of the failing test cases. You'd want to pick the easiest one to manage in your head, so in this case I recommend one of those with an array length of 1.
So let's walk through
input [1] target 1 returned false expected true
Your function first creates two large arrays, each with 4999 zeros in them. See this answer for why they're zero.
Then that nested for loop runs, but it doesn't actually do anything because the inner loop will not run -- j=1 is not less than nums.size(), which is 1.
So by the time you do your binary searches below, both f and x are filled with 4999 zeros. Your code does the binary search on f, so it won't find your target of 1.
If you want to see the solution to this problem, check out this Stack Overflow answer.

My code won't print when submitted for codecheck even though it compiles without error

I've been assigned this question for my lab (and yes I understand there will be backlash because it's homework). I've been working on this question for a couple of days to no avail and I feel like I'm missing something glaringly obvious.
My code:
int processSuitors(vector<int>& currentSuitors, list<int>& rekt)
{
int sizeSuitors = currentSuitors.size();
int eliminated = 2;
while(sizeSuitors != 1)
{
rekt.push_back(currentSuitors[eliminated]);
currentSuitors.erase(currentSuitors.begin() + eliminated);
sizeSuitors--;
if(eliminated > sizeSuitors)
{
eliminated -= sizeSuitors;
}
}
return currentSuitors[0];
}
Prompt:
In an ancient land, the beautiful princess Eve had many suitors. She decided on the following procedure to determine which suitor she would marry. First, all of the suitors would be lined up one after the other and be assigned numbers. The first suitor would be number 1, the second number 2, and so on up to the last suitor, number n. Starting at the first suitor she would then count three suitors down the line (because of the three letters in her name) and the third suitor would be eliminated from winning her hand and he would be removed from the line. Eve would then continue, counting three more suitors and eliminating every third suitor. When she reached the end of the line she would continue counting from the beginning.
Write a function named processSuitors that takes as arguments an STL vector of type int containing the suitors, and an STL list of type int that will collect all the suitors that are eliminated. The function returns an int storing the position a suitor should stand in to marry the princess if there are n suitors. The function that calls processSuitors will send the vector already filled with n suitors (1, 2, 3... n), and an empty list that needs to be filled with the position number of the suitors that were eliminated, in the order they were eliminated.
Restrictions: You may not create any containers (no arrays, no vectors, etc.); you need to use the vector and the list that are passed as parameters.
Use ONLY the following STL functions:
vector::size
vector::erase
vector::begin
ist::push_back
vector::operator[ ]
The adjacent files are hidden since we are to rely on what is given. Any clean-up of my code would be extremely appreciated as well.
What do you think of this solution.
Keep another vector that marks whether an index in your currentSuitors vector has been removed. Then have a helper function that will always find the next free index.
Instead of trying to reduce currentSuitors, you just keep marking elements in the taken list.
size_t findNextFreeSlot(const vector<bool>& taken, size_t pos)
{
// increment to the next candidate position
pos = (pos + 1) % taken.size();
// search for the first free slot
for (size_t i = 0; i < taken.size(); i++)
{
if (taken[pos] == false)
{
return next;
}
pos = (pos + 1) % taken.size();
}
// assert(false); // we should never get here as long as there's one free slot index in taken
return -1;
}
int processSuitors(vector<int>& currentSuitors, list<int>& rekt)
{
size_t len = currentSuitors.size();
vector<bool> taken(len); // keep a vector of eliminated indices from current
size_t index = len; // initialize one past the last valid element
size_t eliminated = 0;
if (len == 0)
{
return -1;
}
while (eliminated < (len-1))
{
// advance the index three times to the next "untaken" index
index = findNextFreeSlot(taken, index);
index = findNextFreeSlot(taken, index);
index = findNextFreeSlot(taken, index);
taken[index] = true; // claim this index as taken
rekt.push_back(currentSuitors[index]); // add the value at this index to the eliminated list
eliminated++;
}
index = findNextFreeSlot(taken, index); // find the last free index
return currentSuitors[index];
}

C++ Comparing value from 2 different list to get rid of duplicate number using 2 for loop. Doesn't detect duplicate correctly

ArrayBag foundBag;
int z;
z = getCurrentSize(); // tell you have many items exit in the bag
for (int i = 0; i < z; i++ )
{
int cur = items[i]; //cur is use to hold each number in the vector and items is the first list of number.
bool found = false; // start as false so it doesnt trigger the true right away
for (int j = 0; j < foundBag.getCurrentSize(); j++) // this loop check the number currently inside cur agianst everything in the foundbag at the moment
{
if (foundBag.items[i] = cur)
{
found == true; // << it didnt detect that it have found the number. I think the problem is here
}
}
if (found == true)
{
// do nothing if found since number is already in the foundbag
}
else if (found != true)
{
foundBag.add(cur); // if number is not found in the foundBag add it to the found bag.
}
}
So what I m trying to do is comparing value from an existing list to a new empty one that is called foundBag in this case. So basically it suppose to get value from the first bag and then check if that number exit in the first bag or not then it will add that number to the foundBag if it did not find it. If it already found the number it will do nothing and move to the next element in the first bag.
say the first bag have number 3 4 5 7 5 8 it should add everything from 3 4 5 7 then do nothing when it get to the second 5 then add 8 to the foundBag.
at the end foundBag should contain: 3 4 5 7 8
The problem is it doesnt seem to correctly detect that the number is already in the foundBag so it add everything.
I been using the step-over function in visual studio to look at each step but I couldnt figure out why the bool still go to false when it found the identical number.
Im not very strong in english so if this doesnt make sense please ask for more explanation
Thank you
It looks like you have your = and == mixed up.
if (foundBag.items[j] == cur) // Use == here for comparison
{
found = true; // Use = here for assignment
}
By the way, if all you're doing is looking for an element in a collection, prefer an algorithm from the standard library:
auto result = std::count(std::begin(foundBag.items), std::end(foundBag.items), cur);
if (result == std::end(foundBag.items)) {
// Not found; Add it
foundBag.add(cur);
}

Boolean variable is automatically changing its value

This problem is from SPOJ. I was required to find whether the graph is Bi-partite or not. I'm using BFS to find it.
The problem here is in a while loop under the section //PROBLEM COMING HERE (please see the code under to find this statement.)
Problem description:
I want to toggle between 0 and 1. So I have chosen a bool value called flag and initialised it with 0. Now, per iteration I want to toggle it's value. So I have used flag = !flag. However, for some unknown reasons the flag value automatically toggles after the first iteration before executing the statement flag = ! flag.
So, because of this lot of problems are coming.
//BUG LIFE
#include <cstdio>
#include <vector>
#include <queue>
#define DEFAULT 2
using namespace std;
int main()
{
int t,n,e;
bool eflag;
//freopen("input.txt", "r", stdin);
//Taking the Testcase
scanf("%d",&t);
//Iterating each Testcase
for(int itr=1; itr<=t; itr++)
{
//n is the number of nodes in the graph and e is the no of edges.
scanf("%d %d",&n,&e);
//eflag is exit flag in short. this is used to early exit to save time if we already found out that the given graph isn't bi-partite.
//Assuming the graph is bi-partite hence eflag = false meaning no exit is required yet.
eflag = false;
//Graph data structure vector 2D Array
vector < vector < int > > graph(n+1);
//Taking edges as input and adding in the graph
for(int i = 1; i <=e; i++)
{
int v1,v2;
scanf("%d %d",&v1,&v2);
graph[v1].push_back(v2);
graph[v2].push_back(v1);
}
//Check the graph is bi-partite or not
//vis is an array which will hold whether a node has been explored or not. label is an array which segregates all the nodes in two groups 0 or 1.
bool vis[n+1]; int label[n+1];
//Initialising vis and label.
for(int i=1; i<=n; i++)
{
vis[i] = 0;
//DEFALUT VALUE IS 2. This is to tell that label of the node i hasn't been given yet or in otherwords, it's not be put in a group yet.
label[i] = DEFAULT;
}
//Taking nodes one by one and doing a BFS on it.
//LOGIC Here is: Take a node assign it a label 0 and add all the children of it in the queue and give them label 1. Now explore all children and give their children label 0. So like this, we alternate between labels.
//Now if we see that a node already has a label apart from 2 and a children is trying to label it with something different label it will mean that specific node is involved in both the groups. Hence we will set the eflag as true.
for(int i=1; i<=n && !eflag; i++)
{
if(!graph[i].empty() && !vis[i])
{
//Initialising the queue and adding the first node which has children.
queue <int> q;
q.push(i); bool flag;
//PROBLEM COMING HERE
//Assigning the label for this node as 0. meaning group 0
label[i] = 0; flag = false;
//BFS Starts
while(!q.empty() && !eflag)
{
int x = q.front(); q.pop();
printf("%d **\n",flag);
//The children of this node needs to have different label than parent. Hence flag = !flag
flag = !flag;
printf("%d %d\n",x,flag);
if(vis[x]) continue;
vis[x] = 1;
//Exploring the children and assigning them labels
for(vector <int>::iterator it = graph[x].begin(); it != graph[x].end(); it++)
{
//If the children doesn't have a default label and the label which it has is different than the one the parent is trying to put then it means that this child belongs to both the groups 0 and 1. So exit.
if(label[*it] != DEFAULT && label[*it] != flag)
{
printf("%d %d %d %d\n",x,*it,label[*it],flag);
eflag = true;
break;
}
else
{
label[*it] = flag;
}
}
printf("asd %d **\n",flag);
}
//PROBLEM ENDS HERE
}
}
if(eflag == false)
printf("Scenario #%d:\nNo suspicious bugs found!\n",itr);
else
printf("Scenario #%d:\nSuspicious bugs found!\n",itr);
}
return 0;
}
OUTPUT:
0 **
1 1
asd 1 **
0 **
2 1
2 1 0 1
asd 1 **
Scenario #1:
Suspicious bugs found!
Sample Input:
1
3 3
1 2
2 3
1 3
Your assumption in the comment:
After it prints asd 1** it should print again 1 ** because flag = ! flag hasn't been executed yet. However it shows 0 **
Is wrong. (Not the assumption that flag = ! flag hasn't been executed, that's correct.)
In the following snippet, I've cut most of the irrelevant code away (you're welcome). Let's name some of your loops:
for(int i=1; i<=n && !eflag; i++) // outer loop
{
// ..
queue <int> q;
q.push(i); bool flag;
label[i] = 0; flag = false; // (1)
while(!q.empty() && !eflag) // inner loop
{
int x = q.front(); q.pop();
printf("%d **\n",flag); // (2)
flag = !flag;
printf("%d %d\n",x,flag);
// ...
printf("asd %d **\n",flag); // (3)
}
// ...
}
You only ever push exactly one element into q. That's at the top of outer loop. You always pop it at the top of inner loop. Inner loops condition is true only if the queue is not empty. Therefore the inner loop always runs at most once per outer loop. Because the inner loop is never repeated more than once, you always jump to the beginning of the outer loop after printing asd 1** at the end of inner loop (3). At the top of outer loop (1), you assign flag = false. Therefore, regardless of the value of flag when it's printed at (3), it's value will always be false at (2).
As you can see, the variable isn't changing "automatically" or because of "unknown reasons". It's changing because you assign it at (1).

Recursion: subset sum algorithm setting value in parameters

How do I reset the value of blockIndex to its inital state when I call the method?
Say if I call it and pass in the value 4. I check if that value is greater than 9, if not I add the element at pos(0). But in tracing my function I see that it adds all the values of the vector. I just want it to add 1 element, then when it check if it is greater than 9, and it is not, revert it back to the initial value. How do I do this?
int NumCriticalVotes :: CountCriticalVotes(Vector<int> & blocks, int blockIndex)
{
if (blockIndex >= 9 && blocks.isEmpty())
{
return 1;
}
if (blocks.isEmpty()) //Fail case
{
return 0;
} else {
int element = blocks.get(0);
Vector<int> rest = blocks;
rest.remove(0);
return CountCriticalVotes(rest, blockIndex) || CountCriticalVotes(rest, blockIndex + element);
}
}