Generating Random UNIQUE and converting to binary in C - c

I have implemented a basic program which generates 10 random and unique numbers from 1 to 10 as shown below. I have added an extra part in which I want the binary representation for each unique and random number. My program looks like this.
int value=1, loop, loop1, get=0, x, arr[10], array[20], count, i =0, y;
srand(time(NULL));
for (x = 0; x < 10; x++)
{
for (count = 0; count < 10; count++) {
array[count] = rand() % 10 + 1; //generate random number between 1 to 10 and put in array
}
while (i < 10) {
int r = rand() % 10 + 1; // declaring int r
for (x = 0; x < i; x++)
{
if (array[x] == r) { //if integer in array x is equal to the random number generated
break; //break
}
}
if (x == i) { //if x is equal to i then
array[i++] = r; //random number is placed in array[10]
}
}
for (y = 0; y < 10; y++) {
printf("unique random number is %d\n", array[y]);
array[y] = value;
for (loop = 0; loop < 1000; loop++)
{
if (value <= 1) { arr[loop] = 1; break; } //if value is 1 after dividing put 1 in array
if (value % 2 == 0) arr[loop] = 0;
else arr[loop] = 1;
value = value / 2;
}
for (loop1 = loop; loop1 > -1; loop1--)
printf("%d", arr[loop1]);
printf("\n");
}
}
My problem is that The binary value for each random unique number is being given as 1. In this program it is seen that I initialised value=1 and this can be the source for my error, however when I remove this I get an error stating that the local variable is uninitialised.
The first part of my program which generates the unique numbers is working fine, however the second part where I am converting to binary is not.
EDIT: I tested The second part of my program and it works well on it's own. The problem must be the way I am combining the two programs together.

Statement array[y] = value overrides the previously generated random values with constant 1.write
value = array[y];

Here is the commented code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//function to check unique random number
int check(int array[],int count,int val)
{
int i=0;
for( ;i<count ;++i )
{
if (array[i]==val)
return 1;
}
return 0;
}
int main(void)
{
int value,loop, loop1, get, x, arr[10];
int oldRandoms[10]; // array to preserve old random values
srand(time(NULL));
for (x = 0; x < 10; x++)
{
do // do while to get only unique random number
{
get = rand() % 10 + 1;
}while(check(oldRandoms,x,get));
oldRandoms[x]=get; // backup the number
printf("random number is %d \n", get);
value = get;
for (loop = 0; loop < 1000; loop++)
{
if (value <= 1) { arr[loop] = 1; break; } //if value is 1 after dividing put 1 in array
if (value % 2 == 0) arr[loop] = 0;
else arr[loop] = 1;
value = value / 2;
}
for (loop1 = loop; loop1 > -1; loop1--)
printf("%d", arr[loop1]);
printf("\n");
}
}

Related

C- Function that compares two four digit number arrays

I'm trying to create a function that compares two four digit numbers and
returns the number of similar digits between the two. For example, with a generated number of 4311 and the user entered 1488,
the score should return 2 (4 and 1).
If it was 4311 and the other is 1147,
the score should return three (1, 1 and 4). I don't know why it isn't giving me the right outputs, hope you can help.
int getSameDigitScore(int playerGuess, int generatedNum) {
int score = 0;
int i;
int j;
int k;
int generatedNumArray[4];
int playerGuessArray[4];
// turns playerGuess into an array
while (playerGuess > 0 ) {
i = 0;
playerGuessArray[i] = playerGuess % 10;
i++;
playerGuess /= 10;
}
// turns generatedNum into an array
while (generatedNum > 0) {
i = 0;
generatedNumArray[i] = generatedNum % 10;
i++;
generatedNum /= 10;
}
// compares the two arrays
for (k = 3; k >= 0; k--) {
for (j = 3; j >= 0; j--) {
if (generatedNumArray[k] == playerGuessArray[j]) {
score++;
playerGuessArray[j] = 0;
j = -5;
}
}
}
return score;
}
You are assigning i = 0 inside the while loop while generating the playerGuessArray and generatedNumArray. Due to which the playerGuess and generatedNumArray array will have elements as first digit of your number 0 0 0 .
Move the initialization out of the loop.
int getSameDigitScore(int playerGuess, int generatedNum) {
int score = 0;
int i, j, k, n;
int generatedNumArray[4];
int playerGuessArray[4];
// turns playerGuess into an array
i = 0; // This has been out of while loop
while (playerGuess > 0 ) {
playerGuessArray[i] = playerGuess % 10;
i++;
playerGuess /= 10;
}
// turns generatedNum into an array
int n = 0; // This has been out of the while loop
while (generatedNum > 0) {
generatedNumArray[n] = generatedNum % 10;
n++;
generatedNum /= 10;
}
// compares the two arrays
for (k = 3; k >= 0; k--) {
for (j = 3; j >= 0; j--) {
if (generatedNumArray[k] == playerGuessArray[j]) {
score++;
playerGuessArray[j] = 0;
j = -5;
}
}
}
return score;
}
int main() {
int m;
n = getSameDigitScore(1231, 2342);
printf("Score is: %d\n", m);
}
You're re-initializing increment variable i on every iteration which should be moved out of the while loop. With that moved out the above code works fine.
There are the following issues with the code.
You are initializing the integer i inside the while loop. This needs to be done before the loop for each loop.
You need a separate array to get the output of equal digits. See AnswerArray in code below. Also it is a good design practice to pass this array to the function and clear this array inside the function.
In the last for loop, you should break from the inner loop after getting a match. This is to take care of cases where playerGuess == 1222 and generatedNum = 1111 In the code shown this will result in a score of 1.
See the final code below with some test cases.
int getSameDigitScore(int playerGuess, int generatedNum, int *AnswerArray) {
int score = 0;
int i;
int j;
int k;
int generatedNumArray[4] = {0};
int playerGuessArray[4] = {0};
memset(AnswerArray,0,4*sizeof(int));
// turns playerGuess into an array
i = 0;
while (playerGuess > 0 ) {
playerGuessArray[i] = playerGuess % 10;
i++;
playerGuess /= 10;
}
// turns generatedNum into an array
i = 0;
while (generatedNum > 0) {
generatedNumArray[i] = generatedNum % 10;
i++;
generatedNum /= 10;
}
// compares the two arrays
score=0;
for (k = 3; k >= 0; k--) {
for (j = 3; j >= 0; j--) {
if (generatedNumArray[k] == playerGuessArray[j]) {
AnswerArray[score++] = generatedNumArray[k];
playerGuessArray[j] = -1;
break;
}
}
}
return score;
}
int main(void)
{
int AnswerArray[4],score;
score = getSameDigitScore(4311,1488,AnswerArray);
printf ("\nScore = %d \n Answer Array = ",score);
for (int i=0; i<score; i++)
{
printf ("%d ",AnswerArray[i]);
}
score = getSameDigitScore(4311,1147,AnswerArray);
printf ("\nScore = %d \n Answer Array = ",score);
for (int i=0; i<score; i++)
{
printf ("%d ",AnswerArray[i]);
}
score = getSameDigitScore(1222,1111,AnswerArray);
printf ("\nScore = %d \n Answer Array = ",score);
for (int i=0; i<score; i++)
{
printf ("%d ",AnswerArray[i]);
}
score = getSameDigitScore(1111,1222,AnswerArray);
printf ("\nScore = %d \n Answer Array = ",score);
for (int i=0; i<score; i++)
{
printf ("%d ",AnswerArray[i]);
}
}
The initializing i=0 which you made inside the loop should be outside the loop.
while (playerGuess > 0 ) {
i = 0;
playerGuessArray[i] = playerGuess % 10;
i++;
playerGuess /= 10;
}
If the initialization is inside the looop then,
Everytime playerGuessArray[0] value will be updated.
FYI:
If playerGuess can contain 0 aat the begin of four digit like 0123
For example, playerGuessValue is 0123, Then by using
while (playerGuess > 0 ) {
i = 0;
playerGuessArray[i] = playerGuess % 10;
i++;
playerGuess /= 10;
}
playerGuessArray will contain only [1,2,3] instead of [0,1,2,3].
So, the better solution would be taking two temporary variables and checking last digit one by one.
Like this:
int temp1=playerGuess, temp2=GeneratedNum;
int i=0;
bool flag = true;
while(flag && i < 4){
if(temp1%10 != temp2%10){
flag = false;
}
temp1 /= 10;
temp2 /= 10;
i++;
}
if(flag){
score++;
}
FYI:
Debugging will help you in finding out these little mistakes.So, try to debug your code with multiple inputs and verify your answer.
Here are few reference on how to debug:
https://blog.hartleybrody.com/debugging-code-beginner/
https://www.codementor.io/mattgoldspink/how-to-debug-code-efficiently-and-effectively-du107u9jh%60
Thanks.

Need to find Max, Min, Avg number in Array - no size declared

So I have this array, I need to find the Min, Max, and Average. I have figured out how to get the Max, my code looks right for the minimum but it does not work so I must be missing something. I also need to find the average of the numbers entered. Everything I can find on this only works when you have the size of the array set. I have a max size set for the array but it does not get filled by user input. I have been staring and testing on this for days and still cant figure it out.
I know for the average I need something like (with added declartions at the top), but I cannot figure out how to get it to work:
for (i = 0; i < numOfGrades; i++) {
sum += grades[i];
}
avg = (double) sum / numOfGrades;
Here is the rest of my code:
#include <stdio.h>
int main(){
int grades [100];
int i = 0;
int small, big, input;
printf("Enter a series of grades. When done, enter any number above 100.\n\n");
while (i <= 100) { //while loop to set maximum for array
printf("Enter grade:");
if (scanf("%d", &input) == 1) {
if (input >= 0 && input <=100) {
grades[i] = input; //if good, add to array
i++;
}
else {
printf("\n\nExiting entry.\n");
printf("\n\nGrades entered:\n\n");
i = i - 1;
break; //exiting loop
}
}
}
int x, y;
for (x = 0; x <= i; x++) {
printf("Grade: %d\n", grades[x]); //print array
}
big = small = grades[0];
for (y = 0; y < i; y++) {
if (grades[y] > big) {
big = grades[y];
}
else if (grades[y] < small) {
small = grades[y];
}
}
printf("Highest number : %d\n", big);
printf("Smallest number: %d\n", small);
return 0;
}
Here you do the right thing:
for (x = 0; x <= i; x++) {
Because x <= i will take you from 0 to the value of i. Then in your min/max loop you do this:
for (y = 0; y < i; y++) {
So you are going from 0 to to i-1. You have 2 options:
Make the above loop correct with y <= i.
Dont decrement i in the while loop (Dont do this i = i - 1;) That way, i represents the number of numbers entered, instead of number of numbers entered -1 (you will need to fix the x <= i to x < i).
Here is a live example. http://ideone.com/ZEaDue
To calculate the average, you are doing the right thing, you can re-use i though:
int sum = 0, avg = 0;
for (y = 0; y < i; y++) {
sum += grades[y];
}
avg = (double) sum / i;
printf("Avg: %d\n", avg);
Actually you do have the number of grades
if (scanf("%d", &input) == 1) {
if (input >= 0 && input <=100) {
grades[i] = input; //if good, add to array
i++;
}
else {
numOfGrades=i;
printf("\n\nExiting entry.\n");
printf("\n\nGrades entered:\n\n");
i = i - 1;
break; //exiting loop
}
As for the minimum, your logic should be like this:
for (y = 0; y < numOfEdges; y++) {
if (grades[y] > big) {
big = grades[y];
}
if (grades[y] < small) {
small = grades[y];
}
}
The else statement I removed should do the trick. Also I would always use
for(int var = 0; var < numOfEdges; var++) in any of the loop constructs. It's easyer to follow the logic this way: You have counted the number of edges (numOfEdges), but your loop goes only to numOfEdges-1 since you start with index 0.

Return which digit occurs the most times

I have to return which digit in a number occurs the most frequently ( though not how many times it occurs )
So far I can only get this, I don't know how to isolate the digit, only to show how many times each digit occurs.
#include <stdio.h>
int frequentDigit(int);
int main()
{
frequentDigit(123032333);
return 0;
}
int frequentDigit(int arg)
{
int tmp; int i; int myArr[9] = { 0 };
tmp = (arg < 0) ? -arg : arg;
do
{
myArr[tmp % 10]++;
tmp /= 10;
} while (tmp != 0);
for (i = 0; i < 9; i++) { printf("\nThere are %d occurances of digit %d", myArr[i], i); }
}
The array where you are storing the frequency of the digits, i.e myArr[]. Its suppose to hold the frequency of all the number from 0...9. And since there are 10 numbers, you would need an array of lenght 10.
int myArr[10];
Later, you need to traverse through the array once, checking for the max element, and saving the index accordingly, to find which number has occured most number of times.
To traverse, the for loop should go till 9
for (i = 0; i <= 9; i++)
Edited
As someone commented, you can find the max value while you are computing the frequencies itself.
int max = -1, max_num = -1;
do
{
myArr[tmp % 10]++;
if( myArr[tmp % 10] > max)
{
max = myArr[tmp % 10];
max_num = tmp % 10;
}
tmp /= 10;
} while (tmp != 0);
printf("%d", max_num);
Its simple. At the end of your code you have an array of frequencies, if you find the max of that you get the most common element
Just use a loop to find the max and print that:
int max = myArr[0]; // start with max = first element
int max_position=0;
for(int i = 1; i<9; i++)
{
if(myArr[i] > max){
max = myArr[i];
max_position=i;
}
}
printf("\The max is %d occuring %d times ", max_position, max_position)

How to divide digits and compare them, in C

Write a program that will find the largest number smaller than N that is totally different from a given number X. One number is totally different from other only if it doesn't contain any of the digits from the other number. N and X are read from standard input. The problem should be solved without the use of arrays.
Example Input 1: 400 897
Example Output 1: 366
Example Input 2: 1000 1236498
Example Output 2:777
No it's not homework, it was on one of the midterms and it's been killing me. I though about taking the first numbers last digit with %10 then taking the second numbers digit with %10 comparing them but...I just can't get it to work...I ended up with an endless loop...I just don't understand how to get every digit of the numbers and compare them to the other number.
#include <stdio.h>
int main () {
int N, X, num_N, num_X, i, lastDigit_N, lastDigit_X, flag, smaller_than_N;
scanf("%d%d", &N, &X);
smaller_than_N = N - 1;
for (i = smaller_than_N; i > 0; i--) {
num_N = i;
num_X = X;
flag = 0;
while (num_N > 0) {
lastDigit_N = num_N % 10;
while (num_X > 0) {
lastDigit_X = num_X % 10;
if (lastDigit_N == lastDigit_X) {
break;
}
else {
flag = 1;
}
num_X /= 10;
}
num_N /= 10;
}
if(flag) {
printf("%d", i);
break;
}
}
return 0;
}
You could build a bitmask for your numbers showing the digits which are contained.
uint16_t num2bitmask(int number)
{
uint16_t result = 0;
while (number) {
int digit = number % 10;
number /= 10;
result |= (1 << digit);
}
return result;
}
With this function, you can create your bitmask for X and then iterate from N-1 down to 1 until you find a value which doesn't have any bits in common with the other value.
If you have a number with digits d_1, d_2, ..., d_n, and you're allowed to use digits in the set D, then possible solutions look like:
d_1, ..., d_{i-1}, max(d in D | d < d_i), max(d in D), ..., max(d in D).
That is, the digits are the same up to some point, then the next digit is as large as possible while being below the input digit, then the rest are just as large as possible.
Not all these "solutions" will be valid, but if you iterate through them in reverse order (there's exactly n for an input number of size n), the first valid one you find is the answer.
Some code, including tests:
#include <stdio.h>
int digit_length(int a) {
int r = 0;
while (a) {
a /= 10;
r += 1;
}
return r;
}
int get_digit(int a, int k) {
while (k--) a /= 10;
return a % 10;
}
int largest_different(int a, int b) {
int lena = digit_length(a);
int invalid = b ? 0 : 1;
for (; b; b /= 10) invalid |= 1 << (b % 10);
int max_valid = 9;
while (max_valid >= 0 && (invalid & (1 << max_valid)))
max_valid--;
if (max_valid == -1) return -1;
for (int i = 0; i < lena; i++) {
int d = get_digit(a, i) - 1;
while (d >= 0 && (invalid & (1 << d)))d--;
if (d < 0) continue;
int solution = 0;
for (int k = lena - 1; k >= 0; k--) {
solution *= 10;
solution += (k < i ? max_valid : k > i ? get_digit(a, k) : d);
}
return solution;
}
return -1;
}
int main(int argc, char *argv[]) {
struct {int n; int x; int want;} examples[] = {
{400, 897, 366},
{1000, 1236498, 777},
{998, 123, 997},
};
int error = 0;
for (int i = 0; i < sizeof(examples) / sizeof(*examples); i++) {
int got = largest_different(examples[i].n, examples[i].x);
if (got != examples[i].want) {
error = 1;
printf("largest_different(%d, %d) = %d, want %d\n",
examples[i].n, examples[i].x, got, examples[i].want);
}
}
return error;
}
There's not always a solution. In that case, the function returns -1.

Project Euler Problem 4

I've created a solution to problem 4 on Project Euler.
However, what I find is that placing the print statement (that prints the answer) in different locations prints different answers. And for some reason, the highest value of result is 580085. Shouldn't it be 906609? Is there something wrong with my isPalindrome() method?
#include <stdio.h>
#include <stdbool.h>
int isPalindrome(int n);
//Find the largest palindrome made from the product of two 3-digit numbers.
int main(void)
{
int i = 0;
int j = 0;
int result = 0;
int palindrome = 0;
int max = 0;
//Each iteration of i will be multiplied from j:10-99
for(i = 100; i <= 999; i++)
{
for(j = 100; j <= 999; j++)
{
result = i * j;
if(isPalindrome(result) == 0)
{
//printf("Largest Palindrome: %d\n", max); //906609
//printf("Result: %d\n", result); //580085
if(result > max)
{
max = result;
//printf("Largest Palindrome: %d\n", max); //927340
}
printf("Largest Palindrome: %d\n", max); //906609
}
}
}
//printf("Largest Palindrome: %d\n", max); //998001
system("PAUSE");
return 0;
} //End of main
//Determines if number is a palindrome
int isPalindrome(int num)
{
int n = num;
int i = 0;
int j = 0;
int k = 0;
int count = 0;
int yes = 0;
//Determines the size of numArray
while(n/10 != 0)
{
n%10;
count++;
n = n/10;
}
int numArray[count];
//Fill numArray with each digit of num
for(i = 0; i <= count; i++)
{
numArray[i] = num%10;
//printf("%d\n", numArray[i]);
num = num/10;
}
//Determines if num is a Palindrome
while(numArray[k] == numArray[count])
{
k = k + 1;
count = count - 1;
yes++;
}
if(yes >= 3)
{
return 0;
}
}//End of Function
I remember doing that problem a while ago and I simply made a is_palindrome() function and brute-forced it. I started testing from 999*999 downwards.
My approach to detect a palindrome was rather different from yours. I would convert the given number to a string and compare the first char with the nth char, second with n-1 and so on.
It was quite simple (and might be inefficient too) but the answer would come up "instantly".
There is no problem in the code in finding the number.
According to your code fragment:
.
.
}
printf("Largest Palindrome: %d\n", max); //906609
}
}
}
//printf("Largest Palindrome: %d\n", max); //998001
system("PAUSE");
.
.
.
you get the result as soon as a palindrome number is found multiplying the number downwards.
You should store the palindrome in a variable max and let the code run further as there is a possibility of finding a greater palindrome further.
Note that for i=800,j=500, then i*j will be greater when compare with i=999,j=100.
Just understand the logic here.
A few issues in the isPalindrome function :
the first while loop doesn't count the number of digits in the number, but counts one less.
as a result, the numArray array is too small (assuming that your compiler supports creating the array like that to begin with)
the for loop is writing a value past the end of the array, at best overwriting some other (possibly important) memory location.
the second while loop has no properly defined end condition - it can happily compare values past the bounds of the array.
due to that, the value in yes is potentially incorrect, and so the result of the function is too.
you return nothing if the function does not detect a palindrome.
//Determines if number is a palindrome
bool isPalindrome(int num) // Change this to bool
{
int n = num;
int i = 0;
int j = 0;
int k = 0;
int count = 1; // Start counting at 1, to account for 1 digit numbers
int yes = 0;
//Determines the size of numArray
while(n/10 != 0)
{
// n%10; <-- What was that all about!
count++;
n = n/10;
}
int numArray[count];
//Fill numArray with each digit of num
for(i = 0; i < count; i++) // This will crash if you use index=count; Array indices go from 0 to Size-1
{
numArray[i] = num%10;
//printf("%d\n", numArray[i]);
num = num/10;
}
//Determines if num is a Palindrome
/*
while(numArray[k] == numArray[count-1]) // Again count-1 not count; This is really bad though what if you have 111111 or some number longer than 6. It might also go out of bounds
{
k = k + 1;
count = count - 1;
yes++;
}
*/
for(k = 1; k <= count; k++)
{
if(numArray[k-1] != numArray[count-k])
return false;
}
return true;
}//End of Function
That's all I could find.
You also need to change this
if(isPalindrome(result) == 0)
To
if(isPalindrome(result))
The Code's Output after making the modifications: Link
The correct printf is the one after the for,after you iterate through all possible values
You are using int to store the value of the palidrome but your result is bigger then 65536,
you should use unsigned
result = i * j;
this pice of code is wrong :
while(n/10 != 0) {
n%10;
count++;
n = n/10;
}
it should be:
while(n != 0) {
count++;
n = n/10;
}
As well as the changes that P.R sugested.
You could do something like this to find out if the number is palindrome:
int isPalindrom(unsigned nr) {
int i, len;
char str[10];
//convert number to string
sprintf(str, "%d", nr);
len = strlen(str);
//compare first half of the digits with the second half
// stop if you find two digits which are not equal
for(i = 0; i < len / 2 && str[i] == str[len - i - 1]; i++);
return i == len / 2;
}
I converted the number to String so I'd be able to go over the number as a char array:
private static boolean isPalindrom(long num) {
String numAsStr = String.valueOf(num);
char[] charArray = numAsStr.toCharArray();
int length = charArray.length;
for (int i = 0 ; i < length/2 ; ++i) {
if (charArray[i] != charArray[length - 1 - i]) return false;
}
return true;
}
I got correct answer for the problem, but I want to know is my coding style is good or bad from my solution. I need to know how can I improve my coding,if it is bad and more generic way.
#include<stdio.h>
#define MAX 999
#define START 100
int main()
{
int i,j,current,n,prev = 0;
for(i = START;i<=MAX;i++)
{
for(j=START;j<=MAX;j++)
{
current = j * i;
if(current > prev) /*check the current value so that if it is less need not go further*/
{
n = palindrome(current);
if (n == 1)
{
printf("The palindrome number is : %d\n",current);
prev = current; // previous value is updated if this the best possible value.
}
}
}
}
}
int palindrome(int num)
{
int a[6],temp;
temp = num;
/*We need a array to store each element*/
a[5] = temp % 10;
a[4] = (temp/10) %10;
a[3] = (temp/100) %10;
a[2] = (temp/1000) %10;
a[1] = (temp/10000) %10;
if(temp/100000 == 0)
{
a[0] = 0;
if(a[1] == a[5] && a[2] == a[4])
return 1;
}
else
{
a[0] = (temp/100000) %10;
if(a[0] == a[5] && a[1] == a[4] && a[2] == a[3])
return 1;
else
return 0;
}
}
No, the largest should be: 906609.
Here is my program:
def reverse_function(x):
return x[::-1]
def palindrome():
largest_num = max(i * x
for i in range(100, 1000)
for x in range(100, 1000)
if str(i * x) == reverse_function(str(i * x)))
return str(largest_num)
print(palindrome())

Resources