100
\$\begingroup\$

Consider a square of printable ASCII characters (code points 0x20 to 0x7E) for side length N, like the following (here, N = 6):

=\    
 g \  
7     
m+y "g
  L ~ 
e> PHq

We also require each row and each column to contain at least 1 space and 1 non-space character. (The above example satisfies this.)

We define the negative of such a square, to be a square of the same size, where each space is replaced with a non-space and vice versa. E.g., the following would be a valid negative of the above example:

  1234
a b cd  
 ZYXWV
   !  
{} [ ] 
  ?   

The choice of non-space characters is irrelevant (as long as they are from the printable ASCII range).

The Challenge

You're to write a program, with square source code with side length N > 1, which prints a negative of itself to STDOUT. Trailing spaces have to be printed. You may or may not print a single trailing newline.

The usual quine rules also apply, so you must not read your own source code, directly or indirectly. Likewise, you must not assume a REPL environment, which automatically prints the value of each entered expression.

The winner is the program with the lowest side length N. In the event of a tie, the submission with the fewest non-space characters in the source code wins. If there's still a tie, the earliest answer wins.

\$\endgroup\$
  • \$\begingroup\$ Is a function's return value accepted or should it be printed to STDOUT? \$\endgroup\$ – Paul Guyot Nov 29 '14 at 23:30
  • 1
    \$\begingroup\$ @PaulGuyot For this challenge, please stick to full programs and STDOUT (as it's, loosely speaking, a quine variant). \$\endgroup\$ – Martin Ender Nov 29 '14 at 23:32
  • \$\begingroup\$ You should clarify that the board size must be N>0. I see that your example specifies N>1 (and did you mean N>=1?), but this is not in the rules proper. \$\endgroup\$ – imallett Nov 30 '14 at 6:11
  • 2
    \$\begingroup\$ @imallett implied by "We also require each row and each column to contain at least 1 space and 1 non-space character". Wait. No. It isn't. Good point. It does imply N==0||N>1, though. \$\endgroup\$ – John Dvorak Nov 30 '14 at 6:38
  • 1
    \$\begingroup\$ @jpcooper Yes, that's a square, but it doesn't satisfy "We also require each row and each column to contain at least 1 space and 1 non-space character." because the first m columns don't contain spaces, and the last n columns don't contain non-spaces. \$\endgroup\$ – Martin Ender Dec 1 '14 at 13:53

25 Answers 25

18
\$\begingroup\$

CJam, 4 x 4 (8 non-spaces)

 L _
{ _ 
 _ }
_ p 

Try it online in the CJam interpreter.

Output

{ _ 
 _ }
{ _ 
 _ }

How it works

  • L pushes an empty array and _ pushes a copy of it.

  • The block

    { _ 
     _ }
    

    pushes that block on the stack.

  • _ pushes a copy of the code block and p prints it, followed by a linefeed.

  • Finally, the interpreter prints all remaining items on the stack: two empty arrays that do not affect the output, and the original code block.

Alternate version

 L ~
{ _ 
 p }
_ ~ 

Try it online in the CJam interpreter.

Output

{ _ 
 p }
{ _ 
 p }

How it works

  • L pushes an empty array and ~ dumps it. The stack is empty again.

  • The block

    { _ 
     p }
    

    pushes that block on the stack.

  • _ pushes a copy of the block and ~ executes the copy.

    The _ inside the copy of the block will push a copy of the original block, which p will print, followed by a linefeed.

  • Finally, the interpreter prints the remaining item on the stack: the original code block.

\$\endgroup\$
104
\$\begingroup\$

Perl, 7×7 (42 non-spaces)

for$i( 
1..56 )
{$_= $i
%8? $i%
7? $":7
: $/;1;
 print}

Output:

      7
     7 
    7  
   7   
  7    
 7     
7      
\$\endgroup\$
  • 10
    \$\begingroup\$ This is one of the coolest pieces of code I've seen in a long time. \$\endgroup\$ – Kasran Nov 29 '14 at 23:40
  • \$\begingroup\$ Straightforward and simple, but quite boring. Still +1. \$\endgroup\$ – Nova Nov 30 '14 at 0:57
  • 8
    \$\begingroup\$ It would be even more cool if it displayed a 7 made of 7. :) \$\endgroup\$ – A.L Nov 30 '14 at 23:09
  • 1
    \$\begingroup\$ @A.L Just need 8 more characters (7 spaces and a newline). \$\endgroup\$ – Qix Dec 1 '14 at 7:08
77
\$\begingroup\$

CJam, 4X4 (12 10 non-spaces)

 6, 
SS +
* 4/
 N* 

Output:

0  1
  2 
 3  
4  5

Previous version with 12 non-spaces:

 4a4
* 4S
** 4
/N* 

And the output is

4   
 4  
  4 
   4

As pointed out by Martin, this version has

  • 4 Spaces,
  • 4 *,
  • 4 4,
  • 4 other characters, and
  • 4 4 as the output

;)

Try it online here

\$\endgroup\$
  • 22
    \$\begingroup\$ It also has 4 upvotes, but I'm about to spoil that for you. Sorry! :-D \$\endgroup\$ – squeamish ossifrage Nov 30 '14 at 14:10
  • 7
    \$\begingroup\$ Maybe we can get it to 44? +1 :) \$\endgroup\$ – Doorknob Nov 30 '14 at 17:38
  • 4
    \$\begingroup\$ Keep the pace going till 4^4 \$\endgroup\$ – Optimizer Dec 1 '14 at 6:28
  • 17
    \$\begingroup\$ Doesn't 4^4 == 0? ;) \$\endgroup\$ – zennehoy Dec 1 '14 at 17:22
  • 1
    \$\begingroup\$ Yeah, I don't like the fact that bitwise XOR stole the symbol that should have been used for exponents. Messes up code readability, honestly. \$\endgroup\$ – SuperJedi224 Apr 10 '15 at 2:01
50
\$\begingroup\$

Marbelous - 16x16

....@0..@1....  
@3..0A08..@2  ..
/\--....>1  ..Hp
..@2..\\  =0@3..
ss..//  --\\\\..
@0/\  @1/\Hp..!!
:s  #the-cake-is
  2020#a-pie/lie

Test it here! Spaces as blanks, cylindrical board, and include libraries all must be checked.

Output

              07
            06  
          05    
        04      
      03        
    02          
  01            
01              

Explanation

There are two boards here: the main board (shown below), and the ss board, which takes no inputs and outputs two spaces (0x20) to STDOUT.

A blank cell is equivalent to a .., and anything after a # is a comment.

Picture of Board

Every tick, ss outputs two spaces to STDOUT.

The green path is a simple loop that outputs a newline (0x0A) at the end of every 7th tick.

The blue path will output the numbers (Hp prints a marble as two hex digits) present in the output, at the end of every 6th tick.

After we have printed 01 once, the loop ends, and moves down the red path, which duplicates this marble.

One duplicate is printed (the second 01), and the other is sent down the black path, which terminates the board at the !! cell. Because of the location of the Hp used in this last print, the 01 appears before the same tick's two spaces, rather than after, the behavior of every other Hp call.

\$\endgroup\$
  • 9
    \$\begingroup\$ Upvoting for the graphical representation of the source. \$\endgroup\$ – Riking Dec 1 '14 at 6:33
35
\$\begingroup\$

Python - 11x11

import re
[print(
    re.sub(
"0",   " ",
bin(x)[
2:].zfill(
11)))for x
in[19,15,
1920,116,
15,1,5,3,
3,3, 67]]

Output

      1  11
       1111
1111       
    111 1  
       1111
          1
        1 1
         11
         11
         11
    1    11

It's a pretty messy and boring solution, but I just thought I'd show that...

  1. It can be done in Python
  2. If you can compress information about your code shorter than your code, then you can pull off something like this :)

This solution takes advantage of the fact that, if you're within a pair of brackets in Python, then you can split your code over several lines and arbitrarily add spaces without getting an IndentationError. Another way of doing something like this is by ending the line with a backslash.

\$\endgroup\$
33
\$\begingroup\$

Python - 7x7 (37 non-spaces)

print( 
'%+7s' 
'\n'%1 
*6+'%' 
'-7s'% 
111111 
      )

Output

      1
      1
      1
      1
      1
      1
111111 

Uses Python's old % string formatting operator to do the job: +7 and -7 take care of right/left justification, and the last space to match the closing parenthesis for print in particular. In preparing the format string, we also have

  • automatic concatenation of string literals across lines, and
  • string repetition by multiplication (giving us multiple replacement fields for the price of one)
\$\endgroup\$
18
\$\begingroup\$

JavaScript (9x9)

 i=9;q=""
; for(;++
i< 91;){;
var q=q+(
!(i% 10.0
)?1:" ");
;i%9|| (q
+="\n") }
alert(q) 

Output

1        
 1       
  1      
   1     
    1    
     1   
      1  
       1 
        1

Notes

I made and golfed (to the best of my ability) code for a square with diagonal of any size n:

q="";for(i=***n***;++i<***n^2+n+1***;i%***n***||(q+="\n"))q+=i%***n+1***?"0":1

replacing the ***asdf*** numbers with constants depending on the side length n, for example for n=6:

q="";for(i=6;++i<43;i%6||(q+="\n"))q+=i%7?" ":1

But, even though that code is length 46, I couldn't get the constant space to line up with a space in the diagonal of the code until it was as big as a 9x9, with a wasted line (the 5th one)

Edit: Changed to add alert(). Before:

 i=9;q=""
; while((
++ i)<91)
{q= q+""+
""+( "")+
(!((i %10
))?1:" ")
;i%9||( q
+="\n")} 
\$\endgroup\$
  • \$\begingroup\$ Ahh, yea, oops, I see what you mean. I'm fixing it right now, sorry. \$\endgroup\$ – Kuilin Li Nov 30 '14 at 7:37
  • \$\begingroup\$ You've got some unitialised global variables over there :P \$\endgroup\$ – Tomáš Zato - Reinstate Monica Dec 2 '14 at 14:20
16
\$\begingroup\$

CJam, 5x5, 12 non-spaces

Not a winner, but I wanted to add a rather small and sparse submission, since most answers just print a diagonal.

 1 ]
D * S
 * 5
/ N *
 1 ; 

prints

1 1 1
 1 1 
1 1 1
 1 1 
1 1 1

Test it here.

The last two characters of the code, don't do anything, so it actually only has 10 bytes of real code. For a smaller grid, I could even reduce it by another two bytes to 8, but that doesn't fit on 3x3, and this code doesn't work for even grid sizes.

How it works:

1]           "Push [1].";
  D*         "Repeat 13 times.";
    S*       "Riffle with spaces.";
      5/     "Split into runs of five elements.";
        N*   "Join those with line breaks.";
          1; "Push and pop a 1. No-op.";
\$\endgroup\$
  • \$\begingroup\$ The exploded CJam and Pyth answers are by far my favourite thing on the site. Have an upvote, Reddit-style. \$\endgroup\$ – Soham Chowdhury Dec 6 '14 at 18:53
14
\$\begingroup\$

Befunge, 9x9

I have no idea why I did this. It took way too long. I have a massive headache now.

8>v_20gv 
v9<^v#<4 
1@,/<>^6 
v1,*$:<p 
->,!-^87 
:^*25<^g 
_88g,^^4 
9vp\v#6< 
        @

Output:

        @
        @
        @
        @
        @
        @
        @
        @
$$$$$$$$ 

Some explanation

The code uses g to read the @ characters from the grid "on the fly" (and also the final space, which is @ / 2), and p to modify the loop to write the last output line.

Every single character on the code is used at some point, either as code or as data (the 9 and the @ on the two last lines).

I basically had to do a lot of workarounds to make the code work. The instruction pointer does multiple intersections during execution, of which some are jumped over. (I couldn't use any instruction there for different directions as they would interfere. There is no NOP.) Elsewhere I either reused the same character or just undid it (see the $: in the middle).

I also did some creative work on the stack:

  • When the (inner) character writing loop terminates (all spaces done for this line), the stack has n,0. I then have to decrement n. The obvious solution would be $1-, but I managed to shorten it by using !-.
  • When the (outer) line writing loop terminates (all normal lines printed), the stack has a 0. I then organized code changer (20g46p7g46\p) to use that 0, instead of wasting 2 characters on $0.
\$\endgroup\$
  • \$\begingroup\$ Befunge always gets a +1 from me. Nice with the !-; that's something I'd do. Fun fact: In Funge-98, z is a NOP. \$\endgroup\$ – Kasran Dec 4 '14 at 20:09
  • \$\begingroup\$ @Kasran Yeah. z wasn't listed on the wiki and I used this for coding, which meant any non-command flipped the IP direction. Pretty much had to refactor 70% of the code due to one place that should be NOP. \$\endgroup\$ – PurkkaKoodari Dec 4 '14 at 20:47
  • \$\begingroup\$ Well, the advantage of doing that is that your code will run in Befunge-95 (which I don't believe has a non-space NOP) as well as 98; since it's a lot harder to use 95, I've always found those answers extra impressive. \$\endgroup\$ – Kasran Dec 4 '14 at 20:52
13
\$\begingroup\$

Python 3, 8x8

There are 50 non-space characters and 14 spaces. The last line has one useless character, but everything else is necessary.

(*_,q,n 
)=p=''' 
       p
'''[2:] 
print(p 
*2+q*7, 
n+p*4+p 
[0:-1]) 

Output:

       p
       p
ppppppp 
       p
       p
       p
       p
       p
\$\endgroup\$
  • 2
    \$\begingroup\$ Just tried playing around with (a,*b,c)="12345"... starred assignment is interesting :) \$\endgroup\$ – Sp3000 Nov 30 '14 at 5:43
  • \$\begingroup\$ @sp3000 kind of haskell-esque. i use python way more than haskell, how did i not know this \$\endgroup\$ – undergroundmonorail Nov 30 '14 at 10:53
11
\$\begingroup\$

Ruby, 8x8

 (0...8)
. map(){
|x |$><<
32. chr*
x+[x ]*'
'<<32 .\
chr*(7 -
x)+?\n} 

Output:

0       
 1      
  2     
   3    
    4   
     5  
      6 
       7
\$\endgroup\$
9
\$\begingroup\$

CJam, 5X5

SSSS 
1N]4 
*B11 
    S

And the output is

    1
    1
    1
    1
1111 

I was this close to 4X4 solution. <sigh> See my other answer

Try it online here

\$\endgroup\$
9
\$\begingroup\$

C++, 12x12

Edit: So, I became a little obsessed with this challenge and managed to get it down from 17x17 to 12x12. It took me a little while to realize I could use /**/ as a token delimiter. This code takes advantage of the fact that a line splice still works in Clang with a space after it, though it does give warnings and ruins Xcode's colorization of the code.

#include<c\ 
stdio>/***/ 
int/**/mai\ 
n(){for(in\ 
t/**/i=0;i\ 
<12;++i)pr\ 
intf(i^8?"\ 
           \
|\n":"~~~~\ 
~~~~~~~\x2\ 
0\n");}/**/ 

Output:

           |
           |
           |
           |
           |
           |
           |
           |
~~~~~~~~~~~ 
           |
           |
           |
\$\endgroup\$
5
\$\begingroup\$

Befunge-98, 8x8 (56 non-spaces [11 nops])

Note: In the interest of good sports-person-ship, this reads its own source via ', making it a cheat-quine to some. Read the debate here.

Program

 07'?>:8v
v y+da:%<
<v ':vj!-
,+# '<zzv
v1#a vj!<
>z,\1 -\v
z>+,$v z<
1_@#:<v -
zzzzzv<z 

Output

(       
 ,      
  &     
   %    
    $   
     #  
      " 
       !

Explanation

The un-golfed version

07'?>:8%:ad+y-!jv>'n,$v
  !jv   a,\1-\v > 's,  
    >         >       v
    v-1_@#:           <

(non-space and space are replaced with 'n and 's for readability sake.)

This solution is based off of the fact that using an index [0,width^2) mod the width of the square can tell you if you are at the end of the row or on the diagonal. Since all spaces are placed along the diagonal, it is easy to tell when to print a non-space!

In Pseudocode

const int WIDTH = 8
push 0    //Because of the way the 'y' instruction works when picking
int row=7 //8-1 rows
int i=63  //Starting at the end allows for the cheaper i != 0
do
{
    pick variable row from the stack bottom + 1//ad+y
    if(i%WIDTH == row)
    {
        print non-space
    }
    else
    {
        print space
        if(i%WIDTH == 0)
        {
            print new-line
            --row
        }
    }
  --i
}
while(i != 0);

Discussion

I'm very proud of it, though I wish I could have made every non-space also a non-nop. I'm also proud that I didn't use the standard Befunge get-increment-put trope! It prints out different symbols for non-space because I had the room for it and didn't want to be boring.

Try it on Windows with BefungeSharp!

\$\endgroup\$
4
\$\begingroup\$

CJam, 4 x 4 (8 non-spaces)

 N a
` S 
 * N
X $ 

Try it online in the CJam interpreter.

Output

[ " 
 " ]
[ " 
 " ]

How it works

  • N pushes a linefeed as a singleton string. a wraps that string in an array.

  • ` inspects the result, i.e., it pushes a string representation of the array.

    This is the result:

    ["
    "]
    
  • S* joins the resulting string (array of characters), separating its elements using spaces. In other words, it puts a space character between all pairs of adjacent characters of the string.

    This is the result:

    [ " 
     " ]
    
  • N pushes another linefeed.

  • X$ copies the stack item at index 1 (counting from the top), i.e., the multi-line string.

  • Finally, the interpreter prints all items on the stack: the original multi-line string, the linefeed and the copy of the multi-line string.

\$\endgroup\$
4
\$\begingroup\$

SOGL V0.12, 2x2 (2 non-spaces)

2 
 ╚

Try it Here!

Output

 /
/ 

Explanation

In SOGL all lines except the last are replacing lines - it replaces everywhere in the continuing code the last character of the line with everything before it. SO the 1st line here is replace space with 2 in the next line.
Then the next line - 2╚ gets executed: 2 pushes 2, and creates a diagonal of size 2.

\$\endgroup\$
3
\$\begingroup\$

CBM BASIC v2.0 (8×8)

An improvement over my previous answer, using a completely different approach:

1s=56/8 
2?sP7); 
3?"?":: 
4s=s-+1 
5ifsgO2 
6?-8^6; 
7?sP1): 
       8

Output:

       ?
       ?
       ?
       ?
       ?
       ?
       ?
-262144 
\$\endgroup\$
3
\$\begingroup\$

Ruby, 8x8 7x7

 print(
 (?f+"\
 "*6+?\
 )*6).!
 $><<"\
 f"<<!1
;      

Output:

f      
f      
f      
f      
f      
f      
 ffalse

Previous version, 8x8 with 20 spaces:

  puts((
  "ff"+#
  ?\s*6+
  ?\n)*7
  );$><<
  ?\s*2+
  ?f;p:p
.!

Output:

ff     
ff     
ff     
ff     
ff     
ff
ff     
  ffalse
\$\endgroup\$
3
\$\begingroup\$

Pushy, 4x4 square

Non-competing as the language postdates the challenge:

Code:

 H32
2 C4
:" } 
\o/

Outputs:

d   
 d  
  d 
   d

Try it online!

Because whitespace is irrelevant in Pushy, the code is easily arranged to match the negative of its output. The actual program looks like this:

H      \ Push char 100, 'd'
32 2C  \ Push char 32, a space, and make 2 extra copies
       \ We now have the string 'd   '
4:     \ 4 times do:
  "    \   Print the string
   }   \   Cyclically shift it right, once

Backslashes begin a comment, so the trailing \o/ is just there to complete the negative, and look cool.


Alternatively, for the same score, we can have the following solutions:

Code    Output

 35;    #
3 2j     #
2C 4      #
:"}        #

K 36     #
33 2      #
Ct4        #
 :}"    #
\$\endgroup\$
3
\$\begingroup\$

Haskell, 10 × 10

main=let{ 
0&c='\32' 
!c;n&c=c! 
'\32'>>(n 
-1)&c;a!b 
=putStrLn 
$(b<$[1.. 
10])++[a] 
}in(9&'*' 
         )

Defines a helper function a ! b that prints a line of the form bbbbbbbbba, and a recursive function n & c that prints n lines of the form ccccccccc␣ followed by one line of the form ␣␣␣␣␣␣␣␣␣c.

Uses <$ (fmap const, again) on a range to repeat a character. Note that <$ is only available without imports since GHC 7.10, which post-dates this challenge. I am not entirely sure if this makes this submission noncompeting.

Nothing really exciting with the choice of layout or algorithm here; I didn't have a lot of bytes to spare and it's just fortunate one can get the line breaks to occur around the putStrLn the way they did.

\$\endgroup\$
3
\$\begingroup\$

05AB1E, 3x3 (6 non-space bytes)

 3Ð
Λ q
°° 

Output:

3  
 3 
  3

Try it online.

Explanation:

3Ð       # Push three 3s to the stack
  Λ      # Canvas with parameters num; filler; pattern
         #  num: The amount of characters to display (3)
         #  filler: The character to display ('3')
         #  pattern: The available options are single-digit integers in the range [0,7]
         #           indicating the direction to print in.
         #           (Option 3 is a top-left to bottom-right diagonal line)
    q    # Exit the program
°°       # no-ops to complete the pattern
\$\endgroup\$
2
\$\begingroup\$

Perl, 6x6 (26 non-spaces)

I spent a whlie looking through these and was sure there would be a Perl solution smaller than 7x7 somehow... A very fun challenge! This solution requires -E.

say+( 
$"x5, 
"5$/" 
)x5,5 
x5,$" 
     ;

Usage:

perl -E 'say+( 
$"x5, 
"5\n" 
)x5,5 
x5,$" 
     ;'

Output:

     5
     5
     5
     5
     5
55555 
\$\endgroup\$
2
\$\begingroup\$

CBM BASIC v2.0 (9×9)

0dA8,7,6 
1dA5,4, 3
2dA2,1 ,0
3rEs: rem
4?sP s)::
5:? "*";:
6p =8---s
7 ?sPp):?
 8ifsgO3:

Output:

        *
       * 
      *  
     *   
    *    
   *     
  *      
 *       
*        
\$\endgroup\$
1
\$\begingroup\$

C (gcc), 7x7 8x8

EDIT: Previous version had incorrect behaviour.

 main(i)
{ for(;i
<9 ;pri\
ntf ("%\
*d%" "*\
c",i, 1,
9-i,10 )
,i++);} 

Try it online!

\$\endgroup\$
  • \$\begingroup\$ "We also require each row and each column to contain at least 1 space and 1 non-space character." Your first column is missing a non-space character. \$\endgroup\$ – Kevin Cruijssen Jul 26 '18 at 13:07
  • \$\begingroup\$ @KevinCruijssen Somehow I missed the columns criterion, so they're all wrong. Will remake when I have a real computer at hand. \$\endgroup\$ – gastropner Jul 26 '18 at 13:34
1
\$\begingroup\$

Jelly, 4 x 4 (12 non-spaces)

 4=þ
¢ +⁴
¢+ ⁴
¢ỌY

Try it online!

Output:

!   
 !  
  ! 
   !

This was pretty fun.

How it works

 4=þ    Link 1 (nilad): Generate an identity matrix of size 4
¢ +⁴    Link 2 (nilad): Add 16 to above
¢+ ⁴    Link 3 (nilad): Add 16 again
¢ỌY     Main link (nilad): Convert the above to ASCII chars, and join by newline

Easy part: Jelly ignores whitespaces (as long as only one-byte builtins are used).

Hard part: Each line in Jelly is a separate link (or function), so it's not very short to spread a constant statement in multiple lines. Using a string literal is a good candidate, but no idea how to generate the negative.

\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.