I need to find the maximum remainder for n divided by any integer number from 1 to n, and the denominator which this remainder is found with.
In my implementation fun1 works as expected and returns the max remainder, fun2 is supposed to give 3 but its giving 2 .probably mistake is at break statement.
Sample input: 5
Expected output: 2 3.
My output: 2 2.
#include <iostream>
#include <algorithm>
using namespace std;
int fun2(int a);
int fun1(int n ,int num);
int main(){
int n = 0; int num = 0;;
cin >> n;
int p = fun1(n, num);
cout << p << "\n";
cout << fun2(p);
}
int fun1(int n, int num){
int b = 0;
for(int i = 1; i <= n; i++){
num = n % i;
b = max(num, b);
}
return b;
}
int fun2(int n,int p ){
int num = 0; int c = 0; int d = 0;
for(int i = 1; i <= n; i++){
num = n % i;
c = max(num, c);
if(c == p){
break;
}
d = i;
}
return d;
}
Since you already managed to successfully find the biggest remainder, you may get use of this function and return the number this remainder is found with:
std::pair<int, int> biggestRemDem(int value) {
int dm = 1;
int rm = 0;
for(int i = dm; i <= value; ++i){
const auto tmpRm = value % i;
if (tmpRm > rm) {
rm = tmpRm;
dm = i;
}
}
return { rm, dm };
}
The signature of the function needs to return std::pair however, but you no longer need the std::max, so the headers required to include are also changed:
#include <iostream>
#include <utility>
std::pair<int, int> biggestRemDem(int value);
int main(){
int n{};
std::cin >> n;
const auto result = biggestRemDem(n);
std::cout << result.first << " " << result.second << std::endl;
}
In fun2 you have:
if(c == p){
break;
}
d = i;
When you found the right index so that c == p the break will exit the loop and d == i; is not execute. Therefore d has the value from the previous loop, i.e. one less than you need.
Apart from that the code really smells:
fun1
should not have a second argument sum.
should remember the index where if found the largest remainder and you would be done
fun2
the maximum remainder is p, no need to max(num, c). Actually drop the c alltogether and just use num == p
n % 1 == 0 and n % n == 0. The loop will always break with i < n. Might as well not have a conditional: for(int i = 1; ; i++)
you need d because at the end of the loop i disappears. Why not pull i out of the loop? int i; for(i = 1; ; i++)
and now you can use a different conditional again
int fun2(int n,int p ){
int i;
for(i = 1; n % i != p; i++) { }
return i;
}
or
int fun2(int n,int p ){
int i = 1;
for(; n % i != p; i++) { }
return i;
}
or
int fun2(int n,int p ){
int i = 1;
while(n % i != p) ++i;
return i;
}
I need to find the maximum remainder for n divided by any integer number from 1 to n, and the denominator which this remainder is found with.
It seems that the asker decided to solve this in two steps. They wrote a function fun1 returning the maximum remainder and a function fun2, which fed with the previously calculated remainder, returns the corresponding dividend.
While not an efficient approach, it could work if implemented correctly, but that's not the case.
Other than some (very) bad naming choices, we can find:
In the original version of the posted code, fun2 has a function prototype with a single parameter and it is called passing the value returned by fun1, which is the maximum remainder. The problem is that this way the function has no way to know what was the original value of n and actually declares a local n, initialized to zero, so that the body of the loop for(int i = 1; i <= n; i++) is never executed.
The actual version of this question shows a definition of fun2 with two parameters, that can't compile unless both the prototype and the call site are changed accordingly.
Assuming that the original n and the remainder p were succesfully passed to fun2, there still would be another issue:
int fun2(int n, int p ) {
int c = 0, d = 0;
for(int i = 1; i <= n; i++) {
int num = n % i;
c = max(num, c);
if(c == p){ // So, if we reach the passed remainder...
break; // We break out of the loop, skipping...
}
d = i; // this line, meaning...
}
return d; // That the dividend previous to the correct one is returned!
}
They could just return i; when c == p.
The answer by The Dreams Wind presents a much better approach to this task. I'd like to suggest an O(1) solution, though. Consider these points:
The result of n % i can't be equal or greater than i. It's in the range [0, i).
n / 2 is the greatest number that can divide n other than n itself. It means that all the numbers i in (n/2, n) are such that n % i > 0.
For every number i in (n/2, n), we can actually say that n % i = n - i.
So, when n is greater than 2, the i corresponding to the maximum remainder is just 1 + n/2 and said remainder is n - n/2 - 1.
Related
I'm trying to write a c++ program which gets an integer n (n>=1 && n<=100000) from the user and puts the sum of its digits into b. The output needed is the b-th prime number coming after n. I'm an absolute beginner in programming so I don't know what's wrong with the for loop or any other code that it doesn't show the correct output. For example the 3rd prime number after 12 (1+2=3) is 19 but the loop counts the prime numbers from 2 instead of 12, so it prints 7 as result.
#include <iostream>
using namespace std;
bool isPrime(int n)
{
if(n <= 1)
return false;
for(int i = 2; i <= (n/2); i++)
if(n % i == 0)
return false;
return true;
}
int main()
{
long int n;
int b = 0;
cin>>n;
while(n >= 1 && n <= 100000){
b += n % 10;
n /= 10;
}
for(int i = n, counter = b; counter <= 10; i++)
if(isPrime(i)){
counter++;
if(i > n)
cout<<counter<<"th prime number after n is : "<<i<<endl;
}
return 0;
}
So one of the possible solutions to my question, according to #Bob__ answer (and converting it to the code style I've used in the initial code) is as follows:
#include <iostream>
using namespace std;
bool isPrime(long int number)
{
if(number <= 1)
return false;
for(int i = 2; i <= (number / 2); i++)
if(number % i == 0)
return false;
return true;
}
int sumOfDigits(long int number)
{
int sum = 0;
while(number >= 1 && number <= 100000)
{
sum += number % 10;
number /= 10;
}
return sum;
}
long int bthPrimeAfter(int counter, long int number)
{
while(counter)
{
++number;
if(isPrime(number))
--counter;
}
return number;
}
int main()
{
long int number;
cin>>number;
int const counter = sumOfDigits(number);
cout<<bthPrimeAfter(counter, number)<<"\n";
return 0;
}
As dratenik said in their comment:
You have destroyed the value in n to produce b in the while loop. When the for loop comes around, n keeps being zero.
That's a key point to understand, sometimes we need to make a copy of a variable. One way to do that is passing it to a function by value. The function argument will be a local copy which can be changed without affecting the original one.
As an example, the main function could be written like the following:
#include <iostream>
bool is_prime(long int number);
// ^^^^^^^^ So is `n` in the OP's `main`
int sum_of_digits(long int number);
// ^^^^^^^^^^^^^^^ This is a local copy.
long int nth_prime_after(int counter, long int number);
int main()
{
long int number;
// The input validation (check if it's a number and if it's in the valid range,
// deal with errors) is left to the reader as an exercise.
std::cin >> number;
int const counter = sum_of_digits(number);
std::cout << nth_prime_after(counter, number) << '\n';
return 0;
}
The definition of sum_of_digits is straightforward.
int sum_of_digits(long int number)
{
int sum = 0;
while ( number ) // Stops when number is zero. The condition n <= 100000
{ // belongs to input validation, like n >= 0.
sum += number % 10;
number /= 10; // <- This changes only the local copy.
}
return sum;
}
About the last part (finding the nth prime after the chosen number), I'm not sure to understand what the asker is trying to do, but even if n had the correct value, for(int i = n, counter = b; counter <= 10; i++) would be just wrong. For starters, there's no reason for the condition count <= 10 or at least none that I can think of.
I'd write something like this:
long int nth_prime_after(int counter, long int number)
{
while ( counter )
{
++number;
if ( is_prime(number) )
{
--counter; // The primes aren't printed here, not even the nth.
}
}
return number; // Just return it, the printing is another function's
} // responsabilty.
A lot more could be said about the is_prime function and the overall (lack of) efficiency of this algorithm, but IMHO, it's beyond the scope of this answer.
How to count comparisons in selectionsort?
terms:
when the statements you perform to find the maximum value is 'true'
then count comparison.
The value to get the maximum value is held at the first element in the array, not at random.
I try with C
variable count position change - no work
new variable 'first' , first=sort[MAX] insert first for loop, - no work
#include <stdio.h>
int main() {
int sort[10000], i, n, MAX, temp, count;
scanf("%d", &n);
for (i = 0; i < n; i++) {
scanf("%d", &sort[i]);
}
for (MAX = 0; MAX < n; MAX++)
for (i = MAX + 1; i < n; i++) {
if (sort[MAX] > sort[i]) {
count++;
temp = sort[MAX];
sort[MAX] = sort[i];
sort[i] = temp;
}
}
printf("%d ", count);
return 0;
}
Sample Input
10
0 7 1 6 7 7 6 6 5 4
Sample Output
17
EDIT: new code:
#include <stdio.h>
#define SWAP(x, y, temp) ( (temp)=(x), (x)=(y), (y)=(temp) )
int count = 0;
void selection_sort(int list[], int n) {
int i, j, least, temp;
for (i = 0; i < n - 1; i++) {
least = i;
for (j = i + 1; j < n; j++) {
if (list[j] < list[least]) {
least = j;
count++;
}
}
SWAP(list[i], list[least], temp);
}
}
int main() {
int list[10000], i, n;
scanf("%d", &n);
for (i = 0; i < n; i++) {
scanf("%d", &list[i]);
};
selection_sort(list, n);
printf("%d", count);
}
how about this? why this code didn't move too?
You aren't counting the right thing, this code
if(sort[MAX]>sort[i])
{
count++;
temp=sort[MAX];
sort[MAX]=sort[i];
sort[i]=temp;
}
counts the times that two numbers are swapped. But you want to count comparisons so it should be this
count++;
if(sort[MAX]>sort[i]) // this is what we are counting
{
temp=sort[MAX];
sort[MAX]=sort[i];
sort[i]=temp;
}
Another problem is that you don't give count an initial value of zero
int sort[10000],i,n,MAX,temp,count;
should be
int sort[10000],i,n,MAX,temp,count = 0;
how to count comparison selectionsort?
Your definition of the term is oddly worded, but it seems to be intended to focus on the essential comparisons of the algorithm, as opposed to comparisons performed incidentally for other purposes, or inside library functions. That is, in the implementation you present (whose correctness I do not evaluate), you're to count each evaluation of sort[MAX]>first, but not MAX<n or i<n.
You appear to be using variable count for that purpose, but you are counting only comparisons that evaluate to true. My interpretation of the problem, based both on the wording presented and on my general expectations for such a problem, is that every evaluation of sort[MAX]>first should be counted, regardless of the result. That would be achieved by lifting the expression count++ out of the if block, but leaving it inside the inner enclosing for loop.
Of course, as #john observes, you do need to initialize count to 0 before beginning to sort. You might luck into getting that by accident, but the initial value of a local variables without an initializer is indeterminate (at least) until a value is assigned.
i try with c variable count position change - no work
new variable 'first' , first=sort[MAX] insert first for loop, - no work
Even with the misplacement of your increment to count, if your sort were in fact working then you would expect to see some counts for most inputs. That you don't is a good sign that your sort in fact does not work correctly. I would suggest outputting also the the sorted results so that you can debug the details of the sort algorithm.
You could abstract out the comparison into a function or macro that also increments a counter. The macro approach could be
#define GT(x,y,counter) (counter++, (x) > (y) ? 1 : 0)
...
if ( GT( sort[MAX], sort[i], count ) == 1 )
{
// perform swap
}
whereas the function approach would be
int gt( int x, int y, int *counter )
{
(*counter)++;
if ( x > y )
return 1;
return 0;
}
...
if ( gt( sort[MAX], sort[i], &count ) == 1 )
{
// perform swap
}
You are counting the number of swaps, not the number of comparisons.
Here is a corrected without a global variable and a few extra checks:
#include <stdio.h>
#define SWAP(x, y, temp) ((temp) = (x), (x) = (y), (y) = (temp))
int selection_sort(int list[], int n) {
int count = 0;
int i, j, least, temp;
for (i = 0; i < n - 1; i++) {
least = i;
for (j = i + 1; j < n; j++) {
count++;
if (list[j] < list[least]) {
least = j;
}
}
SWAP(list[i], list[least], temp);
}
return count;
}
int main() {
int list[10000], i, n, count;
if (scanf("%d", &n) != 1 || n > 10000)
return 1;
for (i = 0; i < n; i++) {
if (scanf("%d", &list[i]) != 1)
return 1;
}
count = selection_sort(list, n);
printf("%d\n", count);
return 0;
}
Not however that your algorithm will always perform the same number of comparisons for any set of n values: n * (n - 1) / 2 comparisons, and since you do not test of i != least, it will perform n - 1 swaps.
I have this problem from hackerearth
Given an array of N integers, C cards and S sum. Each card can be used
either to increment or decrement an integer in the given array by 1.
Find if there is any subset (after/before using any no.of cards) with
sum S in the given array.
Input Format
First line of input contains an integer T which denotes the no. of
testcases. Each test case has 2 lines of input. First line of each
test case has three integers N(size of the array), S(subset sum) and
C(no. of cards). Second line of each test case has N integers of the
array(a1 to aN) seperated by a space.
Constraints
1<=T<=100 1<=N<=100 1<=S<=10000 0<=C<=100 1<=ai<=100
Output Format
Print TRUE if there exists a subset with given sum else print FALSE.
So this is basically a variation of the subset sum problem, but instead of finding out whether a given subset with a sum S exists, we need to find the largest subset from sequence index to N-1 that has a value of s and compare it's length with our C value to see if it is greater. If it is, then we have enough elements to modify the sum using our C cards, and then we print out our answer. Here is my code for that
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int N, S, C;
int checkSum(int index, int s, vector<int>& a, vector< vector<int> >& dP) {
if (dP[index][s] != -1)
return dP[index][s];
int maxNums = 0; // size of maximum subset array
for (int i = index; i < N; i++) {
int newSum = s - a[i];
int l = 0;
if (newSum == 0) {
l = 1;
} if (newSum > 0) {
if (i < (N-1)) { // only if we can still fill up sum
l = checkSum(i + 1, newSum, a, dP);
if (l > 0) // if it is possible to create this sum
l++; // include l in it
} else {
// l stays at 0 for there is no subset that can create this sum
}
} else {
// there is no way to create this sum, including this number, so skip it;
if (i == (N-1))
break; // don't go to the next level
// and l stays at 0
}
if (l > maxNums) {
maxNums = l;
}
}
dP[index][s] = maxNums;
return maxNums;
}
int main() {
int t;
cin >> t;
while (t--) {
cin >> N >> S >> C;
vector<int> a(N);
for (int i = 0; i < N; i++)
cin >> a[i];
vector< vector<int> > dP(N, vector<int>(S + C + 2, -1));
bool possible = false;
for (int i = 0; i <= C; i++) {
int l = checkSum(0, S-i, a, dP);
int m = checkSum(0, S+i, a, dP);
if ( (l > 0 && l >= i) || (m > 0 && m >= i) ) {
cout << "TRUE" << endl;
possible = true;
break;
}
}
if (!possible)
cout << "FALSE" << endl;
}
return 0;
}
So basically, 0 means it's not possible to create a subset equal to s from elements index to N-1, and -1 means we haven't computed it yet. And any other value indicates the size of the largest subset that sums up to s. This code isn't passing all the test cases. What's wrong?
You miss an else in following line
} if (newSum > 0) {
This make your program has an unexpected early break before updating maxNums by l in some cases.
For example, N=1, S=5, C=0, a={5}
Potential logic problem
You have limited the no. of card to be used to not exceed the subset size while the question never state you cannot apply multiple cards to same integers.
I mean l >= i and m >= i in
if ( (l > 0 && l >= i) || (m > 0 && m >= i) ) {
Seems you have logic flaw.
You need to find the shortest subset (with sum in range S-C..S+C) and compare it's size with C. If subset is shorter, it is possible to make needed sum.
Basically i want to write a function that takes values from 0 to 6 and gives back a random assortment such as 2,3,4,5,0,1,6. Here is the code that i came up with. However the problem is that the integer prev (meaning previous) does not store all the old values of r (random number) and thus some values end up being repeated. How might i fix this?
int s(int b)
{
// b is 7
int h = b-1;
int prev = -1;// to store the previous r value
srand(time(0));
for (int i = 0; i < b; i++)
{
int r = rand()%(h - 0 + 1) + 0;
if (r != prev)
{
cout << r << endl;
prev = r;
}
else if (r == prev)
{
s(b);
}
}
return 0;
}
From the comments, this sounds more like a homework problem than a practical problem because you said "No arrays allowed". But I suppose it is an interesting problem.
Here's some code, in Java with only loops, if statements, and with no arrays, as required.
It outputs a random permutation of the set 0, 1, ..., N, shuffled with the Fisher-Yates algorithm.
void printRandom(int N) {
long used = 0;
for (int i = 0; i < N; i++) {
int randomIndex = ThreadLocalRandom.current().nextInt(N - Long.bitCount(used));
for (int j = 0; j < N; j++) {
if ((used & (1L << j)) == 0) {
if (randomIndex-- == 0) {
System.out.print(j + " ");
used = used | (1L << j);
break;
}
}
}
}
}
It is unfortunately limited to the size of a long on your system :)
I think the best way to solve this problem is by using an aux funtion that stores in a variable all the numbers printed until the moment, check if the new number is in the used numbers variable, if not add it to the variable (you can use strings? I know that they are arrays of char's but maybe you can)
Something like this:
function aux(int b, char *variables_printed, int iterations_left)
if (b = 0) then print variables_printed
else
int n = generate_random_number() %b
while (n in variables_printed)
n= (n+random_number) % b
variables_printed += n
aux(b, variables_printed, iterations_left-1)
And your other function:
function s(b)
if b < 0 return 0
else
char *variables_to_print
aux(b, variables_to_print, b)
If you can not use strings, you can do it with long as konsolas said.
I have to find multiplicity of smallest prime factor in all numbers till 10^7.I am using Sieve of Eratosthenes to find all the prime numbers. And there in a seperate array phi i am storing smallest prime factors of composite numbers.Here is my code for that
for(ull i=2;i<=m;i++)
{
if (check[i])
{
uncheck[i]=true;
for (ull k=i*i; k<=n; k+=i)
{
if(check[k]==true)
phi[k]=g;
check[k]=false;
}
}
}
Now i am running a loop till n and using a loop inside it to calculate it.
Here is code for that
for(ull i=4;i<=n;i++)
{
if(check[i]==false)
{
ull count=0;
ull l=i;
ull r=phi[i];
while(l%r==0)
{
l=l/r;
count++;
}
cout<<count<<'\n';
}
}
Is there any faster way to compute this?
Absolutely, you can do this without a loop.
c is probably at most 64 bits. It cannot contain any factor other than 1 more than 63 times. So instead of a loop, you write 63 nested if-statements.
For the case j == 2 your compiler may have some intrinsic functions that count trailing zero bits. If that is the case, then you handle that case separately and you need only 40 if's, because 3^41 > 2^64.
If you want to evaluate n such that jn = c, then recast the problem to
n = log(c) / log(j).
If n is an integer then your problem is solved.
Of course you need to consider floating point precision here; n might not be an exact integer, but close to one.
One alternative option, though not necessarily the most efficient, is to write a simple recursive function, such as this, assuming you are dealing with ints:
int recurseSubtract(int c, int j, int count){
if ((c==j)) {
return count + 1;
} else {
c = c-j;
subtract(c, j, count++);
}
}
int count = recurseSubtract(c,j,0);
However, see here for the pros and cons of loops vs. recursion.
Since you asked for the "multiplicity of smallest prime factor" you could easily use the same sieve approach to get multiplicity as you used to get the smallest factor.
for(ull i=2;i<=m;i++)
{
if (check[i])
{
uncheck[i]=true; // WHY??
ull k=i*i;
for (ull q=i; q<maxq; k=(q*=i))
for ( ; k<=n; k+=q)
{
if(check[k]==true)
phi[k]=g; // I copied 'g' from you, but didn't you mean 'i'?
if ( phi[k]==g )
count[k]++;
check[k]=false;
}
}
}
If you want to do a little better than that, the step of phi[k]==g and the some of the redundancy in check[k] access are needed only because q values are processed in forward sequence. It would be faster to work with q in reverse. Since q's are only easily computed in forward sequence and there are fairly few q's per i, the easiest way to process q backward would be to convert the loop over q into a recursive function (compute q on the way in and process it after the recursive call).
I found one simple rule but can not really describe in words. Here is another code calculating primenumbers
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
double f_power(double val, int exp);
int main(int argc,char* argv[]) {
int p[2];
int ctr = 0;
int ctr2 = 0;
int it_m = 0;
int it_1 = 0;
int it_2 = 0;
int it_c = 0;
int index = 3;
srand(time(NULL));
double t = clock();
double s = clock();
int prime = 2;
FILE *file;
file = fopen("ly_prime.txt", "w");
//f_power(2.0, 57885161)
for (it_m = 2; it_m <= 2000; it_m++) {
for (it_1 = it_m, ctr2 = 0, it_c = it_m; it_1 >= 2; it_1--) {
for (it_2 = it_1; it_2 >= 2; it_2--) {
if (it_1 * it_2 - it_c == 0) {
p[ctr % 2] = it_c;
if (ctr >= 1 && p[ctr % 2] - p[(ctr - 1) % 2] == 2) {
//prime[0] = (p[ctr % 2] - 1);
prime = (p[ctr % 2] - 1);
fprintf(stdout, "|%d _ i: %d _ %d\n", isPrime(prime),index, prime);
index++;
}
ctr++;
}
}
}
}
t = clock() - t;
fprintf(file, "|%d_ %d_ %d ", prime, index - 2, ctr);
}
double f_power(double val, int exp) {
int i = 0;
double help = val;
for(i = 1; i < exp; i++) {
val *= help;
}
return val;
}
int isPrime(int number)
{
int i = 2;
for(i=2; i < number; i++)
{
int leftOver=(number % i);
if (leftOver==0)
{
return 1;
break;
}
}
return 0;
}
perhaps it helps understanding, best regards