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;
Related
So, what I am trying to do is a three in a row game, and so far I have managed to make it work, but I am struggling a bit when it comes to getting a winner, since I need to check that all the elements of either a row, a column or a diagonal are the same.
So far I have managed to get it to kinda work by using a boolean, a counter and a for loop. Here is an example of how my code looks
//Code to check the rows horizontally
public void checkH(){
int cont1 = 0;
Boolean winner1 = false;
for(int i=0;i<size;i++){
if(a[0][i]==1 || a[1][i]==1 || a[2][i]==1){
cont1++;
if(cont1==3){
winner1 = true;
}
So, as y'all can see what I am doing in that code is telling the program that if the array in either one of the rows is equal to one and if that same case happens when it goes through all the positions in the row, then the counter is going to add plus one, and once the counter hits 3, the boolean will be true and there will be a winner, but here is the catch: if, for example, the 2D array looks like this:
int a[][] = {{1,0,0},
{1,1,0},
{0,0,0}};
then the counter is still hitting three, even though they are not aligned. I know I havent specified that kind of condition in the program, but that's what I am struggling with. What I would like to do is to be able to make that condition with loops, so that I dont have to fill the whole thing with if statements.
Any leads you guys could give me on this would be highly appreciated. Thanks in advance!
If you are finding it difficult to search for a solution/tutorial on the web, notice that the three in a row game is also called tic-tac-toe. So, if you search for "tic tac toe algorithm" you will find several examples on how to solve it, as it is a somewhat usual interview question. Here is a reference for the reader’s convenience.
Now, for the desire to use for loops instead of chained ifs (or an if with multiple logical comparisons), it is a question about row-wise, column-wise and diagonal-wise traversal of a matrix. Here is a reference for the row and column traversals, and here is another reference for the diagonal traversal.
Specific to your question, below is a pseudo-code showing the check for column and row using for and the cell values to have a small number of if statements. But please notice this is just an example, as there are many interesting ways to solve a tic-tac-toe game that you may want to take a look, from traversing trees to using a string and regex.
public bool checkRow() {
int i, j;
int count = 0;
// accessing element row wise
for (i = 0; i < MAX; i++) {
for (j = 0; j < MAX; j++) {
// Considering we were checking for 1
// And array can have 0 or 1
// You can add the cell value and avoid an if
count += arr[i][j];
// if you go with arr[j][i] you will be traversing the columns and not the rows.
}
// if all cells in the row are 1, we have a winner
if(count == MAX)
return true;
}
return false
}
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 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.
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 am writing a very simple program, yet I can not seem to get it to work properly. I want to start with an array with numbers from 1-69 and then randomly select 5 numbers from this array without repeating. And I do not want to just shuffle the array and take the first 5 numbers. I want it to resemble more of a darwing numbers out of a hat with the probability being the way it should be.
For Example:
Array1[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
Array2[]
// I want it to randomly choose an element from Array1, remove it from Array1, and place it in Array2. Then repeat the process until I have 5 randomly pulled numbers from Array1 without repeating.
Any help is greatly appreciated! Thank You!
P.s. I am writing this project in C.
Pseudo-code:
Create 69-element array A[] with values [1 ... 69]. Length = 69;.
Randomly create an index index = rand()%Length;
Swap that indexed element A[index] with array element A[Length-1].
Decrement: Length--
Repeat steps 2-4 four more times.
The last five elements of A[] are the desired set - no repeats.
Note: code is not shuffling the complete array - which would be a waste of time.
You can't simply "remove" a cell in a C array; if you really want to do it that way, the best you can do is:
select the element with rank n (from array A) and do whatever you want with it
move elements n+1, n+2, etc. (from array A) one cell left (backward) with something like memcpy
remember the new size of the array A (because the allocated memory will remain the same during the whole process)
You absolutely need to just "try something", post your work, and ask questions about what you've tried. Especially if this is a homework assignment, we can't "do your work for you" :(
There are many ways you can approach this.
Some example options:
a) Fill the array with "legal" numbers, select five numbers from five random positions, then mark those positions "taken" (so they won't be selected again).
b) Randomly fill the array with legal numbers, and choose five at a time, starting with position "0". Increment current position by "five" each time.
c) Etc.
"I want it to resemble more of a darwing numbers out of a hat." That is exactly how you can implement this:
Create a hat array with all lottery ticket in it.
Pick a random ticket from the array, store it and remove the ticket from the hat.
Repeat until you have as many tickets as you need.
Deletions from arrays require the tail of the array being shifted, but you don't need that here: The order of the items in the hat isn't important, so you can move the last element to the gap the drawn ticket has left in the array and decrement the array length.
So:
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
int main()
{
int hat[70]; // pool of numbers
size_t n = 70; // size of pool
size_t i;
// get pseudo-random-number generator underway
srand(time(NULL));
// fill pool with all numbers
for (i = 0; i < n; i++) hat[i] = i;
// pick five numbers and print them
for (i = 0; i < 5; i++) {
size_t pick = rand() % n;
printf("%d\n", hat[pick]);
hat[pick] = hat[--n];
}
return 0;
}
In your case, the number of drawn numbers is small in comparison to the pool, so you might actually look at things the other way: Instead of restricting the items that you draw, you could look at the items you have already drawn and draw a ticket until you get one that you haven't seen yet. But the method above is genneral.
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... :)