31
\$\begingroup\$

Goal

You have to print the ASCII printable characters' code page (0x20-0x7E). The output should look like this:

 !"#$%&'()*+,-./
0123456789:;<=>?
@ABCDEFGHIJKLMNO
PQRSTUVWXYZ[\]^_
`abcdefghijklmno
pqrstuvwxyz{|}~

Rules

  • The output should be exactly like shown above, but trailing whitespace is OK.
  • No builtins that trivialize the question (e.g. the ones that print the ASCII table) ! They can be posted for documentation purposes, but will not be in the leaderboards.
  • Standard rules for I/O and loopholes apply.
  • Lowest bytecount wins.

Good Luck!

P.S. This challenge is well-known, but a straight "print every single printable ASCII character" has somehow never been done here.

\$\endgroup\$
17
  • 7
    \$\begingroup\$ Could you clarify exactly what you mean by "No builtins"? No builtins if they return exactly that output? No builtins that return any kind of ASCII table? No builtins at all (which would make this impossible in most languages)? \$\endgroup\$
    – pxeger
    Jun 29, 2022 at 7:23
  • 5
    \$\begingroup\$ Many built-ins for the ascii table seem to include characters like the line break and tab so I think they wouldn't work anyways. \$\endgroup\$
    – mousetail
    Jun 29, 2022 at 7:27
  • 5
    \$\begingroup\$ trivialize the question is not objectively defined. If a builtin outputs the string of ASCII codes (not formatted as a table), does that trivialize the question? If it outputs an ASCII table with a different format? \$\endgroup\$
    – Luis Mendo
    Jun 29, 2022 at 12:24
  • 6
    \$\begingroup\$ Is a trailing space accepted, to make the last line the same length as the others? \$\endgroup\$
    – Luis Mendo
    Jun 29, 2022 at 12:28
  • 2
    \$\begingroup\$ @LuisMendo Yes, it trivializes the question. A trailing space is OK but not necessary. \$\endgroup\$
    – loggeek
    Jun 29, 2022 at 14:24

81 Answers 81

2
\$\begingroup\$

C (clang), 51 \$\cdots\$ 49 48 bytes

f(c){for(c=32;putchar(c)<126;++c%16||puts(""));}

Try it online!

Saved a 2 bytes thanks to tsh!!!
Saved a bytes thanks to ovs!!!

\$\endgroup\$
7
  • \$\begingroup\$ 50 bytes: c;f(){for(;c=-~c%96;c%16||puts(""))putchar(c+31);} \$\endgroup\$
    – tsh
    Jun 29, 2022 at 9:42
  • \$\begingroup\$ Also 50 bytes: main(c){for(;++c<97;)~putchar(30+c)%16||puts("");} and c;f(){++c%96&&f(~putchar(c+31)%16||puts(""));c=0;} \$\endgroup\$
    – tsh
    Jun 29, 2022 at 9:54
  • \$\begingroup\$ Also, seems that the third one may be 49 bytes if we can allow the function not been reusable after c got integer overflow (\$>2^{31}-1\$): c;f(){++c%96&&f(~putchar(c%96+31)%16||puts(""));} \$\endgroup\$
    – tsh
    Jun 29, 2022 at 10:06
  • \$\begingroup\$ @tsh Sorry, my bad. Was doing it too quickly and didn't have a puts("") in between f();f();! \$\endgroup\$
    – Noodle9
    Jun 29, 2022 at 10:07
  • \$\begingroup\$ @tsh Very clever - thanks! :D \$\endgroup\$
    – Noodle9
    Jun 29, 2022 at 10:10
2
\$\begingroup\$

Factor, 36 bytes

32 126 [a,b] 16 group "\n"join write

Attempt This Online!

\$\endgroup\$
2
\$\begingroup\$

Pyth, 15 9 bytes

jsMc6rd\

Try it online!

There's a literal DEL character after the \.

jsMc6rd\
     rd\  Half-inclusive string range from ' ' (space) to DEL
   c6     Chop into 6 equal-sized lists (last chunk is smaller)
 sM       Join each list on '' (empty)
j         Join on newlines, implicitly output
\$\endgroup\$
2
\$\begingroup\$

Raku, 33 bytes

.say for (' '..'~').join.comb(16)

Try it online!

\$\endgroup\$
2
\$\begingroup\$

GeoGebra, 68 67 bytes

UnicodeToText(Flatten(Zip(If(Mod(a,16)>14,{a,10},{a}),a,32...126)))

Text is shown on the graph.

Might be golfable with some different strategy, but I'm not too experienced with GeoGebra.

Try It Online!

\$\endgroup\$
3
  • \$\begingroup\$ I think you also printed a Del character at the end, is it allowed? \$\endgroup\$ Jun 29, 2022 at 11:27
  • \$\begingroup\$ @NobodyNeedsNames That is an easy fix. \$\endgroup\$
    – Aiden Chow
    Jun 29, 2022 at 20:31
  • \$\begingroup\$ Good (filler)))))))))) \$\endgroup\$ Jun 30, 2022 at 2:23
2
\$\begingroup\$

Ruby, 53 44 bytes

Thanks user for telling me about each_slice, saving 9 bytes!

(' '..'~').each_slice(16).each{|x|puts x*""}

Try it online!

My first time golfing in Ruby lol, just wanted to try a new language :D . Tell me if there are any golfs, I'm anticipating a lot!

\$\endgroup\$
2
  • 2
    \$\begingroup\$ '~' can be ?~, and you can use _1 instead of x and |x| if you use a newer version, like on ATO \$\endgroup\$
    – naffetS
    Jun 29, 2022 at 23:19
  • 2
    \$\begingroup\$ .each isn't needed; you can pass the block directly to each_slice: ATO. A port of xnor's Python answer is shorter though. \$\endgroup\$
    – Dingus
    Jun 29, 2022 at 23:55
2
\$\begingroup\$

stacked, 23 bytes

95:>32+16 chunk chr out

Try it online!

Slightly shorter than the more obvious 24 bytes:

32 126|>16 chunk chr out

Explanation

95:>32+16 chunk chr out
95:>                       the range of numbers from 0 to 94 inclusive
    32+                    add 32 to each
       16 chunk            split into chunks of 16
                chr        convert each number to a character
                    out    output it

stacked's default output behavior with out for 2D character arrays is exactly joining them, and produces the correct output.

\$\endgroup\$
2
\$\begingroup\$

Pip, 15 bytes

P*C:32,127<>16u

Try It Online!

Explanation

P*C:32,127<>16u
    32,127       Range(32, 127)
          <>16   Group into chunks of size 16 (with the last one being shorter)
  C:             Convert to characters
P*               Print each sublist (concatenated together, by default)
              u  Suppress autoprinting of the last expression

Or, with the -l flag to handle the output formatting, it would be 12 bytes:

C:32,127<>16

Using built-in

PA is a string containing all printable ASCII characters, so:

PA<>16Jn

Or, with the -l flag:

PA<>16
\$\endgroup\$
2
\$\begingroup\$

Regenerate -a -s=, 45 bytes

[ -/]|
|[0-?]|
|[@-O]|
|[P-_]|
|[`-o]|
|[p-~]

Attempt This Online!

Explanation

The -a flag requests all possible matches; the -s= flag sets the separator between matches to empty string. Then the regex is just a big alternation: "match any character from to /, or a newline, or any character from 0 to ?, or a newline, or..." The regex always matches one character, and the -a flag outputs all of them.

\$\endgroup\$
2
\$\begingroup\$

Brainfuck + head + sh, 65 + 10 bytes

>-[-[-<]>>+<]>->++++++[->>++++[-<++++>]<[-<<.+>>]++++++++++.[-]<]

Execute <brainfuck-program>|head -c-2 (see meta).

head removes a trailing \del char of the brainfuck program output (as noted by @mousetail).

Attempt This Online!

\$\endgroup\$
1
  • \$\begingroup\$ This prints \del at the end, which is not allowed \$\endgroup\$
    – mousetail
    Jul 1, 2022 at 14:43
2
\$\begingroup\$

Kotlin, 80 72 56 bytes

56 bytes versuin

(' '..'~').chunked(16).flatMap{it+"\n"}.joinToString("")

Directly using a char range instead of an integer range.

Try it online!

72 bytes version

(32..126).chunked(16).flatMap{it.map{it.toChar()}+"\n"}.joinToString("")

Try it online!

80 bytes version

(32..126).chunked(16){it.joinToString(""){""+it.toChar()}+"\n"}.joinToString("")

Try it online!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Welcome to Code Golf, and nice answer! \$\endgroup\$
    – Seggan
    Jul 9, 2022 at 16:19
2
\$\begingroup\$

Nibbles, 7.5 bytes (15 nibbles)

`/16+' '`,95
`/16+' '`,95
        `,95    # range from 0 to 95
    +' '        # add each to a space character
`/16            # and split into chunks of 16

enter image description here


Nibbles, 5 bytes (10 nibbles)

`/16>>`<@

Uses the special value assigned to @ when input is empty, corresponding to a list of ascii characters including newline, in a non-standard order.


`/16>>`<@
        @       # " abcdefghijklmnopqrstuvwxyz.,!?_"
                # + newline +
                # "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-+:;\"'~`@#$%^&*()[]{}<>\\/=|"
      `<        # sort 
    >>          # remove first item (newline)
`/16            # and split into chunks of 16
```
\$\endgroup\$
2
\$\begingroup\$

Piet + ascii-piet, 59 bytes (4×26=104 codels)

tliusqrfvrtqqqqijsmva???Bt  t?sd???vmjftrqaaaaqrsb_t eTt ee

Try Piet online!

How it works

4 dup * dup +         Initialize n to 32
Loop:
    dup outC          [n] Print as char
    1 + dup dup       [n n n] Add 1 and make two more copies
    4 dup * % !       [n n n%16==0] Is this number divisible by 16?
    CC+               [n n] If so,
        5 dup + outC        Print newline
    5 dup dup * * >   [n n>125] Is this number greater than 125?
    ! DP+             [n] If not, go back to start of Loop
outC                  Otherwise, print n (126) and exit
\$\endgroup\$
1
  • \$\begingroup\$ I thought my Piet answer was pretty good. Lol nope \$\endgroup\$
    – Aiden Chow
    Jul 4, 2022 at 8:05
2
\$\begingroup\$

Vim, 50 bytes

i<C-r>=joi<Tab>m<Tab>r<Tab>32,126),'"<C-v><C-v>".v:val'),"")
<Esc>qq16|a
<Esc>q4@q

Try it online!

As pointed out by @Ray, if you have version 8.1.26 or newer, you'll have to replace r<Tab> with rang<Tab> for 53 bytes.

Explanation

i<C-r>=                                                       # Insert the result of:
               m<Tab>             ,                    )      #   Map...
                                   '"<C-v><C-v>".v:val'       #     Convert to char...
                     r<Tab>32,126)                            #     over range [32,126]
       joi<Tab>                                         ,"")  #   Join with empty strings
<Esc>
     qq                                                       # Record macro @q:
       16|                                                    #   Go to 16th character
          a                                                   #   Add a newline
<Esc>q
      4@q                                                     # Run macro @q 4 times
\$\endgroup\$
1
\$\begingroup\$

Clojure, 72 63 bytes

(doseq[x(range 32 127)](print(str(char x)({15 \
}(rem x 16)))))

Try it online!

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

Retina, 19 bytes


6*$(16*1¶
Y`1` -~_

Try it online! Explanation:


6*$(16*1¶

Insert 6 rows of 16 1s.

Y`1` -~_

Cyclically transliterate the first 95 1s to the range from to ~ and delete the 96th.

\$\endgroup\$
1
  • \$\begingroup\$ The question has since been edited to allow any trailing whitespace, in which case save 1 byte removing the _, which makes the transliteration wrap around so that the 96th 1 transliterates to ` ` again. \$\endgroup\$
    – Neil
    Jun 29, 2022 at 17:41
1
\$\begingroup\$

Husk, 11 bytes

↓2C16mcŀ127

Try it online!

       ŀ127 # range from zero to 126
     mc     # map across this & get characters
  C16       # cut into sublists with length 16
↓2          # drop the first 2 of them
\$\endgroup\$
1
\$\begingroup\$

Python 2, 68 bytes

l=''.join(chr(x+32)for x in range(95))
while l:print l[:16];l=l[16:]

Try it online!

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

MATL, 8 bytes

'~':16e!

Try it online! Outputs a trailing whitespace (to make the last row have the same length as the others).

How it works

'~'   % Push this character
:     % Range from space to that character, including both. Gives a character vector
16e   % Format as a 16-row character matrix, in major-column order. Pads with
      % character 0 at the end
!     % Transpose
      % Implicit display. Character 0 is displayed as space
\$\endgroup\$
0
1
\$\begingroup\$

Jelly, 10 bytes

32r126Ọs⁴Y

Try it online!

5 if we can just use our langauage's features:

ØṖs⁴Y

How?

32r126Ọs⁴Y - Link: no arguments
32         - 32                }
   126     - 126               }
  r        - inclusive range   }
      Ọ    - cast to ordinals  } - together this is the same as ØṖ yields
        ⁴  - 16
       s   - split into chunks of length (up to 16)
         Y - join with newline characters
\$\endgroup\$
1
\$\begingroup\$

Bubblegum, 102 bytes

00000000: 5350 5452 5651 5553 d7d0 d4d2 d6d1 d5d3  SPTRVQUS........
00000010: e732 3034 3236 3135 33b7 b0b4 b2b6 b1b5  .20426153.......
00000020: b3e7 7270 7472 7671 7573 f7f0 f4f2 f6f1  ..rptrvqus......
00000030: f5f3 e70a 080c 0a0e 090d 0b8f 888c 8a8e  ................
00000040: 898d 8be7 4a48 4c4a 4e49 4d4b cfc8 ccca  ....JHLJNIMK....
00000050: cec9 cdcb e72a 282c 2a2e 292d 2baf a8ac  .....*(,*.)-+...
00000060: aaae a9ad 0300                           ......

Try it online!

For some reason, compressing it made it actually a bit larger than the original string.

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

JavaScript (Node.js), 63 bytes

for(i=33,a=' ';i<129;a+=Buffer([i++]))i%16||console.log(a,a='')

Attempt This Online!

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

Haskell, 65 bytes

_#[]=[]
n#x=take n x:n#drop n x
main=putStr$unlines$16#[' '..'~']

Attempt This Online!

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

Forth (gforth), 52 bytes

: f 127 32 do i emit i 16 mod 15 = if cr then loop ;

Try it online!

Explanation

Loops from 32 to 127 (end is non-inclusive). Outputs the ascii char for each number, if index % 16 == 15, outputs a newline.

Code Explanation

: f            \ start a new word definition
  127 32       \ set up loop bounds
  do           \ start a new counted loop
    i emit     \ output the ascii character for the current loop index
    i 16 mod   \ get index modulo 16
    15 =       \ check if result is equal to 15
    if cr then \ if it is, output a newline
  loop         \ end the counted loop
 ;             \ end the word definition
\$\endgroup\$
1
\$\begingroup\$

Acc!!, 67 bytes

Count i while i-100 {
1/((i+1)%17+1)
Write 10*_+(i+32-i/17)*(1-_)
}

Try it online!

Explanation

We run a single loop that outputs one character each time, using math to switch between ASCII characters and newlines.

The loop index i runs from 0 through 99. We want to print newlines at indices 16, 33, 50, 67, and 84--that is, where (i+1)%17 is zero. With no comparison operators in Acc!!, we use integer division instead: when (i+1)%17 is zero, 1/((i+1)%17+1) is one, and it is zero otherwise. We store this quantity in the accumulator.

Now if the accumulator value is one, we want to write a newline, and if it is zero, we want to write something else. This is easily accomplished by multiplying the two quantities by _ and (1-_) respectively, and adding the results: Write 10*_+(...)*(1-_). It only remains to calculate the ASCII character's codepoint. At first, it is just i+32, but we need to adjust for the newlines. The number of newlines printed so far is i/17, so subtracting this from the index gives us the correct codepoint formula: i+32-i/17.


A more straightforward solution with two loops is 73 bytes:

Count i while i-6 {
Count j while j-16+i/5 {
Write i*16+32+j
}
Write 10
}
\$\endgroup\$
1
\$\begingroup\$

*><>, 53 bytes

e9*&1f+2*   v
v;?=&:&:+1o:<
\:1f+%?!`   /
        `ao

Try it online!

Unfortunately, I feel like a lot of these bytes are spent setting, storing, and checking if we're at 126 yet, but I'm unsure of a better way of accomplishing this.

e9*&            push 126 to the stack, and pop it into a register
    1f+2*       push 32 to the stack
            v   Change IP direction downwards

            <   Change IP direction to the left
          o:    Duplicate the top of the stack, then pop it to STDOUT as a char
       :+1      Add one to the value on the top of the stack, and duplicate it
    &:&         Pop the register back onto the stack, duplicate it, then pop that into the register
 ;?=            If our two duplicated values match, end execution
v               Change IP direction downwards

\               Mirror IP to the right
 :              Duplicate the top of the stack
  1f+           Put 16 on the stack
     %          Get the modulus of our counter and 16
      ?!`       If the result is 0, drop down a line, and 
         ao         Print a newline
        `           And raise back up a line
            /   Else, mirror the IP up
\$\endgroup\$
1
\$\begingroup\$

PARI/GP, 43 bytes

for(i=1,95,printf("%c",i+31);i%16||print())

Attempt This Online!


PARI/GP, 44 bytes

for(i=2,7,print(Strchr([s=16*i..s+15-i\7])))

Attempt This Online!

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

Fig, \$17\log_{256}(96)\approx\$ 13.993 bytes

Without printable ascii builtin

nOC+32r95 16'+xcn

Try it online!

With printable ascii builtin \$10\log_{256}(96)\approx\$ 8.231 bytes

ncp16'+xcn

Try it online!

nOC+32r95 16'+xcn
      r95          # range [0,95)
   +32             # add 32 to each, range [32,126)
  C                # convert each element to str
 O                 # join by nothing
n         16       # every 16th element, apply the function
            '+     # add
               cn  # newline
              x    # to the element

ncp16'+xcn
 cp                # printable ascii
n  16'+xcn         # same as above
\$\endgroup\$
1
\$\begingroup\$

Julia 1.0, 53 52 bytes

0:16:80 .|>n->(prod(' ':'~')*" ")[n+1:n+16]|>println

Try it online!

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

Julia 1.0, 69 63 bytes

map(i->println(String(reshape([' ':'~';' '],(16,6))[:,i])),1:6)

Try it online!

-6 bytes thanks to @amelies: ' ':'~' is a valid range in Julia; no need to convert from integers

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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