C program to check lottery numbers: why some tests fail? - c

This program takes as an input the following lines:
23 12 33 19 10 8
5
23 19 8 12 60 18
14 60 12 44 54 10
8 3 12 19 33 10
33 15 7 60 12 10
22 12 19 23 33 11
23 12 33 19 10 8 ( The first line ) are the lottery results.
n ( in this specific case, 5 ) informs how many lines will follow below.
Each line has 6 numbers. The number order doesn't matter.
The rules are: numbers range from 1 to 60 ( including 1 and 60 ) and they never repeat themselves in the same line.
The variable "quadra" stores how many lines have got 4 numbers right.
The variable "quina" stores how many lines have got 5 numbers right.
The variable "sena" stores how many lines have got 6 numbers right.
So, a computer program is running some tests over my code below and it's claiming that it goes wrong for most of them, but I can't see what's the problem here. Does anybody have a clue? Is this code wrong, or is there something wrong with the software that's testing this code?
#include <stdio.h>
int main(){
int mega[6];
int v[50500][6];
int n,swap;
int i,j,k; //counters
int quadra,quina,sena;
quadra = 0;
quina = 0;
sena = 0;
for(i=0;i<6;++i) scanf("%i",&mega[i]); //first line, lottery results
scanf("%i",&n);
for(i=0;i<n;++i){
for(j=0;j<6;++j){
scanf("%i",&v[i][j]);
}
}
for(i=0;i<n;++i){
for(j=0;j<6;++j){
for(k=0;k<6;++k){
if(v[i][j] == mega[k]){
v[i][j] = 61;
}
}
}
}
//reverse bubble sort
for(i=0;i<n;++i){
for(j=0;j<6;++j){
for(k=j+1;k<6;++k){
if(v[i][j] < v[i][k]){
swap = v[i][k];
v[i][k] = v[i][j];
v[i][j] = swap;
}
}
}
}
for(i=0;i<n;++i){
for(j=0;v[i][j] == 61 && j<6;++j);
if(j == 4) ++quadra;
else if(j == 5) ++quina;
else if(j == 6) ++sena;
}
return 0;
}

Your code is true, I understood and tried the flow of it. Looks fine but if you dont need to sort everyline (and use j as a counter in this loop for(j=0;v[i][j] == 61 && j<6;++j); ), you can use simpler ifstatements to compare real lottery results with the ones that entered. What I mean is that your algorithm is a little complex. Try a simple one and see how it works.

Yes, there are a couple of noteworthy issues with your code:
Compile time indicates possibility of uninitialized variable:
But, run-time results in fatal run-time at unknown source location. Stack overflow. It is likely due to this line:
int v[50500][6];
Increase your stack size. It needs to be about 2.5Mbytes for v alone.
Also, this line may not be what you intended:
for(i=0;i<6;++i) scanf("%i",&mega[i]); //first line, lottery results
^
If you meant to loop around the remainder of the code, remove the ; after the for() statement, and use curly braces:
for(i=0;i<6;++i) scanf("%i",&mega[i]) //first line, lottery results
{
scanf("%i",&n);
....

Related

I am trying to set a value to an array, but I can't seem to figure out why what I did on line 31 is wrong

I have a data file in the format <0:00> - <19321> , <1:00> - <19324>, up to <24:00> - <19648>, so for every hour there is the total power used so far(the total is incremented), I am supposed to calculate the power used, find the average, and the highest usage of power and its index(time), (I don't need help with finding the max power used at its time index). I traced the problem down to line 31, but I don't understand why what I did was wrong. Can someone explain to me why the code in line 31 isn't saving the value of power used into the array? And how I can fix it? Thanks in advance!
float compute_usage(int num, int vals[], int use[], int *hi_idx)
15 {
16 int i;// i is a general counter for all for loops
17 int r1, r2, u, v, pow_dif, temp;//for loop 1
18 int tot;//for loop 2
19 int max_use, init, fina, diff;//for loop 3 //don't have to worry about this for loop, I am good here
20 float avg;//average power used
21
22 for(r1=r2=i=u=v=0;i<num;i++)//for loop 1
23 {
24 r1= vals[v++];//I set values of every hour as reading 1 & 2(later)
25 #ifdef DEBUG
26 printf("pre-debug: use is %d\n", use[u]);
27 #endif
28 if(r1!=0 && r2!=0)
29 {
30 pow_dif = (r1 - r2);//I take the to readings, and calculate the difference, that difference is the power used in the interval between a time period
31 use[u++] = pow_dif; //I'm suppose to save the power used in the interval in an array here
32 }
33 r2=r1;//the first reading becomes the second after the if statement, this way I always have 2 readings to calculate the power used int the interval
34 #ifdef DEBUG
35 printf("for1-debug3: pow_dif is %d\n", pow_dif);
36 printf("for1-debug4: (%d,%d) \n", u, use[u]);
37 #endif
38
39 }
40 for(tot=i=u=0;i<num;i++)//for loop 2
41 {tot = tot + use[u++];}
42
43 avg = tot/(num-1);
44 #ifdef DEBUG
45 printf("for2-debug1: the tot is %d\n", tot);
46 printf("for2-debug2: avg power usage is %f\n", avg);
47 #endif
Just to understand, how did you figure out that the code in line 31 is problematic? Is it the printf statement in line 36?
When you do this:
use[u++] = pow_dif; //I'm suppose to save the power used in the interval in an array here
printf("for1-debug4: (%d,%d) \n", u, use[u]);
The "u" variable in printf statement is incremented in the previous operation (u++), so you are looking past the element you changed.
use[u++] = pow_dif; //I.e. u=0 here, but u=1 after this is executed.
printf("...\n", u=1, use[1]);
What is the "i" for in this loop? Why don't you try "u++" in the for statement instead of "i++" and remove the "u++" in the use assignment expression?

Incorrect output with counting and tallying bits in C

This is only my 2nd programming class. There are 30 rooms. We have to see what is in each room and tally it. I already used the for loop to go through the 30 rooms and I know I have tried to use a bit counter to see what is in each room. I am not getting the correct sample output after I redirect the sample output. When I printf("%d", itemCnt[loc]);, my output is 774778414trolls
When I printf("%d", itemCnt[0]);, my output is 0trolls. I'm just trying to get one output right so I can figure out how to get the rest of the 8 outputs. From the sample output, the first number is supposed to be 6, followed by 6, 1, 4, 4 ... and so on. Below are sample inputs/outputs and what I have so far in code.
Sample input:
1 20 ##
2 21 #A
3 22 ##
4 23 #1
5 22 ##
6 22 ##
7 22 ##
8 22 ##
9 23 #Z Here be trolls � not!
10 23 #+
12 23 ##
13 24 ##
11 22 ##
14 22 #2
15 21 #1
16 20 ##
17 19 ##
18 20 ##
19 19 ##
20 18 ##
21 17 #*
22 16 #*
23 15 #%
0 14 #7
0 gold_bar
1 silver_bar
2 diamond
3 copper_ring
4 jumpy_troll
5 air
6 angry_troll
7 plutonium_troll
Sample Output:
6 gold_bar
6 silver_bar
1 diamond
4 copper_ring
4 jumpy_troll
8 air
15 angry_troll
0 plutonium_troll
code
int main()
{
// contains x and y coordinate
int first, second;
char third[100];
char fourth[100];
char Map[30][30];
// map initialization
for(int x=0; x<30; x++){
for(int y=0; y<30; y++){
Map[x][y] = '.';
}
}
while(scanf("%d %d %s",&first, &second, third) != -1) {
// Condition 1: a zero coordinate
if (first==0 || second==0) exit(0);
// Condition 2: coordinate out of range
if (first<0 || first>30 || second<0 || second>30){
printf("Error: out of range 0-30!\n");
exit(1);
}
Map[second-1][first-1] = third[1];
fgets(fourth, 100, stdin);
// bit counter
int itemCnt[8] = {0}; // array to hold count of items, index is item type
unsigned char test; // holds contents of room.
int loc;
for(loc = 0; loc < 8; loc++) // loop over every bit and see if it is set
{
unsigned char bitPos = 1 << loc; // generate a bit-mask
if((test & bitPos) == bitPos)
++itemCnt[loc];
}
// print the map
for(int h=0; h<30; h++){
for(int v=0; v<30; v++){
printf("%c", Map[h][v]);
}
printf("\n");
}
// print values
printf("%d", itemCnt[0]);
}
return 0;
}
test is not initialized. It looks like you intended to assign 'third[1]' to test.
Also, 774778414 = 0x2E2E2E2E in hex, and 0x2E is the numeric value of ASCII '.', your initial value for map locations. (Tip: when you see wild decimals like that, try Google. I entered, "774778414 in hex" without the quotes.)
I would also suggest breaking down the code into two functions: the first reads from stdin to populate Map (like you do), and the second reads from stdin to populate 8 C strings to describe your objects. It's important to note, the first loop should not go until end of input, because your posted input continues with descriptions, not strictly 3 fields like the beginning.

What is a fast way to compare a big list of pairs of integers?

Thing is, we have N pairs of integers, as an example:
23 65
45 66
22 65
80 20
30 11
11 20
We say one pair is bigger than another one if both numbers from one pair are greater than the other two, or if the first number is equal and the other one is bigger, or vice-versa. Otherwise, if you can't compare them that way, then you can't establish which one is bigger.
The idea is to know, for each pair, how many pairs it is bigger to (in the example, the first pair is bigger than the third and the last one, therefore the answer for the first is 2).
The trivial solution would be O(n2), which is simply comparing every pair to every other one and adding one to a counter for each positive match.
Can anybody come up with a faster idea?
I have implemented the simple solution (N2), works reading from "sumos.in":
#include <iostream>
#include <fstream>
#define forn(i, x, N) for(i=x; i<N; i++)
using namespace std;
ifstream fin("sumos.in");
ofstream fout("sumos.out");
struct sumo{
int peso, altura;
};
bool operator < (sumo A, sumo B) {
if( A.altura == B.altura )
if( A.peso < B.peso )
return true;
else
return false;
else
if( A.peso == B.peso )
if( A.altura < B.altura )
return true;
else
return false;
else
if( (A.altura < B.altura) && (A.peso < B.peso) )
return true;
else
return false;
}
int L;
sumo T[100000];
int C[100000];
int main()
{
int i, j;
fin >> L;
forn(i, 0, L)
fin >> T[i].peso >> T[i].altura;
forn(i, 0, L)
forn(j, 0, L)
if( j!=i )
if( T[j]<T[i] )
C[i]++;
forn(i, 0, L)
fout << C[i] << endl;
return 0;
}
Example of input:
10
300 1500
320 1500
299 1580
330 1690
330 1540
339 1500
298 1700
344 1570
276 1678
289 1499
Outputs:
1
2
1
6
3
3
2
5
0
0
I solved this problem by using a segment tree. If you wish to see the implementation: http://pastebin.com/Q3AEF1WY
I think I came up with a solution to this but it is rather complex. The basic idea is that there are these groups where the pairs can be arranged in dominated order for example:
11 20 30 11
22 65 80 20
23 65
45 65
If you start thinking about taking your pairs and trying to create these groupings you realize you will end up with a tree structure. For example imagine we added the pair 81 19 to the list and add a pair (-∞, -∞)
(-∞, -∞)
/ \
11 20 30 11 ---\
22 65 80 20 81 19
23 65
45 65
If you follow the path from a node to the root you will count how many pairs the current pair dominates. From this example it kind of looks like you can use binary search to figure out where to insert a pair into the structure. This is where the complexity troubles start. You can't do a binary search/insertion on a linked list. However there is a very neat data structure called a skip list you might use. You can basically search and insert in O(logn) time.
There's still one problem. What if there are tons of these groupings? Imagine a list like
11 20
12 19
13 18
14 17
You're tree structure will look like:
(-∞, -∞)
/ / \ \
11 20 12 19 13 18 14 17
Again use skip lists to order these nodes. I think this will require two different kinds of nodes in the tree, a horizontal type like above and a vertical type like in the first examples. When you are done constructing the tree, do a iterate the tree with DFS while recording the current depth to associate each pair with the number of nodes it dominates.
If the above algorithm is correct you could insert a the pair into the tree in O(logn) time and thus all the pairs in O(nlogn) time. The DFS part will take O(n) time thus constructing the tree and associating a pair with the number it dominates will take O(nlogn) time. You can sort the pairs based on the number of dominations in O(nlogn) time so the whole process will take O(nlogn) time.
Again there is probably a simpler way to do this. Good luck!
You can use. A sort. like this
int z = {23,65,45, 66,22,65,80,20,30,11,11, 20};
int i, j, k, tmp;
for (i=1; i<n; i++){
j= n-i-1;
for (k=0; k<=j; k++)
//Put attention on this block.
if (z[k]>z[k+1]){
tmp= z[k];
z[k]= z[k+1];
z[k+1]= tmp;
}
}

Arrays and for loops trouble

I am doing an array exercise and I almost finished it.I have trouble finishing the last part.I create two arrays that store coursework points and exam points and then using a third array I calculate the module result(it is determined by both exam and coursework points). I got this part working and assuming I have 5 modules the output is 5 numbers.However I want to calculate my stage mark so if I have 5 modules I get their marks,add them together and then divide them by 5.Here is my problem I am using for loop because that is the only way it will work(as far as I know) so given that I already have my module result I use this for loop to calculate the stage result:
for(int i = 0; i < module_result.length; i++)
{
sum = sum + module_result[i];
System.out.println(sum/5);
}
I saw in this site similar question and I used the code in the answers.I can use enhanced for loop as well.
So given that coursework array={45,70,60,55,80} and exam array={83,72,45,25,89} my module results are 64,71,60,87. By using the above for loop I get anticipated outcome:
10
22
32
37
52
So I get my result. It is 52. But I don't want the rest of the numbers.
My question is how can I get just that number(52). I guess it is not possible by using for loop because it will inevitably is going to loop 5 times not one. I thought about using while loop but I don't see how I will get much different outcome.
I'm not sure if I totally understand the question, but I think this is what you're going for:
for(int i = 0; i < module_result.length; i++)
{
sum = sum + module_result[i];
}
System.out.println(sum/5);
All you have to do is simply move the println statement outside of the loop (if I understand the question correctly).
If you just want to print out the last number, just do a condition in the for loop that would print out at the index just before the length like this:
for (int i = 0; i < module_result.length; i++) {
if (i == module_result.length - 1) {
// print results
}
else {
// Do calculations
}
}
OK here is my code.
public int[] computeResult(int []courseWork,int[] examMarks ){
int[] module_result = new int[6];
for(int i=0;i<module_result.length;i++){//CALCULATE EACH MODULE
module_result[i]= ((courseWork[i] * cw[i]) + (examMarks[i] * (100 - cw[i]))) / 100;//THIS LINE IS SIMPLY A CONDITION HOW TO CALCULATE A MODULE YOU DON'T NEED TO KNOW WHAT IS HAPPENING INSIDE
}
int sum = 0;
for(int i = 0; i < module_result.length; i++)//USE THIS FOR LOOP TO ADD THE MODULES TOGETHER.
{
sum = sum + module_result[i];
// Add this extra line
// This allows you to only print out the value when you reach the end
if (i == module_result.length - 1) {
System.out.println(sum/6);
}
}
return module_result;
}
However here is what happens-the first for loop calculate the module results.Say they are as follows in the output console:
64
71
60
31
87
33
Next the second for loop is adding them together-first is 64,next loop at 71 to 64 and you get 135,next add to 135 the next module result 60 and so on until I get the total sum of all 6 modules which is just in this example 346 and then divide it by 6 to get my stage result.So I need in my output console just 346/6.Nothing else no zeros no nothing.
What my current code does is this-the second loop star running,it already knows my module results(they have been calculated) and so it starts- the first one is 64,divide it by 6 I get outcome 10,then the loop add 71 to 64 get 135 and divide it by 6 and so on until it reaches the number 346 and divide it by 6.So I get this output:
10
22
32
37
52
57
I don't need 10,22,32,37 and 52 they hold no meaning.I just need 57.What your solution will give me is this outcome:
0
0
0
0
0
57
It still gives unnecessary numbers.

Find the longest sequence of ascending numbers in unsorted array

Suppose the Array[10] = {10,6,11,9,-18,0,91,18,24,32}
The largest sequence will be 10,11,18,24,32 or -18,0,18,24,32
The solution to this is make another Array[10] which will store the number of sequences. Starting from the last element 32 which makes just 1 sequence i.e. the number itself.
24 makes 2
18 makes 3
91 makes 1
0 makes 4
-18 makes 5
9 makes 4
11 makes 4
6 makes 4
10 makes 5
The output should be either 5 starting from -18 or 5 starting from 10.
Can anyone help me with the code please.
more or less it will look like that, now you need to translate this to language what you are using
largestSequience = [];
temporaryArray = [];
for (element in array)
{
if (temporatySize not empty and temporarySize[lastElement]>=element)
{
if (temporaryArray.length > largestSequence.length) largestSequence = temporaryArray;
temporaryArray = [element]
}
temporaryArray.add(element)
}
What you want in C++. The running time is O(NlogN), in which N is the size of Array[]
#include<stdio.h>
#include<map>
using namespace std;
int main(void) {
int Array[10] = {10,6,11,9,-18,0,91,18,24,32};
int p[10],next[10];
int i,j,n=10;
map<int,int> places;
for(i=n;i>=0;i--){
map<int,int>::iterator ii=places.upper_bound(Array[i]);
if(ii==places.end()){ //no item on the right is larger
p[i]=1;
next[i]=-1;
}else{
next[i]=ii->second;
p[i]=p[ii->second]+1;
}
places[Array[i]]=i;
ii=places.find(Array[i]);
while(ii!=places.begin()){
ii--;
if(p[ii->second]<=p[i]){
places.erase(ii);
}else
break;
ii=places.find(Array[i]);
}
}
int longestI=0;
for(i=1;i<n;i++){
if(p[i]>p[longestI])
longestI=i;
}
for(i=longestI;i>=0;i=next[i]){
printf("%d\n",Array[i]);
}
return 0;
}

Resources