g | x | w | all
Bytes Lang Time Link
045AWK241129T194717Zxrs
006Japt190519T144708ZShaggy
021Wolfram Language Mathematica190519T225604Zatt
040Haskell240203T211243Zuser1210
021Rattle240203T165031Zd01
816Nibbles240203T102524Z鳴神裁四点一号
008Uiua SBCS240202T020304Zchunes
005Thunno 2230726T112520ZThe Thon
007Vyxal220426T030716ZnaffetS
027Factor + grouping.extras220426T033215Zchunes
006Jelly210416T111529Zcaird co
021Ruby210414T152216ZAsone Tu
006Husk201205T162453ZRazetime
063C clang190519T163108Za stone
010GolfScript200326T090059Zuser9206
060APLNARS190608T215608Zuser5898
027GNU sed190608T171655Zseshouma
040Julia 1.0190603T193523Zgggg
093SNOBOL4 CSNOBOL4190603T191946ZGiuseppe
059Haskell190524T172157Zpommicke
084GoLang190526T123532Zsalixor
093Rust190525T053718ZJakob
035PowerShell190524T212254ZAndrei O
025JavaScript190522T221445ZLuvexina
009Pyth190519T193942Zuanirudh
029Befunge93190522T164457Znegative
090Bash190521T145200ZPJF
055C gcc190520T152245Zl4m2
034Kotlin190520T151652Zsnail_
015Perl 5190519T150418ZKjetil S
031Scala190520T110454Zpme
074C# Visual C# Interactive Compiler190520T120149ZInnat3
042Ruby190520T095326ZMax Lang
113Java 10190520T084142ZKevin Cr
016J190520T064131ZGalen Iv
067C gcc190519T230709Zatt
010Charcoal190519T223149ZNeil
010Retina 0.8.2190519T222315ZNeil
023Attache190519T194725ZConor O&
025JavaScript190519T205332ZShaggy
009Jelly190519T192833ZJonathan
00805AB1E190519T130104ZEmigna
010Jelly190519T163655ZNick Ken
034Python 3190519T122400ZBenjamin
011CJam190519T151945ZLuis Men
022APL+WIN190519T124615ZGraham
007Stax190519T150242Zrecursiv
045JavaScript Babel Node190519T150210ZLuis fel
019Perl 6190519T122923ZJo King

AWK, 59 45 bytes

{for(;length%3;)$0=$0"_";gsub(/(...)/,"& ")}1

Attempt This Online!

59 bytes

{for($0=$0"__";i++<(NF-2)/3*3;i+=2)printf$i$(i+1)$(i+2)" "}
{for(;length%3;)$0=$0"_"; # tail padding
gsub(/(...)/,"& ")}       # matches groups of three
1                         # print

Japt, 6 bytes

ò3 ú'_

Try it here

Wolfram Language (Mathematica), 28 21 bytes

-7: No longer requires falsy (False) value on empty input

Apparently this has been wrong for 5 years (trivial fix)

Partition[#,3,3,1,_]&

Try it online!

Takes a list of characters as input. Returns a list of 3-tuples of characters padded with Blanks (_).


34 27 bytes

StringPartition[#<>"__",3]&

Try it online!

String input, list of strings output

Haskell, 40 bytes

f(a:b:c:t)=[a,b,c]:f t
f _=[]
f.(++"__")

Rattle, 21 bytes

\__|!II^/3P[[gb>]3B]`

Try it Online!

Outputs groups of 3 separated by newlines.

Explanation:

\__|                  take input and concatenate "__"
    !                 disable implicit output
     I                save characters of the input in consecutive memory slots
      I^              get length of the input
        /3            divide by 3 to get n
          [...]`      loop n times (ignoring any values after the decimal point)

[...]3                loop 3 times
 g                    get the character at the pointer
  b                   add this character to the print buffer
   >                  move pointer right
      B               print contents of buffer and reset

Nibbles, 8 bytes (16 nibbles)

In literal form:

`/3;_<3:$"__"

Attempt This Online!

`/             chunks of
  3              3 characters
   ;_            for input string
               then, apply map(\chunk->...):
     <3          take first 3 characters of
       :$"__"    concatenation of chunk and "__"

Uiua SBCS, 8 bytes

⬚@_↯¯1_3

Try it!

Thunno 2, 5 bytes

³'_3Ŀ

Try it online!

³'_ƬṬ

Try it online!

Explanation

³'_3Ŀ  '# Implicit input
³       # Split into threes
    Ŀ   # Left-justify each,
 '_    '# padding with "_"s
   3    # to length 3
        # Implicit output
³'_ƬṬ  '# Implicit input
³       # Split into threes
   Ƭ    # Transpose with
 '_    '# filler "_"
    Ṭ   # Tranpose again
        # Implicit output

Vyxal, 7 bytes

3ẇ∩\_ÞṪ

Try it Online!

How?

3ẇ∩\_ÞṪ
3ẇ      # Split into chunks of three
  ∩     # Transpose
   \_ÞṪ # Transpose with "_" as filler

Factor + grouping.extras, 27 bytes

[ 3 95 pad-groups 3 group ]

enter image description here

Jelly, 6 bytes

s3Zz”_

Try it online!

How it works

s3Zz”_ - Main link. Takes a string S on the left
s3     - Split into chunks of 3
  Z    - Transpose
   z”_ - Transpose, using "_" as a filler

Ruby, 27 21 bytes

p"#{$_}__".scan /.../

Try it online!

-6 bytes thanks to vrintle

Husk, 9 6 bytes

TT'_C3

Try it online!

look ma, no unicode!(-3)

Explanation

TT'_C3
    C3 cut into pieces of 3
 T'_   transpose, padding with underscore
T      transpose again
 

C (clang), 128 126 94 67 63 bytes

63 bytes thanks to @ceilingcat.

f(char*k){for(;*k;k++)printf("%c%c%c\n",*k,*++k?:95,*++k?:95);}

Try it online!

GolfScript, 10 bytes

"___"+3/);

Try it online!

APL(NARS), 30 chars, 60 bytes

{(3/⍳3÷⍨≢v)⊂v←⍵,'_'⍴⍨3∣3-3∣≢⍵}

test:

  f←{(3/⍳3÷⍨≢v)⊂v←⍵,'_'⍴⍨3∣3-3∣≢⍵}
  ⎕fmt f 'abcde'
┌2────────────┐
│┌3───┐ ┌3───┐│
││ abc│ │ de_││
│└────┘ └────┘2
└∊────────────┘
  ⎕fmt f '1234'
┌2────────────┐
│┌3───┐ ┌3───┐│
││ 123│ │ 4__││
│└────┘ └────┘2
└∊────────────┘
  ⎕fmt f ''
┌0──┐
│┌0┐│
││ ││
│└¯┘2
└∊──┘
  ⎕fmt f 'Three spree!'
┌4──────────────────────────┐
│┌3───┐ ┌3───┐ ┌3───┐ ┌3───┐│
││ Thr│ │ ee │ │ spr│ │ ee!││
│└────┘ └────┘ └────┘ └────┘2
└∊──────────────────────────┘

GNU sed, 27 bytes

s:$:__:
s:...:& :g
s: _*$::

Try it online!

It gets a bit tricky regarding the empty string input, since sed has no meaning of a falsy value. So to deal with this, I provide you with two possible interpretations of the rules to validate my submission:


A. You essentially provide nothing as input, not even a trailing newline (as it is the case with all the examples, including that 6 Mb file).

Usage:

echo -n ""|sed -f script

Output: nothing is printed, because sed doesn't even run the script without input.


B. One could consider as falsy value for sed to be an unique string, i.e., returned only when the input is an empty string.

Usage:

echo ""|sed -f script

Output:

__

I prefer the first interpretation so much more, as I believe it to be the closest to the intended rule, but the last one helps if you run the script using that TIO link.

Julia 1.0, 40 bytes

s->[(s*"__")[i:i+3] for i=1:3:length(s)]

Try it online!

SNOBOL4 (CSNOBOL4), 93 bytes

	S =INPUT
	S =S DUPL('_',REMDR(3 - REMDR(SIZE(S),3),3))
R	S LEN(3) . OUTPUT REM . S	:S(R)
END

Try it online!

SNOBOL has a size limit on the length of its input (1023 bytes).

Haskell, 62 61 59 bytes

z(a:b:c:d)=[a,b,c]:z d
f s=takeWhile(/="___")$z$s++cycle"_"

Infinite lists and strings!

Try it online!

GoLang, 84 bytes

func(x string)[]string{return regexp.MustCompile("...").FindAllString(x+"__",-1)}(s)

Try it !

Rust, 93 bytes

Works for ASCII input strings. Empties the input string and returns a Vec<String>.

|mut s:String|{s+="__";let mut v=vec![];while s.len()>2{let t=s.split_off(3);v.push(s);s=t}v}

Try It Online

PowerShell, 58 35 bytes

$args-split'(...)'-ne''|% *ht 3 '_'

-23 bytes thanks to mazzy.

Try it online!

JavaScript, 51 50 48 27 25

b=>(b+"__").match(/.../g)

Try it online!

Pyth, 10 9 bytes

Pc+z*3\_3

Try it online!

-1 from u_ndefined.

Is it ok if it throws an error on empty input? (does that count as falsey)

Befunge-93, 30 29 bytes

~:1+%,~:1+!"`"*+,~:1+!"`"*+,,

Try it online!

Outputs nothing for an empty input, otherwise outputs strings of length 3 separated by NUL characters.

Explanation:

~                               Push character of input to stack
 :1+                            Duplicate input and add 1
    %                           Modulo top 2 values of stack and push result
                                If input was -1 (end of stream), calculate -1%0 -> halt
                                Otherwise calculate input%(input+1) -> input
     ,                          Pop and output character
      ~                         Push character of input to stack
       :1+!                     Duplicate input, add 1 and perform logical NOT
           "`"*                 Multiply by 96 (ASCII code for '`')
                                This returns 96 or 0 depending on the result of the NOT
               +                Add the top 2 values from the stack and push the result
                                If the input was -1 (end of stream), pushes -1+96=95, or the ASCII code for '_'
                                Otherwise pushes input+0
                ,               Pop and output character
                 ~:1+!"`"*+,    Same block again to handle the third character
                            ,   Output a NUL character (stack is empty, so popping from stack just returns 0)

The instruction pointer wraps around at the end, looping the entire line.

Bash, 90 bytes

This uses Bash features rather than a combination of more traditional Bourne shell plus *nix commands (which one version I created ended up at 205 bytes). I cheated by using the dodge of adding two _ characters to the string.

c=;read a;a=${a}__;while (($(echo ${#a})>2));do b=${a:0:3};c=$c\ $b;a=${a#$b};done;echo $c

Try it online!

C (gcc), 55 bytes

i;f(char*s){for(;i%4|*s;)putchar(++i%4?*s?*s++:95:10);}

Try it online!

Kotlin, 34 bytes

{"${it}__".chunked(3).dropLast(1)}

Try it online!

Perl 5, 16 15 bytes

"@_\__"=~/.../g

Try it online!

Scala, 31 bytes

(s+"___").grouped(3).toSeq.init

Try it online!

Explanation

(s+"___")       // add "___"
  .grouped(3)   // make groups of 3
  .toSeq        // change to Seq
  .init         // take all but last

C# (Visual C# Interactive Compiler), 74 bytes

Just append two underscores '_' at the end of the input to make sure they get printed if the length of the input isn't a factor of 3.

s=>Enumerable.Range(0,(s.Length+2)/3).Select(i=>(s+"__").Substring(i*3,3))

Try it online!

Ruby, 73 42 bytes

a=gets
a.length!=0?a.scan(/.{1,3}/).map{|s|(s+'_'*3)[0,3]}:'falsey value'

Edit: As falsey value looks like it's not required:

gets.scan(/.{1,3}/).map{|s|(s+'_'*3)[0,3]}

Java 10, 116 113 bytes

s->{s+="__";int l=s.length()/3,i=l;var r=new String[l];for(;i-->0;)r[i]=s.substring(i*3,i*3+3);return l<1?0>1:r;}

Try it online.

Or 104 101 bytes if an empty array instead of false is allowed as output..

s->{s+="__";int l=s.length()/3;var r=new String[l];for(;l-->0;)r[l]=s.substring(l*3,l*3+3);return r;}

Try it online.

Explanation:

s->{                             // Method with String as both parameter and return-type
  s+="__";                       //  Append two "_" to the input-String
  int l=s.length()/3;            //  Get the length, integer-divided by 3
  var r=new String[l];           //  Create a string-array with that many parts
  for(;l-->0;)                   //  Loop `l` in the range (l, 0]:
    r[l]=                        //   Set the `l`'th value of the array to:
         s.substring(l*3,l*3+3); //   Get the substring of size 3 from index `l*3` from `s`
  return r;}                     //  Return the array

J, 16 bytes

[:}:_3]\'___',~]

Try it online!

K (oK), 19 17 bytes

-2 bytes thanks to ngn!

{-1_0N 3#x,"___"}

Try it online!

C (gcc), 67 bytes

i;f(char*_){for(;*_;puts(""))for(i=3;i--;)putchar(*_?*_++:95);_=0;}

Try it online!

Always returns a falsey value (0).

Charcoal, 10 bytes

E⪪S³…⁺ι__³

Try it online! Link is to verbose version of code. Explanation:

  S         Input string
 ⪪ ³        Split into groups of up to 3 characters
E           Map over each group
      ι     Current group
     ⁺      Concatenated with
       __   Literal `__`
    …    ³  Moulded to length 3
            Each group implicitly printed on its own line

Retina 0.8.2, 10 bytes

$
__
!`...

Try it online! Link includes test cases. Explanation:

$
__

Append two _s, in case the last group needs to be padded.

!`...

Match as many groups of three as possible, outputting the matches themselves rather than the count. (In Retina 1 this would be L instead of !.)

Attache, 34 23 bytes

PadRight&"_"&3=>@Chop&3

Try it online!

Explanation (outdated)

{On[#_-1,PadRight&"_"&3,_]}@Chop&3
                           @Chop&3    chop the input string into groups of 3s
{On[#_-1               ,_]}           on the last group
        ,PadRight                         pad it
                     &3                   to length three
                 &"_"                     with underscores

JavaScript, 25 bytes

s=>`${s}__`.match(/.../g)

Try it

Jelly, 9 bytes

s3o€“___”

A monadic Link accepting a list of characters which yields a list of lists of characters (an empty input yields empty output).

Try it online!

How?

s3o€“___” - Link: list of characters
s3        - split into chunks of three
   €      - for each chunk:
  o       -   OR (vectorises):
    “___” -     list of characters = ['_', '_', '_']

Notes:
The is only necessary to handle the edge case of an empty input.
A full program can drop a trailing , but here we can't do that as the printing behaviour of a full program smashes everything together.


Equivalent 9:

o3ÐƤ“___”

Try it


Alternative 9:

;“___”s3Ṗ

Try it

05AB1E, 9 8 bytes

…___«3ô¨

Try it online! or as a Test Suite

Explanation

…___«      # append "___" to input
     3ô    # split into groups of 3
       ¨   # discard the last group

Jelly, 10 bytes

s3;€⁾__ḣ€3

Try it online!

It feels like an 8 or 9 should be possible, but haven’t found one yet.

Python 3, 58 47 34 bytes

I'm sure someone else can do better Someone else did better. Thanks Jo King for -11 -24 bytes!

Output is unrestricted, welcome to tuple hell. Returns empty list (falsy) on empty input

lambda x:[*zip(*[iter(x+"__")]*3)]

TIO

CJam, 11 bytes

q'_3*+3/);p

Try it online!

For empty input this gives an empty string, which is falsy.

How it works

q     e# Read input as a string
'_    e# Push char '_'
3*    e# String formed by that char repeated 3 times
+     e# Concatenate to input string
3/    e# Split in groups of 3, the last of which may be shorter. Gives array of strings
);    e# Detach last string from the array and delete it
p     e# Print string representation of the array

APL+WIN 36 24 22 bytes

12 bytes saved as a result of output now being de-restricted and using the code in @Adám's first comment modified to work in APL+WIN and a further 2 with his second comment. Thanks.

(⌈(↑⍴s)÷3)3⍴(s←⎕),'__'

Prompts for input of the string and outputs the result as a nx3 array

Try it online! Courtesy of Dyalog Classic

Stax, 7 bytes

é☻εgP▀╪

Run and debug it

For an empty string input, the result is an empty array, which is a falsey value in stax.

JavaScript (Babel Node), 45 bytes

_=>_.match(/.{1,3}/g).map(a=>a.padEnd(3,`_`))

Try it online!

Perl 6, 19 bytes

{$_~"__"~~m:g/.../}

Try it online!

Pads the string by two underscores then splits the string into chunks of three characters. Returns as an array of Match objects.