For an assignment, I have to write code which accepts as input an integer n and outputs the nth 'superunusual' number.
The first few su-numbers are: 22, 23, 26, 33, ... So when the input is 1, the output should be 22. 2 gives 23 and 3 gives 26.
I already have a code that checks if the input number is a su-number, but I can't find a way to calculate the nth number.
So when I now input 22, it says that 22 is a superunusual number.
The code:
/* calculates largest prime factor */
int lprime(int n) {
int max = -1;
while (n % 2 == 0) {
max = 2;
n /= 2;
}
for (int i = 3; i*i <= n; i += 2) {
while (n % i == 0) {
max = i;
n = n / i;
}
}
if (n > 2) {
max = n;
}
return max;
}
/* check unusual number */
int unus(int n) {
/* find largest prime of number */
int factor = lprime(n);
/* Check if largest prime > sqrt(n) */
if ((factor*factor) > n) {
return 1; /* true */
}
else {
return 0; /* false */
}
}
/* delete digit from number */
int del(int num, int n) {
int d = log10(num)+1; /* checks amount of digits */
int revnew = 0;
int new = 0;
for (int i = 0; num != 0; i++) {
int dig = num % 10;
num = num / 10;
if(i == (d - n)) {
continue;
} else {
revnew = (revnew * 10) + dig;
}
}
for (int i = 0; revnew != 0; i++) {
new = (new*10) + (revnew % 10);
revnew = revnew / 10;
}
return new;
}
/* driver code */
int main(int argc, char* v[]) {
int m=22, n;
int x = 0;
int i = 1;
int counter = 0;
scanf("%d", &n);
int d = log10(m)+1;
while (counter < n) {
if (unus(m++)) {
counter++;
}
}
for(unus(m); i < d; i++) {
int nmin = del(m, i);
if (unus(nmin)) {
continue;
} else {
printf("%d is not supurunusual\n", (m-1));
x++;
}
}
if(x==0) {
printf("%d is superunusual!\n", (m-1));
}
return 0;
}
I hope you can understand my code. Otherwise I will explain it better.
Also, I'm quite new to coding, so please don't be to harsh...
You have a function to determine whether a number is unusual, but you do the check whether a number is super-unusual in the body of the main routine. If you extract that code into a proper function:
int is_superunusual(int m)
{
int d = log10(m) + 1;
if (unus(m) == 0) return 0;
for(int i = 0; i < d; i++) { // see footnote
int nmin = del(m, i);
if (unus(nmin) == 0) return 0;
}
return 1;
}
then you can use Eugene's code:
while (counter < n) {
if (is_superunusual(m++)) {
counter++;
}
}
printf("The su number #%d is %d\n", n, m - 1);
Your code tested for unusual numbers, not super-unusual numbers.
Footnote: If you take del(num, n) to mean "remove the nth digit from the end", you can do away with the log10 call in del. You must check all deletions anyway, so the order doesn't really matter here.
Related
A number and a reversed number form a pair. If both numbers are prime numbers, we call it a reversed prime number pair. For instance, 13 and 31 is a 2 digit reversed prime number pair, 107 and 701 is a 3 digit reversed prime number pairs.
Write a program to output all n (2<=n<=5) digit reversed prime number pairs. If the input is less than 2 or greater than 5, output "Wrong input." and terminate the program. While ouputting , every 5 pairs form a new line, and only output the pair in which the first number is smaller than the second number.
Input: 1
Output: Wrong input.
Input: 3
Output:
(107,701)(113,311)(149,941)(157,751)(167,761)
(179,971)(199,991)(337,733)(347,743)(359,953)
(389,983)(709,907)(739,937)(769,967)
There are 14 results.
Can anyone give me hints how to do this?
I know how to determine if a number is a reversed prime number, but i couldn't understand how to complete this challenge from my friend
#include <stdio.h>
int checkPrime(int n) {
int i, isPrime = 1;
if (n == 0 || n == 1) {
isPrime = 0;
}
else {
for(i = 2; i <= n/2; ++i) {
if(n % i == 0) {
isPrime = 0;
break;
}
}
}
return isPrime;
}
int main (void)
{
int a, reverse = 0, remainder, flag=0;
scanf("%d",&a);
int temp = a;
while (temp!=0) {
remainder = temp%10;
reverse = reverse*10 + remainder;
temp/=10;
}
if (checkPrime(a)==1) {
if (checkPrime(reverse)==1){
printf("YES\n");
flag=1;
}
}
if (flag==0)
printf("NO\n");
}
This will be the correct solution:
#include <stdio.h>
#include <stdbool.h>
#include <math.h>
#include <stdlib.h>
#define MAX_N 100000
int *primes;
int num_primes;
void init_primes() {
int sqrt_max_n = sqrt(MAX_N);
primes = (int *) malloc(sqrt_max_n / 2 * sizeof(int));
num_primes = 0;
primes[num_primes] = 2;
num_primes++;
for (int i = 3; i <= sqrt_max_n; i += 2) {
bool is_prime = true;
for (int j = 0; j < num_primes; j++) {
if (i % primes[j] == 0) {
is_prime = false;
break;
}
}
if (is_prime) {
primes[num_primes] = i;
num_primes++;
}
}
}
int is_prime(int n) {
for (int i = 0; i < num_primes; i++) {
if (primes[i] == n) {
return 1;
}
if (n % primes[i] == 0) {
return 0;
}
}
return 1;
}
int reverse(int n) {
int reversed_n = 0;
while (n > 0) {
reversed_n = reversed_n * 10 + n % 10;
n /= 10;
}
return reversed_n;
}
int main() {
init_primes();
int n;
printf("Enter n (2 <= n <= 5): ");
scanf("%d", &n);
if (n < 2 || n > 5) {
printf("Wrong input.\n");
return 0;
}
int min = (int) pow(10, n - 1);
int max = (int) pow(10, n) - 1;
int count = 0;
for (int i = min; i <= max; i++) {
if (is_prime(i)) {
int reversed_i = reverse(i);
if (i < reversed_i && is_prime(reversed_i)) {
printf("(%d %d)", i, reversed_i);
count++;
if (count % 5 == 0) {
printf("\n");
} else {
printf(" ");
}
}
}
}
return 0;
}
After testing this code I get the same result what you need:
Enter n (2 <= n <= 5): 3
(107 701) (113 311) (149 941) (157 751) (167 761)
(179 971) (199 991) (337 733) (347 743) (359 953)
(389 983) (709 907) (739 937) (769 967)
The init_primes method caches all the required prime numbers until the sqrt of your limit to a dynamic array.
The is_prime method uses that cache for detecting whether a number is prime or not.
I have to solve a problem where one of the important tasks is to reorder the digits of the input in ascending order and we are not allowed to use arrays and lists. I have no problem with that and my code works, but only if we do not consider leading 0, which we should in this problem. The only way I see how to do is to check digit by digit and then add then ordered by multiplying the number by 10 and adding the next digit. (1*10 = 10, 10+3= 13, we got 1 and 3 ordered) However, if we have a 0 in our number this method will not work because if I want to make 0123 with the * 10 method, I won't be able to have the 0 as the first digit never. Does anyone know how to solve this? My code is below:
int ascendingNumbers (int n) { //This function sorts the number on an ascending order
int number = n;
int sortedN = 0;
for (int i = 0; i <= 9; i++) {
int toSortNumber = number;
for (int x = 0; x <= 4; x++) {
int digit = toSortNumber % 10;
if (digit == i) {
if (digit == 0) {
sortedN==10;
}
sortedN *= 10;
sortedN += digit;
}
toSortNumber /= 10;
}
}
return sortedN;
}
Normally I don't do homework problems, but for especially awful ones I'll make an exception.
(Also I'm making an exception to my general rule not to have anything to do with these absurd "desert island" constraints, where you're stranded after a shipwreck and your C compiler's array functionality got damaged in the storm, or something.)
I assume you're allowed to call functions. In that case:
#include <stdio.h>
/* count the number of digits 'd' in 'n'. */
int countdigits(int n, int d)
{
int ret = 0;
/* do/while so consider "0" as "0", not nothing */
do {
if(n % 10 == d) ret++;
n /= 10;
} while(n > 0);
return ret;
}
int main()
{
int i, n;
printf("enter your number:\n");
scanf("%d", &n);
printf("digits: ");
for(i = 0; i < 10; i++) {
int n2 = countdigits(n, i);
int j;
for(j = 0; j < n2; j++) putchar('0' + i);
}
printf("\n");
}
This solution does not involve a function int ascendingNumbers() as you asked about. If you want to handle leading zeroes, as explained in the comments, you can't do it with a function that returns an int.
Your zero problem is solved, check it...
class Main {
public static void main(String[] args) {
int number = 24035217;
int n = number, count = 0;
int sortedN = 0;
while (n != 0) {
n = n / 10;
++count;
}
for (int i = 9; i >= 0; i--) {
int toSortNumber = number;
for (int x = 1; x <= count; x++) {
int digit = toSortNumber % 10;
// printf("\nBefore i = %d, x = %d, toSortNumber = %d, sortedN = %d, digit = %d",i,x,toSortNumber,sortedN,digit);
if (digit == i) {
sortedN *= 10;
sortedN += digit;
}
// printf("\nAfter i = %d, x = %d, toSortNumber = %d, sortedN = %d, digit = %d",i,x,toSortNumber,sortedN,digit);
toSortNumber /= 10;
}
}
System.out.print(sortedN);
}
}
I need to find the sum of all numbers that are less or equal with my input number (it requires them to be palindromic in both radix 10 and 2). Here is my code:
#include <stdio.h>
#include <stdlib.h>
int pal10(int n) {
int reverse, x;
x = n;
while (n != 0) {
reverse = reverse * 10 + n % 10;
n = n / 10;
}
if (reverse == x)
return 1;
else
return 0;
}
int length(int n) {
int l = 0;
while (n != 0) {
n = n / 2;
l++;
}
return l;
}
int binarypal(int n) {
int v[length(n)], i = 0, j = length(n);
while (n != 0) {
v[i] = n % 2;
n = n / 2;
i++;
}
for (i = 0; i <= length(n); i++) {
if (v[i] == v[j]) {
j--;
} else {
break;
return 0;
}
}
return 1;
}
int main() {
long s = 0;
int n;
printf("Input your number \n");
scanf("%d", &n);
while (n != 0) {
if (binarypal(n) == 1 && pal10(n) == 1)
s = s + n;
n--;
}
printf("Your sum is %ld", s);
return 0;
}
It always returns 0. My guess is I've done something wrong in the binarypal function. What should I do?
You have multiple problems:
function pal10() fails because reverse is not initialized.
function binarypal() is too complicated, you should use the same method as pal10().
you should avoid comparing boolean function return values with 1, the convention in C is to return 0 for false and non zero for true.
you should avoid using l for a variable name as it looks very similar to 1 on most constant width fonts. As a matter of fact, it is the same glyph for the original Courier typewriter font.
Here is a simplified and corrected version with a multi-base function:
#include <stdio.h>
#include <stdlib.h>
int ispal(int n, int base) {
int reverse = 0, x = n;
while (n > 0) {
reverse = reverse * base + n % base;
n = n / base;
}
return reverse == x;
}
int main(void) {
long s = 0;
int n = 0;
printf("Input your number:\n");
scanf("%d", &n);
while (n > 0) {
if (ispal(n, 10) && ispal(n, 2))
s += n;
n--;
}
printf("Your sum is %ld\n", s);
return 0;
}
in the function pal10 the variable reverse is not initialized.
int pal10(int n)
{
int reverse,x;
^^^^^^^
x=n;
while(n!=0)
{
reverse=reverse*10+n%10;
n=n/10;
}
if(reverse==x)
return 1;
else
return 0;
}
In the function binarypal this loop is incorrect because the valid range of indices of an array with length( n ) elements is [0, length( n ) - 1 ]
for(i=0;i<=length(n);i++)
{
if(v[i]==v[j])
{
j--;
}
else
{
break;
return 0;
}
}
And as #BLUEPIXY pointed out you shall remove the break statement from this else
else
{
break;
return 0;
}
#include <stdio.h>
#include <math.h>
int prime (long n);
long reverse(long n);
int main(void)
{
long n;
long i, j;
puts("Enter n dight number, and we will help you find symmetrical prime number");
scanf("%ld", &n);
for (i = 11; i < (pow(10, n) - 1); i+= 2)
{
if (prime(i))
{
j = reverse(i);
if (i == j)
{
printf("%ld\n", i);
}
}
}
}
int prime (long n) //estimate whether the number n is primer number
{
int status = 0;
int j;
//1 is prime, 0 is not
if (n % 2 == 0 || n == 3)
{
if (n == 2)
status = 1;
if (n == 3)
status = 1;
else
{
n++;
status = 0;
}
}
else
{
j = 3;
while (j <= sqrt(n))
{
if (n % j == 0)
{
status = 0;
break;
}
else
status = 1;
j+= 2;
}
}
return status;
}
long reverse(long n) //reverse a number
{
int i, j, x;
long k, sum;
int digit = 0;
int ar[1000];
while (n > 0)
{
k = n;
n = n / 10;
x = (k - n*10);
digit++;
ar[digit] = x;
}
for (i = 1,j = digit - 1; i <= digit; i++, j--)
{
sum += ar[i] * pow(10, j)
}
return sum;
}
I build a reverse function in order to reverse numbers, for example, 214, to 412.
This function works fine in individual number, for instance, I type reverse(214), it return 412, which is good. But when I combine reverse() function with for loop, this function can not work... it produces some strange number...
so How can I fix this problem?
The reverse function is extremely complicated. The better way to go about it would be:
long reverse (long n)
{
long result = 0;
while (n != 0)
{
result *= 10;
result += n % 10;
n /= 10;
}
return result;
}
I think the problem in your code is that in the following segment
digit++;
ar[digit] = x;
you first increment the position then assign to it, thus leaving ar[0] unintialized.
How can I fix this problem?
You need to initialize sum
long k, sum = 0;
^
See the code from #Armen Tsirunyan for a simpler approach.
The code is trying to find the largest palindrome made from the product of two 2-digit numbers. The answer is 91*99 = 9009 but I keep getting 990, which is not even a palindrome. I really appreciate the help!
#include <stdio.h>
int main()
{
int i = 10;
int j = 10;
int a = 0;
int b = 0;
int array[100] = {0};
int divider = 10;
int num;
int great;
int product;
int n;
int flag;
/*Loop through first 2 digit number and second 2 digit number*/
while (i<100)
{
while (j < 100)
{
product = i*j;
array [a] = product % 10;
n = product / divider;
while (n != 0)
{
a++;
num = n%10;
divider *=10;
array[a]=num;
n = product/divider;
}
flag = 0;
while (b<a)
{
if (array[b] != array[a])
{
flag = 1;
}
b++;
a--;
}
if (flag == 0)
{
great = product;
}
j++;
a = 0;
b = 0;
}
i++;
}
printf("The largest palindrome is %d \n", great);
return 0;
}
Here is a code snippet you can try.
#include <stdio.h>
void main()
{
int a = 1; // first integer
int b = 1; // second integer
int currentNumber;
int currentPalin; if a palindrome is found, its stored here
while (a<100){ //loop through the first number
while (b<100){ // loop through the second number
currentNumber = a*b;
if (currentNumber == reverse(currentNumber) ){ //check for palindrome
currentPalin = currentNumber;
}
b = b+1; //increment the second number
}
b = a; // you could have set b=1 but it would not be an efficient algorithm because
//some of the multiplication would occur twice. eg- (54*60) and (60*54)
a = a +1; //increment the first number
}
printf ("Largest palindrom is %d \n", currentPalin);
getchar();
}
// method for finding out reverse
int reverse(int n){
int reverse = 0;
while (n != 0)
{
reverse = reverse * 10;
reverse = reverse + n%10;
// when you divide a number by 10, the
//remainder gives you the last digit. so you are reconstructing the
//digit from the last
n = n/10;
}
return reverse;
}
Update:- As suggested by M Oehm, I have modified the code to make it more general.
#include <stdio.h>
void main()
{
int a = 1;
int b = 1;
int currentNumber;
int currentPalin=0;
while (a<100){
while (b<100){
currentNumber = a*b;
if (currentNumber == reverse(currentNumber) ){
if (currentNumber>currentPalin){
currentPalin = currentNumber;
}
}
b = b+1;
}
b = 1;
a = a +1;
}
if (currentPalin==0){
printf("No Palindrome exits in this range");
}
else {
printf ("Largest palindrome is %d \n", currentPalin);
}
getchar();
}
int reverse(int n){
int reverse = 0;
while (n != 0)
{
reverse = reverse * 10;
reverse = reverse + n%10;
n = n/10;
}
return reverse;
}
An alternative approach to solve the problem.
#include<stdio.h>
int reverse(int num)
{
int result = 0;
while( num > 0)
{
result = result * 10 + (num%10);
num/=10;
}
return result;
}
int main()
{
int last_best = 1;
int best_i=1;
int best_j = 1;
const int max_value = 99;
for( int i = max_value ; i > 0 ; --i)
{
for(int j = i ; j > 0 ; --j){
int a = i * j;
if( last_best > a )
break;
else if ( a == reverse(a) )
{
last_best = a;
best_i = i;
best_j = j;
}
}
}
printf("%d and %d = %d\n", best_i,best_j,last_best);
}
And it is quite simple to follow.
It seems that you do not reinitialize variables at the beginning of loop. They keeps values from previous iterations. For example, j and divider. Put
j = 10;
before starting "j" loop, i.e.:
j = 10;
while (j < 100) ...
The same for divider:
...
j = 10;
while (j < 100) {
divider = 10;
...
If you were using for loops you would avoid this problem naturally:
for(i=10; i<100; i++) {
for(j=10; j<100; j++) {
...
}
}