Which is the simplest way to add a number to itself incrementally until some condition is reached? In the code bellow, we can calculate when an event will occur by simply adding event_occurence to itself until we reach max_events. I know it can be done with std::IOTA and vectors, but I want it to keep it to the simplest math possible.
My idea was to use: i=1, i * number to be multiplied, for i<=some value, i++. But only the first value gets incremented correctly.
int main()
{
int curent_year = 2021;
int input_year;
int event_occurence = 4;
std::cout << "When did you watch your first World Cup?" << std::endl;
std::cin >> input_year;
int max_events = (curent_year - input_year) / event_occurence;
int last_event = input_year + (max_events * event_occurence);
int next_first_event = input_year + event_occurence;
std::cout << "Next world cup was held in " << next_first_event << "... Meanwhile, another " << max_events << " world cups took place. The last world cup took place in " << last_event <<"." << std::endl;
int i=1;
int inbetween_events = input_year + i * event_occurence;
for (int i = 1; i <= max_events; i++)
std::cout << "The were also these worlds cups held in the following years: " <<inbetween_events <<std::endl;
}
code above compiled
int i=1;
int inbetween_events = input_year + i * event_occurence;
for (int i = 1; i <= max_events; i++)
std::cout << "The were also these worlds cups held in the following years: " <<inbetween_events <<std::endl;
}
Problem 1:
You're using a local variable (counted in CPU registers) with the same name function variable that is the parent of function for (...). You declare it in there by saying "int i = 1", what means "make new temp variable name i, value = 1)
Move the "calc"
int inbetween_events = input_year + i * event_occurence;
inside the function if you want to print out series of numbers (print inbetween_events = input_year + i * event_occurence;) , or make it
for (; i <= max_events; i++)
or
for (i = 1; i <= max_events; i++)
That could work, but I can't test it :P
You could change variables' names, but then it's still pretty ineffective, because you would increment one variable inside a loop, making 2 operations instead of one.
Problem 2:
You also don't increment the "inbetween_events" in the "for" loop.
You ask it to print out that variable "i" times. You initialized that variable as output of arithmetic operation, it wont change its value unless you order it to change it.
C++ doesn't store instructions and run them later when needed. It runs them right away. So, if you want to compute the in-between events at multiple dates, you need to code it this way:
for (int i = 1; i <= max_events; i++)
// compute inbetween_events for each value of i
int inbetween_events = input_year + i * event_occurence;
std::cout << "The were also these worlds cups held in the following years: " <<inbetween_events <<std::endl;
}
You'll probably want to fix the output with something like:
// output header first
std::cout << "The were also these worlds cups held in the following years: ";
for (int i = 1; i <= max_events; i++)
// compute inbetween_events for each value of i
int inbetween_events = input_year + i * event_occurence;
// output each year with a comma and space
std::cout << inbetween_events << ", ";
}
// end the line
std::cout << std::endl;
Related
The example I talked about is this one on cppreference.com.
The code snippet is pasted below.
int main(){
const std::size_t ThreadNumber = 5;
const int Sum = 5;
std::atomic<int> atom{0};
std::atomic<int> counter{0};
// lambda as thread proc
auto lambda = [&](const int id){
for (int next = 0; next < Sum;){
// each thread is writing a value from its own knowledge
const int current = atom.exchange(next);
counter++;
// sync writing to prevent from interrupting by other threads
std::osyncstream(std::cout)
<< '#' << id << " (" << std::this_thread::get_id()
<< ") wrote " << next << " replacing the old value "
<< current << '\n';
next = std::max(current, next) + 1;
}
};
std::vector<std::thread> v;
for (std::size_t i = 0; i < ThreadNumber; ++i){
v.emplace_back(lambda, i);
}
for (auto& tr : v){
tr.join();
}
std::cout << ThreadNumber << " threads adding 0 to "
<< Sum << " takes total "
<< counter << " times\n";
}
To me, the value of counter is 25 because 5 threads and each thread loops 5 times. However, the shown output is 16. I also ran it myself, the possible value varies, but it never gets to be 25.
Why the printed value of counter is actually smaller?
Consider one of the possible executions:
Lets say one of the threads finishes the loop before other threads start.
This gives you atom == 4. The next thread to enter the loop will get current == 4 and will exit the loop after the first iteration.
This way the second thread increments current once instead of 5 times like you expect it to.
I haven't taken the trouble to analyse the code in detail, but the for loop in the lambda is broken (or, at least, not doing what you are expecting it to do). If you replace it with something more straightforward, namely:
for (int next = 0; next < Sum; ++next){
then 25 is output.
I am receiving an error that says "core dumped" when running my program. I'm a beginner, and I'm not sure how to fix it. It prints out correctly up until part 1-4
int main() {
string unshuffledDeck = "AAAA222233334444555566667777888899990000JJJJQQQQKKKK";
string shuffledDeck = "";
srand(time(0));
for ( ; unshuffledDeck.length() != 0 ; ){
// (1-2a) Generate a random number between 0 and the current unshuffled deck size
minus 1 to select the card we are going to move
int randomIndex = rand() % (unshuffledDeck.length() - 1);
shuffledDeck = shuffledDeck + unshuffledDeck[randomIndex];
unshuffledDeck.erase(randomIndex, 1);
} // end for
string playerHand = "";
string dealerHand = "";
// (1-4b) Deal the cards by moving them from the deck to the player and dealer hands
do {
playerHand += shuffledDeck[0];
shuffledDeck.erase(0,1);
} while((playerHand.length() - 1) < 2);
do {
dealerHand += shuffledDeck[0];
shuffledDeck.erase(0,1);
} while((dealerHand.length() - 1) < 2);
// (1-4c) Print out the deck and hands to verify cards moved in the appropriate order
cout << shuffledDeck << endl;
cout << "player: " << playerHand << endl;
cout << "dealer: " << dealerHand << endl;
}
int randomIndex = rand() % (unshuffledDeck.length() - 1); this cuses this core dump when unshuffledDeck.length() equals to 1 division by zero is hapening. So you should cange it to int randomIndex = rand() % unshuffledDeck.length(); because modulo operator a % b returns value from -b exclusive to b exclusive e.g. (-b,b) in your case all numbers are positive so it returns value from zero inclusive to b exclusive e.g. [0,b)
there is code.
#include "pch.h"
#include <algorithm>
#include <iostream>
#include <vector>
#include <stdlib.h>
using namespace std;
vector<int> SearchInt(vector<int> vec, int num) {
vector<int> temp(2);
sort(begin(vec), end(vec));
int j = 0;
for (int i : vec) {
if (i > num) {
temp[0] = i;
temp[1] = j;
return { temp };
}
//cout << i << " !>= " << num << endl ;
j++;
}
cout << "NO";
exit(0);
}
int main()
{
int n;
cin >> n;
vector<int> nums(n, 0);
vector<int> NewNums(n, 0);
for (int i = 0; i < n; i++) {
cin >> nums[i];
}
if (n != nums.size()) {
cout << "://";
return 0;
}
sort(begin(nums), end(nums));
NewNums[1] = nums[nums.size() - 1];
nums.erase(nums.begin() + nums.size() - 1);
NewNums[0] = nums[nums.size() - 1];
nums.erase(nums.begin() + nums.size() - 1);
for (int j = 2; j <= NewNums.size() - 1; j++) {
NewNums[j] = SearchInt(nums, NewNums[j-1]- NewNums[j-2])[0];
nums.erase(nums.begin() + SearchInt(nums, NewNums[j] - NewNums[j - 1])[1]);
}
if (NewNums[NewNums.size()-1] < NewNums[NewNums.size() - 2] + NewNums[0]) {
cout << "YES" << endl;
for (int i : NewNums) {
cout << i << " ";
}
return 0;
}
else {
cout << "NO";
return 0;
}
}
His task is to check whether it is possible from the given Each number is less than the sum of the two adjacent ones.
(each number is less than both of two adjacent ones)
But there is a problem - with a large number of numbers, the code takes too long. Please help me to optimize it, or just give some advice.
numbers cаn not be null.
time limit: 3.0 s
n <= 500000
You are given n numbers a1, a2,…, an. Is it possible to arrange them in a circle so that each number is strictly less than the sum of its neighbors?
For example, for the array [1,4,5,6,7,8], the left array satisfies the condition, while the right array does not, since 5≥4 + 1 and 8> 1 + 6.
Input data
The first line contains one integer n (3≤n≤105) - the number of numbers.
The second line contains n integers a1, a2,…, an (1≤ai≤109) - the numbers themselves. The given numbers are not necessarily different.
Output
If there is no solution, print "NO" on the first line.
If it exists, print "YES" on the first line. After that, on the second line print n numbers - the elements of the array in the order in which they will stand on the circle. The first and last elements you print are considered neighbors on the circle. If there are multiple solutions, output any of them. You can print a circle starting with any of the numbers.
First I'll only briefly analyze technical shortcomings of your code - without analyzing its meaning. After that I'll write my solution of the problem you defined.
Performance problems of your code are due to some strange decisions:
(1) passing std::vector<int> by value and not by reference to SearchInt function - this implies allocating and copying of the whole array on each function invocation,
(2) call SearchInt two times per loop iteration in function main instead of only one,
(3) sort array within each invocation of SearchInt - it is already sorted before the loop.
To be honest your code feels ridiculously time-consuming. I'm only wondering if that was your intention to make it as slow as you possibly can...
I will not analyze correctness of your code according to problem description. To be honest even after fixing technical shortcomings your code seems to me utterly sub-optimal and quite incomprehensible - so it is just easier to solve the problem from scratch to me.
The answer to the problem as defined is YES if the biggest number is smaller than the sum of the second big and the third big and NO otherwise - this follows from the fact that all numbers are positive (in range 1 - 109 according to newly found problem description). If the answer is YES then to make a circle that satisfies the problem description you just need in a sorted sequence of input numbers switch places of the biggest number and the next big one - that's all.
Here is my code for that (for slightly relaxed input format - I'm not checking if number of items is on a separate line and that all items are on the same line - but all correct inputs will be parsed just fine):
#include <set>
#include <iostream>
int main()
{
std::multiset<unsigned> input_set;
unsigned n;
if( !( std::cin >> n ) )
{
std::cerr << "Input error - failed to read number of items." << std::endl;
return 2;
}
if( n - 3U > 105U - 3U )
{
std::cerr << "Wrong number of items value - " << n << " (must be 3 to 105)" << std::endl;
return 2;
}
for( unsigned j = 0; j < n; ++j )
{
unsigned x;
if( !( std::cin >> x ) )
{
std::cerr << "Input error - failed to read item #" << j << std::endl;
return 2;
}
if( x - 1U > 109U - 1U )
{
std::cerr << "Wrong item #" << j << " value - " << x << " (must be 1 to 109)" << std::endl;
return 2;
}
input_set.insert(x);
}
std::multiset<unsigned>::const_reverse_iterator it = input_set.rbegin();
std::multiset<unsigned>::const_reverse_iterator it0 = it;
std::multiset<unsigned>::const_reverse_iterator it1 = ++it;
if( *it0 >= *it1 + *++it )
{
std::cout << "NO (the biggest number is bigger than the sum of the second big and the third big numbers)" << std::endl;
return 1;
}
std::cout << "YES" << std::endl;
std::cout << "Circle: " << *it1 << ' ' << *it0;
do
{
std::cout << ' ' << *it;
}
while( ++it != input_set.rend() );
std::cout << std::endl;
return 0;
}
I am trying to calculate the final digit of a 13 digit ISBN using the first 12 digits using C++. I feel like my code should be correct but I have a feeling the formula I'm using may be wrong.
The formula is:
10 - (d0 + d1 * 3 + d2 + d3 * 3 + d4 + d5 * 3 + d6 + d7 * 3 + d8 + d9 * 3 + d10 + d11 * 3) % 10
Here's what I have:
#include <cstring>
#include <iostream>
int main() {
int weightedSum = 0;
int checksum = 0;
int i; //for loop decrement
int mul = 3;
const int LENGTH = 12;
char ISBNinput[LENGTH];
std::cout << "Enter first 12 digits of ISBN: "; //ask user for input
std::cin >> ISBNinput; //stores input into ISBNinput
std::cout << std::endl;
for (i = 0; i < strlen(ISBNinput); i++) {
weightedSum += (ISBNinput[i] % 12) * mul;
if (mul == 3) {
mul = 1;
} else {
mul = 3;
}
}//close for loop
checksum = weightedSum % 10; //calculates checksum from weightedSum
std::cout << checksum << std::endl; //prints checksum with new line for format
return 0;
}
For example:
978007063546 should return 3
and
978032133487 should return 9
Thank you for any help.
Here's how I go about this.
First, let's decide how we're going to test this. I'll assume that we've written the function, and that it gives the correct output. So I pick up a couple of books off my desk, and test that it works for them:
#include <iostream>
int main()
{
std::cout << "Book 1 - expect 3, got " << checksum("978032114653") << std::endl;
std::cout << "Book 2 - expect 0, got " << checksum("978020163361") << std::endl;
}
Of course, when we try to compile that, we get an error. So create the function, before main():
char checksum(const char *s)
{
return '1';
}
Now it compiles, but the result is always 1, but now we can start to fill in the body. Let's start with some smaller examples, that we can calculate by hand; add these at the beginning of main():
std::cout << "1 digit - expect 4, got " << checksum("6") << std::endl;
Now let's get this one working - this gives us conversion from character to digit and back, at least:
char checksum(const char *s)
{
int digit = *s - '0';
return '0' + 10 - digit;
}
Let's try 2 digits:
std::cout << "1 digit - expect 6, got " << checksum("11") << std::endl;
And now our test fails again. So add some more processing, to make this pass (and not break the single-digit test):
char checksum(const char *s)
{
int sum = 0;
int digit = *s - '0';
sum += digit;
++s;
if (*s) {
digit = *s - '0';
sum += 3 * digit;
}
return '0' + (10 - sum)%10;
}
We're probably ready to make this into a loop now. Once that's passed, we no longer need the short tests, and I have:
#include <iostream>
char checksum(const char *s)
{
int sum = 0;
for (int mul = 1; *s; ++s) {
int digit = *s - '0';
sum += mul * digit;
mul = 4 - mul;
}
return '0' + (1000 - sum)%10;
}
int test(const char *name, char expected, const char *input)
{
char actual = checksum(input);
if (actual == expected) {
std::cout << "PASS: " << name << ": "
<< input << " => " << actual
<< std::endl;
return 0;
} else {
std::cout << "FAIL: " << name << ": "
<< input << " => " << actual
<< " - expected " << expected
<< std::endl;
return 1;
}
}
int main()
{
int failures = 0;
failures += test("Book 1", '3', "978032114653");
failures += test("Book 2", '0', "978020163361");
return failures > 0;
}
I factored out the actual checking into a function here, so we can keep count of failures, and exit with the appropriate status, but everything else is as I described above.
You'll want to add a few more test cases - in particular, make sure the function correctly returns the extreme values 0 and 9 when it should.
There is one clear bug in your code: you are not allocating enough space in for ISBNinput. You should make it one character longer:
const int LENGTH = 13;
The reason for this is that that character-array strings are terminated with an extra null character. You might be lucky and the next byte in memory could sometimes happen to be a null byte, in which case the program would still work sometimes.
If you run the program with valgrind or a similar memory checker you are likely to see an error as the program access memory beyond what was allocated on the stack.
Also I think there is another bug. I think that mul should be initialized to 1.
By the way, this code is very fragile, depending on you entering no more than 12 characters, all of which are assumed to be digits. It might be OK as a quick hack for a proof-of-concept, but should not be used in any real program.
I have a homework problem for my C++ class and the problem wants us to have the user input a wavelength and then output the correct type of radiation. The point to notice is that there are more Wave Name values than there are Wave Lengths.
My solution is listed below:
const double WAVE_LENGTH[] = { 1e-11, 1e-8, 4e-7, 7e-7, 1e-3, 1e-2 };
const char* WAVE_NAME[] = { "Gamma Rays", "X Rays", "Ultraviolet", "Visible Light", "Infrared", "Microwaves", "Radio Waves" };
double waveLength;
std::cout << "Enter a wavelength in decimal or scientific notation\nWavelength: ";
std::cin >> waveLength;
for (unsigned short i = 0U; i < 6U; ++i)
{
if (waveLength < WAVE_LENGTH[i])
{
std::cout << "The type of radiation is " << WAVE_NAME[i] << std::endl;
break;
}
if (i == 5U) // Last iteration
std::cout << "The type of radiation is " << WAVE_NAME[i + 1] << std::endl;
}
My question is regarding my approach at solving the problem, specifically within the loop. I can't seem to find a way to handle all the situations without creating two conditions inside the loop which seems like it is a poor design. I realize I could use a series of if/else if statements, but I figured a loop is cleaner. Is my approach the best way or is there a cleaner way of coding this?
Thanks!
I think you can simplify your loop to this:
unsigned short i;
for (i = 0U; i < 6U; ++i)
{
if (waveLength < WAVE_LENGTH[i])
{
break;
}
}
std::cout << "The type of radiation is " << WAVE_NAME[i] << std::endl;
In my view a somewhat cleaner design is to add positive infinity as the last element of WAVE_LENGTH. This way your corner case will require no special handling:
#include <iostream>
#include <limits>
...
const double WAVE_LENGTH[] = { 1e-11, 1e-8, 4e-7, 7e-7, 1e-3, 1e-2,
std::numeric_limits<double>::infinity() };
const char* WAVE_NAME[] = { "Gamma Rays", "X Rays", "Ultraviolet", "Visible Light",
"Infrared", "Microwaves", "Radio Waves" };
double waveLength;
std::cout << "Enter a wavelength in decimal or scientific notation\nWavelength: ";
std::cin >> waveLength;
for (int i = 0; i < sizeof(WAVE_LENGTH) / sizeof(WAVE_LENGTH[0]); ++i)
{
if (waveLength < WAVE_LENGTH[i])
{
std::cout << "The type of radiation is " << WAVE_NAME[i] << std::endl;
break;
}
}
Also note how I've avoided having to hard-code the length of the array (6U in your code) in the loop's terminal condition.
You can test the last iteration in the same if. Notice there is no test anymore itn for.
for (unsigned short i = 0U; ; ++i)
{
if (i == 6 || waveLength < WAVE_LENGTH[i])
{
std::cout << "The type of radiation is " << WAVE_NAME[i] << std::endl;
break;
}
}
Alternatively, you can add a extra wavelength set to MAX_FLOAT (or whatever is called in C++) or set the last one to zero and exit if wave_length[i] == 0.0. That way you don't need to "know" the number of wave lengths.