array of pointer game not sure how to move pointers to back - c

there is a game that this program needs to play X-boom its supposed to take out the x player each turn and put it in the back of the array and then shorten the array so its no longer a part of it in that function. for example
player 1 2 3 4 and the x for the game is 3
players remaining: 1 2 4
players remaining: 1 4
players remaining: 1
i made this code that i think should do it but im not sure why its not working properly
i have a photo to how the output is supposed to look like but i dont know how to share it here if any one knows please tell me in the comments
my problem is mostly with the play function notice that is number 3 in the array was kicked you are supposed to keep on playing from number 3 just that there will be a new pointer there
i tried to solve this be just going to the one that needed to be kicked and doing a swap for it to go back while moving everyone else forward and then shortening the array by 1
in the end the main function will print the array and it needs to be in order that the first player to be kicked will be last in the array
void get_boom_number(int * i){
printf("enter the boom number\n");
scanf("%d",i);
return ;
}
#define LENGTH 31
void play(char * players[],int length,int boomnum){
int count=-1;
count = (count+boomnum-1)%(length);
char * temp;
for (int i = 0; i<30; i++) {
printf("%d\n",count);
for (int start=count; start<length-1; start++) {
temp=*(players+start);
*(players+start)=*(players+start+1);
*(players+start+1)=temp;
}
count=(count+boomnum-1)%(length);
length=length-1;
}
return ;
}
int main()
{
char * players[LENGTH]={"Tyrion Lannister","Daenerys Targaryen","Jon Snow","Arya Stark","Theon Greyjoy", "Joffrey Baratheon","Khal Drogo","Ted Mosby","Marshall Eriksen","Robin Scherbatsky","Barney Stinson", "Lily Aldrin", "Tracy McConnell", "Ted Mosby", "Leonard Hofstadter","Sheldon Cooper", "Penny", "Howard Wolowitz", "Raj Koothrappali", "Bernadette Rostenkowski-Wolowitz","Amy Farrah Fowler", "Gregory House", "Lisa Cuddy", "James Wilson","Eric Foreman", "Allison Cameron", "Robert Chase" ,"Lawrence Kutner", "Chris Taub","Remy 13 Hadley", "Amber Volakis"};
int boom_number, i;
get_boom_number(&boom_number);
play(players,LENGTH,boom_number);
and then just printing the array also we are not alowed to use "[]" for the hole thing.

A problem with your code is that count will become negative if the boomnum number is e.g. 1. I don't understand why count is initialized to -1 and why you subtract 1 more when recalculating count. Your code is the same as:
int count = (boomnum-2)%(length);
Again, it seems strange to subtract 2. Anyway, you must check that the result isn't negative.
Another problem is this:
count=(count+boomnum-1)%(length);
length=length-1;
This can cause count to be equal to length in the next iteration. I guess that's not what you want. You need to swap the two lines to avoid that. Like:
length=length-1;
count=(count+boomnum-1)%(length);
Doing that and input 2 for boom_number leads to the result:
Remy 13 Hadley
(Strange name by the way).
I would also change:
for (int i = 0; i<30; i++) {
to
while(length > 1) {
It's a bad idea to hard code the number of loops.
Further, this line:
count=(count+boomnum-1)%(length);
is also a problem. If boomnum is zero it may again cause count to become negative.

Related

Swapping elements in Array of Pointers

I have the following array in C (Used random names)
char * inputs[6] = {
"Kangaroo my shoe", "Fly high dragonfly",
"Philosophical Monkey", "Jumping Ape",
"Fearful lemurs", "Tall Giraffes"
};
The goal is to swap the first element by the next. As in to do this
char * inputs[6] = {
"Fly high dragonfly", "Kangaroo my shoe",
"Jumping Ape", "Philosophical Monkey",
"Tall Giraffes", "Fearful lemurs"
};
I have tried the following and some more.
ArrSwap(char *Arr[]){
int i;
for(i=0;i<6;i++){
void*temp = Arr[i];
Arr[i]=Arr[i+1];
Arr[i+1] = temp;
}
}
Thanks in advance! I've spent some hours trying to figure this out, each time I do it it ends up with a messed up order or not swapping any elements expect for the first and last.
There are two problems in your code -
In function ArrSwap() you are looping over index 0 to 5. So, when i becomes 5, Arr[i+1] points to Arr[6] which leads to read from a memory past your array bounds. Which is undefined behavior.
Secondly, if I get your requirement correctly, you want to swap the first and second elements swapped, then third and fourth and so on. So, your code has a logic error. In that case, in ArrSwap() the loop needs to increment by 2 instead of 1.
So the code may look like this after both issues are addressed -
void ArrSwap(char *Arr[]){
int i;
for(i=0; i<5; i+=2) {
char *temp = Arr[i];
Arr[i]=Arr[i+1];
Arr[i+1] = temp;
}
}
Notice there are following changes done in the ArrSwap() function -
The loop test condition changed from i < 6 to i < 5 (the reason mentioned in point 1 above). As ikegami mentioned, best practice would be to pass the array size as an argument (say n) and use n - 1 in loop condition.
The logic is fixed (as mentioned in point 2 above)
For swap, use char * instead of void * (The type of elements in Arr is char *)
The return type of ArrSwap() is mentioned as void. With void it is clearly conveyed that ArrSwap() will not return anything.
After fix the inputs will be:
{"Fly high dragonfly", "Kangaroo my shoe", "Jumping Ape", "Philosophical Monkey", "Tall Giraffes", "Fearful lemurs"}

Debug-print for loop omitting 1st value

I was debugging a low level program, I had to ensure that my array exp have all values I expect it to have. So I wrote a code snippet that prints my array to help debug it. Problem is standard library isn't available so I need to use my own code.
My code snippet:
int test=0;char val[5]={};
int l=0;
for(int k=0;exp[k]!=0;k++)
{
test=exp[k]; //taking in value
int_to_ascii(test, val);
print_char(val,2*l,0xd);
for(int m=0;val[m]!='\0';m++)//clearing out val for next iteration
val[m]='\0';
l=k*0xA0; //next line
}
exp is an integer array..
code for int_to_ascii:
if(src==0)
{
stack[i++]='\0'; //pushing NULL and 0 to stack
stack[i++]='0';
}
else
{
while(src!=0) //converting last digit and pushing to stack
{
stack[i]=(0x30+src%10);
src/=10;
i++;
}
}
i--;
len=i;
while(i>=0)
{
dest[len-i]=stack[i]; //popping and placing from left to right
i--; //inorder not to get reversed.
}
print_char works because I use it to print entire window and interface. It basically takes
char* szarray,int offset,int color.
I was yelling at my computer for nearly 2 hours because I thought my array is incorrect but it shouldn't be, but the actual problem was in this debug code.It doesn't print exp[0].
When it should output:
20480
20530
5
It just prints
20530
5
I even tried brute forcing values into exp[0]. If I give any value except 20480 into that, it will print invalid characters into first entry,like this:
20530P\. ;not exact value, demonstration purpose only
5
I think something is off in int_to_ascii, but that also is extensively used in other parts without any problems.
Any one have any idea with it?

C program stops responding for large inputs

I am (re-)learning C and in the book I am following we are covering arrays, and the book gives an algorithm for finding the first n primes; myself being a mathematician and a decently skilled programmer in a few languages I decided to use a different algorithm (using the sieve of Eratosthenes) to get the first n primes. Well making the algorithm went well, what I have works, and even for moderately large inputs, i.e. the first 50,000 primes take a bit to run as you would expect, but no issues. However when you get to say 80,000 primes pretty much as soon as it begins a window pops up saying the program is not responding and will need to quit, I made sure to make the variables that take on the primes were unsigned long long int, so I should still be in the acceptable range for their values. I did some cursory browsing online and other people that had issues with large inputs received the recommendation to create the variables outside of main, to make them global variables. I tried this for some of the variables that I could immediately put outside, but that didn't fix the issue. Possibly I need to put my arrays isPrime or primes outside of main as well? But I couldn't really see how to do that since all of my work is in main.
I realize I should have done this with separate functions, but I was just writing it as I went, but if I moved everything into separate functions, my arrays still wouldn't be global, so I wasn't sure how to fix this issue.
I tried making them either static or extern, to try and get them out of the stack memory, but naturally that didn't work since they arrays change size depending on input, and change over time.
the code is:
#include <math.h>
#include <stdbool.h>
#include <stdio.h>
unsigned long long int i,j;
unsigned long long int numPrimes,numPlaces;
int main(void)
{
bool DEBUG=false;
printf("How many primes would you like to generate? ");
scanf("%llu",&numPrimes);
// the nth prime is bounded by n*ln(n)+n*ln(ln(n)), for n >=6
// so we need to check that far out for the nth prime
if (numPrimes>= 6)
numPlaces = (int) numPrimes*log(numPrimes)+
numPrimes*log(log(numPrimes));
else
numPlaces = numPrimes*numPrimes;
if(DEBUG)
printf("numPlaces: %llu\n\n", numPlaces);
// we will need to check each of these for being prime
// add one so that we can just ignore starting at 0
bool isPrime[numPlaces+1];
// only need numPrimes places, since that is all we are looking for
// but numbers can and will get large
unsigned long long int primes[numPrimes];
for (i=2; i<numPlaces+1;i++)
isPrime[i] = true; // everything is prime until it isn't
i=2; // represents current prime
while (i < numPlaces + 1)
{
for (j=i+1;j<numPlaces+1;j++)
{
if (isPrime[j] && j%i ==0) // only need to check if we haven't already
{
isPrime[j] = false;// j is divisibly by i, so not prime
if(DEBUG)
{
printf("j that is not prime: %llu\n",j);
printf("i that eliminated it: %llu\n\n",i);
}//DEBUG if
}//if
}//for
// ruled out everything that was divisible by i, need to choose
// the next i now.
for (j=i+1;j<numPlaces+2;j++)// here j is just a counter
{
if (j == numPlaces +1)// this is to break out of while
{
i = j;
break;
}// if j = numPlaces+1 then we are done
else if (isPrime[j]==true)
{
i = j;
if (DEBUG)
{
printf("next prime: %llu\n\n",i);
}//DEBUG if
break;
}//else if
}// for to decide i
}//while
// now we have which are prime and which are not, now to just get
// the first numPrimes of them.
primes[0]=2;
for (i=1;i<numPrimes;i++)// i is now a counter
{
// need to determine what the ith prime is, i.e. the ith true
// entry in isPrime, 2 is taken care of
// first we determine the starting value for j
// the idea here is we only need to check odd numbers of being
// prime after two, so I don't need to check everything
if (i<3)
j=3;
else if (i % 2 ==0)
j = i+1;
else
j = i;
for (;j<numPlaces+1;j+=2)// only need to consider odd nums
{
// check for primality, but we don't care if we already knew
// it was prime
if (isPrime[j] && j>primes[i-1])
{
primes[i]=j;
break;
}//if, determined the ith prime
}//for to find the ith prime
}//for to fill in primes
// at this point we have all the primes in 'primes' and now we just
// need to print them
printf(" n\t\t prime\n");
printf("___\t\t_______\n");
for(i=0;i<numPrimes;i++)
{
printf("%llu\t\t%llu\n",i+1,primes[i]);
}//for
return 0;
}//main
I suppose I could just avoid the primes array and just use the index of isPrime, if that would help? Any ideas would help thanks!
Your problem is here, in the definition of the VLA ("Variable Length Array", not "Very Large Array")
bool isPrime[numPlaces+1];
The program does not have enough space in the area for local variables for the array isPrime when numPlaces is large.
You have two options:
declare the array with a "big enough" size outside of the main function and ignore the extra space
use another area for storing the array with malloc() and friends
option 1
#include <stdio.h>
unsigned long long int i,j;
bool isPrime[5000000]; /* waste memory */
int main(void)
option 2
int main(void)
{
bool *isPrime;
// ...
printf("How many primes would you like to generate? ");
scanf("%llu",&numPrimes);
// ...
// we will need to check each of these for being prime
// add one so that we can just ignore starting at 0
isPrime = malloc(numPrimes * sizeof *isPrime);
// ... use the pointer exactly as if it was an array
// ... with the same syntax as you already have
free(isPrime);
return 0;
}
The array you allocate is a stack variable (by all likelihood), and stack size is limited, so you are probably overwriting something important as soon as you hit a certain size threshold, causing the program to crash. Try using a dynamic array, allocated with malloc, to store the sieve.

Finding all possible words from inputted phone number [duplicate]

This question already has answers here:
Generating all Possible Combinations
(12 answers)
Closed 9 years ago.
I have a problem that I need some help in figuring out. I was hoping I could get a few pointers on a better way to approach what i'm doing. My main issue is a few lines below (//This is whats hanging me up) and described at the bottom of page.
I need to permutate all possible outcomes of a phone number: (not just dictionary words)
I.E. 222-2222
Should output a list 3^7 long with all the possible permutations of a,b,c
I.E.
AAAAAAA
AAAAAAB
AAAAAAC
AAAAABA // THIS IS WHATS HANGING ME UP
AAAAABB
AAAAABC
AAAAACA // HERE TOO AND SO ON
MY CODE (purposely shortened for testing) GIVES ME:
AAAA
AAAB
AAAC
AABC
AACC
ABCC
ACCC
BCCC
CCCC
I'm a beginning programming student so my knowledge goes as far as using for, while, if, statements and grabbing individual chars from the array.
Here's what my code looks like so far: (this is a part of a function. Code missing)
char alphaFunc(char n[]){
int d1=n[0]-48;
int d2=n[1]-48;
int d3=n[2]-48;
int d4=n[3]-48;
int d5=n[4]-48;
int d6=n[5]-48;
int d7=n[6]-48;
int a=0,b=0,c=0,d=0,e=0,f=0,g=0;
int i=0;
char charArray[10][4]={ {'0','0','0'},{'1','1','1'},{'A','B','C'},
{'D','E','F'},{'G','H','I'},{'J','K','L'},{'M','N','O'},
{'P','R','S'},{'T','U','V'},{'W','X','Y'} };
while(i <=14){
printf("%c%c%c%c\n", charArray[d1][a],
charArray[d2][b],charArray[d3][c],charArray[d4][d],
charArray[d5][e],charArray[d6][f],charArray[d7][g]);
g++;
if(g==3){
g=2;
f++;
}
if(f==3){
f=2;
e++;
}
if(e==3){
e=2;
d++;
}
I'm not exactly looking for someone to do this for me I just need a little help in figuring out which sort of statement will work b/c when you have a digit get to CharArray[d-][a] location [3] and reset it to [0] it sends you to a different part of the loop. (hope that makes sense).
Since the values of charArray are constant, I would recommend making it a global variable, rather than declaring it in your function. In addition, since some numbers have 4 letters, whereas others have 3, you may want to look into using a jagged array to represent it.
As far as printing the permutations you can get from a phone number, I think recursion is going to be your friend. Assuming you can store the phone number in an int array, the following should work:
public void printPermutations(int[] phoneNumber)
{
printPermutations(phoneNumber, 0, String.Empty);
}
private void printPermutations(int[] phoneNumber, int index, string permutation)
{
if(index >= phoneNumber.Length)
{
// If we've reached the end, print the number
printf(permutation + "\n");
}
else
{
// Otherwise, generate a permutation for each
// character this digit can be
int digit = phoneNumber[index];
char[] chars = charArray[digit];
for (int i = 0; i < chars.Length; i++)
{
printPermutations(phoneNumber, index+1, permutation + chars[i]);
}
}
}

What am I doing wrong (C arrays)?

I'm just a beginner at C.
I'm trying to make a simple program to arrange the user-entered digits in ascending order. I have figured out the solution but can't understand why my other code wouldn't work :(
-------------------------------------------------------------------------
working code:
-------------------------------------------------------------------------
#include <stdio.h>
int main()
{
int i,j,num[10];
printf("Enter 10 numbers\n");
for (i=0;i<10;i++)
{scanf("%d",&num[i]);}
for (i=0;i<9;i++)
{
for (j=i+1;j<10;j++)
{
if (num[i]>num[j])
{
num[i]+=num[j];
num[j]=num[i]-num[j];
num[i]=num[i]-num[j];
}
}
}
printf("The numbers in ascending order are:");
for (i=0;i<10;i++)
{
printf(" %d",num[i]);
}
return 0;
}
-------------------------------------------------------------------------
code that won't work:
-------------------------------------------------------------------------
#include <stdio.h>
int main()
{
int i,j,num[10];
printf("Enter 10 numbers\n");
for (i=1;i<=10;i++)
{scanf("%d",&num[i]);}
for (i=1;i<10;i++)
{
for (j=i+1;j<=10;j++)
{
if (num[i]>num[j])
{
num[i]+=num[j];
num[j]=num[i]-num[j];
num[i]=num[i]-num[j];
}
}
}
printf("The numbers in ascending order are:");
for (i=1;i<=10;i++)
{
printf(" %d",num[i]);
}
return 0;
}
In the latter program, numbers appear out of order, and there even are numbers that haven't been entered.
My question is, isn't it basically the same code? Just that in the latter program numbers would be stored from num[1] to num[10] instead of num[0] through num[9]?
Does it have something to do with array definitions?
It seems I have serious misconceptions, please help me out!
In C, when you have int num[10];, your indexes need to go from 0 to 9, never to 10. So look over your code, if any i or j ends up with a value of 10 any time during the program run, that's bad news.
Indexes in C go start from 0. so when you declare an array of size 10, and you try to get element at index 10, you're actually getting the 11th element. Since you haven't defined the 11th element, the array will most likely get some random numbers from memory, which is why you are noticing numbers you have note entered.
Since you are new to programming, I would suggest taking the time now to really learn about how C manages memory, and how different data structures access the memory. It might be a little boring now, but you'll save yourself some headaches in the future, and you will start to build good habits and good practices, which will lead to writing good, optimal code
for(i=0;i<9;i++) //**i<9**
for (j=i+1 ...)
If i=8 then j=9 , everything is OK.
In second code snippet:
for(i=0;i<10;i++) //**i<10**
for (j=i+1 ...)
If i=9 then j=10, so you try to access num[10] and it gives you error.
If you want to access num[10] then you must declare array int num[11] and then you can access num[10].
Array Basics
int num[10]
Capacity of array = 10
Every element of this array are integer.
First element index is 0. So If you want to access first element , num[0]
Last element index is 9. So If you want to access last element, index must be length of array - 1 , so num[9]
There are 10 elements in the array and they are :
num[0] , num[1] , num[2] , num[3] , num[4] , num[5] , num[6] , num[7] , num[8] and num[9]
You can learn further at http://www.cplusplus.com/doc/tutorial/arrays/
In your non-working example, you have invalid memory accesses. For example, when i = 9 and j = 10, you access num[10], which is invalid memory.
Welcome to programming! I believe you are a bit confused about how arrays are indexed in C.
Arrays in most languages (including C) are known as zero-indexed arrays. This means the start of an array is always at position 0. So if you make int num[10], trying to access num[10] isn't actually a valid call at all, because the start is num[0]. Hence you can only access from num[0] to num[9].
It's an easy mistake to make, even though I've been programming for years sometimes when it's been a long night I'll still make silly array indexing issues.
In your other code example, you were doing this:
int num[10];
for(int i = 1; i <= 10; i++) {
//...
}
That means you have an array with ten spaces [0-9], and for the last part of your for loop, you were trying to access num[10] which doesn't exist.
Your working example goes from 0-9 and never tries to read num[10], so it works.
Arrays in C, as in most languages, start with position 0 and count that as position one. So the last element of your array would be the size you entered when you declared the variable, minus one.

Resources