Numeric palindromes from a given range and given length - c

So i wanna do this C problem where i need to read N (0<=N<=20) and M( 0<=M<=10) then print all numeric palindromes formed with numbers from {1....N} and of length M.
Input:
N=15
M=3
Output:
1 2 1
2 2 2
3 2 3
...
11 3 11
...
Things like 12 3 12 are not considered palindrome.
I tried to find compress this this palindrome to be just a number but it shows me numbers that are not supposed to be palindroms to.
Can you give me some hints on how to do this? Or if you can help me do this it would be very nice.

I'm not sure if this is what you were looking for but to be honest the problem intrigued me so I created a rather simplistic brute-force approach to it. Hope you'll find it useful.
The logic is the following:
Create a function that will iterate through all possible numbers(not digits) for a given position in our array of numbers.
Make that function call itself recursively until there is one instance of it handling each position in our array of numbers.
The instance of the function that is handling the last(rightmost) number will check each combination of numbers for being a palindrome. If one is it will be printed out.
Ah yes, to determine if a given array of numbers is a palindrome I used the simple approach to transform the array of numbers into an array of digits. So, in other words single digit numbers are transferred as is BUT double digit ones get separated into two digits and transferred as two entries. Once I trans-coded the array of numbers into an array of digits I just run a simple algorithm that starts from both ends of the digits array moving towards the middle checking each pair for differences. If no difference is found the array of digits (and consequently the array of numbers it comes from) is a palindrome.
That is basically it.
I'll supply the code below. Hope I could help. If you need any clarification or have a comment (like if I totally missed the point of the question :)) just ask!
The code:
#include "stdint.h"
#include "stdbool.h"
#include "stdio.h"
#define NUMBER_ARRAY_SIZE (10UL)
#define DIGIT_ARRAY_SIZE (NUMBER_ARRAY_SIZE * 2UL)
bool isPalindrome(uint32_t numbers[], uint32_t lastIndex)
{
bool retVal = true;
uint32_t digits[DIGIT_ARRAY_SIZE];
int32_t digitsLastIndex = -1;
// Turn number-array into a digit-array.
for(uint32_t pos = 0u; pos <= lastIndex; pos++)
{
if(numbers[pos] < 10u)
{
// single digit => transfer it 1on1
digits[++digitsLastIndex] = numbers[pos];
}
else
{
// double digits => split in two digits
uint32_t firstDigit = numbers[pos]/10u;
uint32_t secondDigit = numbers[pos] - (firstDigit * 10u);
digits[++digitsLastIndex] = firstDigit;
digits[++digitsLastIndex] = secondDigit;
}
}
// This is where we check if we really have a palindrome formed by all the digits.
uint32_t numOfSteps = (digitsLastIndex + 1u) / 2u;
for(uint32_t i = 0u; i < numOfSteps; i++)
{
if(digits[i] != digits[digitsLastIndex - i])
{
retVal = false;
break;
}
}
return retVal;
}
void processNumberAtGivenPosition(uint32_t positionOfNumber, uint32_t lastAllowedPosition, uint32_t largestNumberAllowed, uint32_t numbers[])
{
// Generate and process all numbers in the actual position.
for (uint32_t number = 1u; number <= largestNumberAllowed; number++)
{
// Update the number-array with the actual number(at the actual position).
numbers[positionOfNumber] = number;
if(positionOfNumber == lastAllowedPosition)
{
// We are at the last position already. Check if the current number-array is a palindrome..
if(isPalindrome(numbers, lastAllowedPosition))
{
// ..if yes, then print it on the screen.
for (uint32_t i = 0u; i <= lastAllowedPosition; i++)
{
printf("%u", numbers[i]);
}
printf("\n");
}
}
else
{
// We still have more positions on the right. Move on to the next(->) one.
processNumberAtGivenPosition(positionOfNumber + 1u, lastAllowedPosition, largestNumberAllowed, numbers);
}
}
}
int main()
{
uint32_t N, M;
scanf("%u", &N);
scanf("%u", &M);
uint32_t numberArray[NUMBER_ARRAY_SIZE];
processNumberAtGivenPosition(0u, M - 1u, N, numberArray);
}

Related

How to see if integer has a specific digit in it in C

I need to build a program, that would write all numbers from 0 to 100, but will place an * instead of any number that contains the digit 3 or can be divided by 3. This is what I have so far. How can I make it work?
#include <stdio.h>
main() {
int i, c;
c = 100;
for (i = 0; i <= c; i++) {
if (i % 3 == 0) {
printf("*");
}
if (i)
printf("%d\n", i);
}
}
place an * instead of any number that contains the digit 3 or can be divided by 3.
OP's code took care of the "can be divided by 3" with i % 3 == 0.
How about a little divide and conquer for the "contains the digit 3"? Put a function in there.
if (contains_the_digit(i, 3) || (i % 3 == 0)) {
printf("*\n");
} else {
printf("%d\n", i);
}
Now what is left is to define contains_the_digit(int i, int digit)
Mathematically (nice and efficient):
bool contains_the_digit_via_math(int i, int digit) {
do {
if (abs(i % 10) == digit) { // Look at the least digit, abs() to handle negative `i`
return true;
}
i /= 10; // Now look at the upper decimal digits
} while (i);
return false;
}
Or textually:
bool contains_the_digit_via_string(int i, int digit) {
char buf[30]; // Something certainly big enough
sprintf(buf, "%d", i);
return strchr(buf, digit + '0') != NULL;
}
Or use your imagination for other ideas.
The key is to take your problems and reduce them to smaller ones with helper functions: divide and conquer.
Concert the number to a string
Replace '3' with '*' within that string
i.e.
int to_be_converted =12345612343242432; // Or summat else
char num[100]; // Should be more than enough
sprintf(num, "%d", to_be_converted);
for (int i =0; num[i]; i++) {
if (num[i] -- '3') num[i] = '*';
}
printf("Here you go %s", num);
That should do the trick
Just ad the bit to go through the numbers and check if divisible by 3. I leave that to the reader.
Seeing you forgot to add the return type int to your int main(), I think this is a good time to learn to write your own function!
In this case, you want a function that can check whether the last digit of a number is a 3 when you represent that number as base-10. That's easy! The function should look like (you need to #include <stdbool.h> at the beginning of your file, too):
bool ends_in_decimal_3(int number) {
// figure out a way to find the difference
// between number, rounded to multiples of 10
// and the original number. If that difference==3,
// then this ends in 3 and you can `return true;`
}
Armed with that function, you can see whether your i itself ends in 3, or whether i/10 ends in 3 and so on. Remembering that division / in C between ints always rounds down is a good trick to do that, and also an important hint on how to implement your rounding in ends_in_decimal_3.

How can I find the largest number in an array that is less than or equal to a random integer?

I am working on an assignment and I'm asked to create an array of fibonacci numbers in a range of 0 to 50,000. Once this array has been initialized I am suppose to create a random number between 2 and 10,000. Then, I'm suppose to compare the members of the fibonacci array with the random number to find the greatest fibonacci number that is less than or equal to the random number.
This is the code that I have so far, it correctly creates the array of fibonacci numbers and the random number. How would I start with comparing the members of the array to the random number?
#include <stdio.h>
#include <string.h>
#include <time.h>
void Get_Fibonacci(int n)
{
int fibArray[25];
int lower = 2, upper = 10000, count = 1;
int i, FibRange = 50000;
int first = 0, second = 1, next = 1;
printf("%d %d", first, second);
//Create fibonacci sequence between 0 and 50,000 and store in array
for (i = 2; (first + second) < FibRange; i++)
{
next = first + second;
fibArray[i] = next;
printf(" %d\n", fibArray[i]);
first = second;
second = next;
}
//Create Random Number between 2 and 10,000
srand(time(0));
int k;
for (k = 0; k < count; k++)
{
n = (rand() % upper - lower + 1) + lower;
}
}
I did a little tweaking to your algorithm. This should do what you are asking.
Basically since the Fibonacci sequence combines of sorted numbers, you can do binary search. Also, in your implementation, your array doesn't have to be of size 25 since you are only holding 23 integers. 0 and 1 are saved in independent variables. In addition, your random number generator was wrong.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX_N 10000
#define MIN_N 2
void Get_Fibonacci()
{
int fibArray[25];
int lower = 2, upper = 10000, count = 1, middle = 0,found=0;
int low=0,high=0;
int i, FibRange = 50000,n;
int first = 0, second = 1;
printf("\n\t Fibonacci sequence:\n");
fibArray[0]=0;
fibArray[1]=1;
printf("%d\n%d\n",fibArray[0],fibArray[1]);
/* Creates a fibonacci sequence between 0 and 50,000 and store in an array */
for (i=2; (first+second)<FibRange; i++)
{
fibArray[i]=first+second;
first=second;
second=fibArray[i];
printf("%d\n",fibArray[i]);
}
high=i-1 /* Using the for loop exit condition, as chux suggested */
/* Generates a random number between 2 and 10,000 */
srand(time(0));
n = rand()%(MAX_N+1-MIN_N)+MIN_N;
/* Binary search algorithm */
while (low<=high&&!found)
{
middle=(low+high)/2;
if (n==fibArray[middle])
{
count=fibArray[middle];
found=1; /* To terminate the loop if we have an exact match */
}
else if (n<fibArray[middle])
{
high=middle-1;
}
else
{
low=middle+1;
count=fibArray[middle]; /* Saving the number less than key value */
}
}
printf("\n\tRandom number was: %d\n",n);
printf("\n\tClosest match was: %d\n",count);
return;
}
int main(void)
{
Get_Fibonacci();
return 0;
}
First, need to claify somethings:
1) the for loop for creating a random number is useless since count is always is one
2) n should not be a parameter for the function since you generate a random number in the function
3) the i should start from 0, starting from 2 doesn't make any sense to me. You’re just wasting the first two elements in the array
Largest is the variable that carries the value of the largest element and still smaller than n.
int Largest = fibArray[0];
for(int counter=1; counter<25; counter++){
if(fibArray[counter]>Largest && fibArray[counter]<n)
Largest = fibArray[counter];
}
return Largest;
Lambda expression makes these sort of things significantly easier. I suggest learning about lambda and delegates to help with problems like this in the future

Finding numbers with unique digits in C

I have to write a program that finds every number (except 0) which can be factored by numbers from 2-9.
For example first such a number would be number 2520 as it can be divided by every single number from 2 to 9.
It also has to be a number that contains only 1 type of digit of its own (no multiple digits in a number). So for example 2520 will not meet this requirement since there are two same digits (2). The example of a number that meets both requirements is number 7560. That is the point I don't how to do it. I was thinking about converting value in an array to string, and then putting this string in another array so every digit would be represented by one array entry.
#include <stdio.h>
#include <math.h>
int main() {
int i, n, x, flag, y = 0;
scanf("%d", &n);
double z = pow(10, n) - 1;
int array[(int)z];
for (i = 0; i <= z; i++) {
flag = 0;
array[i] = i;
if (i > 0) {
for (x = 2; x <= 9; x++) {
if (array[i] % x != 0) {
flag = 1;
}
}
if (flag == 0) {
y = 1;
printf("%d\n", array[i]);
}
}
}
if (y == 0) {
printf("not exist");
}
return 0;
}
This should give you a base:
#include <stdio.h>
#include <string.h>
int main()
{
char snumber[20];
int number = 11235;
printf("Number = %d\n\n", number);
sprintf(snumber, "%d", number);
int histogram[10] = { 0 };
int len = strlen(snumber);
for (int i = 0; i < len; i++)
{
histogram[snumber[i] - '0']++;
}
for (int i = 0; i < 10; i++)
{
if (histogram[i] != 0)
printf("%d occurs %d times\n", i, histogram[i]);
}
}
Output:
Number = 11235
1 occurs 2 times
2 occurs 1 times
3 occurs 1 times
5 occurs 1 times
That code is a mess. Let's bin it.
Theorem: Any number that divides all numbers in the range 2 to 9 is a
multiple of 2520.
Therefore your algorithm takes the form
for (long i = 2520; i <= 9876543210 /*Beyond this there must be a duplicate*/; i += 2520){
// ToDo - reject if `i` contains one or more of the same digit.
}
For the ToDo part, see How to write a code to detect duplicate digits of any given number in C++?. Granted, it's C++, but the accepted answer ports verbatim.
If i understand correctly, your problem is that you need to identify whether a number is consisted of multiple digits.
Following your proposed approach, to convert the number into a string and use an array to represent digits, i can suggest the following solution for a function that implements it. The main function is used to test the has_repeated_digits function. It just shows a way to do it.
You can alter it and use it in your code.
#include <stdio.h>
#define MAX_DIGITS_IN_NUM 20
//returns 1 when there are repeated digits, 0 otherwise
int has_repeated_digits(int num){
// in array, array[0] represents how many times the '0' is found
// array[1], how many times '1' is found etc...
int array[10] = {0,0,0,0,0,0,0,0,0,0};
char num_string[MAX_DIGITS_IN_NUM];
//converts the number to string and stores it in num_string
sprintf(num_string, "%d", num);
int i = 0;
while (num_string[i] != '\0'){
//if a digit is found more than one time, return 1.
if (++array[num_string[i] - '0'] >= 2){
return 1; //found repeated digit
}
i++;
}
return 0; //no repeated digits found
}
// test tha function
int main()
{
int x=0;
while (scanf("%d", &x) != EOF){
if (has_repeated_digits(x))
printf("repeated digits found!\n");
else
printf("no repeated digits\n");
}
return 0;
}
You can simplify your problem from these remarks:
the least common multiple of 2, 3, 4, 5, 6, 7, 8 and 9 is 2520.
numbers larger than 9876543210 must have at least twice the same digit in their base 10 representation.
checking for duplicate digits can be done by counting the remainders of successive divisions by 10.
A simple approach is therefore to enumerate multiples of 2520 up to 9876543210 and select the numbers that have no duplicate digits.
Type unsigned long long is guaranteed to be large enough to represent all values to enumerate, but neither int nor long are.
Here is the code:
#include <stdio.h>
int main(void) {
unsigned long long i, n;
for (n = 2520; n <= 9876543210; n += 2520) {
int digits[10] = { 0 };
for (i = n; i != 0; i /= 10) {
if (digits[i % 10]++)
break;
}
if (i == 0)
printf("%llu\n", n);
}
return 0;
}
This program produces 13818 numbers in 0.076 seconds. The first one is 7560 and the last one is 9876351240.
The number 0 technically does match your constraints: it is evenly divisible by all non zero integers and it has no duplicate digits. But you excluded it explicitly.

grey codes using 2d arrays (C)

My assignment is to print out grey codes using recursion. A user puts in a bit value between 0-8, therefore the maximum amount of strings you can have is 256 (2^8).
I've got the base case done but i don't know what I would do for the else portion.
My code so far:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
void gcodes (int n) {
char bits[256][8];
int i, j;
int x = pow (2, n);
if (n == 1) {
bits[0][0] = '0';
bits[1][0] = '1';
} else {
gcodes (n-1);
}
for (i=0; i<x; i++) {
for (j=0; j<n; j++) {
printf("%c", reverse[i][j]);
}
printf("\n");
}
}
int main(int argc, char *argv[]) {
if (argc != 2) {
printf("Invalid number of arguments\n");
return 0;
}
int n;
n = atoi (argv[1]);
if (n > 8 || n <= 0) {
printf("Invalid integer\n");
return 0;
}
gcodes (n);
}
a gray code can have only one bit change from one number to the next consecutive number. and over the whole sequence, there are no repeated values.
Given that criteria, there are several possible gray code implementations.
There are several deadend sequences where the values start off ok, then fail,
Calculating a gray code via code will take lots of experimentation.
In reality it is much easier to simply find a valid gray code sequence from the net, and paste that into any program that needs a gray code sequence.
Most often, a input is a gray coded wheel that is read to determine if the wheel moved rather than something generated in code.
however, if I were implementing a gray code generator, I would expect it to perform exclusive-or between the last generated value and the proposed new/next value and if that is valid (only one bit changed) I would search through the existing table of values to assure it is not a duplicate.
this SO question suggests a possible algorithm:
Non-recursive Grey code algorithm understanding
and the answer is repeated below:
The answer to all four your questions is that this algorithm does not start with lower values of n. All strings it generates have the same length, and the i-th (for i = 1, ..., 2n-1) string is generated from the (i-1)-th one.
Here is the first few steps for n = 4:
Start with G0 = 0000
To generate G1, flip 0-th bit in G0, as 0 is the position of the least significant 1 in the binary representation of 1 = 0001b. G1 = 0001.
To generate G2, flip 1-st bit in G1, as 1 is the position of the least significant 1 in the binary representation of 2 = 0010b. G2 = 0011.
To generate G3, flip 0-th bit in G2, as 0 is the position of the least significant 1 in the binary representation of 3 = 0011b. G3 = 0010.
To generate G4, flip 2-nd bit in G3, as 2 is the position of the least significant 1 in the binary representation of 4 = 0100b. G4 = 0110.
To generate G5, flip 0-th bit in G4, as 0 is the position of the least significant 1 in the binary representation of 5 = 0101b. G5 = 0111.
Since you define
char bits[256][8];
with automatic storage duration inside the function gcodes(), the array's lifetime ends when returning from the function, so you lose the results of the recursive calls. Thus, at least define it
static char bits[256][8];
or globally if you want to keep the resulting bits for use outside of gcodes().
Since in the standard Gray code the least significant bit (bit 0) follows the repetitive pattern of 0110, it is convenient to set the complete pattern in the base case even if it is not needed for n = 1.
For the ith code's bit j where j > 0, its value can be taken from bit j-1 of code i/2.
This leads to the completed function:
void gcodes(int n)
{
static char bits[256][8];
int i, j, x = pow(2, n);
if (n == 1)
{
bits[0][0] = '0';
bits[1][0] = '1';
bits[2][0] = '1';
bits[3][0] = '0';
}
else
{
gcodes(n-1);
// generate bit j (from n-1 down to 1) for codes up to x-1
for (i=0, j=n; --j; i=x/2)
for (; i<x; i++)
bits[i][j] = bits[i/2][j-1];
// replicate bit 0 for codes up to x-1
for (; i<x; i++)
bits[i][0] = bits[i%4][0];
}
for (i=0; i<x; i++, printf("\n"))
for (j=n; j--; )
printf("%c", bits[i][j]);
}

how do i make my c program randomly select

I want to make a C program which randomly selects 6 numbers from numbers the range 1 - 37, without repeating any previously permutations. For example, suppose the program randomly selects 1,2,3,4,5,6. If the next permutation is randomly selected as 2,1,3,4,5,6, then that is OK. However, if 1,2,3,4,5,6 is selected again, that this is not OK. I want this to continue until there are no more possible sets available. How would I go about writing this C program?
Use the Knuth Shuffle. Gives you O(n) asymptotic complexity.
#include <stdlib.h>
#include <string.h>
int rrand(int m)
{
return (int)((double)m * ( rand() / (RAND_MAX+1.0) ));
}
#define BYTE(X) ((unsigned char *)(X))
void shuffle(void *obj, size_t nmemb, size_t size)
{
void *temp = malloc(size);
size_t n = nmemb;
while ( n > 1 ) {
size_t k = rrand(n--);
memcpy(temp, BYTE(obj) + n*size, size);
memcpy(BYTE(obj) + n*size, BYTE(obj) + k*size, size);
memcpy(BYTE(obj) + k*size, temp, size);
}
free(temp);
}
Ref: http://rosettacode.org/wiki/Knuth_shuffle#C
Now the KNUTH shuffle answer posted below is quite elegant. But it doesn't meet a particular requirement set forth by the OP in his question.
The OP said he wanted to be able to select all sets in random order until his program has consumed them all. So here goes. For purposes of demonstrate, we'll understand "select" to mean "print".
The total number of possible sets of "6 unique digits in the range of 1-37" can be expressed as:
TOTAL_NUMBER_OF_SETS = 37*36*35*34*33*32 = 1673844480
1673844480 (1.6 billion) fits nicely within a signed 32-bit number. And every unique set could potentially be assigned a unique integer id.
So... if you can generate a random number between [0,1673844479], we can map that to a very specific set of 6 unique integers.
To construct the set, we'll need a helper function that will allow us to keep track of which values between 1-37 have already been used during the iteration process of constructing the set. Then a little modulo arithmetic math to help us map an ID number to it's set of 6-digits:
#include <stdio.h>
#include <stdlib.h
#include <stdint.h>
const uint32_t TOTAL_NUMBER_OF_SETS = 37*36*35*34*33*32; // = 1673844480
// returns the Nth value value from the ordered set {1,range},
// skipping over elements previous selected
int GetAvailableElementFromSet(int n, int range, int inuse[])
{
int i = 0, x;
for (x = 0; x < range; x++)
{
if (inuse[x] == 0)
{
if (i == n)
{
inuse[x] = 1;
return x + 1; // +1 since the loop variable has a zero-based index
}
i++;
}
}
return -1; // error
}
void GetSpecificSet(uint32_t setindex, int output[])
{
int index;
int inuse[37] = {}; // boolean array of elements already picked for the output set. zero-init to all false
int j,k;
if (setindex >= TOTAL_NUMBER_OF_SETS)
return; // error!
for (j = 0; j < 6; j++)
{
index = setindex % (37-j);
output[j] = GetAvailableElementFromSet(index, 37, inuse);
setindex = setindex / (37-j) ;
}
}
And just to prove that this works, we can have another function iterate over all sets:
void PrintSet(uint32_t setindex)
{
int output[6];
GetSpecificSet(setindex, output);
printf("%d, %d, %d, %d, %d, %d\n", output[0], output[1], output[2], output[3], output[4], output[5]);
}
void PrintAllSetsInOrder()
{
uint32_t index;
for (index = 0; index < TOTAL_NUMBER_OF_SETS; index++)
{
PrintSet(index);
}
}
Now the program above will print out all the sets starting from:
{1,2,3,4,5,6} // first set
{2,1,3,4,5,6} // second set
{3,1,2,4,5,6} // third set
And ending with
{36, 37, 35, 34, 33, 32} // next to last set
{37, 36, 35, 34, 33, 32} // last set
And then obviously to print a random set:
void PrintRandomSet()
{
PrintSet(rand() % TOTAL_NUMBER_OF_SETS);
}
But the OP wanted all sets printed in random order without repeats. This gets tricky, because we have to keep track of random number values previously generated. I can think of several ways to do this. The most obivous candidate solution is to keep a bitmask comprised of TOTAL_NUMBER_OF_SETS bits. That is:
#define IS_BIT_SET(bmask, bitindex) (bmask[bitindex/8] & (0x01<<(bitindex%8)))
#define SET_BIT(bmask, bitindex) {bmask[bitindex/8] |= (0x01<<(bitindex%8));}
uint8_t* bitmask = calloc(TOTAL_NUMBER_OF_SETS/8 + 1);
That's about 200MB of memory allocated. Large, but workable. Then we keep picking random numbers from the range [0-TOTAL_NUMBER_OF_SETS), checking the bitmask if it's already been used, then call PrintSet with the random number after setting its bitmask position. Repeat until all TOTAL_NUMBER_OF_SETS have been printed.
Pseudo code for a working, yet problematic solution
for (x = 0; x < TOTAL_NUMBER_OF_SETS; x++)
{
index = rand()%TOTAL_NUMBER_OF_SETS;
while (IS_BIT_SET(bitmask, index))
{
index = (index + 1) % TOTAL_NUMBER_OF_SETS;
}
SET_BIT(bitmask, index);
PrintSet(index);
}
Now this should work just fine. But it's going to get dog-slow as the bitmask array starts to get filled up. The later iterations will spend most of its time just scanning the array of bits looking for an unset index value. There have been other discussions on StackOverflow on how to do efficient and uniform permutations of large sets. Perhaps a database is warranted. Go search for those solutions and apply it here for the win.

Resources