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 6 years ago.
Improve this question
Task is to read some random line (odd or even, I'll specify it) from txt file, and user just writes absolutely the same, and if it is correct (the same) program'll print success. Problem is that I don't know how to read only odd or only even line# and it should be randomly generated as well (such odd or even number). Thanks
The usual way to loop and ignore the even items is...
for( int i = 0; thing = get_thing(); i++ ) {
/* It's even, skip it */
if( abs(i % 2) == 0 )
continue;
...do stuff with thing...
}
abs(i % 2) == 0 checks for even numbers, abs(i % 2) == 1 checks for odd. If you want to select one or the other, use int parity and abs(i % 2) == parity.
Efficiently selecting a random line out of a file takes a small amount of math. You must read the file once, because it's impossible to know where lines start and end otherwise.
An inefficient algorithm would read in all N lines then pick one, potentially consuming a lot of memory. A more efficient algorithm would just store where each line starts. Both are O(n) memory (meaning memory usage grows as the file size grows). But there's an O(1) memory algorithm which only has to store one line.
Each line has a 1/N chance it will be selected. The efficient algorithm applies this to each line as it's read in but N is the number of lines read so far. In pseudo-code...
int num_lines = 0;
char *picked_line = NULL;
while( line = getline() ) {
num_lines++;
if( roll(num_lines) == num_lines ) {
picked_line = line;
}
}
So the first line has a 1/1 chance of being selected. The second line has a 1/2 chance of being selected. The third has a 1/3 chance, and so on.
Why does this add up to each line having a 1/N chance? Well, let's walk through the first line being selected out of three.
1st line has a 1/1 chance.
It is picked. The 1st line's total odds are now 1.
2nd line has a 1/2 chance.
1st line, the picked one, has a 1/2 chance of surviving.
1st line's odds of being picked are now 1 * 1/2 or 1/2.
3rd line has a 1/3 chance.
1st line, the picked one, has a 2/3 chance of surviving.
1st line's odds of being picked are now 1 * 1/2 * 2/3 or 2/6 or 1/3.
You can do the same for the 2nd line and 3rd lines to prove to yourself this works.
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I have an exercise (please take a look at picture):
Problem
The problem:
You input any number (number is integer) then the program will find numbers in binary tree has 4 levels. The top is your number you input, and the pair of 2 numbers at lower level will be added together and 2 times the parent number above. And the numbers must be used only once.
Here my code, but it still doesn't work properly. Please figure out for me what is my mistake here.
#include <stdio.h>
#include <stdbool.h>
#define MAX 15
int data[MAX]; // binary tree with 4 levels
void init_Data(){
int i=0;
for(i=0; i<=MAX; i++){
data[i] = -1;
}
}
void BackTracking(int index){
int c1, c2; // c1 and c2 are a pair that is added and equal 2 times the parent number
for(c1=1; c1<data[index]; c1++){
c2 = 2*data[index] - c1;
if(!Search(c1) && !Search(c2)){ // checking c1 and c2 is used or not
data[2*index+1] = c1; // put c1 into data
data[2*index+2] = c2; // put c2 into data
if(index == MAX/2) // the stop condition
print_Data(); // print out
else
BackTracking(index+1);
}
}
}
bool Search(int number){
int i=0;
for(i=0; i<MAX; i++){
if(number == data[i])
return true;
}
return false;
}
int main(int argc, char const *argv[]) {
int n = 0;
init_Data();
printf("Enter your number: ");
scanf("%d\n", &n);
data[0] = n;
BackTracking(0);
return 0;
}
I've got working code for this exercise, but since it is an exercise, I'll just give some primers.
How do you solve the problem? One way to find a valid configuration (of Sudoku grids, of eight non-attacking queens on a chess board or of numbers in a tree) is backtracking: You prober various possible solutions and when you find that it is invalid, you revert to a previous partial solution that is still valid.
One way to implement backtracking is to use recursion, where each step in the solution (put a number in the Sudoku grid, placing a queen, assigning a pait of numbers in your problem) is one level of recursion. Backracking then means to return to previous levels in the recursion.
How do you represent the tree? Your picture shows a binary tree. You can represent such a tree as a linear array:
0
1 2
3 4 5 6
7 8 9 10 11 12 13 14 15
For a node with the array index i, you get:
parent(i) == (i - 1) / 2
left(i) == 2*i + 1
right(i) == 2*i + 2
You need the array to print the solution once you have found it.
How do you traverse the tree? There are many ways to traverse a tree. Here, you can use many ways as long as you have assigned a value to the parent node before visiting it.
In your case, the easiest way is to do a level-wise iteration that follows the linear array. You can use the fact that the two numbers you need to find for each parant node are adjacent. Start with index i = 1 and if you can find two valid numbers, advace to i + 2.
That way to iterate also provides a nice terminating condition: When you reach the fifth level, you have found a valid solution.
How do you find out whether a number has been used? The straightforward solution is to look at all numbers up to the current index. This method will become slow the deeper you go in your tree, though. (But that shouldn't be a concern for a tree of 4 levels.)
If you choose your numbers such that the smaller number if always to the right, you have a binary search tree. You can use that to find whether a number has been used in (O log n), that is you have to visit each level of the tree once instead of visiting each node once.
There are other ways to keep track of which numbers have been used like bit sets or hashes, but these have to be implemented in C.
Edit: You've got the basics of the code right, but:
The termination criterion should be checked for the next step, so index + 1 == MAX/2. Alternatively, you can check index before (and instead of) entering the loop. (I prefer the latter, because it puts the termination criterion at the top of the function, but the former is closer to your existing code.)
In Search, you check the whole range of elements. That's okay, because the unused elements are −1. There is one problem, though: You don't reset the used elements, so that the check is against values from solutions that you have backtracked from. You can reset these values to −1 before backtracking. A better approach might be to check only the values that you have already entered. (Not resetting the values means that you will find fewer solutions. The first value for which there are solutions is 8, but without resetting, it won't find a solution here.)
Currently, you print all solutions. (Well, all solutions for which the left bracnch has the smaller number.) Depending on the value, there will be a lot of solutions. If you just want to print one solution, you can stop backtracking short by returning early.
You should provide prototypes of the functions before you use them, so that the compiler can make sure you are passing the correct arguments.
Here's a corrected version:
void BackTracking(int index){
int c1, c2;
for(c1=1; c1<data[index]; c1++){
c2 = 2*data[index] - c1;
if(!Search(c1) && !Search(c2)){
data[2*index+1] = c1;
data[2*index+2] = c2;
if(index + 1 == MAX/2)
print_Data();
else
BackTracking(index+1);
data[2*index+1] = -1;
data[2*index+2] = -1;
}
}
}
I think you can solve it using dynamic programming, if you do not care about number of computations, then you can also use combination algorithms.
your input = 10
for first level there could be X possible pair of numbers {n1,n2} = 2*10
for each of the pairs above pick one and use recursion to check further
run(input,tree)
for n1 from 0 to input:
for n2 from n1+1 to input:
if n1+n2 = 2*input:
pairs.add(n,input-n)
//if no pairs staisfy our condition
if pairs ==null:
return false
//check each pair
foreach pair in pairs:
run(pair.numbers, tree)
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I'm trying to complete a sudoku solution checker program in c. I'm still trying to understand the steps in building this program before I start coding it. I found this example online http://practicecprogram.blogspot.com/2014/10/c-program-to-find-out-if-solved-sudoku.html
There are a few questions I still don't understand.
1 For my program I am given a text file with the first number being a number that says how many sets of sudoku solutions it contains. I am almost understanding how to check just one solution but having to do it for N solutions and making the program work for multiple sudoku solutions confuses me. Especially in making my 2d arrays for the values. My ouput is supposed to only be Yes or No on a new line for however many N sets.
2 Is checking that all rows and columns have sums of 45 and that the values are >0, <10 enough to prove that the solution is valid? I'm assuming since every puzzle only has one solution I don't have to check each 3x3 grid to make it doesn't contain duplicates if each row and column sum to 45.
1) simple:
/// Read the number of puzzles;
...
for (i = 0; i < number_of_puzzless; i++) {
// Read Data for a puzzle
...
// Process puzzle data
...
// Print result
...
}
2) The sum or all cells in a row/column is equal to 45 and all numbers are in a range from 1 to 9. Is this enough to check only rows and columns to state that the whole puzzle is valid?
Yes it is. Even if you try to fool your checker and would give it a row that, say, has two sixes and two nines and no sevens and eights, this would break the checks on some columns.
Your problem statement is missing an input. The sample assumes that the solution for each game is typed in, but in #1 you state that the only input is the number of games to solve. There has to be a source of data for each game solution. Let's assume there is another file for each game. Your program needs to read in each game solution, verify the solution, and simply report pass or fail as the result. The sample code needs to be re-coded to accept a file-based input but it does not need to retain all solutions in memory at once.
Another rule for Sudoku is that each digit in a row or column may only appear once. Just calculating a total for each row or column won't catch duplicates.
1) Handle each puzzle one at a time. Read the puzzle into the array. Check it. Then read the next puzzle into the same array. If you only want a single yes/no for all the puzzles collectively you can print no and exit as soon as any check fails. If you make it to the end without any failed checks, then print yes. If you need to print whether individual puzzles passed, then answer before moving on to the next puzzle.
2)No! Absolutely not. One simple example is a sudoku filled with all 5s. This will give a 45 sum for every block, row, and column, but obviously is incorrect. It is also not sufficient to only check the presence of each digit along the rows and columns. For example consider one filled with 1 - 9 on the first row. Each successive row is a left rotate of the previous row. This would give all digits in each row and each column, but the blocks would be wrong e.g. block 0,0 would be 123,234,456.
One (maybe the best) way to check for each number is to set up an array of flags. Each index represents that number in the puzzle. Scan the line (or row or block) and set the flag for each number when you reach it. Then check to make sure all the flags are set. For checking a row:
int i,col;
int flags[9];
//zero the flags
for(i 0 1; i < 9; i++)
flags[i] = 0;
//check row
for(col = 0; col < 9; col++)
flags[data[row][col] - '1'] = 1;
//check flags
for(i 0 1; i < 9; i++)
if( 0 == flags[i] )
fail = true;
How can I run a loop in c for a very large count in c for eg. 2^1000 times?
Also, using two loops that run a and b no. of times, we get a resultant block that runs a*b no. of times. Is there any smart method for running a loop a^b times?
You could loop recursively, e.g.
void loop( unsigned a, unsigned b ) {
unsigned int i;
if ( b == 0 ) {
printf( "." );
} else {
for ( i = 0; i < a; ++i ) {
loop( a, b - 1 );
}
}
}
...will print a^b . characters.
While I cannot answer your first question, (although look into libgmp, this might help you work with large numbers), a way to perform an action a^b times woul be using recursion.
function (a,b) {
if (b == 0) return;
while (i < a) {
function(a,b-1);
}
}
This will perform the loop a times for each step until b equals 0.
Regarding your answer to one of the comments: But if I have two lines of input and 2^n lines of trash between them, how do I skip past them? Can you tell me a real life scenario where you will see 2^1000 lines of trash that you have to monitor?
For a more reasonable (smaller) number of inputs, you may be able to solve what sounds to be your real need (i.e. handle only relevant lines of input), not by iterating an index, but rather by simply checking each line for the relevant component as it is processed in a while loop...
pseudo code:
BOOL criteriaMet = FALSE;
while(1)
{
while(!criteriaMet)
{
//test next line of input
//if criteria met, set criteriaMet = TRUE;
//if criteria met, handle line of input
//if EOF or similar, break out of loops
}
//criteria met, handle it here and continue
criteriaMet = FALSE;//reset for more searching...
}
Use a b-sized array i[] where each cell hold values from 0 to a-1. For example - for 2^3 use a 3-sized array of booleans.
On each iteration. Increment i[0]. If a==i[0], set i[0] to 0 and increment i[1]. If 0==i[1], set i[1] to 0 and increment i[2], and so on until you increment a cell without reaching a. This can easily be done in a loop:
for(int j=0;j<b;++j){
++i[j];
if(i[j]<a){
break;
}
}
After a iterations, i[0] will return to zero. After a^2 iterations, i[0],i[1] will both be zero. AFter a^b iterations, all cells will be 0 and you can exit the loop. You don't need to check the array each time - the moment you reset i[b-1] you know the all the array is back to zero.
Your question doesn't make sense. Even when your loop is empty you'd be hard pressed to do more than 2^32 iterations per second. Even in this best case scenario, processing 2^64 loop iterations which you can do with a simple uint64_t variable would take 136 years. This is when the loop does absolutely nothing.
Same thing goes for skipping lines as you later explained in the comments. Skipping or counting lines in text is a matter of counting newlines. In 2006 it was estimated that the world had around 10*2^64 bytes of storage. If we assume that all the data in the world is text (it isn't) and the average line is 10 characters including newline (it probably isn't), you'd still fit the count of numbers of lines in all the data in the world in one uint64_t. This processing would of course still take at least 136 years even if the cache of your cpu was fed straight from 4 10Gbps network interfaces (since it's inconceivable that your machine could have that much disk).
In other words, whatever problem you think you're solving is not a problem of looping more than a normal uint64_t in C can handle. The n in your 2^n can't reasonably be more than 50-55 on any hardware your code can be expected to run on.
So to answer your question: if looping a uint64_t is not enough for you, your best option is to wait at least 30 years until Moore's law has caught up with your problem and solve the problem then. It will go faster than trying to start running the program now. I'm sure we'll have a uint128_t at that time.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I need to build a tree that looks like this:
So I take in 2 numbers from the user, a and b. a defines the number of rows, and b defines the starting root node value. So if i had a=5 and b=3, then we get:
I basically just print that out to the console. I am just really lost how on how to start. Could anyone give me a little push in the right direction?
This is Pascal's triangle, and the value at row n, column k is b * (n choose k) where n and k are both zero-indexed, and (n choose k) = n! / (k! * (n-k)!)
Once you've figured this out, then the solution to your problem amounts to writing a function int choose(int n, int k) and to laying out the square on the console.
The layout is the hardest part, but here's an approach:
First, you need to pick a width that you're going to print the number out in. Let's say it's W. Probably W = 3 will be good.
Second, you need to figure out how many spaces to print at the start of each line. Each row adds W + 1 width to the printed part, so you need to have (W + 1) / 2 less space before on each subsequent row, ending at 0 space at row (a - 1). That means (a - n - 1) * (W + 1) / 2 spaces beforehand on row n.
Third, you need to write a function int choose(int n, int k)
Finally, you just need to iterate through the rows, first printing the number of spaces determined by step 2, then printing the numbers computed using the function in step 3, making sure that they're printed using something like printf("%-*d ", W, b * choose(n, k)); to keep them aligned.
One way might be to "grow" the tree downwards... Given the number of rows you can figure out how many elements are in the tree and allocate an array of the appropriate size.
Then starting at the top, assuming rows numbered from 1, down_left(x) = x + row(x) where x is the array index and row(x) is the row number x belongs to. down_right(x) = down_left(x) + 1.
Start at the top and go down_left and down_right. Then for each element in the next row you just created do the same, except add to the row below to get the cumulative effect of the "parent" numbers.
e.g. if user asks for 3 rows and root value of 3.
You know you will need 6 array elements. Allocate 6 elements and zero them.
Row 1: Put 3 at array[0].
Row n: Create by looking at each element in the previous row, call it i. Then do array[down_left(i)] += i and array[down_right(i)] += i. This creates row n. Repeat.
That's the rough idea anyway, have a play and see where it gets you... :)
**If you're not interested in the background information explaining my reasoning skip to the very bottom for the end of my question.
I have a set of polynomial equations i need to read into my program to perform unit tests of polynomials such as
Synthetic division
Addition
Subtraction
Scale
Multiplication
Roots
so i need to be able to input a wide range of numbers to test the functions used in BRLCAD, though i am having trouble coming up with an efficient solution to read in numbers. My current approach:
Given the command line:
./unit_test sd 2 3 4 8 1 4 5
sd - perform synthetic division
2 - degree of first poly
3,4,8 - 3x^2 + 4x + 8
1 - degree of second poly
writing an algorithm to read a set of numbers in this format is cumbersome and quite confusing for others to understand, plus i have yet to implement two other polynomials to be read in as the answers to be compared with.(as this is an open source file, i would like my work to have some transparency).
if(strcmp(argv[1],"sd") == 0){
poly_eqn1.dgr = atoi(argv[2]);
/* start at argv[3], run degree count plus one times */
for(counter = 0; counter < (eqn1.dgr + 1); counter++)
poly_eqn1.cf[counter] = atof(argv[counter+3]);
poly_eqn2.dgr = atoi(argv[4 + poly_eqn1.dgr]);
/* start at end of degree one counter */
for(counter = 0; counter < (dgr2 + 1); counter++)
poly_eqn2.cf[counter] = atof(argv[counter+5+dgr]);
/* grab the answer from end of data */
return test_synthetic(//input proper data...);
}
Would using sscanf be more efficent to read in my polynomial given a maximum degree is set? After writing the initial method i thought about using sscanf, but i'm unsure if using it in such a manner would be worth it as opposed to writing in two more polynomial read in's from above:
Given the maximum degree is four for a polynomial
./unit_test sd 2,0,0,2,4,5 1,0,0,0,2,3
2,0,0,2,4,5 - degree 2, 0x^4 + 0x^3 + 2x^2 + 4x + 5
If I were you, I would try hard to support your parameters in human readable format.
For example, it should be possible to parse input in following form:
./unit_test "(3*x^2+4*x+8)/(4*x+5)"
Granted, you may have to write lexical parser to understand this input, but it would be easiest to understand from user perspective.
You really need not worry about efficiency when simply processing the command line arguments. Do so in the simplest, most straightforward fashion appropriate for your task. Spend your time worrying about efficiency where it matter - in tight loops with the actual number crunching algorithms.