Program cannot pass test cases - c

There is a problem on Hacker Earth called Dhoom 4:
Samarpit is the main hero of the Dhoom 4. He is trying to steal from the Code Bank Of Hackers. Samarpit has a key with an integer value printed on it. He also has N other keys with each key having its own specific value. Samarpit is trying to break the Lock for which he is supposed to get to the lock's key value. He can perform one type of operation. Take his own key and one of the other N keys and merge them. During merging, Samarpit's Key value changes to the product of both the keys modulus 100000.
For example, if his key value were X and he took a key with value Y, his new key will be (X*Y)%100000.The other key that was used during the merging process remains along with the other N-1 keys.
This entire process of merging takes 1 second. Now, since he is in a hurry, he asks to you to find the minimum time in which he could reach to the lock's key value.
Input:
The first line contains 2 integers. They are Samarpit's Key value and the Lock's key value.
The second line contains N, indicating the number of other keys Samarpit has.
The third line contains N space-separated integers indicating the value of N other keys.
Output:
The minimum time required to get to the Lock's Key. If he is unable to reach that print -1.
Constraints:
1 ≤ N ≤ 1000
1 ≤ Value of all the keys ≤ 100000
My code is:
#include <stdio.h>
#include <time.h>
void main()
{
int i,f=0,n,skey,lkey,t=0;
long int a[1000],prod;
scanf("%d",&skey);
scanf("%d",&lkey);
prod=skey;
scanf("%d",&n);
if(n<=1000)
{
for(i=0;i<n;i++)
scanf("%ld",&a[i]);
if(skey==lkey)
printf("0");
else
{
for(i=0;i<n;i++)
{
if(a[i]<=100000L && lkey % a[i]==0)
{
prod=(a[i]*prod)%100000L;
t++;
if(prod==lkey)
{
f=1;
printf("%d",t);
break;
}
else
f=0;
}
}
}
}
if(f==0)
printf("-1");
}
My program is working for smaller inputs but not for large inputs like:
18023 15115
356
18121 1326 22175 6108 24870 5429 25714 8945 22404 19339 21602 31878 10196 `14252 7186 6020 15854 2140 6205 25226 32646 14294 6218 30002 21596 17190 18465 8855 32436 28884 27710 5396 22534 27330 9219 22350 17910 12119 9811 28276 31622 7645 11356 27077 23179 8744 32436 2899 2398 17273 22696 28167 4307 6818 5585 19686 5743 29546 24040 20370 1749 7474 17114 20 17538 11993 1311 19928 11962 16862 29256 16889 5314 26820 4568 18624 26960 25787 5205 13415 19008 24188 14495 23842 12424 9845 7040 608 23662 16422 9603 20813 20985 15563 2826 13468 31141 10555 4763 20869 14682 4880 5499 22025 6559 26888 28286 31869 19212 15019 19229 26694 8189 6958 4809 16354 20110 11160 22655 10280 3779 4131 2717 1232 26886 21733 21748 8757 18647 1455 26910 11354 10175 32054 8465 5931 25733 12144 12277 23558 6821 29505 21811 12410 3582 3927 17871 6735 32459 3667 16375 1222 31188 7721 31964 15137 30950 32457 29888 27750 26496 17407 10576 7265 24527 28311 27189 9704 13276 8390 18406 12899 5893 29125 10432 19083 31658 9407 13400 25713 31016 18157 2320 4802 19979 30976 28648 14666 21119 26559 663 27320 28424 14321 30683 21409 27507 27005 2573 22215 10765 30160 11256 16026 8978 11647 32747 10239 13416 6445 17677 2641 6541 25008 12017 165 8143 879 23402 14419 27323 20750 23201 10418 23767 2382 32100 30754 30868 1070 24001 12880 19838 15191 21972 13237 17846 12726 22749 28256 26530 32363 25237 27638 24547 32482 28867 12535 26503 29759 15114 25922 23168 4096 7429 26076 4693 13277 26262 9197 22808 26867 1658 29963 2200 21026 17185 14523 10711 7604 30141 30517 10431 14911 31642 23912 28688 21196 20909 14910 413 22072 3695 24865 24248 3547 11756 5566 21739 1896 25622 25865 745 22036 26976 3969 10691 28411 30088 26805 7775 9407 23732 20487 28455 1650 705 9904 4606 9654 6360 26372 11896 2082 22850 16631 22602 18408 13693 24545 19967 10165 10895 15742 4077 7641 12186 9785 25448 6824 29361 21162 5685 3616 22506 14941 5697 28876 28340 981 12691 21479 20843 13776 4736 15557 9002 3533 19486 20335 8161 8140 2811 3214 29351 9045`

I tried to solve this problem using Queue in java language and below is my code. It worked properly.
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
class Dhoom4 {
public static void main(String args[] ) throws Exception {
//Read input from stdin and provide input before running
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line = br.readLine();
String value[] = line.split(" ");
int Skey = Integer.parseInt(value[0]);
int Lkey = Integer.parseInt(value[1]);
line = br.readLine();
int N = Integer.parseInt(line);
int all_key[] = new int[N];
line = br.readLine();
String temp[] = line.split(" ");
int k=0;
for(String s : temp)
all_key[k++] = Integer.parseInt(s);
//actual code
Queue q = new LinkedList();
q.add(Skey);
//For getting answer
int ans[] = new int[100005];
for(int i=0;i<ans.length;i++)
ans[i] = -1;
ans[Skey] = 0;
while(!q.isEmpty()){
int x = (int) q.poll();
if(x==Lkey)
break;
for(int i=0;i<k;i++){
int y = all_key[i];
y = (y*x);
y = y%100000;
if( y>=0 )
{
if(ans[y]==-1){
ans[y] = ans[x]+1;
q.add(y);}
}
}
}
System.out.println(ans[Lkey]);
}
}

I'm sorry to say your approach is too simplistic. The 'modulus 100000' constraint makes this a hard problem that cannot be solved with a single loop.
You would have noticed this sooner if you would have tested your algorithm with more than just a few trivial numbers. Pick any two 4-digit numbers at random and multiply them; e.g.
1234 * 5678 = 7006652
Obviously, 1234 and 5678 are divisors of 7006652, but 1234 and 5678 are not divisors of 6652. In fact, it's a rare coincidence for successful keys to be divisors of the lock key (unless of course the product is less than 100000). So why the following line of code?
if (a[i]<=100000L && lkey % a[i]==0)
Notice the condition fails for both keys:
lkey % a[i] == 6652 % 1234 == 482 != 0
lkey % a[i] == 6652 % 5678 == 974 != 0
Neither key would be accepted (except for the one held by Samarpit; but not the other).
Try it in a debugger and you will see. Here is the input file:
1234 6652
1
5678
Bottom line is, your algorithm is not suitable to solve this problem; you will have to follow a totally different approach.
The most straightforward way is to generate all possible k-combinations of keys, starting with k = 1 and increase until you find a match. This may not be most efficient approach, but it works. Worry about optimizations later.

Related

C: Initialize variable to random # b/w 50 & 100 so they can be used in Switch statement if user selects an option that doesn't include entering values

So i'm very much a beginner and this is an assignment for class, but i'm not looking to have someone do the assignment for me or anything. Just help on a part i'm having trouble with.
I'm not posting my code as it's an ongoing assignment and I don't want someone to happen upon it and copy it ): But the gist of it is I need to display a menu to the user and create a switch statement. Each case has a corresponding function prototype that executes the choice the user made from the menu.
1 Enter 3 grades
2 Show average (with 3 grades) and letter grade
3 Show highest grade
4 Show lowest grade
5 Exit
I've done pretty much all of the assignment, but the one requirement I can't figure out is how to initialize the 3 grade variables to random numbers between 50 and 100, so if the user chooses menu options 2 3 or 4 first then those random #'s are what is used in my prototypes. But if the user chooses menu option 1, my functions should use the 3 values input by the user from that point until exit, or if they hit 1 again to input new values.
Since I couldnt figure it out I just had each prototype prompt the user to insert 3 grades then proceed to do its assigned task using those values.
We were also instructed to not use arrays as we havent gotten to that yet.
If no one is able to figure it out without seeing the code i'll wait until after the due date and post what I was able to do. i'm honestly just wanting to learn and my professor doesn't really post any videos or lectures (online class) so we just go off our textbook and good ol google.
Thank you to whoever can help(:
If you want a variable with a random standard value, initialize it with a random value. You can generate a random integer between two numbers using the random() function in the stdlib.h header.
Your code can be structured like this.
#include<stdlib.h>
#include<time.h>
int random_range(int start, int end) {
return start + (int) ((double) random() / RAND_MAX * (end - start));
}
int main() {
srandom(time());
int grade1 = random_range(50, 100);
int grade2 = random_range(50, 100);
int grade3 = random_range(50, 100);
...
}
Now the three grade variables are always initialized and can be used. I recommend, you also read the man page for the random() function.
Not a good idea, doing processing with some randomly assigned data simply to not do the work of controlling the user's options. Imagine that one option is to write the current record into persistent storage. Do you want to risk random valued records polluting the company's database? There are stories of "test versions" that have been released "into the wild" (on the day the coder was home with a cold, but management applied pressure to ship) that... well, that would curl your toes.
Here is a sketch whereby the user has two options only: enter the data or quit the program. Presuming valid data has been accepted, the menu features more options.
Do not process junk. It'll come back to bite you.
/* Usual header files */
int main() {
char buf[ 64 ];
int hiMenuOpt = 1;
do {
printf(
"Here's menu options\n"
"0: Quit\n"
"1: Enter data\n"
);
if( hiMenuOpt > 1 )
printf(
"2: Something\n"
"3: Something else\n"
"4: Something other\n"
);
printf( "Select 0-%d : ", hiMenuOpt );
fgets( buf, sizeof buf, stdin );
int val = strtol( buf, NULL, 10 ); // Edit fix. Thanks to Lundin
if( val < 0 || hiMenuOpt < val ) {
printf( "Bad entry\n" );
continue;
}
switch( val ) {
case 0:
hiMenuOpt = 0;
break;
case 1:
puts( "Hi from one\n" );
/* yadda yadda */
hiMenuOpt = 4;
break;
/* More stuff */
}
} while( hiMenuOpt );
return 0;
}
Here's menu options
0: Quit
1: Enter data
Select 0-1 : 1
Hi from one
Here's menu options
0: Quit
1: Enter data
2: Something
3: Something else
4: Something other
Select 0-4 :
Notice that Quit is now item 0. New menu items may be added, and old ones removed. The only constant is exiting the program. It makes sense, imo, to make that the first item on the list.

How to add up repetitive values from input in C?

i'm kinda new to C.
i am trying to make a shopping cart application program that reads data from a txt file that contains a product and a price, seperated by whitespace.
Then in a new line another product is put and a price(also seperated by whitespace).
then outputs the bill in another "bill.txt" text file.
example:
input taken from file (products.txt):
Bread 2.78
cheese 4.59
vegetables 1.99
bread 1.99
Milk 0.56
cheese 2.79
output written in another file(bill.txt):
bread : 4.77 , 2 products, average-price: 2.38
cheese: 7.38 , 2 products, average-price: 3.69
milk: 0.56 , 1 products, average-price: 0.56
vegetables: 1.99 , 1 products, average-price: 1.99
total : 14.70
my main problem is that i am confused about how to add up the sum of the repetitive products like bread from the text file and add them as a quantity instead! The bread is written twice in input but a qty of 2 is written instead.
usually in a language like java i would have used an ArrayList and solved it easily, but since C doesn't have Arraylists, what to do?
here is my code:
#include <stdio.h>
#include <stdlib.h>
int count;
struct Product
{
char productName[30];
double price;
};
struct Product p1;
int main()
{
double total = 0;
//input file
FILE *fp;
fp = fopen("products.txt","r");
//output file
FILE *fp1 = fopen("bill.txt","w");
if (fp == NULL || fp1 ==NULL)
{
perror("files didn't open");
}
printf("this input was written in file:\n");
while(1)
{
fscanf(fp,"%s %d",&p1.productName,&p1.price);
total = total + p1.price;
fprintf(fp1,"%s:\t%d, \n",p1.productName,p1.price);
printf("%s:\t%d, \n",p1.productName,p1.price);
if (feof(fp))
{
fprintf(fp1,"Total: %d",total);
break;
}
}
printf("total: %d", total);
return 0;
}
Any ideas?
You have to track a list of products and totals, otherwise you would have to iterate the input file multiple times to get total for each product in case the products order is mixed. You could add a total to your product struct, and add an int to track how many things are in list:
int itemsInList=0;
struct Product
{
char productName[30];
double price;
int count;
double total;
};
Without worrying about malloc/realloc at first you could use a static list of products.
struct Product prodList[100];
Write a function which will add an item to your list.
Something like this ...
Pseudocode here for you will have to fix up tolower, strcmp, strcpy bits.
And untested code, apologies if syntax/other errors!
addToList(struct Product p)
{
// google how to lowercase the product name
lowname = lowercase(p.productName); // use tolower from ctype.h
// search your list for product already
int i;
int found = 0;
for(i=0;i<itemsInList;i++)
{
if compare(prodList[itemsInList].productName,lowname) // use strcmp
{
// FOUND, add item to total, increment count, set found to true
prodList[itemsInList].total += p.price;
prodList[itemsInList].count++;
found = 1;
// we could allow loop to continue but for efficiency we end for loop now with break
break;
}
}
// if not found already add NEW entry to end of list
if (!found)
{
prodList[itemsInList].productName = lowname; // use strcpy or strncpy is safer
// add with correct total and count
prodList[itemsInList].total = p.price;
prodList[itemsInList].count = 1;
// and increment total items in list count
itemsInList++;
}
}
Google how to lowercase and compare and copy strings:
https://man7.org/linux/man-pages/man3/tolower.3.html
https://man7.org/linux/man-pages/man3/strcmp.3.html
https://man7.org/linux/man-pages/man3/strcpy.3.html
To finish write a function to iterate the list of products and print the bill.
void printBill(void)
{
// iterate list with for loop and print totals and counts
}
Exercise for the future, do it without using global variables to store array and use malloc/realloc to do dynamic memory allocation. Get it working using static array first though.
its correct that you don't have an ArrayList but you still have Arrays you can use
malloc(), realloc() and calloc()
plus, try to use 2 arrays 1 for the names and 1 for the sums, for example:
in
char** names - you can put the names of the product (lets say the the first one in there is bread)
double* sums - so here in the first one will be the sum of all breads.
malloc, realloc and calloc use RAM memory so be sure to
free()
them when you done with them.
I'am not a c programmer but I am a dart programmer (dart is a language with c syntax) so :
Map shoppingList = {
"bread" : 2.45,
"butter" : 2.35,
};
void calculateShoppingList(Map shoppingList) {
int output = 1;
for (auto const& [String key,Int val] : shoppingList) {
output = output + val
}
return output
}
calculateShoppingList(shoppingList)

Why my c program only produce zero answer while using for loop?

I tried to use for loop calculate the number of books keyed in and sum up their total price, but at the end i only get zero price in C program. What is my problem ? How to solve it?
#include<stdio.h>
int main(void)
{
int booknum;
float bookfee,bookgst,nogst,totfee,newfee,newfee_nogst;
bookgst=0.0;
nogst=0.0;
int cnt;
char code;
printf("Key in total books purchased >> ");
scanf("%d",&booknum);
for(cnt=1;cnt<=booknum;cnt++)
{
printf("\n\n");
printf("Key in price of the book >> ");
scanf("%f",&bookfee);
printf("Key in type( S=standard gst,Z=zero gst) \n>> ");
scanf("%c",&code);
getchar();
if(code=='S')
{
newfee=bookfee+0.6;
}
else if(code=='Z')
{
newfee_nogst=bookfee;
}
bookgst=bookgst+newfee;
nogst=nogst+newfee_nogst;
printf("\n");
}
totfee=bookgst+nogst;
printf("Book purchased with GST : RM %.2f\n",bookgst);
printf("Book purchased without GST : RM %.2f\n",nogst);
printf("Total payment : RM %.2f\n",totfee);
return 0;
}
There are a few problems with this code, but you're almost there!
First code reading needs to eat the previous \n (see this), otherwise the code is neither Z not S (it's a newline), and that's why the fees are never added.
(Search also for "fgets vs scanf" to see how to use the safer fgets).
scanf(" %c",&code);
then these lines
bookgst=bookgst+newfee;
nogst=nogst+newfee_nogst;
add the newfee / newfee_nogst ; these variables are set to 0 before the loop, but at the next occurence, they're still set to the value of the previous occurrence, thus either set them to 0 at the beginning of the loop, or, add the value directly in the if (see below). And since we're here, print an error if the code is wrong (and maybe subtract one to cnt to do one more loop with a correct code, in this case).
Also, the GST calculation is probably wrong, 6% of x is 0.06 * x, and if you want GST added to the value that's x * 1.06
if(code=='S')
{
bookgst = bookgst + bookfee*1.06; // or bookgst += bookfee*1.06
}
else if(code=='Z')
{
nogst = nogst + bookfee; // or nogst += bookfee
}
else {
printf("Code not understood\n");
}

Connect 4 game in C

For a small project we need to make a connect four game. Our project is broken up into several parts with each week we are assigned a different part to work on.
This week we have to make up the work on the columns by this I mean we have to use a function is called get_column, and use this to read a valid column number from the user where the next piece will be played.
So we were supplied the following files connect4.h (File used to store functions), week8_object.o (ignore the name its just the current week of sem), and week8.c which is the file I am currently editing.
Note 1: The comment in the code is what the lecturer wrote for us as a note.
When I am compiling I get an error saying undeclared identifier for the if(column_full(board, col)==FALSE) statement (FALSE part). I thought this was declared in the .h file?
EDIT- After some googling I have found that people silence that error by having this in the header. Is it correct to have this in coherence with the .h file?:
#include <stdio.h>
#include "connect4.h"
#define FALSE 0
#define TRUE 1
/* get_move
Prompts the user to enter a column, then checks that
- the column is in the valid range (1-COLS)
- that the column is not full (use function column_full to check)
If an invalid column is entered, the user is reprompted until it is valid
Returns the column number between 1 and COLS
*/
int column_full ( int board[COLS][ROWS], int col ) { return TRUE;}
int get_move ( int board[COLS][ROWS] ){
int col;
printf("Please enter a column number:");
scanf("%d",&col);
if(col>=1 && col<=COLS){
if(column_full(board, col)==FALSE){
printf("You have placed a token in the %d column\n",col);
}
else{
printf("That column is full");
}
}
while(col<=0 || col>COLS){
printf("Your token has not been placed");
printf("Please enter a valid column: ");
scanf("%d",&col);
}
return(col);
}
Header file:
#ifndef CONNECT4_H
#define CONNEXT4_H 1
#define ROWS 6
#define COLS 7
// displays the board to the screen
int display_board ( int[COLS][ROWS] ) ;
// sets up the board to an empty state
int setup_board ( int[COLS][ROWS] ) ;
// Returns TRUE if the specified column in the board is completely full
// FALSE otherwise
// col should be between 1 and COLS
int column_full ( int[COLS][ROWS], int col ) ;
// prompts the user to enter a move, and checks that it is valid
// for the supplied board and board size
// Returns the column that the user has entered, once it is valid (1-COLS)
int get_move ( int[COLS][ROWS] ) ;
// adds a token of the given value (1 or 2) to the board at the
// given column (col between 1 and COLS inclusive)
// Returns 0 if successful, -1 otherwise
int add_move ( int b[COLS][ROWS], int col, int colour ) ;
// determines who (if anybody) has won. Returns the player id of the
// winner, otherwise 0
int winner ( int[COLS][ROWS] ) ;
// determines if the board is completely full or not
int board_full ( int[COLS][ROWS] ) ;
#endif
There are few issues in your code:
In get_move() function, the given condition "If an invalid column is entered, the user is reprompted until it is valid" is not been taken care. You might want to use while loop in case of invalid column entered.
column_full() in your code is called without parameters. This function takes two parameters (refer to you .h file). So, don't forget to add them in call.
You have to use return(col) to take care of "Returns the column number between 1 and COLS"
I don't want to write a code for you. It would be helpful for you in long run, if you code yourself.
Now, to answer your question:
It is perfectly fine to have nested if-else statements.
From your original code:
}; /* <<-- problem 1 */
else() {
/* ^^^^ <<-- problem 2 */
printf("That column is full");
}
Remove these and your code will compile. I won't discuss the logic issues.
So in diff notation:
--- connect4.c.orig 2015-09-19 14:34:36.743337010 -0400
+++ connect4.c 2015-09-19 14:34:23.488222720 -0400
## -24,9 +24,9 ##
if(col>=1 && col<=COLS){
if(column_full(board, col)==FALSE){
- printf("You have placed a token in the %d column\n",col);
+ printf("You have placed a token in the %d column\n",col);
}
- else(){
+ else{
printf("That column is full");
}
}

Please anybody check my code to see what's wrong with it

#include <stdio.h>
int getAvg(int a, int b, int c);
int main()
{
int a,b,c;
int i;
int avg[5];
char name[5][10] ;
int korean[5], english[5], maths[5] ;
char message[2][10] = {"Pass","No Pass"};
for ( i = 0; i < 5; i++ )
{
printf("Enter your marks <name,korean,english,maths \n");
scanf("%s%d%d%d",name[i],&korean[i],&english[i],&maths[i]);
}
for (i = 0; i < 5; i++)
{
printf("name:%s, korean:%d, english:%d, maths:%d, average:%d",name[i],korean[i],english[i],maths[i],avg[i]);
avg[i] = getAvg(a,b,c);
if (avg[i]>60)
{
printf("==%s",message[0]);
}
else
{
printf("==%s",message[1]);
}
}
int getAvg(int a, int b, int c)
{
int avg;
avg = (a+b+c)/3;
return avg;
}
}
I want to print like this
Enter your marks <name,korean,english,maths>
kim 10 50 60
Enter your marks <name,korean,english,maths>
hanna 50 60 70
Enter your marks <name,korean,english,maths>
lee 80 70 60
Enter your marks <name,korean,english,maths>
lori 70 80 90
Enter your marks <name,korean,english,maths>
kang 60 70 80
name:kim,korean:10,english:50,maths:60,average:40 == no pass
name:hanna,korean:50,english:60,maths:70,average:60 == no pass
name:lee,korean:80,english:70,maths:60,average:70 == pass
name:lori,korean:70,english:80,maths:90,average:80 == pass
name:kang,korean:60,english:70,maths:80,average:70 == pass
I'm really sorry if it turns out to be my mistakes or the question is too elementary.. it's due in 5 hours and i couldn't figure out what's wrong.. it keeps telling me that the getAve function is undefined reference and i see nothing wrong with it.. please anybody kindly help me? :(
Your getAvg is inside main. Move it out (or, equivalently, move one outer brace from end of your code to just above getAvg definition start). There is also something wrong with the calculation of averages, but that's a logical error, not a syntactic one. (Specifically, you're calculating the average of a, b and c - check where you define the value of those variables, and you're printing stuff before you calculate it).
You get "undefined reference to getAvg function" because you did not close main before defining the getAvg function. Just move the last } before the function definition and that error should be gone !
Then,You call the function like this
avg[i] = getAvg(a,b,c);
But a,b and c are uninitialized ! So you need
a=korean[i];
b=english[i];
c=maths[i];
Before it. You also print avg[i] before you calculate it. So, move the printf after the function call to get the desired results.
After fixing your brace positioning, also there is a problem here:
printf("name:%s, korean:%d, english:%d, maths:%d, average:%d",name[i],korean[i],english[i],maths[i],avg[i]);
avg[i] = getAvg(a,b,c);
You have to calculate the average before you display it. Also, a, b, c are uninitialized variables. You probably meant:
avg[i] = getAvg( korean[i], english[i], maths[i] );
printf("name:%s, korean:%d, english:%d, maths:%d, average:%d",
name[i], korean[i], english[i], maths[i], avg[i]);
first you put getAvg(...) outside of main()
now call getAvg(...) before printing avg[i];
avg[i] = getAvg(korean[i],english[i],maths[i]);
printf("name:%s, korean:%d, english:%d, maths:%d, average:%d",name[i],korean[i],english[i],maths[i],avg[i]);

Resources