Pattern Programmings - c

I am having difficulty understanding the logic behind drawing patterns with * and numbers in C.
For example, I am drawing this pattern:
*
* *
** **
* *
*
Some things that I understand in this programs are to take various for loops for printing * and whitespaces, but it's getting difficult to determine the conditions for them.
In the above example I think I need to draw half the triangle and the remaining is the reverse of it.
So please help me to understand the logic I should consider to draw such patterns every time.
#include<stdio.h>
#include<conio.h>
void main()
{
int i,j=0,k,l,m,o,n=6;
clrscr();
printf(" ");
for(i=0;i<=3;i++)
{
for(j=2;j>0;j--)
{
printf(" ");
for(k=0;k<=(2*i);k++)
{
printf("*");
// getch();
}
}
// getch();
printf("\n");
}
getch();
}
This is how I tried coding, I am not getting the conditions for nested for loop.

-2 -1 0 1 2
+---+---+---+---+---+
-2 | . | . | X | . | . |
+---+---+---+---+---+
-1 | . | X | O | X | . |
+---+---+---+---+---+
0 | X | X | O | X | X |
+---+---+---+---+---+
1 | . | X | O | X | . |
+---+---+---+---+---+
2 | . | . | X | . | . |
+---+---+---+---+---+
Points are not drawn if (col = 0 and abs(row) != 2) or either row or col is 2 and other is non-zero. You can implement these conditions in your code.
For(row = -2 to 2)
For(col = -2 to 2)
if ( (col = 0 and abs(row) != 2) or (abs(row) = 2 and col != 0) or (abs(col) = 2 and row != 0) )
draw space character
else
draw *
line break

#include<stdio.h>
#include<conio.h>
int main()
{
int n=3,i,j,k,l,m;
clrscr();
for(i=0;i<n;i++)
{
for(j=0;j<n-i-1;j++)
printf(" ");
for(k=0;k<=i-1;k++)
printf("*",k+1);
for(m=0;m<1;m++)
{
if(i<=0)
printf("*");
else
printf(" ");
}
for(l=i-1;l>=0;l--)
printf("*",l+1);
printf("\n");
}
for(i=0;i<n-1;i++)
{
for(j=0;j<=i;j++)
printf(" ");
for(k=0;k<n-i-2;k++)
printf("*",k+1);
for(m=0;m<1;m++)
{
if(i==1)
{}
else
printf(" ");
}
for(l=1;l>0;l--)
printf("*",l+1);
printf("\n");
}
getch();
return 0;
}
Finally I got my solution by myself.

Related

Running into an identifiable Segmentation Fault

Whenever I run my code I get a message: Segmentation fault: 11
My question is why this message is popping up. I have done some research prior to this and have tried to fix it but I still have the same message pop up. Please review my code!
To give some context to my code: The goal of this program is to implement the Connect Four game between a computer and a human player. Functions are to be implemented in the file connect4_functions.c. Forward declarations of these functions are in the file connect4_functions.h. connect4.c contains the main () functions.
The code (connect4_functions.c) is below:
#include "connect4_functions.h"
int print_welcome(void) // PROBLEM: returnerer alltid 1
{
printf ("*** Welcome to the Connect Four game!!! ***\n");
printf ("Would you like to make the first move [y/n]: ");
if (getchar() == 'N' || getchar() == 'n') return 2;
else return 1;
while (getchar()!= '\n');
}
void display_board(int board[][BOARD_SIZE_VERT])
{
int i, j;
for (i = BOARD_SIZE_VERT-1; i >= 0; i--)
{
for (j = 0; j < BOARD_SIZE_HORIZ; j++) printf ("+---");
printf ("+\n");
for (j = 0; j < BOARD_SIZE_HORIZ; j++)
{
switch (board[j][i])
{
case 0: printf ("| "); break;
case 1: printf ("| O "); break;
case 2: printf ("| X "); break;
}
}
printf ("|\n");
} // end for
for (j = 0; j < BOARD_SIZE_HORIZ; j++) printf ("+---");
printf ("+\n");
for (j = 1; j <= BOARD_SIZE_HORIZ; j++) printf (" %d ", j);
printf ("\n");
} //end function display_board
int random_move(int board[][BOARD_SIZE_VERT], int computer_num)
{
int m = (rand() % BOARD_SIZE_HORIZ) + 1;
if (!is_column_full(board,m))
{
update_board(board,m,computer_num);
return m;
}
else return random_move(board,computer_num);
}
int player_move(int board[][BOARD_SIZE_VERT], int player_num)
{
int m;
printf ("Please enter your move: ");
scanf ("%d", &m);
while (getchar() != '\n');
if ( 0 > m || m > BOARD_SIZE_HORIZ)
{
printf ("Not a valid move. Enter a column number!\n");
return player_move(board, player_num);
}
if (is_column_full(board, m))
{
printf ("This column is full. Try again!\n");
return player_move(board, player_num);
}
update_board(board,m,player_num);
return m;
}
bool check_win_or_tie(int board[][BOARD_SIZE_VERT], int last_move)
{
int m, count = 0;
if (check_winner(board, last_move))
{
printf("Player %c won!\n", ( check_winner(board,last_move) == 1 ? '1' : '2' ) );
return true;
}
for (m = 0; m < BOARD_SIZE_HORIZ; m++) if ( is_column_full(board, m) ) count++;
if (count == BOARD_SIZE_HORIZ)
{
printf ("Tie game!\n");
return true;
}
else return false;
}
bool is_column_full(int board[][BOARD_SIZE_VERT], int m)
{
return (board[m-1][BOARD_SIZE_VERT-1]);
}
void update_board(int board[][BOARD_SIZE_VERT], int m, int player_num)
{
int i;
for ( i = 0; i < BOARD_SIZE_VERT ; i++)
{
if (!board[m-1][i])
{
board[m-1][i] = player_num;
return;
}
}
}
int check_winner(int board[][BOARD_SIZE_VERT], int last_move)
{
int i, row, count;
// Find row
for (row = 0; row < BOARD_SIZE_VERT; row++)
{
if (board[last_move-1][row]) count++;
}
row = count;
printf ("row = %d\n", row);
// Vertical
for (i = 0; i < BOARD_SIZE_VERT; i++)
{
if (board[last_move-1][i] == board[last_move-1][row]) count++;
else count = 0;
if (count == 4) return board[last_move-1][row];
else return 0;
}
count = 0; // reset
// Horizontal
for (i = 0; i < BOARD_SIZE_HORIZ; i++)
{
if (board[i][row] == board[last_move-1][row]) count++;
else count = 0;
if (count == 4) return board[last_move-1][row];
else return 0;
}
count = 0; // reset
return 0;
}
The code for connect4_functions.h (cannot be changed) is below:
#ifndef CONNECT4_FUNCTIONS
#define CONNECT4_FUNCTIONS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
#define BOARD_SIZE_HORIZ 7
#define BOARD_SIZE_VERT 6
int print_welcome(void);
void display_board(int board[][BOARD_SIZE_VERT]);
int random_move(int board[][BOARD_SIZE_VERT], int computer_num);
int player_move(int board[][BOARD_SIZE_VERT], int player_num);
bool check_win_or_tie(int board[][BOARD_SIZE_VERT], int last_move);
bool is_column_full(int board[][BOARD_SIZE_VERT], int m);
void update_board(int board[][BOARD_SIZE_VERT], int m, int player_num);
int check_winner(int board[][BOARD_SIZE_VERT], int last_move);
int best_move(int board[][BOARD_SIZE_VERT], int computer_num);
#endif
The code for connect4.c (also cannot be changed) is below:
#include "connect4_functions.h"
int main()
{
int board[BOARD_SIZE_HORIZ][BOARD_SIZE_VERT] = { {0} };
int player_num, computer_num;
int last_move;
/* Ask Alice if she wants to go first */
player_num = print_welcome();
if (player_num == 1) computer_num = 2;
else computer_num = 1;
/* If Alice wants to go first, let her make a move */
if (player_num == 1)
{
display_board(board);
last_move = player_move(board,player_num);
display_board(board);
}
/* The main loop */
while (1)
{
/* Make a computer move, then display the board */
last_move = random_move(board,computer_num);
printf("Computer moved in column: %d\n", last_move);
display_board(board);
/* Check whether the computer has won */
if (check_win_or_tie(board,last_move)) return 0;
/* Let Alice make a move, then display the board */
last_move = player_move(board,player_num);
display_board(board);
/* Check whether Alice has won */
if (check_win_or_tie(board,last_move)) return 0;
} /* end of while (1) */
} /* end of main() */
Also, if you would like to see the original pdf it is linked below:
Link to pdf
The output is:
*** Welcome to the Connect Four game!!! ***
Would you like to make the first move [y/n]: y
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
1 2 3 4 5 6 7
Please enter your move: 4
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | O | | | |
+---+---+---+---+---+---+---+
1 2 3 4 5 6 7
Computer moved in column: 1
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| X | | | O | | | |
+---+---+---+---+---+---+---+
1 2 3 4 5 6 7
row = -355898527
Segmentation fault: 11
(If you have any questions about the context or purpose please don't hesitate to ask!)
Not having actually run the code, I believe the issue may be that count is not initialized in check_winner:
int check_winner(int board[][BOARD_SIZE_VERT], int last_move)
{
int i, row, count;
// Find row
for (row = 0; row < BOARD_SIZE_VERT; row++)
{
if (board[last_move-1][row]) count++;
}
row = count;
// WHAT IF IT EXITS THE for () WITHOUT board[last_move-1][row] being non-zero?
// HINT: count can be anything!
printf ("row = %d\n", row);
You then use row as an access into an array, and boom! You've accessed memory outside your permissions.
In the check_winner function you don't initialise the variable count. I get an unitialised variable runtime error, yet if I continue ahead a couple of lines later you then set:
row = count;
Which in my case is setting row to -858993459;
A couple of lines down in that same function you write:
if (board[last_move - 1][i] == board[last_move - 1][row]) count++;
// You use "row", an initialised variable as the index
// for the second subscript operator of board.
And that's where I get:
Access violation reading location 0x0000005663E82BB4. occurred
I think there should have been a warning shown about this unitialised variable. And honestly, I don't know if that's all that's wrong with it, but it looks like a pretty good game.
First of all, to be able to solve your problem, you should make sure everything that might be printed before the crash, has been printed. In this goal, you should add a fflush(stdout); instruction after each of your printing instructions
secondly, if this doesn't make clear at what place you program crashes, you should add supplementary tracing instruction inside the piece of code where it happens.
And then, when you have identified which instruction causes de crash, you should print it's variables to check if their values are what you expect.
Alternatively, you can use the assert instruction to make sure the variable values are all in the expected ranges.

Unexpected '%' appearing in console

I'm working through the K&R C programming book, and I just completed exercise 1-13 where you print a histogram of the lengths of words that are input. My horizontal histogram is fine, but my vertical histogram has a '%' sign appearing at the end of it, and I can't figure out why that keeps happening. Here is the loop that I think is causing the issue:
for (i = 0; i < array_length; i++) {
printf("%-4d", i + 1);
}
If the array_length is 7, I will have a '%' sign after the 7th position like this:
|
| |
| |
| |
| |
| |
| | | | |
| | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
1 2 3 4 5 6 7 %
If I remove this loop, the vertical bars print fine, I just don't get the numbering below each of them.
What is going on here? As far as I can guess, the printf is running one extra time with garbage data in 'i', but I can't figure out why or how this is happening.
I'm compiling with gcc on Ubuntu, if that makes any difference.
Here is the complete code for your reference:
#include <stdio.h>
#define IN 1
#define OUT 0
#define ARRAY_SIZE 1000
int main() {
int c, current_word_length, state, i, j, current_word, largest, array_length, top;
int word_lengths[ARRAY_SIZE];
current_word_length = current_word = largest = 0;
state = OUT;
for (i = 0; i < ARRAY_SIZE; i++) {
word_lengths[i] = 0;
}
printf("Enter up to 1000 words and this program will calculate their length.\n");
printf("Please enter a newline, tab, or space before the last word entered, then EOF to print summary.\n\n");
while ((c = getchar()) != EOF) {
if (c == ' ' || c == '\t' || c == '\n') {
if (state == IN) {
word_lengths[current_word++] = current_word_length;
if (current_word_length > largest) {
largest = current_word_length;
}
current_word_length = 0;
state = OUT;
}
} else {
state = IN;
current_word_length++;
}
}
array_length = current_word;
printf("\nWord Lengths Histogram Horizontal:\n\n");
for (i = 0; i < array_length; i++) {
printf("%-4d: ", i + 1);
for (j = 0; j < word_lengths[i]; j++) {
printf("=");
}
printf("\n");
}
printf("\nWord Lengths Histogram Vertical:\n\n");
top = largest;
while (top > 0) {
for (i = 0; i < array_length; i++) {
if (word_lengths[i] >= top) {
printf("%-4c", '|');
} else {
printf("%-4c", ' ');
}
}
printf("\n");
top--;
}
for (i = 0; i < array_length; i++) {
printf("%-4d", i + 1);
}
return 0;
}
And here is what I expect to occur using this input string "Bacon ipsum dolor amet frankfurter landjaeger ham":
Enter up to 1000 words and this program will calculate their length.
Please enter a newline, tab, or space before the last word entered, then EOF to print summary.
Bacon ipsum dolor amet frankfurter landjaeger ham
Word Lengths Histogram Horizontal:
1 : =====
2 : =====
3 : =====
4 : ====
5 : ===========
6 : ==========
7 : ===
Word Lengths Histogram Vertical:
|
| |
| |
| |
| |
| |
| | | | |
| | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
1 2 3 4 5 6 7
OK, as pointed out by nos and chqrlie in the comments, I need to add a newline at the end of my program so that the shell prompt will appear on a newline AFTER the program has finished running.
Adding the putchar() call at the end of main() fixed my issue:
for (i = 0; i < array_length; i++) {
printf("%-4d", i + 1);
}
putchar('\n');
return 0;
} // end main()

How does odd number print increasing order?

#include <stdio.h>
#include<string.h>
void Magic(int in);
int Even(int n);
int main()
{
Magic(10);
}
void Magic(int in)
{
if(in == 0)
{
return;
}
if(Even(in))
{
printf("%i\n", in);
}
Magic(in - 1);
if(!Even(in))
{
printf("%i\n", in);
}
return;
}
int Even(int n)
{
return (n % 2) == 0 ? 1 : 0;
}
how does odd number print in increasing order?
It prints 10 8 6 4 2 1 3 5 7 9.
I know upto 10 8 6 4 2 but how come it prints 1 3 5 7 9? after decreasing order?
There are nested calls Magic(in - 1);. If number is even it is printed immediately and then Magic(in - 1); is called. Only when n is zero all functions print not even number in reverse order. The first odd number is printed by the deepest Magic() function:
Magic(10)
|print 10
|Magic(9)
| |Magic(8)
| | print 8
| | ...
| | Magic(1)
| | Magic(0)
| | return;
| | print 1
| | return
| | ...
| | return
| |print 9
| |return
|return
this is caused by the recursion of the function. the function is returning in the order it was called. if you want to print the odd numbers in decreasing order after the even numbers, you need to save them in a variable (array ) that is also passed to the magic function

Solving #1015 (Brush) in LightOJ

I am trying to solve the following problem.
Input
Input starts with an integer T (≤ 100), denoting the number of test cases.
Each case starts with a blank line. The next line contains an integer N (1 ≤ N ≤ 1000), means that there are N students. The next line will contain N integers separated by spaces which denote the dust unit for all students. The dust unit for any student will not contain more than two digits.
Output
For each case print the case number and the total required dust units.
Sample Input
+--------------+-------------------------+
| Sample Input | Output for Sample Input |
+--------------+-------------------------+
| 2 | Case 1: 16 |
| | Case 2: 100 |
| 3 | |
| 1 5 10 | |
| | |
| 2 | |
| 1 99 | |
+--------------+-------------------------+
Here is my code:
#include <stdio.h>
int main() {
int kase = 0;
int i = 0, j = 0;
do {
scanf("%d", &kase);
} while (kase > 100);
int group[kase];
int tdust[kase];
for (i = 1; i <= kase; i++) {
tdust[i] = 0;
printf("\n");
do {
scanf("%d", &group[i]);
} while (group[i] < 1 || group[i] > 1000);
int stdNumber[group[i]];
for (j = 1; j <= group[i]; j++) {
do {
scanf("%d", &stdNumber[j]);
} while (stdNumber[j] >= 100);
tdust[i] = tdust[i] + stdNumber[j];
}
}
for (i = 1; i <= kase; i++)
printf("\nCase %d: %d", i, tdust[i]);
}
When I submit my code, OnlineJudge says I've got the wrong answer. How can I fix it?
You are getting WA because your code exhibits UB(Undefined Behaviour). You assume that the valid indices for an array of length n where n is a natural number, starts from 1 and ends at n. That is wrong.For an array of length n(n is a natural number), Array indices start from 0 and end at n-1.
To fix it, change
for(i=1; i<=kase; i++)
To
for(i=0; i<kase; i++)
And similarly,do the same for all the other loops. Also change
printf("\nCase %d: %d",i,tdust[i]);
To
printf("\nCase %d: %d",i+1,tdust[i]);
So that you get the desired result.

Tic Tac Toe AI issue in C

I tried making a simple tic tac toe project, and I am trying to make the AI move to random places, so that the AI just moves into any available place. However, it always makes 2 moves. I am wondering why it always makes 2 moves instead of just 1.
What I mean is, let's say the user inputs 'O' into slot 1,1.
0 1 2
+----+----+----+
0 | | | |
| | | |
+----+----+----+
| | | |
1 | | O | |
+----+----+----+
| | | |
2 | | | |
+---------------
Then the computer moves 2 moves: into slots 1,2 AND 2,0
0 1 2
+----+----+----+
0 | | | |
| | | |
+----+----+----+
| | | |
1 | | O | X |
+----+----+----+
| | | |
2 | X | | |
+---------------
So I'd like to know why this happens?
Here is my code:
void compMove(char board[][columns])
{
int randomNum, randomNum1, i, j;
bool didMove = FALSE;
srand((int)time(NULL)); //Seed the random number generator
randomNum = rand() % 3;
randomNum1 = rand() % 3;
while(board[randomNum][randomNum1] != ' ')
{
randomNum = rand() % 3;
randomNum1 = rand() % 3;
}
for(i = 0; i < 3; i++)
{
for(j = 0; j < 3; j++)
{
if(i == randomNum && j == randomNum1)
{
board[i][j] = 'X';
didMove = TRUE;
break;
}
}
if(didMove == TRUE) break;
}
}
You do not need a loop to set movement on the board.
board[randomNum][randomNum1] = 'X';
is enough to set.
And you probably call this function twice, because function plays only one move.
I suspect your checkWin function is the culprit. Probably has an = somewhere you meant to have an ==. But that's just a guess without seeing it.
Your compMove function is grossly overcomplicated, but not wrong. Here's code that does the same thing:
void compMove(char board[][columns]) {
int row, col;
/* DON'T seed RNG here; do it once in main() */
do {
row = rand() % 3;
col = rand() % 3;
} while (board[row][col] != ' ');
board[row][col] = 'X';
}

Resources