Prime number loop logic - c

I wanted to ask you somthing that i cant understand why it works.
i need to make a code that you input some number and it gives you all the prime numbers until you get to that num.
now i have this code that does the trick.
like every number that is not prime it goes to the next n and checks it but i dont understand this
if like it gets 4 and then turns it to 5 the j wont go to 3? and then you start checking 5/3 but you miss the division by 2 and so on like i dont get it does it resets the j to 2 every time that i edd i+1?
also if i give it like 10 it prints 11 and i dont want it to pass the original number how do i do that.
int num;
printf("please enter num ");
scanf_s("%d", &num);
int i, j;
for (i = 2; i < num; i++)
{
for (j = 2; j < i; j++)
{
printf("j=%d ", j);
if (i % j == 0)
i += 1;
}
printf("%d ", i);
}

"code that does the trick" simply fails for various num. Going to the next i (if (i % j == 0) i += 1;) fails as code needs to test against smaller j again with the new i. Recommend forming a helper function.
for (i = 2; i < num; i++) {
if (isprime(i)) printf("%d ", i);
}
Sieve of Eratosthenes is a much better approach. #NeilB

now i have this code that does the trick
No, the algorithm is wrong.
This
int num;
printf("please enter num ");
scanf("%d", &num);
int i, j;
for (i = 2; i < num; i++)
{
for (j = 2; j < i; j++)
{
// commented out printf("j=%d ", j);
if (i % j == 0)
i += 1;
}
printf("%d ", i);
}
with input value 30 will give the output
2 3 5 7 11 13 17 19 23 27 29
but 27 is not a prime
A few other values that the algo handles incorrect: 35, 87, 95

Related

How can we replace the higest 5 numbers in an array of 10 with 1 and smallest 5 into 0 in C programing?

Here's the question my teacher gave me
Write a C program to store 10 integers in an array of size 10 and
display the contents of the array. Replace the highest 5 numbers in the array by
1 and lowest 5 numbers by 0 and display the contents of the new array.
[For e.g.
Original Array
44 11 6 99 30 78 32 31 66 55
New Array
1 0 0 1 0 1 0 0 1 1
I have been struggling in this question whole day :(
There are a lot of ways to solve this problem. A good way would be sort the array into another array and then replace the 1st half with 0s and the second half with 1s like this:
#include<stdio.h>
int main(){
const int arraySize = 10;
int i, j;
int arr[arraySize];
int arrSorted[arraySize];
int temp;
// Get input from user
printf("Please enter 10 numbers!\n");
for (i = 0; i < arraySize; i++)
{
scanf("%d", &arr[i]);
// Copy array into another to sort it later
arrSorted[i] = arr[i];
}
// Print input
printf("Input: ");
for (i = 0; i < arraySize; i++)
{
printf("%3d ", arr[i]);
}
printf("\n");
//Sort the array in ascending order
for (i = 0; i < arraySize; i++)
{
for (j = i + 1; j < arraySize; j++)
{
if(arrSorted[i] > arrSorted[j])
{
temp = arrSorted[i];
arrSorted[i] = arrSorted[j];
arrSorted[j] = temp;
}
}
}
// Start replacing procedure
for (i = 0; i < arraySize; i++)
{
for (j = 0; j < arraySize; j++)
{
if (arr[j] == arrSorted[i])
{
if (i < arraySize / 2) // Replace 1st half with 0s
{
arr[j] = 0;
}
else // Replace 2nd half with 1s
{
arr[j] = 1;
}
break;
}
}
}
// Print result
printf("Result: ");
for (i = 0; i < arraySize; i++)
{
printf("%3d ", arr[i]);
}
printf("\n");
return 0;
}
Of course, you can use the C standard library qsort() function if you don't want to sort yourself.
Another solution would be, find the median number of the array then replace any number which is less than it with 0 and any number bigger than it with 1. Although with this solution there will be some challenges regarding what to do with the median number itself and what if there are multiple median numbers (duplicated)?

how to list all pairs of sexy primes

How can i write a program that lists all sexy prime pairs that exist in n numbers.
For example if n = 10 the output should be (5, 11) and (7, 13)
My idea was to generate all primes within n and then add 6 to each and check if the i + 6 is a prime. But it doesnt work, there's no output and the program ends.
#include <stdio.h>
int main() {
int i, j, n, k, isprime = 1, prime2, flag = 0;
scanf("%d", &n);
for (i = 3; i <= n; i++){
for (j = 2; j <= i; j++){
if (i % j == 0)
break;
}
if (i == j){
prime2 = i + 6;
for (k = 3; k <= prime2; k++){
if (prime2 % k == 0){
flag++;
break;
}
}
if (flag == 0){
printf("%d %d\n", i, prime2);
}
}
}
return 0;
}
Any ideas of what im doing wrong or any tips on how to solve it? (with loops only)
As there're a lot of resources about finding a prime number, I'm not going to discuss that. Rather I'll try to point out the bug in your code.
First problem:
for (k = 3; k <= prime2; k++)
Here you need to run the loop till prime2 - 1. Also you should start checking from 2 rather than 3, just like you did previously. That means,
for (k = 2; k < prime2; k++)
or
for (k = 2; k <= prime2 - 1; k++)
Reason: when k = prime2, prime2 % k will be 0. For finding out whether a number is prime we don't need to check if that number is divisible by 1 and that number itself.
Note: Now you might think why the first prime number loop for (j = 2; j <= i; j++) is working .
It's working because you've given an additional condition if (i == j) after it.
Second problem:
You need to declare the flag variable within the first loop.
for (i = 2; i <= n; i++)
{
int flag = 0;
.... (rest of the code)
....
}
Reason: Basically with the flag value, you're trying to find out whether prime2 is a prime number.
Every time you'll get a prime number from the first loop, you'll have a new value of prime2. In your code, once you're incrementing the value of flag, you're never resetting the flag value.
That's why once your code detects a prime2 which is not a prime, it'll never detect the second prime number again (prime2 which is actually prime).
Overall code:
#include <stdio.h>
int main()
{
int i, j, n, k, isprime = 1, prime2;
scanf("%d", &n);
for (i = 3; i <= n; i++)
{
int flag = 0; // changing point
for (j = 2; j <= i; j++)
{
if (i % j == 0)
break;
}
if (i == j)
{
prime2 = i + 6;
for (k = 2; k < prime2; k++) // changing point
{
if (prime2 % k == 0)
{
flag++;
break;
}
}
if (flag == 0)
{
printf("%d %d\n", i, prime2);
}
}
}
return 0;
}
Few resources to know more about finding out prime numbers:
Prime Numbers
C Program to Check Whether a Number is Prime or not
Sieve of Eratosthenes
You can use Sieve to speed up the program. It can generate all pairs in O(N log N) time. Here's the Algorithm.
Now, you have a boolean array, is_prime where is_prime[i] is true if i is a prime, false otherwise.
Now, iterate from i = 1 to i = N and check if is_prime[i] && is_prime[i + 6], if the condition is true, output the pair.

How to write the algorithm of this matrix in this ascending order in C.Where is error in my code?

I am writing this code to print the following matrix in this spiral order(spiral by column).But my code is printing totally different thing.
a a+7 a+8 a+15
a+1 a+6 a+9 a+14
a+2 a+5 a+10 a+13
a+3 a+4 a+11 a+12
Here is what i did:
int main() {
int a;
int Sum = 0;
int i = 0, j = 0,n;
printf("Insert the value of n: ");
scanf("%d",&n);
printf("Insert the value of a number: ");
scanf("%d",&a);
for(i=0;i<n;i++){
for(j=0;j<n;j++){
printf("%d ",a);
a = a + 7;
printf("\t");
}
printf("%d",a);
a = a + 1 ;
printf("\n");
}
return 0;
}
The way I approached this is to build the matrix of values you actually want, but doing so in column order, where we can relatively easily control the logic of value progression by row. Then, with that matrix in hand, print out the values in row order, as you want the output:
int main()
{
int a = 7;
int n = 4;
int array[4][4];
for (int c=0; c < n; ++c)
{
for (int r=0; r < n; ++r)
{
// values ascending for even columns
if (c % 2 == 0)
{
array[r][c] = a + c*n + r;
}
// values descending for odd columns
else
{
array[r][c] = a + c*n + n-r-1;
}
}
}
for (int i=0; i < n; ++i)
{
for (int j=0; j < n; ++j)
{
printf("%d ", array[i][j]);
}
printf("\n");
}
}
Output:
Demo here:
Rextester
Instead of using this complex mechanism to keep track of all elements you can just calculate the value to add at any time by simple arithmetic.
See this
int row;
int column;
printf("\n");
for (row = 0; row < n; row++) {
for (column = 0; column < n; column++) {
int base;
int flag;
if (column % 2 != 0) {
base = (column+1)/2 * 2*n - 1;
flag = -1;
}else {
base = column/2 * 2*n;
flag = 1;
}
printf( "%d ", a + base + flag * row);
}
printf("\n");
}
I hope you are able to follow this logic. If not feel free to ask.
Demo here:
Ideone
There seem to be two issues with your code as it is. As mentioned in the above comment, you are using the variable a in the loop calculation, so it is constantly being updated. This means your loop becomes invalid after a few iterations. If you define a dummy variable, this would avoid the problem. Secondly the implementation of the spiralling is close to being right, but it's not quite there.
Consider in the case n = 4. When you print along each row, the difference between a new element and the last alternates between values of (2n - 1) = 7 and 1. To take this into account, you could for example check every time you want to print whether the column index (j) is odd or even, and use this to determine which difference to add. Once you have the row machinery fixed, it shouldn't be difficult to extend it to the columns.
Simple solution using a matrix to calculate values before print them
#include <stdio.h>
int main(void)
{
int a;
int i = 0, j = 0, n;
printf("Insert the value of n: ");
scanf("%d", &n);
printf("Insert the value of a number: ");
scanf("%d", &a);
int matrix[n][n];
for (i=0; i< n*n; i++)
{
// even columns ascending
if (((i/n) % 2) == 0)
{
matrix[i%n][i/n] = a++;
}
// odd column descending
else
{
matrix[n-(i%n)-1][i/n] = a++;
}
}
for (i=0; i< n; i++)
{
for (j=0; j< n; j++)
{
printf("%d\t", matrix[i][j]);
}
printf("\n");
}
return 0;
}
Output
Insert the value of n: 4
Insert start value: 1
1 8 9 16
2 7 10 15
3 6 11 14
4 5 12 13

Negative numbers are printed

This is a program on sorting integers.
#include <stdio.h>
int main(void) {
int n, i, j, k;
int nmbr[100];
printf("\n How many numbers ? ");
scanf("%d", &n);
printf("\n");
for (i = 0; i < n; ++i) {
printf(" Number %d : ", i + 1);
scanf("%d", &nmbr[i]);
}
for (i = 0; i < n; ++i) {
for (j = 0; j < n; ++j) {
if (nmbr[j] > nmbr[j + 1]) {
k = nmbr[j];
nmbr[j] = nmbr[j + 1];
nmbr[j + 1] = k;
}
}
}
printf("\n Numbers after sorting : \n");
for (i = 0; i < n; ++i) {
printf (" %d", nmbr[i]);
}
return 0;
}
It works fine, but when I enter some number that contains more than 2 digits, the first number that is printed is negative and really big. I don't also get the last integer too. I enter N as 4, then the numbers I entered were 25, 762, 588, and 34. The result I get is:
-1217260830 25 34 588
What seems to be the problem?
You are running the loop as for (j = 0; j < n; ++j) which means j will have values from 0 to n-1 which are valid array indices (or array elements with relevant values).
But, inside that loop you are accessing an element beyond the last. For instance, in
if (nmbr[j] > nmbr[j + 1])
you are accessing nmbr[j + 1]. If the current value of j in n-1, then you are accessing nmbr[n-1 + 1] i.e. nmbr[n] which will be a value outside the array and may contain a garbage value (which might as well be negative!).
If you are trying something like Bubblesort, you might want to run the inner loop like for (j = 0; j < n - 1; ++j).
There are multiple problems in your code:
You do not check the return values of scanf(). If any of these input operations fail, the destination values remain uninitialized, invoking undefined behavior and potentially producing garbage output.
You do not verify that the number of values provided by the user is at most 100. The reading loop will cause a buffer overflow if n is too large.
Your sorting logic is flawed: in the nested loop, you refer to nmbr[j + 1] which is beyond the values read from the user. This invokes undefined behavior: potentially causing a garbage value to appear in the output.
Here is a corrected version:
#include <stdio.h>
int main(void) {
int n, i, j, k;
int nmbr[100];
printf("\n How many numbers ? ");
if (scanf("%d", &n) != 1 || n > 100) {
printf("input error\n");
return 1;
}
printf("\n");
for (i = 0; i < n; ++i) {
printf(" Number %d : ", i + 1);
if (scanf("%d", &nmbr[i]) != 1) {{
printf("input error\n");
return 1;
}
}
for (i = 0; i < n; ++i) {
for (j = 0; j < n - 1; ++j) {
if (nmbr[j] > nmbr[j + 1]) {
k = nmbr[j];
nmbr[j] = nmbr[j + 1];
nmbr[j + 1] = k;
}
}
}
printf("\n Numbers after sorting :\n");
for (i = 0; i < n; ++i) {
printf (" %d", nmbr[i]);
}
printf("\n");
return 0;
}
Your Sorting Logic is wrong. It should be:
for (i = 0; i < n; ++i){
for (j = 0; j < (n-1); ++j){
if (nmbr[j] > nmbr[j + 1]){
k = nmbr[j];
nmbr[j] = nmbr[j + 1];
nmbr[j + 1] = k;
}
}
You are trying to access out of bounds of array, when you iterate in your second loop using j. This is causing the garbage value.
As per your example involving 4 elements, when you try to access j+1, it will try to access nmbr[3+1] in the last iteration of second loop which leads to out of bounds access.
Problem is with the sorting logic as suggested by fellow coders. But It is always good coding habit to initialize the variables. Also use the qualifier if are dealing with positive numbers only.
unsigned int n = 0 , i = 0, j = 0, k = 0;
unsigned int nmbr[100] = {0};
If you would have initialized them, out put of your program would be following, which might help you tracing the problem by yourself.
0 25 34 588

Input to Multi-Array in C

I am trying to assign user input into an array; however, the program below only picks up on the first element in each line of input. The ultimate goal of this program is to find the diagonal sums of integers and return the absolute value of their difference.
Example input (note that the first number gives the number of rows and columns (square array):
Input:
3
11 2 4
4 5 6
10 8 -12
Output:
Expected = 15
Actual = 10
I realize that the issue lies in the way that the array is setup. If I print the array out I get: 111555999
Any hints/help would be very appreciated.
int main() {
int n, i, c, multi_array[200][200], sum1 = 0, sum2 = 0;
scanf("%i", &n); //N = number of rows and number of columns (square 2D array)
for (i = 0; i < n; i++) {
for (c = 0; c < n; c++) {
scanf("%d ", &multi_array[c][i]); //enter integers to store in array
}
}
for (i = 0; i != n; i++) {
sum1 += multi_array[i][i]; //add up top left to bottom right diagonal
}
for (i = 0; i != n; i++) {
sum2 += multi_array[i][n-i]; //add up top right to bottom left diagonal
}
printf("%i", abs(sum1 - sum2)); //print absolute value of the difference between diagonals
return 0;
}
Your major problem is here, where you go out of bounds:
for (i = 0; i != n; i++) {
sum2 += multi_array[i][n - i]; // when i is 0, th
}
When i = 0, you are accessing multi_array[0][3], which is out of bounds when N = 3.
So change it to this:
multi_array[i][n - i - 1]
You should read your array like this:
for (i = 0; i < n; i++) {
for (c = 0; c < n; c++) {
scanf(" %d ", &multi_array[i][c]);
}
}
since C stored its arrays in row-major order. What you have stores the array in column-major order. It's not wrong, but it's something you do only if you really have to.
Finally, change again the input part of your code to this:
scanf("%d", &n);
for (i = 0; i < n; i++) {
for (c = 0; c < n; c++) {
scanf("%d", &multi_array[i][c]);
}
}
so that you have to input exactly what you need to. With your initial code I have to type an extra random number when I had completed the input process.
Last but not least, I am posting the whole code, where I have wrote some extra printf()'s, which are actually for the programmer, so that he can see step-by-step if his code is acting as expected or not.
#include <stdio.h>
#include <stdlib.h> /* abs */
int main() {
int n, i, c, multi_array[200][200], sum1 = 0, sum2 = 0;
scanf("%d", &n);
for (i = 0; i < n; i++) {
for (c = 0; c < n; c++) {
scanf("%d", &multi_array[i][c]);
}
}
for (i = 0; i < n; i++) {
for (c = 0; c < n; c++) {
printf("|%d|", multi_array[i][c]);
}
printf("\n");
}
for (i = 0; i != n; i++) {
sum1 += multi_array[i][i];
}
printf("sum1 is %d\n", sum1);
for (i = 0; i != n; i++) {
sum2 += multi_array[i][n - i - 1];
}
printf("sum2 is %d\n", sum2);
printf("%i", abs(sum1 - sum2));
return 0;
}
Output:
3
11 2 4
4 5 6
10 8 -12
|11||2||4|
|4||5||6|
|10||8||-12|
sum1 is 4
sum2 is 19
15
You are clearly going out of bounds here:
for (i = 0; i != n; i++) {
sum2 += multi_array[i][n-i]; //add up top right to bottom left diagonal
}
When i is equal to 0 the expression n-i will be equal to n, but the range of the array is from 0 to n-1. The code will read uninitialized values and cause undefined behavior.
The second array index should be 1 less.

Resources