Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I have a Dice poker assignment. I have managed to generate an array that holds the frequencies of values rolled, but I can't write a loop to determine what the value of the hand is.
Hoping to get some advice on what combination of loops to use to determine what hand I'm holding. From there, I should be able to transpose this into a function, and write a function to compare this hand against others.
#define _CRT_SECURE_NO_WARNINGS
#define handsz 5 //NO ACES IN THE POCKET WITH THIS GUY!
#define diesz 6 //All dice played will have 6 sides
#define ranks 7 //Seven ranks to hold
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int roll_die(void);
int main() {
srand(time(NULL));
int i;
int player_hand[handsz] = { 0 };
int donkeyvalue = 0;
int RandomNo;
for (i = 0; i < handsz; i++) {
RandomNo = roll_die(donkeyvalue);
player_hand[i] = RandomNo;
}
int player_die_count[7] = { 0 };
for (i = 0; i < handsz; i++) {
player_die_count[player_hand[i]] = player_die_count[player_hand[i]] + 1;
}
return 0;
}
int roll_die(void) {
return (1 + rand() % 6);
}
From the array player_die_count, using loops, you can determine:
the number of five of a kind
the number of four of a kind
the number of three of a kind
the number of pairs
And using a simple formula, you can determine if you have a straight:
has_straight = (player_die_count[1] == 1 && player_die_count[2] == 1 &&
player_die_count[3] == 1 && player_die_count[4] == 1 &&
player_die_count[5] == 1) ||
(player_die_count[2] == 1 && player_die_count[3] == 1 &&
player_die_count[4] == 1 && player_die_count[5] == 1 &&
player_die_count[6] == 1);
Which can be simplified into:
has_straight = (player_die_count[2] * player_die_count[3] *
player_die_count[4] * player_die_count[5]) == 1;
Then you can compute the payer's hand value from 0 to 7:
Five of a kind: 7 points
Four of a kind: 6 points
Full house: three of a kind plus a pair: 5 points
Straight: 4 points
Three of a kind : 3 points
Two pairs : 2 points
One pair : 1 point
Bust: 0 point
You can refine the score by ranking the different combinations according to the values of the highest die. five of a kind of 6 beats five of a kind of 5, etc.
Here is a complete program that outputs the score and the draw for a number of draws either using rand() or using a sequential distribution of all combinations:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define handsz 5
#define diesz 6 // All dice played will have 6 sides, numbered 1 to 6
static int roll_die(void) {
return 1 + rand() % 6;
}
int main(int argc, char *argv[]) {
int iter = 1;
int use_random = 1;
if (argc > 1) {
iter = strtol(argv[1], NULL, 0);
if (iter < 0) {
use_random = 0;
iter = -iter;
}
}
srand(clock());
for (int n = 0; n < iter; n++) {
int player_hand[handsz];
if (use_random) {
for (int i = 0; i < handsz; i++)
player_hand[i] = roll_die();
} else {
for (int i = 0, mm = n; i < handsz; i++, mm /= 6)
player_hand[i] = 1 + mm % 6;
}
int player_die_count[7] = { 0 };
for (int i = 0; i < handsz; i++) {
player_die_count[player_hand[i]] += 1;
}
int pairs, threes, fours, fives, score;
pairs = threes = fours = fives = score = 0;
for (int i = diesz; i > 0; i--) {
switch (player_die_count[i]) {
case 5:
fives = i * 11111;
break;
case 4:
fours = i * 1111;
break;
case 3:
threes = i * 111;
break;
case 2:
pairs = pairs * 100 + i * 11;
break;
case 1:
score = score * 10 + i;
break;
}
}
if (fives)
score += 700000 + fives;
else
if (fours)
score += 600000 + fours * 10;
else
if (threes && pairs)
score += 500000 + threes * 100 + pairs;
else
#ifndef NO_STRAIGHTS
if (score == 54321 || score == 65432)
score += 400000;
else
#endif
if (threes)
score += 300000 + threes * 100;
else
if (pairs >= 100)
score += 200000 + pairs * 10;
else
if (pairs)
score += 100000 + pairs * 1000;
printf("%d: %d %d %d %d %d\n",
score, player_hand[0], player_hand[1],
player_hand[2], player_hand[3], player_hand[4]);
}
return 0;
}
It is very interesting to run the program with an argument of 7776 to check the actual distribution provided by the simplistic roll_die function. On my system, the pseudo-random distribution sometimes gives surprising results:
chqrlie$ ./pokerdice 7776 | sort -nr | head -10
755555: 5 5 5 5 5
744444: 4 4 4 4 4
744444: 4 4 4 4 4
722222: 2 2 2 2 2
711111: 1 1 1 1 1
711111: 1 1 1 1 1
711111: 1 1 1 1 1
711111: 1 1 1 1 1
666665: 6 6 6 5 6
666665: 6 6 5 6 6
Related
The problem I was given to solve is "The number of students who will take the exam is entered from the keyboard, and then the IDs of all the students who will take the exam are entered. The program should divide the students into three groups: students with IDs ending in the digits 0, 1, and 2, students with IDs ending in the digits 3, 4, 5, and students with IDs ending in the digits 6, 7, 8, 9 .The program should print the IDs for each group, in the same order as they were entered. The maximum number of students that can be entered is 1000.".
The code that I can come up with is
#include <stdio.h>
int main() {
int n,br,gr1,gr2,gr3;
scanf("%d",&n);
for (int i = 0; i < n; ++i) {
scanf("%d", &br);
if (br % 10 == 0 || br % 10 == 1 || br % 10 == 2)
{
gr1 = br;
}
else if (br % 10 == 3 || br % 10 == 4 || br % 10 == 5)
{
gr2 = br;
}
else if (br % 10 == 6 || br % 10 == 7 || br % 10 == 8 || br % 10 == 9)
{
gr3 = br;
}
}
printf("Grupa 1\n%d\n",gr1);
printf("Grupa 2\n%d\n",gr2);
printf("Grupa 1\n%d\n",gr3);
return 0;
}
Instead of printing all the IDs and sorting them into groups it is only printing the last input number and group number.
I am in no way an experienced programmer so I can't really tell what is wrong with the way I have written this or how to solve it. I would appreciate it if you can guide me through
The output I am expecting is:
Grupa 1
20010 20581 19452
Grupa 2
20145 19873 19825 20653
Grupa 3
20147 20139 19458
The output I am getting is
Grupa 1
19452
Grupa 2
20653
Grupa 3
19458
Your gr1,gr2,gr3 int variables can only store one values at a time (here, the last value that was assigned to it so its showing only one result.) Make them something like an array eg gr1[],gr2[],gr3[], which will be able to hold multiple values at a time and will be able to print them out at the end.
The way you format you code makes it harder for yourself to figure out what is going on. You need to stash in a data in an ordered data structure (array, linked list etc):
#include <stdio.h>
#include <stdlib.h>
#define MAX_STUDENTS 1000
typedef size_t student_id;
enum group {
GROUP_1 = 1,
GROUP_2,
GROUP_3
};
enum group group_student(student_id id) {
switch(id % 10) {
case 0: case 1: case 2:
return GROUP_1;
case 3: case 4: case 5:
return GROUP_2;
default:
return GROUP_3;
}
}
int main(void) {
student_id ids[MAX_STUDENTS];
size_t n = 0; // required below
for(; n < sizeof ids / sizeof *ids; n++) {
if(scanf("%zu", ids + n) != 1) {
break;
}
}
for(enum group group = GROUP_1; group <= GROUP_3; group++) {
printf("Grupa %d\n", group);
for(size_t j = 0; j < n; j++) {
if(group == group_student(ids[j]))
printf("%zu ", ids[j]);
}
printf("\n");
}
}
and here is an example run:
$ echo '20010 20581 19452 20145 19873 19825 20653 20147 20139 19458' | ./a.out
Grupa 1
20010 20581 19452
Grupa 2
20145 19873 19825 20653
Grupa 3
20147 20139 19458
When you type this in, end input with ctrl-D. I used a enum group here as it's an identifier (not a number) and documents by virtue of the return type that you change the enum you want to change the function group_student(), too.
I have an assignment that requires me to make a quiz which generates random math questions. I'm fine with everything but i'm struggling to find a way to randomly choose between the mathematical operators "+" and "-".
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int main(){
int choice = 0;
int lives = 0;
int question = 1;
int a;
int b;
int answer = 0;
int ans = 0;
int correct = 0;
printf("\n Welcome to Maths Tester Pro.");
printf("\n Please Select a difficulty:");
printf("\n 1) Easy");
printf("\n 2) Medium");
printf("\n 3) Hard \n");
scanf("%d%*c",&choice);
switch(choice)
{
case 1:
printf("You have selected Easy mode!");
lives = lives+3;
while ((lives !=0)&&(question !=6)){
if(question !=5){
//Ask Question
printf("\nQuestion %d of 5. You have %d lives remaining", question, lives);
srand(time(NULL));
a = (rand() % (10 - 1 + 1)) + 1; //make the sign random
b = (rand() % (10 - 1 + 1)) + 1;
printf("\n%d + %d = ",a ,b);
scanf("%d", &answer);
ans = a+b;
//If answer is correct
if((a+b) == answer){
printf("Correct!\n");
correct = correct + 1;
}
//If answer is incorrect
else{
printf("Incorrect! The correct answer was %d\n",ans);
lives=lives-1;
}
question = question + 1;
}
In my code I have it written as ans=a+b but I want it to be able to randomly pick either "+" or "-".
The easiest way to go would be to change the sign of b. To do so, simply multiply it by either 1 (keeps positive sign) or -1 (makes it a negative):
b = b * ((rand() - (RAND_MAX / 2)) > 0 ? 1 : -1);
Upon execution, you will randomly get a + b or a + (-b).
Example print of the resulting operator:
printf("%d%s%d = %d\n", a, (b > 0 ? "+" : ""), b, a + b);
Note: as pointed in earlier comments, you may also want to randomize the seed in order to prevent you application to keep providing the "same" random numbers with:
/* Randomize seed (needed once). */
srand(time(NULL));
/* Then make your calls to `rand()`. */
...
I offer this as an example of how to cleanly generate and print the sort of problems that you seem to want.
This produces 20 'sum' and/or 'difference' equations. You can simply suppress printing the total in order to pose the question to the user.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
srand( time( NULL ) );
for( int i = 0; i < 20; i++ ) {
int a = (rand() % 10) + 1; // 1 <= a <= 10
int b = (rand() % 20) - 9; // -9 <= b <= 10
printf( "%d %c %d = %d\n", a, "+-"[b<0], abs( b ), a+b );
}
return 0;
}
1 + 3 = 4
1 - 6 = -5
4 + 10 = 14
8 + 2 = 10
10 + 0 = 10
4 + 4 = 8
8 + 10 = 18
8 + 9 = 17
8 - 2 = 6
8 - 4 = 4
2 + 1 = 3
8 - 5 = 3
2 - 6 = -4
4 + 9 = 13
6 + 6 = 12
5 + 0 = 5
3 + 4 = 7
1 + 0 = 1
9 - 5 = 4
8 + 8 = 16
The keen eyed reader will notice that even "10 + 0" is a reasonable problem. Zero is the identity operator(?) for addition (like 1 being the identity operator(?) for multiplication.)
You're free to adjust the ranges of the terms to suit your questions.
You can use rand() function, which is defined in stdlib. And if you want your program to give you different random numbers every time you run it, you need to put srand(time(NULL)) at the beginning, but for the time function, you need to include time.h library
i am working on a program where the input is an ID of 9 numbers :
program checks if the id is correct or not by :-
checking if the string is formed by numbers only .
every number has a weight of 1 or 2 so it should be 1 2 1 2 1 2 1 2
1
multiply the weight and the number
if the number is bigger than 9 then add the numbers forming it .
if the number is from multiplication of 10 then the ID is correct ..
example :-
1 7 9 3 7 9 2 5 0-ID
1 2 1 2 1 2 1 2 1-Weight
1 14 9 6 7 18 2 10 0-num x weight
1 5 9 6 7 9 2 1 0-(4)
sum = 40 then it is a correct ID.
I wrote most of it but then i noticed that it has to be a string . so my questions are :
is there a way to put a string into an array?as doing it with an
array is way easier.
how do i locate a place in a string ? like if i want the third
character in a string how do i locate it?.
and here is the code that i did it does not work yet and it needs alot of changes but i guess i will put it anyways :-
#include<stdio.h>
#define N 9
void input(int num[N]);
int check(int num[N]);
int main()
{
int num[N],a;
input(num);
a = check(num);
if (a = 1)
printf("ID is correct");
else printf("ID is NOT correct");
}
void input(int num[N])
{
int i;
printf("Enter your ID (9digits) :-");
for (i = 0;i < N;i++)
scanf("%d",num[i]);
}
int check(int num[N])
{
int w[N] = { 1,2,1,2,1,2,1,2,1 },wxnum[N],i,tota[N],sum,g;
for (i = 0;i < N;i++)
wxnum[i] = num[i] * w[i];
for (i = 0;i < N;i++)
{
if (wxnum[i] > 9)
tota[i] = wxnum[i] / 10 + wxnum[i] % 10;
else tota[i] = wxnum[i];
}
sum = tota[0] + tota[1] + tota[2] + tota[3] + tota[4] + tota[5] + tota[6] + tota[7] + tota[8];
g = sum % 10;
if (g = 0)
return 1;
else
return 0;
}
Thanks everyone for your help.
You can get a string by doing
/*N is defined as 9 in your code.*/
/*Considering there is always a '\0' in every string, we should allocat N + 1 slot for your nine numbers and the extra '\0'.*/
char chStr[N + 1];
scanf("%s", chStr);
After you got the string, you can take advantage of the values of charactor '0' - '9' (their values are from 48 to 57 correspondingly) in ASCII table, and easily transfer the charactors into integers by doing:
int i = 0;
for (i = 0; i < N; i++)
{
chStr[i] = chStr[i] - '0';
}
If you are restrict on the type, you can transfer these char values into int values by adding extra two lines:
int num[N];
int i = 0;
for (i = 0; i < N; i++)
{
chStr[i] = chStr[i] - '0';
num[i] = (int) chStr[i];
}
Please note that my code didn't check the validation of user input. To make it more secure, you can use
scanf("%9s", chStr);
to declare the maximum length that the user can input.
I've tried to solve problem 2 on Project Euler in C. This is the first possible solution that came to my mind, and, in fact, it gives as an output the right answer. The problem is that each time I run my program it gives me a different output, which is either "2" or "4613732" that is the right answer. Sorry for my poor english, can you help me find out what's wrong?
#include <stdio.h>
int main(){
int n, n1 = 1, n2 = 2, sum = 2;
while(n<4000000){
n = n1 + n2; /*calculate the next number of the series*/
n1 = n2;
n2 = n;
if(n%2 == 0){
sum = sum + n; /*if the number it's even add it to the main sum*/
}
}
printf("The sum is %d\n", sum);
}
You didn't initialize n; when you get the right answer, it means you got lucky.
#include <conio.h>
#include <iostream>
using namespace std;
int evenFibSum(int i=1,int j=2)
{
const int max = 3999999;
int eventsum = 2;
int sum = 0;
while (sum < max)
{
sum = i + j;
i = j;
j = sum;
if (sum % 2 == 0)
eventsum +=sum;
}
return eventsum;
}
For more efficient solution apply following logic
Fibbonaci Series => 1 2 3 5 8 13 21 34 55 89 144
Index => 0 1 2 3 4 5 6 7 8 9 10
To get even fibbonanci addition I have to add following index values[1 4 7 10]
Here I am sensing some pattern
[1 4 7 10] => I need advance index by 3
so how to advance index by 3
// k = i+j = > 3 13 55
// i = k+j => 5 21 89
// j = k+i => 8 34 144
int evenFibSumx(int i=1,int j=2)
{
const int max = 3999999;
int eventsum = 2;
int k= 0;
while (1)
{
k = i + j;
i = k + j;
j = k + i;
if(i >= max)
break;
if (j%2 == 0)
eventsum +=j;
}
return eventsum;
}
int main()
{
std::cout << evenFibSum();
std::cout << evenFibSumx();
}
So I have been trying to do a variant of the subset sum problem, which I want to do using dynamic programming. So what I am aiming for is for example, to have an input of
m = 25 // Target value
n = 7 // Size of input set
and the input set to be for example {1, 3, 4, 6, 7, 10, 25}. So the wanted output would be something like
{1, 3, 4, 7, 10} and {25}.
Here is the code
#include <stdio.h>
#include <stdlib.h>
int main()
{
// Get input sequence
int n = 7; // Size of input set
int m = 25; // Target value
int *S; // Input set
int **C; // Cost table
int i,j,potentialSum,leftover;
S=(int*) malloc((n+1)*sizeof(int));
C=malloc((m+1)*sizeof(int*));
for (int rows = 0; rows<=m; rows++) {
C[rows] = malloc((m+1)*sizeof(int));
}
if (!S || !C)
{
printf(" FAILED %d\n",__LINE__);
exit(0);
}
S[0] = 0;
S[1] = 1;
S[2] = 3;
S[3] = 4;
S[4] = 6;
S[5] = 7;
S[6] = 10;
S[7] = 25;
// Initialize table for DP
C[0][0]=0; // DP base case
// For each potential sum, determine the smallest index such
// that its input value is in a subset to achieve that sum.
for (potentialSum=1; potentialSum<=m; potentialSum ++)
{
for (j=1;j<=n;j++)
{
leftover=potentialSum-S[j]; // To be achieved with other values
if (leftover<0) // Too much thrown away
continue;
if (C[leftover][0] == (-1)) // No way to achieve leftover
continue;
if (C[leftover][0]<j) // Indices are included in
break; // ascending order.
}
C[potentialSum][0]=(j<=n) ? j : (-1);
}
// Output the input set
printf(" i S\n");
printf("-------\n");
for (i=0;i<=n;i++)
printf("%3d %3d\n",i,S[i]);
// Output the DP table
printf("\n\n i C\n");
printf("-------\n");
for (i=0;i<=m;i++)
printf("%3d %3d\n",i,C[i][0]);
if (C[m][m]==(-1))
printf("No solution\n");
else
{
printf("\n\nSolution\n\n");
printf("(Position) i S\n");
printf("------------------\n");
for (i=m;i>0;i-=S[C[i][0]])
printf(" %3d %3d\n",C[i][0],S[C[i][0]]);
}
}
This will output the following
i S
-------
0 0
1 1
2 3
3 4
4 6
5 7
6 10
7 25
i C
-------
0 0
1 1
2 -1
3 2
4 2
5 3
6 4
7 3
8 3
9 4
10 4
11 4
12 5
13 4
14 4
15 5
16 5
17 5
18 5
19 6
20 5
21 5
22 6
23 6
24 6
25 6
Solution
(Position) i S
------------------
6 10
5 7
3 4
2 3
1 1
Program ended with exit code: 0
My problem is that I can only output one solution, and that is the solution that needs the smaller values and goes up to 25, so when 25 is used it isn't in the solution. The C array in the code is a 2-D array, since I thought I could maybe do another backtrace while computing the first one? I couldn't figure out how to do so, so I left C[i][0] fixed to the first column, just to demonstrate a single solution. Any tips in the right direction would be greatly appreciated. I found a solution using Python, but the problem is solved recursively, which I don't think helps me, but that code is here.
Thanks for all the help in advance.
I did not fully understand your code. But here is a C code which finds all the subsets that sum to target.
#include <stdio.h>
int a[] = { 0, 1, 3, 4, 6, 7, 10, 25 }; //-- notice that the input array is zero indexed
int n = 7;
int target = 25;
int dp[8][26];
int solutions[1 << 7][8]; //-- notice that the number of subsets could be exponential in the length of the input array a.
int sz[1 << 7]; //-- sz[i] is the length of subset solutions[i]
int cnt = 0; //-- number of subsets
void copy(int srcIdx, int dstIdx){
int i;
for (i = 0; i < sz[srcIdx]; i++)
solutions[dstIdx][i] = solutions[srcIdx][i];
sz[dstIdx] = sz[srcIdx];
}
//-- i, and j are indices of dp array
//-- idx is the index of the current subset in the solution array
void buildSolutions(int i, int j, int idx){
if (i == 0 || j == 0) return; // no more elements to add to the current subset
if (dp[i - 1][j] && dp[i - 1][j - a[i]]){ // we have two branches
cnt++; // increase the number of total subsets
copy(idx, cnt); // copy the current subset to the new subset. The new subset does not include a[i]
buildSolutions(i - 1, j, cnt); //find the remaining elements of the new subset
solutions[idx][sz[idx]] = a[i]; // include a[i] in the current subset
sz[idx]++; // increase the size of the current subset
buildSolutions(i - 1, j - a[i], idx); // calculate the remaining of the current subset
}
else if (dp[i - 1][j - a[i]]){ // we only have one branch
solutions[idx][sz[idx]] = a[i]; // add a[i] to the current subset
sz[idx]++;
buildSolutions(i - 1, j - a[i], idx); // calculate the remaining of the current subset
}
else buildSolutions(i - 1, j, idx); // a[i] is not part of the current subset
}
int main(){
int i, j;
// initialize dp array to 0
for (i = 0; i <= n; i++)
for (j = 0; j <= target; j++) dp[i][j] = 0;
//-- filling the dp array
for (i = 0; i <= n; i++)
dp[i][0] = 1;
for (i = 1; i <= n; i++){
for (j = 1; j <= target; j++){
if (j < a[i])
dp[i][j] = dp[i - 1][j];
else
dp[i][j] = dp[i - 1][j] || dp[i - 1][j - a[i]];
}
}
//-- building all the solutions
for (i = 0; i < sizeof(sz); i++) sz[i] = 0; //-- initializing the sz array to 0
buildSolutions(n, target, 0);
//-- printing all the subsets
for (i = 0; i <= cnt; i++){
for (j = 0; j < sz[i]; j++){
printf("%d ", solutions[i][j]);
}
printf("\n");
}
}
If you have any questions about the code, do not hesitate to ask.