c: draw layout for the table to console - c

Code works, however I do not know how could I format output correctly to match consistency of the layout (drawing dashes in this case) on any size?
#include <stdio.h>
int main(int argc, const char * argv[]) {
int i=0, k = 0, total_x = 3, total_y = 4;
char symbol = '+';
for (k = 1; k <= total_y; k++) {
// print symbol and row numbers
if (k == 1) {
printf("%3c | ",symbol);
int temp;
for (temp = 1; temp <= total_x; temp++) {
printf("%4d", temp);
}
printf("\n");
for (temp = 1; temp < total_x*5; temp++) {
if (temp == 5) {
printf("+");
}
printf("-");
}
printf("\n");
}
printf("%3d | ",k);
for (i = 1; i <= total_x; i++) {
printf("%4d", k + i);
}
printf("\n");
}
return 0;
}
Output when total_x = 3, total_y = 4;:
+ | 1 2 3
----+----------
1 | 2 3 4
2 | 3 4 5
3 | 4 5 6
4 | 5 6 7
Desired result:
+ | 1 2 3
----+--------------
1 | 2 3 4
2 | 3 4 5
3 | 4 5 6
4 | 5 6 7
Output when when total_x = 10, total_y = 4:
+ | 1 2 3 4 5 6 7 8 9 10
----+---------------------------------------------
1 | 2 3 4 5 6 7 8 9 10 11
2 | 3 4 5 6 7 8 9 10 11 12
3 | 4 5 6 7 8 9 10 11 12 13
4 | 5 6 7 8 9 10 11 12 13 14
Desired result:
+ | 1 2 3 4 5 6 7 8 9 10
----+------------------------------------------
1 | 2 3 4 5 6 7 8 9 10 11
2 | 3 4 5 6 7 8 9 10 11 12
3 | 4 5 6 7 8 9 10 11 12 13
4 | 5 6 7 8 9 10 11 12 13 14
Any printf function that could help me to print out correctly? Thank you so much!

You can make the dashes print prettier like this:
printf("----+--");
for (temp = 1; temp <= total_x; temp++) {
printf("----");
}
printf("\n");
OR correct the arithmetic in what you did:
for (temp = 1; temp <= total_x*4+6; temp++) {
if (temp==5)
printf("+");
printf("-");
}
printf("\n");

Related

Can anybody suggest me a better/shorter method for this pattern?

4 4 4 4 4 4 4
4 3 3 3 3 3 4
4 3 2 2 2 3 4
4 3 2 1 2 3 4
4 3 2 2 2 3 4
4 3 3 3 3 3 4
4 4 4 4 4 4 4
I want a shorter code or a more smarter code for this pattern.My code works fine but it is bit long.
MY CODE
#include <stdio.h>
int main()
{
int n,i,j;
scanf("%d",&n);
for(i=n;i>=1;i--)
{
for(j=n;j>i;j--)
{
printf("%d ",j);
}
for(j=1;j<(2*i)-1;j++)
{
printf("%d ",i);
}
for(j=i;j<=n;j++)
{
printf("%d ",j);
}
printf("\n");
}
for(i=2;i<=n;i++)
{
for(j=n;j>i;j--)
{
printf("%d ",j);
}
for(j=1;j<(2*i)-1;j++)
{
printf("%d ",i);
}
for(j=i;j<=n;j++)
{
printf("%d ",j);
}
printf("\n");
}
return 0;
}
How about like this:
#include <stdio.h>
#include <stdlib.h>
int max (int a, int b) {
return a > b ? a : b;
}
void pattern (int width) {
int count = width;
int digits = 1;
while (count /= 10)
++digits;
for (int line = 0; line < (2*width-1); ++line) {
for (int col = 0; col < (2*width-1); ++col) {
int val = max (abs (1+line-width)+1, abs (1+col-width)+1);
if (col > 0)
putc (' ', stdout);
printf ("%*d", digits, val);
}
puts ("");
}
}
int main (int argc, char* argv []) {
int width = argc > 1 ? atoi (argv [1]) : 4;
pattern (width);
}
The idea is to loop through all positions, calculate the distance to the middle position in both X and Y direction, and take the maximum of that.
I can suggest the following solution. Enjoy!:)
#include <stdio.h>
#include <limits.h>
#include <stdlib.h>
int main()
{
while ( 1 )
{
printf( "Enter a non-negative number (0 - exit): " );
int n;
if ( ( scanf( "%d", &n ) != 1 ) || ( n <= 0 ) ) break;
if ( INT_MAX / 2 < n )
{
n = INT_MAX / 2;
}
int width = 1;
for ( int tmp = n; tmp /= 10; ) ++width;
putchar( '\n' );
int m = 2 * n - 1;
for ( int i = 0; i < m; i++ )
{
for ( int j = 0; j < m; j++ )
{
int value1 = abs( n - i - 1 ) + 1;
int value2 = abs( n - j - 1 ) + 1;
printf( "%*d ", width, value1 < value2 ? value2 : value1 );
}
putchar( '\n' );
}
putchar( '\n' );
}
return 0;
}
The program output might look like
Enter a non-negative number (0 - exit): 10
10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
10 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10
10 9 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 9 10
10 9 8 7 7 7 7 7 7 7 7 7 7 7 7 7 8 9 10
10 9 8 7 6 6 6 6 6 6 6 6 6 6 6 7 8 9 10
10 9 8 7 6 5 5 5 5 5 5 5 5 5 6 7 8 9 10
10 9 8 7 6 5 4 4 4 4 4 4 4 5 6 7 8 9 10
10 9 8 7 6 5 4 3 3 3 3 3 4 5 6 7 8 9 10
10 9 8 7 6 5 4 3 2 2 2 3 4 5 6 7 8 9 10
10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10
10 9 8 7 6 5 4 3 2 2 2 3 4 5 6 7 8 9 10
10 9 8 7 6 5 4 3 3 3 3 3 4 5 6 7 8 9 10
10 9 8 7 6 5 4 4 4 4 4 4 4 5 6 7 8 9 10
10 9 8 7 6 5 5 5 5 5 5 5 5 5 6 7 8 9 10
10 9 8 7 6 6 6 6 6 6 6 6 6 6 6 7 8 9 10
10 9 8 7 7 7 7 7 7 7 7 7 7 7 7 7 8 9 10
10 9 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 9 10
10 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10
10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
Enter a non-negative number (0 - exit): 0
In fact there are used only two loops that output the pattern itself.
for ( int i = 0; i < m; i++ )
{
for ( int j = 0; j < m; j++ )
{
int value1 = abs( n - i - 1 ) + 1;
int value2 = abs( n - j - 1 ) + 1;
printf( "%*d ", width, value1 < value2 ? value2 : value1 );
}
putchar( '\n' );
}

Print a console "picture" using recursion

I'm having some trouble printing the following picture.
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 (16 times)
2 2 2 2 2 2 2 2 2 2 2 2 (12 times)
3 3 3 3 3 3 3 3 (8 times)
4 4 4 4 (4 times)
3 3 3 3 3 3 3 3 (8 times)
2 2 2 2 2 2 2 2 2 2 2 2 (12 times)
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 (16 times)
It's easy for me to implement an iterative algorithm, but I have to use recursion. I've written the following code (C++) that seems to do the job.
void print(int n, int current)
{
int offset = (n / 2) * (current - 1);
int i;
for (i = 0; i < offset; i++)
printf(" ");
for (i = 1; i <= (n - current + 1) * n; i++)
printf("%i ", current);
printf("\n");
}
void picture(int n, int current)
{
if (current < n) {
print(n, current);
picture(n, current + 1);
print(n, current);
}
else
if (current == n)
print(n, current);
}
int main()
{
int n;
input: printf("Enter n --> ");
scanf_s("%i", &n);
if ((n < 1) || (n > 9) || (n % 2 == 1)) {
printf("ERROR: n must be an even decimal digit!\n");
goto input;
}
picture(n, 1);
return 0;
}
I wonder whether there is a simpler way to write the recursive function here.
Update: I've tried to identify the recursion in a much simpler problem of printing the "pyramid":
1
2 2
3 3 3
4 4 4 4
5 5 5 5 5
The function pyram receives two parameters: the maximum number n (5 in our case) and the current number k. k is printed k times, then pyram is called with the parameters n and k + 1. This happens only when k <= n.
void pyram(int n, int k)
{
if (k <= n) {
for (int i = 1; i <= k; i++)
printf("%i ", k);
printf("\n");
pyram(n, k + 1);
}
}
I've written my solution to the original problem in a similar manner.
You can use static variables in the recursive function. In this case the function declaration will look simpler and you will not need an auxiliary function.
For example
#include <stdio.h>
void display_pattern( unsigned int n )
{
const unsigned int FACTOR = 4;
static unsigned int value = 1;
static int indent = 1;
if ( n )
{
printf( "%*u", indent, value );
for ( unsigned int i = 1; i < FACTOR * n; i++ ) printf( " %u", value );
putchar( '\n' );
indent += FACTOR;
++value;
display_pattern( --n );
indent -= FACTOR;
--value;
}
if ( n++ )
{
printf( "%*u", indent, value );
for ( unsigned int i = 1; i < FACTOR * n; i++ ) printf( " %u", value );
putchar( '\n' );
}
}
int main(void)
{
const unsigned int N = 10;
while ( 1 )
{
printf( "Enter a non-negative number less than %u (0 - exit): ", N );
unsigned int n;
if ( scanf( "%u", &n ) != 1 || n == 0 ) break;
if ( !( n < N ) ) n = N - 1;
putchar( '\n' );
display_pattern( n );
putchar( '\n' );
}
return 0;
}
The program output can look like
Enter a non-negative number less than 10 (0 - exit): 10
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5
6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
7 7 7 7 7 7 7 7 7 7 7 7
8 8 8 8 8 8 8 8
9 9 9 9
8 8 8 8 8 8 8 8
7 7 7 7 7 7 7 7 7 7 7 7
6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5
4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
Enter a non-negative number less than 10 (0 - exit): 4
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
2 2 2 2 2 2 2 2 2 2 2 2
3 3 3 3 3 3 3 3
4 4 4 4
3 3 3 3 3 3 3 3
2 2 2 2 2 2 2 2 2 2 2 2
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
Enter a non-negative number less than 10 (0 - exit): 0
As for the function pyram then it can look like
void display_triangle( unsigned int n )
{
if ( n )
{
display_triangle( n - 1 );
for ( unsigned int i = 0; i < n; i++ ) printf( "%u ", n );
putchar( '\n' );
}
}

Running weighted quick union

So I have to take an ID array
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
And perform weighted quick union on it. I have to perform the operations 9-0, 3-4, 5-8, 7-2, 2-1, 5-7, 0-3, and 4-2. Here's what I did to the array for these operations:
9-0
0 1 2 3 4 5 6 7 8 9
9 1 2 3 4 5 6 7 8 9
3-4
0 1 2 3 4 5 6 7 8 9
9 1 2 3 3 5 6 7 8 9
5-8
0 1 2 3 4 5 6 7 8 9
9 1 2 3 3 5 6 7 5 9
7-2
0 1 2 3 4 5 6 7 8 9
9 1 7 3 3 5 6 7 5 9
2-1
0 1 2 3 4 5 6 7 8 9
9 7 7 3 3 5 6 7 5 9
5-7
0 1 2 3 4 5 6 7 8 9
9 7 7 3 3 7 6 7 5 9
0-3
0 1 2 3 4 5 6 7 8 9
9 7 7 3 3 7 6 7 5 3
4-2
0 1 2 3 4 5 6 7 8 9
9 7 7 3 3 7 6 3 5 9
The problem is that the ID array operations are different depending on if you're using quick find or quick union or weighted quick union. So would this be right for weighted quick union? Here's the code I'm using for weighted quick union:
public class WeightedQuickUnionUF
{
private int[] id; // parent link (site indexed)
private int[] sz; // size of component for roots (site indexed)
private int count; // number of components
public WeightedQuickUnionUF(int N)
{
count = N;
id = new int[N];
for (int i = 0; i < N; i++) id[i] = i;
sz = new int[N];
for (int i = 0; i < N; i++) sz[i] = 1;
}
public int count()
{ return count; }
public boolean connected(int p, int q)
{ return find(p) == find(q); }
private int find(int p)
{ // Follow links to find a root.
while (p != id[p]) p = id[p];
return p;
}
public void union(int p, int q)
{
int i = find(p);
int j = find(q);
if (i == j) return;
// Make smaller root point to larger one.
if (sz[i] < sz[j]) { id[i] = j; sz[j] += sz[i]; }
else { id[j] = i; sz[i] += sz[j]; }
count--;
}
}
The code for weighted quick union shows you how it works but basically it's a type of Union-find where you connect two trees together. With weighted quick union you always connected the smaller tree to the larger one. The ID array is a representation of a tree where there's numbers on the top row and bottom row. If the number on top matches the bottom then that number is a root in the forest but for example if the top number is a 9 and the bottom number is 0 then it means 9 is a child of 0. The ID array starts out with 9 single node trees and operations like 9-0 connects two trees together.

Index manipulation of array in C

Begining with an ordered array
[1, 2, 3, 4, 5, 6, 8, 9, 10]
How would be the way to get every iteration the following results?
1 2 3 4 5 6 7 8 9 10
1 3 4 5 6 7 8 9 10 2
1 4 5 6 7 8 9 10 2 3
1 5 6 7 8 9 10 2 3 4
1 6 7 8 9 10 2 3 4 5
1 7 8 9 10 2 3 4 5 6
1 8 9 10 2 3 4 5 6 7
1 9 10 2 3 4 5 6 7 8
1 10 2 3 4 5 6 7 8 9
#include <stdio.h>
#define MAX 10
int a[MAX], i,j,cnt=2;
main (){
for (i=0; i<MAX; i++){
a[i]= i+1;
}
for (i=0; i<MAX; i++) {
printf ("%d ", a[i]);
}
printf ("\n");
for (j=0; j < MAX-2;j++){
a[0]=1;
for (i=1; i < MAX-1; i++){
if (a[i]%MAX != 0){
a[i]= a[i] + 1;
}else{
if (a[i]==10) {
//printf ("a[%d]: %d \t ** %d\n", i , a[i] ,cnt);
//a[i-1]= i;
a[i] = cnt;
}
}
}
for (i=0; i<MAX; i++) {
printf ("%d ", a[i]);
}
printf ("\n");
}
}
Now I almost get it but the last column is not right, What should I do?
1 2 3 4 5 6 7 8 9 10
1 3 4 5 6 7 8 9 10 10
1 4 5 6 7 8 9 10 2 10
1 5 6 7 8 9 10 2 3 10
1 6 7 8 9 10 2 3 4 10
1 7 8 9 10 2 3 4 5 10
1 8 9 10 2 3 4 5 6 10
1 9 10 2 3 4 5 6 7 10
1 10 2 3 4 5 6 7 8 10
C arrays are indexed from 0. So when you access elements from 1 to MAX, you are running off the end of the array.
Have your loops go from 0 to MAX-1. Customary way to write it is
for (i=0 ; i < MAX ; ++i)
...so anybody reading your code can immediately prove that the array index never equals MAX.
Well, at a minimum, arrays in C are zero based so you are writing past the end of the array. For an array declared int foo[MAX] valid elements are from foo[0]…foo[MAX-1]
Specifically a[MAX] might well reference the memory location that the variable i uses, causing the loop to reset when it attempt to overwrite a[MAX].
Either shift everything down by one, or declare your array MAX+1 and ignore the zero bit.
Oh, and you should not need to set a[1]=1; every time.

Need help with logic (C)

I need to swap first n elements from two non repeating sequences(arrays), where n is a random integer.
Seq1: 1 4 5 6 9 8 2 3 7
Seq2: 3 9 1 2 8 7 4 5 6
If n = 4
Seq1: 3 9 1 2 | 9 8 2 3 7
Seq2: 1 4 5 6 | 8 7 4 5 6
Now i need to repair the sequence by replacing the repeated numbers after '|'.
How to do this?
This is my effort..
for(left1 = 0; left1<pivot; left1++)
{
for(right1 = pivot; right1 < no_jobs; right1++)
{
if(S1->sequence[left1] == S1->sequence[right1])
{
for(left2 = 0; left2<pivot; left2++)
{
for(right2 = pivot; right2<no_jobs; right2++)
{
if(S2->sequence[left2] == S2->sequence[right2])
{
swap_temp = S1->sequence[right1];
S1->sequence[right1] = S2->sequence[right2];
S2->sequence[right2] = swap_temp;
break;
}
}
}
}
}
}
Swapping the first n elements is straightforward using a single for loop.
for(int i = 0; i < n; i++){
int tmp = array1[i];
array1[i] = array2[i];
array2[i] = tmp;
}
Now you need to find what has changed in the arrays. You can do this by comparing the parts you swapped.
int m1 = 0, m2 = 0;
int missing_array1[n];
int missing_array2[n];
for(int i = 0; i < n; i++){
bool found = false;
for(int j = 0; j < n; j++){
if(array1[i] == array2[j]){
found = true;
break;
}
}
if(!found){
missing_array2[m2++] = array1[i];
}
}
for(int i = 0; i < n; i++){
bool found = false;
for(int j = 0; j < n; j++){
if(array2[i] == array1[j]){
found = true;
break;
}
}
if(!found){
missing_array1[m1++] = array2[i];
}
}
missing_array2 now contains the numbers that are missing from array2. These are all the numbers that will be duplicated in array1. The same goes for missing_array1. Next you need to scan both arrays and replace the duplicates with the missing numbers.
while(m1 >= 0){
int z = 0;
while(missing_array1[m1] != array2[n + z]){
z++;
}
array2[n + z] = missing_array2[m1--];
}
while(m2 >= 0){
int z = 0;
while(missing_array2[m2] != array1[n + z]){
z++;
}
array1[n + z] = missing_array1[m2--];
}
In summary, you compare the parts you swapped to find the values that will be missing from each array. These value are also the values that will be duplicated in the opposite array. Then you scan each of the arrays and replace the duplicate values with one of the missing values (I assume you don't care which of the missing values, as long as all the values are unique.
If the swapped portions of the sequences contain the same values, then there would be no repeats - performing the swap would just shuffle the first n elements. So the values you need to repair are the values which occur in one of the swapped sequences
Firstly, I'd create a histogram of the n swapped elements, with those from sequence 1 counting as bit 0, and those from sequence 2 as bit 1. If any members of the histogram are non-zero, then they occur in one or the other sequence only.
If there are values requiring repair, then you can construct a look-up table of the values which require rewriting. This should map i to i unless i is one of the asymmetric values in the histogram, in which case it needs to map to the another asymmetric value.
Seq1: 1 4 5 6 9 8 2 3 7
Seq2: 3 9 1 2 8 7 4 5 6
If n = 4
Seq1: 3 9 1 2 | 9 8 2 3 7
Seq2: 1 4 5 6 | 8 7 4 5 6
histogram
value 1 2 3 4 5 6 7 8 9
count 3 1 1 2 2 2 0 0 1
mapping for sequence 1 ( while histogram [S1[i]] & 1, replace[S1[i]] with S2[i] )
value 1 2 3 4 5 6 7 8 9
replace 1 6 5 4 5 6 7 8 4
apply mapping to sequence 1 for i > n
Seq1: 3 9 1 2 | 9 8 2 3 7
replace - - - - | 4 8 6 5 7
result 3 9 1 2 | 4 8 6 5 7
mapping for sequence 2 ( while histogram [S2[i]] & 2, replace[S2[i]] with S1[i] )
value 1 2 3 4 5 6 7 8 9
replace 1 2 3 9 3 2 7 8 9
apply mapping to sequence 1 for i > n
Seq2: 1 4 5 6 | 8 7 4 5 6
replace - - - - | 8 7 9 3 2
result 1 4 5 6 | 8 7 9 3 2
Alternatively, replace with the next value with the other bit set in the histogram (the iterated replace will also need to check for replacing a value with itself); I'm assuming it doesn't really matter what value is used as the replacement as long as the values in the result are unique.

Resources