21
\$\begingroup\$

Context

Just look around! Whenever someone posts an answer, the same template is followed over and over again! A first line with the byte count and language name. Then the code. Then the TIO link. This is the basic skeleton almost everyone follows.

Task

Your task, should you choose to accept it, is to write a program/function/procedure/etc that takes as input the variable bits and produces the basic CGCC answer.

Input

The language name, some code and a TIO link, in any sensible formats. For the language name and the TIO link, a string is suggested. For the code, sensible formats include a string with possibly some newlines, or a list of strings, one string per line.

Additionally, you may also take the byte count as input. If you don't, you have to compute it yourself (if you compute it yourself, you can assume the byte count equals the length of the code string).

You have to support that the input strings may contain any printable, non-whitespace ASCII characters plus the space. The only exclusion being the newlines in the source code. You don't have to worry about the weird characters used by golfing languages in their code pages.

The inputs may be ordered in any way you like.

Output

You should output this raw content:

# {name}, {byte count} bytes

    {code}

You can [try it online][tio]!

[tio]: {link}

Where {name}, {byte count}, {code} and {link} should be filled in by your code. Three of those are inputs, the byte count should be computed within your code if you chose not to receive it as input (you can assume the byte count is equal to the number of characters in the code argument). Beware that the code given may be multiline, in which case the {code} section must be indented by 4 spaces for each line of code.

Test cases

You can check some test cases.

Related challenge


This is , so shortest answer in bytes wins. If you liked the challenge, consider upvoting it... And happy golfing!

\$\endgroup\$
  • \$\begingroup\$ What if the code has a tab character? In TIO this makes the code formatting start with <pre><code> and HTML formatting to insert the tab, along with a bunch of other edge cases. \$\endgroup\$ – Value Ink Feb 14 at 7:12
  • \$\begingroup\$ @ValueInk TIO also uses random ids for its link, but this challenge has nothing more to do with the actual TIO than inspiration. \$\endgroup\$ – Adám Feb 14 at 7:16
  • \$\begingroup\$ @ValueInk sorry, I didn't understand your concern. \$\endgroup\$ – RGS Feb 14 at 7:17
  • \$\begingroup\$ If you have a literal tab character \t, the code needs to be formatted differently to display it correctly, or something, so on TIO it will emit something like <pre><code>&#9;print 3</code></pre> instead of (four spaces)(tab)print 3 (because otherwise SE will change the tab into 4 spaces or something). Do we need to handle this case??? \$\endgroup\$ – Value Ink Feb 14 at 7:20
  • \$\begingroup\$ @ValueInk I tweaked the specs to guarantee that whitespace won't be too annoying \$\endgroup\$ – RGS Feb 14 at 7:26

17 Answers 17

7
\$\begingroup\$

Ruby, 98 95 94 bytes

Really simple string interpolation. I don't think there's all that much to optimize here that will save a lot of bytes.

Takes the byte count as a parameter in order to save 3 bytes, as per Kevin Cruijssen's suggestion.

->n,b,c,l{"# #{n}, #{b} bytes

#{c.gsub /^/,' '*4}

You can [try it online][tio]!

[tio]: "+l}

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Looks fairly simple to me, you are right. But simple doesn't mean it doesn't deserve a +1! \$\endgroup\$ – RGS Feb 14 at 7:43
  • 3
    \$\begingroup\$ -3 bytes by taking the byte-count as additional input b and replacing the #{c.size} with #{b}. The challenge states it's optional to take the length as input. \$\endgroup\$ – Kevin Cruijssen Feb 14 at 9:30
6
\$\begingroup\$

05AB1E (legacy), 56 53 52 51 50 bytes

“# ÿ, ÿ¡Ï“I4ú»"[tio]"D“You€© [try€•€Ø]ÿ!“s¶·ý„: IJ

Inputs in the order name, byte-count, [code-lines], link, where the [code-lines] is a list of lines.

Try it online.

50 bytes alternative (credit to @Grimmy):

“:# ÿ, ÿ¡Ï“I4ú»“You€© [try€•€Ø][tio]!“Â6£R¨¶·ýÀ$ú«

Try it online.

Explanation:

“# ÿ, ÿ¡Ï“  # Push dictionary string "# ÿ, ÿ bytes", where the `ÿ` are automatically
            # filled with the first two implicit inputs (name & byte-count)
I           # Push the third input-list of code-lines
 4ú         # Prepend 4 spaces before each line of code
   »        # And join it by newlines
"[tio]"     # Push string "[tio]"
       D    # Duplicate it
        “You€© [try€•€Ø]ÿ!“
            # Push dictionary string "You can [try it online]ÿ!", where the `ÿ` is
            # automatically filled with the "[tio]"
s           # Swap to get "[tio]" at the top of the stack again
¶           # Push a newline character
 ·          # Double it, which in the legacy version built in Python works with strings
  ý         # And join the stack by this double newline as delimiter
„:          # Push string ": "
   I        # Push the fourth input (link)
    J       # Join the entire stack together without delimiter
            # (after which the result is output implicitly)

“:# ÿ, ÿ¡Ï“ # Push dictionary string ":# ÿ, ÿ bytes", where the `ÿ` are automatically
            # filled with the first two implicit inputs (name & byte-count)
I4ú»        # Same as above
“You€© [try€•€Ø][tio]!“
            # Push dictionary string "You can [try it online][tio]!"
 Â          # Bifurcate it; short for Dulpicate & Reverse Copy
  6£        # Only leave the first 6 characters (the "![oit]")
    R       # Reverse it to "[tio]!"
     ¨      # Remove the last character: "[tio]"
¶·ý         # Same as above
À           # Rotate once towards the left, so the leading ":" becomes trailing
 $          # Push the fourth input (link) and a 1
  ú         # Prepend this link-string with that 1 space
   «        # And append it to the earlier created string
            # (after which the result is output implicitly)

See this 05AB1E tip of mine (section How to use the dictionary?) to understand why “# ÿ, ÿ¡Ï“ is "# ÿ, ÿ bytes" and “You€© [try€•€Ø]ÿ!“ is "You can [try it online]ÿ!".

\$\endgroup\$
  • \$\begingroup\$ Cool answer +1! String compression ftw \$\endgroup\$ – RGS Feb 14 at 9:37
  • 2
    \$\begingroup\$ Good golfs, I'm not finding anything shorter. Here's an alternative 50 \$\endgroup\$ – Grimmy Feb 14 at 13:34
  • \$\begingroup\$ @Grimmy Oh, original alternative! Shall I add it to my answer, or you want to post it as separated answer, since the approach is quite different than mine? \$\endgroup\$ – Kevin Cruijssen Feb 14 at 13:37
  • \$\begingroup\$ I'm not gonna make a separate answer, feel free to add it if you want to! \$\endgroup\$ – Grimmy Feb 14 at 13:38
5
\$\begingroup\$

Red, 102 94 bytes

-6 bytes thanks to Kevin Cruijssen!

func[l n c u][reduce["#"rejoin[l","]n{bytes

   }c{

You can [try it online][tio]!

[tio]:}u]]

Try it online!

\$\endgroup\$
  • \$\begingroup\$ @KevinCruijssen Oh, yes! Apparently I didn't read the question carefully enough :) \$\endgroup\$ – Galen Ivanov Feb 14 at 14:28
  • \$\begingroup\$ Your code looks "funny" because it looks like you have some strings in there with the " but then I can't understand what is wrapping the template string. \$\endgroup\$ – RGS Feb 14 at 14:29
  • \$\begingroup\$ @RGS I don't have just one template string. The argument of the reduce function is a block, containing strings (they remain unchanged) and words (let's say they are variables) which are reduced (evaluated). The multline string is enclosed in {} \$\endgroup\$ – Galen Ivanov Feb 14 at 14:34
  • 2
    \$\begingroup\$ @KevinCruijssen I noticed, thanks. I tried editing the question to make it more clear. Thanks for the explanation Galen! \$\endgroup\$ – RGS Feb 14 at 15:21
4
\$\begingroup\$

Haskell, 125 121 119 113 bytes

-4 bytes thanks to kronicmage
-2 bytes thanks to xnor

(l!b)c t="# "++l++", "++show b++" bytes\n"++(("\n    "++)=<<c)++"\n\nYou can [try it online][tio]!\n\n[tio]: "++t

Try it online!

\$\endgroup\$
  • \$\begingroup\$ You can shave 4 bytes by using (=<<) instead of concatMap in your first answer (which you've already done in your second answer) \$\endgroup\$ – kronicmage Feb 14 at 19:59
  • \$\begingroup\$ I liked how you defined your ! function! Good job +1 \$\endgroup\$ – RGS Feb 14 at 21:28
  • \$\begingroup\$ You can cut a paren pair with (("\n "++)=<<lines c) \$\endgroup\$ – xnor Feb 15 at 10:14
4
\$\begingroup\$

PHP, 134 132 125 119 bytes

# <?=($a=$argv)[1].", $a[2] bytes

".preg_replace("/^/m","    ",$a[3])."

You can [try it online][tio]!

[tio]: $a[4]";

Try it online!

Finally an easy job for PHP!

EDIT: easily saved 2 bytes with concatenation in first <?=

EDIT 2: saved another 7 bytes, just remembered that multi-lines strings work in PHP with "

EDIT 3: and another 6 with using /^/m instead of /\n/

\$\endgroup\$
  • \$\begingroup\$ Good job here! +1 for you! \$\endgroup\$ – RGS Feb 14 at 11:09
  • 1
    \$\begingroup\$ You can also take advantage of NL's in strings instead of \n too. Obviously, I changed it a bit to be able to use it, but just an idea (118 bytes): tio.run/… \$\endgroup\$ – 640KB Feb 14 at 16:46
  • \$\begingroup\$ @640KB Thanks! improved it with str_replace ;) \$\endgroup\$ – Kaddath Feb 17 at 9:57
  • \$\begingroup\$ @640KB actually rolled back to the 119 version, the problem with your version and the improve I made on it is that there is not the 4 spaces in front of the first line of displayed code :/ so it would be a 120 with those spaces added.. \$\endgroup\$ – Kaddath Feb 17 at 11:32
3
\$\begingroup\$

JavaScript (ES6), 102 bytes

(n,b,c,l)=>`# ${n}, ${b} bytes

${c.replace(/^/gm, '    ')}

You can [try it online][tio]!

[tio]: `+l

Try it online!

"/^/gm" is a Global Multi-line replace of start line (^)

\$\endgroup\$
  • \$\begingroup\$ You can save a byte by removing the space at gm,'. :) \$\endgroup\$ – Kevin Cruijssen Feb 14 at 10:48
  • \$\begingroup\$ Welcome to this community! Really good job here :D +1 \$\endgroup\$ – RGS Feb 14 at 11:09
3
\$\begingroup\$

Python 3, 97 \$\cdots\$ 118 116 bytes

Added 28 bytes to fix a bug kindly pointed out by RGS.

Saved 2 bytes thanks to ovs!!!

lambda n,b,c,l,x='\n':f"""# {n}, {b} bytes

    {c.replace(x,x+' '*4)}

You can [try it online][tio]!

[tio]: {l}"""

Try it online!

Takes code length as a parameter to save 3 bytes.

\$\endgroup\$
  • \$\begingroup\$ Hey, thanks for your submission ! If you check Haskell's test case, the second line of code isn't indented! \$\endgroup\$ – RGS Feb 14 at 14:12
  • \$\begingroup\$ You can save one extra byte by deleting the space between a newline and You. Also, I mean that in my Haskell test case, the output has two lines of indented code but yours doesnt \$\endgroup\$ – RGS Feb 14 at 15:25
  • \$\begingroup\$ @RGS Ok, got it now - problem fixed! :-) \$\endgroup\$ – Noodle9 Feb 14 at 18:46
  • \$\begingroup\$ I can't really be sure now, but taking multiline code as a list of lines and joining with "\n&nbsp;&nbsp;&nbsp;&nbsp;" might be shorter! \$\endgroup\$ – RGS Feb 14 at 19:32
  • 1
    \$\begingroup\$ @S.S.Anne You can't use escapes (\) in f-string expressions (inside ({ and }).. \$\endgroup\$ – Noodle9 Feb 14 at 22:30
3
\$\begingroup\$

Kotlin, 83 109 101 95 bytes

{n,b,c,l->"""# $n, $b bytes

${c.prependIndent()}

You can [try it online][tio]!

[tio]: $l"""}

Try it online!

-6 bytes thanks to @snail_

-2 bytes thanks to @ovs

-6 bytes since prependIndent has a default of 4 spaces

\$\endgroup\$
  • \$\begingroup\$ Unfortunately your submission doesn't indent the code correctly when it is multiline! I hope you can fix it :) \$\endgroup\$ – RGS Feb 14 at 19:29
  • \$\begingroup\$ @RGS lol damn, that adds quite a few bytes, but fixed \$\endgroup\$ – Quinn Feb 14 at 19:34
  • \$\begingroup\$ still, good job! +1 \$\endgroup\$ – RGS Feb 14 at 20:24
  • \$\begingroup\$ you can use String.prependIndent to save some bytes. tio.run/##NU/BboMwDD2Pr/… \$\endgroup\$ – snail_ Feb 15 at 5:24
  • \$\begingroup\$ a multiline string is 2 bytes shorter: tio.run/##NU/… (combined with snail_'s suggestion) \$\endgroup\$ – ovs Feb 15 at 10:24
3
\$\begingroup\$

Japt, 60 bytes

i`# {V}, {W} ßs

{XmiSp4 R}

YŒ ¯n [try Š Ò‚][o]!

[o]: 

Try it

\$\endgroup\$
  • \$\begingroup\$ +1 nice handling of newline code blocks! \$\endgroup\$ – RGS Feb 15 at 8:28
2
\$\begingroup\$

W j, 77 bytes

# "a", "ck" bytes
"c'
,"
    ":@\+"

You can [try it online][tio]!

[tio]: "b

Explanation

% Header section
# "               % The beginning header
   a              % The first input (the language name)
    ", "          % The comma & space
        ck        % The length of the program (taken at the 3rd input)
          " bytes % Appended with " bytes"
"                 % And a trailing newline

% Code section
c           % The third input
'
,           % Splitted by a newline
"
    "      % Add string representing a newline and 4 spaces
      :    % Stack: '\n'split(c), "    ", "    "
       @   % Stack: "     ",'\n'split(c), "    "
        \  % Join with 4 spaces
         + % Prepend 4 spaces

% Link section
          "

You can [try it online][tio]!

[tio]: "   % The template
         b % The second input
```
\$\endgroup\$
  • \$\begingroup\$ Nice answer +1! \$\endgroup\$ – RGS Feb 14 at 9:37
  • 1
    \$\begingroup\$ This also calculates the byte-count, but it's just 1 byte longer than without calculation. \$\endgroup\$ – a'_' Feb 14 at 10:52
2
\$\begingroup\$

Java 10, 141 bytes

(n,b,c,l)->{var t="";for(var p:c)t+="    "+p+"\n";return t.format("# %s, %d bytes\n\n%s\nYou can [try it online][tio]!\n\n[tio]: "+l,n,b,t);}

Takes the byte-count as integer-input, and the code as an array of String-lines.

Try it online.

Explanation:

(n,b,c,l)->{    // Method with four parameters and String return-type
  var t="";     //  Temp-String, starting empty
  for(var p:c)  //  Loop over the code-lines:
    t+="    "   //   Append four spaces,
       +p       //   the code-line itself,
       +"\n";   //   and a newline to this temp-String
  return t.format("# %s, %d bytes\n\n%s\nYou can [try it online][tio]!\n\n[tio]: "
                //  Return this String above, where:
    +l,         //   The link is appended at the end
    n,          //   The first `%s` is replaced with the name `n`
    b,          //   The `%d` is replaced with the byte-count `b`
    t);}        //   And the second `%s` is replaced with the temp-String
\$\endgroup\$
  • \$\begingroup\$ Standard string formatting method, right? +1 for your work! \$\endgroup\$ – RGS Feb 14 at 11:08
2
\$\begingroup\$

Wren, 117 bytes

Just a normal string interpolation here.

Fn.new{|a,b,c,d|"# %(a), %(b) bytes

%("    "+c.split("
").join("
    "))

You can [try it online][tio]!

[tio]: "+d}

Try it online!

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

Japt, 85 bytes

"# {U}, {V} bytes

{"    "+Wq"
" q"
    "}

You can [try it online][tio]!

[tio]: "+X

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Nice answer still! +1 \$\endgroup\$ – RGS Feb 14 at 10:40
2
\$\begingroup\$

Jinja2, 102 bytes

# {{n}}, {{b}} bytes

{%for a in c%}
    {{a}}
{%endfor%}

You can [try it online][tio]!

[tio]: {{l}}

Does this count as a language? Used jinja cli from here: https://pypi.org/project/jinja2-cli/

I think it should as this is the usage to run it:

jinja2 tio.j2 test.json --format=json

It accepts a file as a program, and input in some format. That fits the definition of a language to me.

This was the input json tested with:

{"n": "lang_name", "b": 10, "c": ["line_1", "line_2"], "l": "https://example.com"}
\$\endgroup\$
  • \$\begingroup\$ Funny submission ;) +1 \$\endgroup\$ – RGS Feb 14 at 21:28
2
\$\begingroup\$

Keg, -pn, 92 83 79 75 bytes

®N®l®b`# ©N, ©b  ¬E;s\n`,÷(\    $+,)
,“0:0X“` [try it a.;][tio]!\n[tio]: ©l`+,

Input is: Name, link, byte count and code

Explained

®N®l®b

We first take the inputs name, link and byte count and store them in variable N, l and b respectively.

`# ©N, ©b  ¬E;s\n`,

Next, we construct a string that represents the header. The ©N and ©b are used for. string interpolation, and ¬E; is the compressed word for byte. Printing the string using , formats the string with variables.

÷(\ $+,)

Now, we item split the implicit code list and print each item with a tab appended to it.

<newline>,

Then, we print a newline to separate everything.

“0:0X“` [try it a.;][tio]!\n[tio]: ©l`+,

Finally, we construct two strings: the string You can (represented by “0:0X“) and [try it online][tio]!\n[tio]: ©l (which has the variable l interpolated within it). The two strings are then joined and printed.

Try it online!

Answer History

79 bytes

0&®N®l®b`# ©N, ©b  ¬E;s\n`,÷(`\t`$+,)
,“0:0X“` [try it a.;][tio]!\n[tio]: ©l`+,

Try it Online!

83 bytes

0&®N®l®b`# ©N, ©b  bytes\n`,÷(`\t`$+,)
,`You can [try it online][tio]!\n[tio]: ©l`,

Try it online! Saved 9 bytes due to not calculating the byte count.

92 bytes

0&®N®l÷(:⑴⑼⑹")"⑺⑻®b`# ©N, ©b  bytes\n`,(`\t`$+,)
,`You can [try it online][tio]!\n[tio]: ©l`,

Try it online!

Note that I haven't applied string compression yet, which would get this down to 89 bytes. I'll do it tomorrow. The code is to be given as a list where each item is an individual line.

\$\endgroup\$
  • 1
    \$\begingroup\$ Really impressive answer! (I didn't upvote it because I want to get the Electorate badge.) \$\endgroup\$ – a'_' Feb 14 at 10:55
  • \$\begingroup\$ @a'_' you've got a while left until you reach that badge though... That requires 600 upvotes, meaning it would take at least 15 days. \$\endgroup\$ – Lyxal Feb 14 at 11:00
  • \$\begingroup\$ But there's only a 12-hour interval. That means it would take me 8 days. \$\endgroup\$ – a'_' Feb 14 at 11:10
  • \$\begingroup\$ @a'_' do you mean you will be upvoting a bunch of questions for the next days? \$\endgroup\$ – RGS Feb 14 at 11:13
  • \$\begingroup\$ In fact I've already done it. \$\endgroup\$ – a'_' Feb 14 at 11:14
2
\$\begingroup\$

C (gcc), 162 bytes

t(n,b,c,l)char*n,*c,*l;{for(printf("# %s, %d bytes\n\n    ",n,b);*c;)putchar(*c++)-10?:printf("    ");printf("\n\nYou can [try it online][tio]!\n\n[tio]: %s",l);}

There may be spaces after a trailing newline but I'm not sure if I'll be able to find a solution (or if a solution is even needed).

You can try it online!

\$\endgroup\$
  • \$\begingroup\$ Looking promising! Will wait for the rest. \$\endgroup\$ – RGS Feb 14 at 21:27
  • 1
    \$\begingroup\$ @RGS There's no way to do it without a loop so expect +25 bytes or more. \$\endgroup\$ – S.S. Anne Feb 15 at 0:11
  • \$\begingroup\$ @RGS Take a look. \$\endgroup\$ – S.S. Anne Feb 15 at 15:14
  • \$\begingroup\$ looks good to me! +1 and thanks for fixing your submission ! \$\endgroup\$ – RGS Feb 15 at 21:53
1
\$\begingroup\$

Charcoal, 67 56 bytes

F⪪“`⊟«M["Þ…εU↑⁵ï²¹@↧≡⊗»⭆∧⌕´r⪪ιυNτ⁰⬤N➙⁺⁰UY⟧MyoJb⎇»﹪”¶«ι S

You can try it online!

Try it online! Link is to verbose version of code. Assumes you're not worried about Charcoal's default output padding, which can be turned off at a cost of 2 bytes. Explanation: Each input has a certain amount of text that appears before it, which always ends in a space, so the loop prints the text and space before each input. Because it uses separate print commands for the inputs, the newlines in the code block maintain the indent, but the text strings themselves include carriage returns which turn off the indent (particularly applicable to the TIO gubbins). The four text strings themselves are extracted from a large compressed string.

\$\endgroup\$
  • \$\begingroup\$ Good job on this :) Is there a nice way to go about doing this with Retina? \$\endgroup\$ – RGS Feb 14 at 11:12
  • \$\begingroup\$ @RGS Turns out there's a nice way to go about doing this with Charcoal! \$\endgroup\$ – Neil Feb 14 at 13:31
  • \$\begingroup\$ @a'_' what do you mean? Am I missing something? :O \$\endgroup\$ – RGS Feb 14 at 14:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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