Skip to main content
We’ve updated our Terms of Service. A new AI Addendum clarifies how Stack Overflow utilizes AI interactions.
Code Golf

Return to Answer

Commonmark migration
Source Link

#C, 106#

C, 106

#C, 106#

C, 106

added 1909 characters in body
Source Link
Level River St
  • 28.8k
  • 4
  • 40
  • 112

#C##C, 106#

It's late here. I'll explain how this works and golf it tomorrow.Golfed version

f(n){
 for(int i,h=n*2<<n;h--;(i/3|i/3*2)-i||(putchar(i>>h%n&1?45:124),h%n||puts(h%(n*2)?"":"\n")))
 i=h/2/n;
}

Original version

i,j,n;
main(){
 scanf("%d",&n);
 for(i=1<<n;i--;)if((i/3|i/3*2)==i){
 for(j=1<<n;j/=2;)printf("%c",i&j?'-':'|');puts("");
 for(j=1<<n;j/=2;)printf("%c",i&j?'-':'|');puts("\n");
 }
}

I've tested it upHow it works

The variable i runs from 1<<n-1 down to n=70, producing all possible binary numbers with n digits. 0 encodes for | and 1 encodes for -. We are interested in numbers that contain 1's in pairs. Obviously such numbers are divisible by 3.

When a number is divided by 3, the original number can be recovered by multiplying the result by 2 and adding it seems to be working fineitself (effectively mutliplying by 3. Here's) Most numbers will require a carry, but when the resultprocess is carried out on the numbers of interest, no carry is required, so in these cases only, OR can be used instead of addition. This is used to test for n=6:the numbers of interest, as they are the only ones where the expression i/3|i/3*2 returns the original value of i. See example below.

1111=15 ---> 0101=5 ---> 1111=15 (valid, 0101|1010==0101+1010)

1001=9 ---> 0011=3 ---> 0111=7 (invalid, 0011|0110 != 0011+0110)

The test value is always equal or less than the original value. As numbers that are not multiples of 3 also return a number less than the original when divided by 3 then multipled by 3, the test gives the desired FALSE on these numbers too.

In the original version a couple of loops in j are used to scan through the bits of i and produce the output. In the golfed version a single for loop is used, in which h runs through all numbers from (n*2)*(1<<n)-1 down to 0. Values of i are generated by h/2/n. The variable j is no longer used, as the equivalent quantity is obtained from h%n. The use of n*2 enables both lines to be printed from the same loop, with some nifty multiplexing in the puts statement to print either one or two newlines at the end of the row.

Note that the meat of this is in the increment position of the for() bracket and therefore gets executed after the i=h/2/h.

Sample output n=6:

#C#

It's late here. I'll explain how this works and golf it tomorrow.

i,j,n;
main(){
 scanf("%d",&n);
 for(i=1<<n;i--;)if((i/3|i/3*2)==i){
 for(j=1<<n;j/=2;)printf("%c",i&j?'-':'|');puts("");
 for(j=1<<n;j/=2;)printf("%c",i&j?'-':'|');puts("\n");
 }
}

I've tested it up to n=7 and it seems to be working fine. Here's the result for n=6:

#C, 106#

Golfed version

f(n){
 for(int i,h=n*2<<n;h--;(i/3|i/3*2)-i||(putchar(i>>h%n&1?45:124),h%n||puts(h%(n*2)?"":"\n")))
 i=h/2/n;
}

Original version

i,j,n;
main(){
 scanf("%d",&n);
 for(i=1<<n;i--;)if((i/3|i/3*2)==i){
 for(j=1<<n;j/=2;)printf("%c",i&j?'-':'|');puts("");
 for(j=1<<n;j/=2;)printf("%c",i&j?'-':'|');puts("\n");
 }
}

How it works

The variable i runs from 1<<n-1 down to 0, producing all possible binary numbers with n digits. 0 encodes for | and 1 encodes for -. We are interested in numbers that contain 1's in pairs. Obviously such numbers are divisible by 3.

When a number is divided by 3, the original number can be recovered by multiplying the result by 2 and adding it to itself (effectively mutliplying by 3.) Most numbers will require a carry, but when the process is carried out on the numbers of interest, no carry is required, so in these cases only, OR can be used instead of addition. This is used to test for the numbers of interest, as they are the only ones where the expression i/3|i/3*2 returns the original value of i. See example below.

1111=15 ---> 0101=5 ---> 1111=15 (valid, 0101|1010==0101+1010)

1001=9 ---> 0011=3 ---> 0111=7 (invalid, 0011|0110 != 0011+0110)

The test value is always equal or less than the original value. As numbers that are not multiples of 3 also return a number less than the original when divided by 3 then multipled by 3, the test gives the desired FALSE on these numbers too.

In the original version a couple of loops in j are used to scan through the bits of i and produce the output. In the golfed version a single for loop is used, in which h runs through all numbers from (n*2)*(1<<n)-1 down to 0. Values of i are generated by h/2/n. The variable j is no longer used, as the equivalent quantity is obtained from h%n. The use of n*2 enables both lines to be printed from the same loop, with some nifty multiplexing in the puts statement to print either one or two newlines at the end of the row.

Note that the meat of this is in the increment position of the for() bracket and therefore gets executed after the i=h/2/h.

Sample output n=6:

Source Link
Level River St
  • 28.8k
  • 4
  • 40
  • 112

#C#

It's late here. I'll explain how this works and golf it tomorrow.

i,j,n;
main(){
 scanf("%d",&n);
 for(i=1<<n;i--;)if((i/3|i/3*2)==i){
 for(j=1<<n;j/=2;)printf("%c",i&j?'-':'|');puts("");
 for(j=1<<n;j/=2;)printf("%c",i&j?'-':'|');puts("\n");
 }
}

I've tested it up to n=7 and it seems to be working fine. Here's the result for n=6:

$ ./a
6
------
------
----||
----||
--|--|
--|--|
--||--
--||--
--||||
--||||
|----|
|----|
|--|--
|--|--
|--|||
|--|||
||----
||----
||--||
||--||
|||--|
|||--|
||||--
||||--
||||||
||||||

AltStyle によって変換されたページ (->オリジナル) /