C programming - A array and a random number combined question? - c

this is the part of my code I'm having trouble with. I can't understand why its doing it wrong. I have an array where it stores numbers 0 - 25 which are cases. The numbers are to be randomized and overwritten into the array. Only condition is is that no number can be doulbes, there can only be one of that number. I'm not asking you to do my code but do hint me or point me in the write directions. I am trying to learn :)
The problem lies within the second do loop. I can get the numbers to be randomized, but I get doubles. I have created a loop to check and fix this, but it's not working. The code does run, and doubles do still happen and I can't see why. It looks correct to me. Please look, thank you (:
This is what I have done originally (at the very end is where I am at now):
int check_double = 0;
int i = 0;
int counter = 0;
int array_adder = 0;
int random_number = 0;
int cases[] = {
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26
};
float money[] = {
0.01,1,5,10,25,50,75,100,200,300,400,500,750,1000,5000,10000,25000,50000,750000,100000,200000,300000,400000,500000,750000,1000000
};
//Randomize all case number and realine them in the array
srand ( time(NULL) );
do
{
cases[counter]= rand() % 26;
counter += 1;
printf("%d\n", cases[counter]);
}
while (counter <= 25);
//make sure there are no doubles in the array, just 0 - 25 and not a single number repeated twice
do
{
check_double = 0;
for (i = 0; i < counter; i++)
{
if (cases[counter] == cases[i])
{
cases[counter] = rand()% 26;
check_double == 1;
}
}
}
while (check_double != 0);
Currently, what I had achived after that was combing both loops and check for doubles as the array goes. This is what I made, it still has doubles and im not sure why, I only posted the cose with both loops combined:
do
{
cases[counter]= rand() % 26;
if (cases[counter]>=1);
for(i=0;i<=counter;i++)
if (cases[counter]==cases[i])
{
cases[counter]=rand()% 26;
}
printf("%d\n",cases[counter]);
counter+=1;
}

Robsta, you could try the following piece of code, I have run this in Dev-C++, any changes that you require can be made from your side. But, I assure you that this code generates what you intend.
int check_double = 0;
int i = 0;
int counter = 0;
int cases[] = {
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26
};
//Randomize all case number and realine them in the array
srand ( time(NULL) );
do
{
cases[counter]= rand() % 26;
for(i=0;i<counter;i++)
if (cases[counter]==cases[i]){
while (cases[counter]==cases[i])
{
cases[counter]=rand()% 26;
}
i=0;
}
printf("%d\t%d\n",counter,cases[counter]);
counter+=1;
}while (counter <= 25);
If you have any clarifications required, I would love to discuss with you.
-Sandip

You're only ever writing over the last value in the array:
for(i=0;i<counter;i++)
if (cases[counter]==cases[i])
You need to loop through as you are, then have an inner loop, where you compare all the other entries to the current one.
Even easier would be to do the loop where you set each random number, so when you set cases[3] for example, loop from 0 to 2 and check to see if your new value for 3 clashes, if so, wash - rinse - repeat!

You have this line of code:
check_double==1;
That doesn't change check_double because it's ==, not =. == compares; it doesn't assign. Change that line to this:
check_double=1;
A helpful compiler (clang in this example) will give you a warning about this:
test.c:5:14: warning: expression result unused [-Wunused-value]
check_double==1;
~~~~~~~~~~~~^ ~

You can't check for duplicates with a single loop. You need to at least compare every possible pair of elements to be able to see if there's a duplicate. I'm guessing you forgot to loop over counter somewhere inside the second do...while?
Note that your method is not guaranteed to terminate. (Very, very likely but not certain.) Why don't you simply shuffle the cases array? Shuffling is simple but tricky; see Fisher-Yates (or Knuth) Shuffle for a simple algorithm.

If you are asking how to randomly sequence the number 1-25 then you could do something like this. This is a very brute-force way of generating the sequence, but it does work and might give you a starting point for something more optimized.
#include "stdafx.h"
#include <stdlib.h>
#include <time.h>
#include <conio.h>
const int LastNumber = 25;
bool HasEmpty(int available[LastNumber][2])
{
bool result = false;
for(int i = 0; i < LastNumber; i++)
{
if (available[i][1] == 0)
{
result = true;
break;
}
}
return result;
}
int _tmain(int argc, _TCHAR* argv[])
{
int available[LastNumber][2];
int newSequence[LastNumber];
srand((unsigned int)time(NULL));
for(int i = 0; i < LastNumber; i++)
{
available[i][0]=i;
available[i][1]=0;
}
int usedIndex = 0;
while (HasEmpty(available))
{
int temp = rand() % (LastNumber + 1);
if (available[temp][1] == 0)
{
newSequence[usedIndex++] = available[temp][0];
available[temp][1] = 1;
}
}
for(int i = 0; i < LastNumber; i++)
{
printf("%d\n",newSequence[i]);
}
getch();
return 0;
}

Related

Why isn't this program showing any number above 3?

Wrote this to find the prime numbers between 2 to 1000. But it stops after showing that 2 and 3 are prime numbers. I know I can find how to write a code for finding out prime numbers on the internet. But I really need to know what's going wrong here.
#include <stdio.h>
main() {
int i, j;
int ifPrime = 1;
for (i = 2; i < 1000; i++) {
for (j = 2; j < i; j++) {
if (i % j == 0) {
ifPrime = 0;
break;
}
}
if (ifPrime == 1) {
printf("%d is prime\n", i);
}
}
}
The line
int ifPrime=1;
must be inside the outer for loop. There it will be initialized for every i. This corresponds to the natural language words "to check whether a number i is prime, first assume it is. Then check if it is divisible". The code you had before said "to check whether the numbers 2 to 1000 are prime, first assume they are", and this wording was too broad.
The code should be:
int main()
{
for (int i = 2; i < 1000; i++)
{
int ifPrime = 1;
for (int j = 2; j < i; j++)
I replaced main with int main since that is required since 20 years. (You should not learn programming from such old books.)
I moved the int i and the int j into the for loops so that you cannot accidentally use these variables outside the scope where they have defined values.
To avoid this bug in the future, it's a good idea to extract the is_prime calculation into a separate function. Then you would have been forced to initialize the ifPrime in the correct place.
Another way of finding the cause of this bug is to step through the code using a debugger and ask yourself at every step: does it still make sense what the program is doing?
You are not setting ifPrime back to 1 after checking for the single number. So once you get a number that is non_prime, ifPrime is now 0 and hence if(ifPrime == 1) would never return true post that and hence you only see 2, 3 as prime
#include <stdio.h>
int main(void) {
for( int i=2;i<1000;i++)
{
int ifPrime = 1;
for(int j=2;j<i;j++)
{
if(i%j==0)
{
ifPrime=0;
break;
}
}
if(ifPrime==1)
{
printf("%d is prime\n",i);
}
}
return 0;
}

Trying to turn the factorial part into another function

I have to begin my thanking you guys for the help. I am trying to turn the factorial part of the code into another function and was wondering if I needed to add everything within the
#include <stdio.h>
#include <stdlib.h>
int main()
{
int num;
int indx;
int arrayIndx;
int accumulator;
int fact;
int individualDigit[50];
int length;
for(indx = 99999; indx > 0; indx--)
{
num = indx;
for (length = 0; num > 0; length++)
{
individualDigit[length] = num % 10;
num /= 10;
}
accumulator = 0;
for (arrayIndx = 0; arrayIndx < length; arrayIndx++)
{
fact = 1;
while(individualDigit[arrayIndx] > 0)
{
fact*= individualDigit[arrayIndx];
individualDigit[arrayIndx]--;
}
accumulator += fact;
}
if(accumulator == indx)
{
printf("%d ", accumulator);
}
}
return 0;
}
You program is badly designed. It is not indented, you are using variable names index, indx and idex which is confusing for the reader and would lead to nightmares for long term maintenance. Also the factorial computation would deserve to be in a function for better modularity.
But apart from that, your program does what you ask, correctly computes factorials and adds them in the accumulator variable. The only problem is that you never print that accumulator except for the last 2 cases (2 and 1) where n = n!.
Simply replace :
if (accumulator == indx)
{
printf("\n%d\n", indx);
}
with
printf("\n%d\n", accumulator);
and you will see your results.
If you want to store the sum of factorials in an array, you just have to declare int sumOfFact[26] = {0}; just before int individualDigit[50]; to define the array and initialize sumOfFact[0] to 1, and then add sumOfFact[indx] = accumulator; just before printing the accumulator.
To put the factorial part in a function, it is quite simple. First declare it above your main:
int ffact(int n);
the define it anywhere in your code (eventually in another compilation unit - a .c file - if you want)
inf ffact(int n) {
fact = 1;
while (n > 1) {
fact *= n--;
/* if (fact < 0) { fprintf(stderr, "Overflow in ffact(%d)\n", n); return 0; } */
}
return fact
}
I commented out the test for overflow, because I assume you use at least 32 bits int and fact(9) will not overflow (but fact(13) would ...)
The loop computing the sum of factorials becomes:
accumulator = 0;
for (arrayIndx = 0; arrayIndx < length; arrayIndx++)
{
accumulator += ffact(individualDigit[arrayIndx]);
}
printf("\n%d\n", accumulator);
Advantages for that modularity: it is simpler to separately test the code for ffact. So when things go wrong, you have not to crawl among one simple piece of code of more than 40 lines (not counting the absent but necessaries comments). And the code no longers clutters the individualDigit array.

Segmentation Fault 11 with recursive function in C

I keep receiving a Segmentation Fault 11 for the following code. I believe it has something to do with recursion but I'm not entirely sure how. The method should take in an array, skip the odd values, and keep repeating until it has an array with only value left and returns that value.
Thanks!
#include <stdio.h>
int callTable(int table[], int size)
{
int i = 0;
int j = 0;
int cHeight = size / 2;
int cTable[cHeight];
while (i < size)
{
if (table[i] % 2 == 0)
{
cTable[j] = table[i];
j++;
}
i++;
}
if (size > 1)
return callTable(cTable, cHeight);
else
return cTable[0];
}
int main()
{
int tPass[100];
int i, answer;
for (i = 0; i < 100; i++)
tPass[i] = i + 1;
answer = callTable(tPass, sizeof(tPass) / sizeof(tPass[0]));
printf("%d\n", answer);
}
Do you want to skip the odd values or the odd indexes? You are currently skipping the odd values, so after you call callTable once, there are only even values left. Then, on the second call, you try to use an array of half the size to store the even values (which are all of them), so you try to store the entire array on another with half the size.
If you intended to skip the odd indexes, then change this line:
if (table[i]%2==0)
for this one:
if (i%2==0)
That runs fine and returns 1 (which is the number with index 0).

Can't subtract in a for loop in C/Objective-C

I'm going through the Big Nerd Ranch book on Objective-C, which takes you through some early C stuff. I've played with C before, and am pretty experienced in PHP.
Anyhow, I'm doing the challenges and this one is not working the way I think it should. It's pretty simple - start at 99, loop through and subtract three until you get to zero, and every time you get a number that is divisible by 5 print "Found one." Pretty straightforward. However, subtracting by three in the for loop is not working
#include <stdio.h>
int main (int argc, const char * argv[])
{
int i;
for(i = 99; i > 0; i-3){
printf("%d\n", i);
if(i % 5 == 0) {
printf("Found one!\n");
}
}
return 0;
}
It creates and endless loop at 99, and I'm not sure why.
i-3 doesn't modify the variable i. Do something like -
for( i=99; i>0; )
{
// ....
i -= 3;
}
It should be i-=3 instead of i-3.
#include <stdio.h>
int main (int argc, const char * argv[])
{
int i;
for(i = 99; i > 0; i-=3){
printf("%d\n", i);
if(i % 5 == 0) {
printf("Found one!\n");
}
}
return 0;
}
i-3 does not change the value of i.
i-=3 does.
Your loop statement doesn't modify the value of i. Just doing i - 3 doesn't change i, it just returns the value of i - 3.
Use: for(i = 99; i > 0; i = i - 3)
In the for loop, it should be i=i-3.
You are just subtracting 3 from i, but you are not assigning it to i.
Use i = i - 3 instead of just i - 3.
Change your for statement like this:
for(i = 99; i > 0; i = i - 3) {
// Write your code here.
}
The Last Term in the For loop is the increment of decrement operation. While i-3 is none. If you want the Value of i to get reduced by 3, then you should store that value in i itself.
To do that Following code should be written: i = i-3 or shorthand i-=3.

Finding the largest palindrome of the product of two three digit numbers problem

So on Project Euler the Problem 4 states the following:
A palindromic number reads the same
both ways. The largest palindrome made
from the product of two 2-digit
numbers is 9009 = 91 99.
Find the largest palindrome made from
the product of two 3-digit numbers.
I have tried the following:
#include <stdio.h>
#include <stdlib.h>
int check(int result)
{
char b[7];
sprintf(b, "%d", result);
if (b[0] == b[5] && b[1] == b[4] && b[2] == b[3])
{
return 1;
}
else
{
return 0;
}
}
int main () {
int i;
int g;
int final;
for (i = 999; i > 99; i--)
{
for (g = 999; g > 99; g--)
{
if (check(g*i) == 1)
{
final = g*i;
goto here;
}
}
}
here:
printf("%d", final);
}
But, this does not work. Instead of the right answer, I get 580085, which I guess is a palindrome at least, but still not the right answer.
Let me explain my program starting from int main:
int i and int g are my multipliers. They are those two three digit numbers.
int final is the number that will store the largest palindrome.
I start two for loops going to down to get every number possibility.
I get out of the loop using a goto when the first palindrome is reached(probably should not but, it doesn't effect a small program like this too much).
The first palindrome should be the biggest one possible since I am counting down from the top.
Let me now explain my check:
First off since these are two three digit numbers multiplying together to determine the size a char would need to be to hold that value I went to a calculator and multiplied 999 * 999 and it ended up being 6 then I need to add one because I found out from one the questions I posted earlier that sprintf puts a \0 character at the end.
Ok, now that I have a char and all, I copied result (which i*g in int main) and put it in char b[7].
Then I just checked b to see if it equalled it self with by hard coding each slot I needed to check for.
Then I returned accordingly, 1 for true, and 2 for false.
This seems perfectly logical to me but, it does not work for some weird reason. Any hints?
This assumption is wrong:
The first palindrome should be the biggest one possible since I am counting down from the top.
You will check 999*100 = 99900 before 998*101 = 100798, so clearly you canĀ“t count on that.
The problem is that the first palindrome that you find is not the bigger one for sure.
Just an example:
i = 900, g = 850 -> 765000
i = 880, g = 960 -> 844800
The first one is smaller, but since you iterate first on i, then on g it will be discovered first.
Ok, they are not palindrome but the concept is the same..
I think you are tackling this problem back to front. It would be more efficient to generate the palindromes from highest to lowest then check by factorizing them. First one that has two three digit factors is the answer.
e.g.
bool found = false;
for (int i = 998; i >= 100; i--)
{
char j[7];
sprintf(j,"%d",i);
j[3]= j[2];
j[4]= j[1];
j[5]= j[0];
int x =atoi(j);
int limit = sqrt((float) x);
for (int z = 999; z >= limit; z--)
{
if (x%z==0){
printf("%d",x);
found = true;
break;
}
}
if (found) break;
}
The first palindrome should be the biggest one possible since I am counting down from the top
The problem is that you might have found a palindrome for a large i and a small g. It's possible that there's a larger palindrome that's the product of j and k where:
i > j and
g < k
(I hope this makes sense).
Java Implementation:
public class Palindrome {
public static void main(String[] args)
{ int i, j;
int m = 1;
int k =11;
boolean flag = false;
while (true)
{;
if (flag) j = m + 1;
else j = m;
for (i = k; i > 0; i--)
{
j++;
int number, temp, remainder, sum = 0;
number = temp = (1000 - i) * (1000 - j);
while (number > 0)
{
remainder = number % 10;
number /= 10;
sum = sum * 10 + remainder;
}
if (sum == temp)
{
System.out.println("Max value:"+temp);
return;
}
}
if (flag)
m++;
k=k+11;
flag = !flag;
}
}
}
A word on performance. You have the possibility of duplicating many of the products because you are using a pretty simple nested loop approach. For instance, you start with 999*999 and then 999*998, etc. When the inner loop finishes, you will decrement the outer loop and start again with 998*999, which is the same as 999*998.
Really, what you want to do is start the inner loop with the same value as the current outer loop value. This will eliminate your duplicate operations. Something like this...
for (i = 999; i > 99; i--)
{
for (g = i; g > 99; g--)
{
...
However, as Emilio pointed out, your assumption that the first palindrome you find will be the answer is incorrect. You need to compute the biggest numbers first, obviously. So you should try them in this order; 999*999, 999*998, 998*998, 999*997, 998*997, etc...
Haven't tested it but I think you want something like this (pseudo code):
x = 999;
n = 0;
while (++n <= x)
{
j = x;
k = j - n;
while (j >= k)
{
y = j-- * k;
if (check(y))
stop looking
}
}
I found this article which might help you. It has improved brute force approach.
All the above provided answers are excellent, but still I could not restrict myself from writing the code. The code posted by #thyrgle is absolutely perfect. Only a slight correction which he needs to do is just check which product is the maximum.
The code can be as
int i,j,max=0,temp;
for(i=999;i>=100;i--){
for(j=i;j>=100;j--){
temp=i*j;
if(isPalin(temp) && temp>max){
max=temp;
}
}
}
cout<<max<<"\n";
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int a[6];
void convertToString(int xy){
int i,t=100000;
for(i=0;i<6;i++){
a[i]=xy/t;
xy = xy % t;
t=t/10;
}
}
int check(){
int i;
for(i=0;i<3;i++){
if(a[i]!=a[6-i]){
return 0;
}
}
return 1;
}
void main(){
int x,y,xy,status=0;
int i=0,j=0,p=0;
for(x=999;x>99;x--){
for(y=x;y>99;y--){
xy=x*y;
convertToString(xy);
status = check();
if(status==1){
if(xy>p){
p=xy;
i=x;
j=y;
}
}
}
}
printf("\nTwo numbers are %d & %d and their product is %d",i,j,p);
}
x,y=999,999
k=0
pal=[]
while (y>99):
while (x>=100):
m=x*y
n=x*y
while (n!=0):
k=k*10+(n%10)
n=int(n/10)
if(m==k):
if k not in pal:
pal.append(k)
x=x-1
k=0
else:
y,x=y-1,999
pal.sort()
print(pal)
it gives 906609 as the largest palindrome number

Resources