18
\$\begingroup\$

Write a program or function that takes input and outputs/returns a full program (in the same language) that outputs said input. Note that the input may contain any printable ASCII character or newline (AKA 0x20-0x7f and 0x0a). However, the input will not have trailing whitespace nor preceding whitespace, nor will it be empty.

Test cases (Javascript):

cat => console.log("cat")
fish => console.log("fish")
m(newline)ta-c t => console.log("m\neta-c t") 
m"'`\c => console.log("m\"'`\\c")

Example program

function metaCat(text){
  return "console.log(\"" + text.replace(/\\/g,"\\\\").replace(/"/g,"\\\"").replace(/\n/g,"\\n") + "\")"
}

Scoring

Score is the sum of your code size and the size of the output for each test case

\$\endgroup\$
8
  • \$\begingroup\$ I'm surprised this hasn't been asked yet \$\endgroup\$
    – mousetail
    Jul 25, 2023 at 4:53
  • 4
    \$\begingroup\$ 0x7f isn't printable ASCII, I'm assuming that's a half-open range? \$\endgroup\$
    – Neil
    Jul 25, 2023 at 6:36
  • \$\begingroup\$ @Neil thats what was in most other questions, so probably? \$\endgroup\$
    – Dadsdy
    Jul 25, 2023 at 7:34
  • 1
    \$\begingroup\$ @KevinCruijssen if the trailing newline does not matter for the code to be correct, and there's one no matter the input, then you don't have to count it. \$\endgroup\$
    – Dadsdy
    Jul 25, 2023 at 17:11
  • 1
    \$\begingroup\$ @c-- no, you dont \$\endgroup\$
    – Dadsdy
    Jul 25, 2023 at 21:32

24 Answers 24

12
\$\begingroup\$

brainfuck, 78 + 2109 = 2187 bytes

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

Try it online!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Welcome to Code Golf, and nice first answer! \$\endgroup\$
    – The Thonnu
    Jul 26, 2023 at 4:24
5
\$\begingroup\$

Python, 19 (program) + 60 (output) = 79 bytes

-3 bytes thanks to loopy walt

"print(%r)".__mod__

Attempt This Online!

\$\endgroup\$
1
  • 2
    \$\begingroup\$ "print(%r)".__mod__ is a bit shorter. \$\endgroup\$
    – loopy walt
    Jul 25, 2023 at 5:50
4
\$\begingroup\$

GolfScript, 1 + 32 = 33 bytes

`

Try it online!

The outputs are:

"cat"
"fish"
"m\nta-c t"
"m\"'`\\c"
\$\endgroup\$
4
\$\begingroup\$

Vyxal, 3 bytes + 23 character sum = 26 score

øDṪ

Try it Online!

So funny story, my previous answer wasn't actually valid because øD already wraps in quotes, making the q useless.

Explained

øDṪ
øD  # dictionary compress the input, quoting it at the same time
  Ṫ # Remove the trailing backtick
\$\endgroup\$
4
\$\begingroup\$

><> (Fish), 71 + 46 bytes = 117

"<o>'"i:0(?v:\
< \ >o<"'"~< |.!05
^v?= "'":v?=a/
^  "'a'"~/
~/^1"'d3*'"

Hover over any symbol to see what it does

Try it

Unformatted version if the code above appears glitched:

"<o>'"i:0(?v:\
< \ >o<"'"~< |.!05
^v?= "'":v?=a/
^  "'a'"~/
~/^1"'d3*'"

Only characters that need escaping are the single quote and line break

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

Haskell, 24 + 76 = 100 bytes

f=("main=putStr"++).show

Attempt This Online!

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

Rust, 51 bytes + 110 bytes = 161 bytes

fn f(x:&str){print!("fn main(){{print!({:?})}}",x)}

Try it online!

We take the input as a string, but print the output, saving having to specify f's return type. Debug does the escaping for us.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ 40 bytes as an expression: |x|print!("fn main(){{print!({:?})}}",x) \$\endgroup\$
    – corvus_192
    Jul 27, 2023 at 16:50
4
\$\begingroup\$

Common Lisp, 21 + 52 = 73

(lambda(s)`(print,s))

For example:

(funcall (lambda(s)`(print,s)) "cat"))
=> (print "cat")
\$\endgroup\$
4
\$\begingroup\$

Bash, 23+49 = 72 bytes

printf 'echo %q\n' "$1"

Try it online!

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

JavaScript (V8), 32 + 60 = 92 bytes

s=>`print(${JSON.stringify(s)})`

Try it online!

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

Lua, 30 bytes, score 82

print(('print%q'):format(...))

Try it online!

No need for parentheses in resulting program since we're printing a string literal.

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

C (gcc), 108 + 84 = 192 bytes

Lots of bytes less thanks to @c--.

f(int*s){for(printf("main(){puts(\"");*s;s++)printf(*s-34?*s-92?*s-10?s:"\\n":"\\\\":"\\\"");puts("\");}");}

Try it online!

\$\endgroup\$
3
  • 1
    \$\begingroup\$ this produces much shorter output, which reduces the score significantly \$\endgroup\$
    – c--
    Jul 25, 2023 at 20:49
  • \$\begingroup\$ You're supposed the add the output lengths to the score. \$\endgroup\$
    – xigoi
    Jul 25, 2023 at 21:41
  • 1
    \$\begingroup\$ @xigoi My bad, sorry! \$\endgroup\$
    – Peter
    Jul 26, 2023 at 6:42
3
\$\begingroup\$

ForWhile, 42 (Program) + (9+10+14+14) (Output) = 89 bytes

34#::`[_~:[~;;=[92#):92=[:#)#])#"(,#)"(,#)

online interpreter

Explanation:

ForWhile allows multi-line strings, so the only characters that need to be escaped are " and \

34#                                         \ print a "
   ::`[                                     \ loop up to 34^34 times (for-while has no infinite loops)
       _                                    \ read a character
        ~:[~                                \ character is not end-of file
            ;;=[92#)                        \ print a backslash if character is "
                    :92=[:#)                \ print a backslash if character is \
                            #               \ print the character
                             ])             \ break loop if character was end of file
                               #"(,#)"(,#)  \ print "(,#) to print the string produced by the program

The printed programs are just a (multi-line) string literal containing the Input-string, followed by (,#) which will print the string.

Output for Test-cases:

"cat"(,#)

"fish"(,#)

"m
ta-c t"(,#)

"m\"'`\\c"(,#)

ForWhile, 35 (Program) + (4*17+3+4+8+6) (Output) = 124 bytes

Shorter program but slightly longer output.

"17-9:`[1-:@:[#])?"(,#)9:`[_~:[~#])

Prints a program (of length 17) that prints all its source code except the first 17 characters and then terminates, followed by the input string.

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

owl lisp, 51 + 176 = 227

this is a very quick and dirty solution

(λ (s) `(print (list->string ',(string->list s))))

example:

> (eval ((λ (s) `(print (list->string ',(string->list s)))) "cat") *toplevel*)
cat
\$\endgroup\$
2
\$\begingroup\$

Thunno 2, 2 + 28 = 30

Ṙṫ

Try it online!

Take the string epresentation, then remove the ail (last character, the end quote).

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

C++14, 132 + 176 = 308 bytes

[](auto&s){auto t=s;s="#include<cstdio>\nint main(){puts(\"";for(auto c:t)s+=c-34?c-92?c-10?s+=c,"":"\\n":"\\\\":"\\\"";s+="\");}";}

Attempt This Online!

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

Go, 91 + 216 = 307 bytes

import."fmt"
func f(s string){Printf(`package main
import."fmt"
func main(){Print(%q)}`,s)}

Attempt This Online!

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

Nim, 49 + 55 = 104 bytes

import strutils
proc m[S](s:S):S="echo "&s.escape

Attempt This Online!

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

Retina, 9 bytes, score 39

¶
$¶
^
K`

Try it online! Explanation:

¶
$¶

Change newlines into pilcrows.

^
K`

Prepend the K instruction (replace buffer with literal string).

The test cases encode as follows:

K`cat
K`fish
K`m¶eta-c t
K`m"'`\c
\$\endgroup\$
2
  • \$\begingroup\$ Doesn't work for all inputs. For instance, $$ \$\endgroup\$
    – Dadsdy
    Jul 25, 2023 at 22:57
  • \$\begingroup\$ @Dadsdy Whoops, I thought I had cleverly golfed nine bytes off my original answer... \$\endgroup\$
    – Neil
    Jul 25, 2023 at 23:03
2
\$\begingroup\$

Ruby, 19 bytes +10+11+16+15 = 71

Chose to count the trailing newline in the score because it's possible to print without it, as per the other answer.

$><<"$><<"
p$<.read

Attempt This Online!

Ruby, 23 bytes +9+10+15+14 = 71

Output doesn't include a trailing newline, but the score turned out to be the same anyways because the solution required 4 more bytes.

$><<"$><<"+$<.read.dump

Attempt This Online!

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

Charcoal, 9 bytes, score 33

SUT¿ⅉ´U´T

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

Write the input string to the canvas. This is sufficient to generate a program that prints only printable ASCII; the rest is newline handling.

UT

Turn off right-padding. (Has no effect if there was no newline in the input.)

¿ⅉ

If the input contained at least one newline...

´U´T

... output the command to turn off right-padding.

The test cases encode as follows:

cat

fish

m
eta-c tUT

m"'`\c

Try it online! (Third test case only; the others are trivial.)

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

PowerShell, 24 + 30 = 54 bytes

% *ce "'" "''"|%{"'$_'"}

Try it online!

Input comes through the pipeline.
% *ce "'" "''" - % is an alias for the ForEach-Object cmdlet, which takes the input string, and runs the string's method "Replace()" (the only one matching "*ce") against it, replacing all single quotes with a double single quote.
This is then piped further to %{"'$_'"}; again ForEach-Object, but this time invoking the scriptblock, which simply takes the input string, and wraps it in single quotes; output is implicit.
In PowerShell, anything inside a string enclosed in single quotes is taken verbatim, so no need to worry about escaping anything, except for the single quotes.

As an alternative, a Here-String @'<LF>...<LF>'@ could be used, which would remove the need to escape even the single quotes:

%{"@'`n$_`n'@"}

This is only 15 bytes instead of 24, but the output has 6 additional characters per test case instead of 2, and would come to a total of 60 bytes.
In the TIO above, the code can just be replaced.

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

05AB1E, score: 28 (3 bytes + 25 output sum)

"“ÿ

Try it online.

The outputs for the four test cases are:

Input:      cat
Output (4): “cat

Input:      fish
Output (5): “fish

Input:      """m
            ta-c t""" (multiline input)
Output (9): “m
            ta-c t

Input:      m"'`\c
Output (7): “m"'`\c

Explanation:

"    "# Push the following string:
 “    #  Regular dictionary quote for the output program
  ÿ   #  String interpolation, which is automatically replaced with the (implicit) input
      # (after which the result is output implicitly - with trailing newline)

If there is no trailing " or , 05AB1E outputs everything after it as a string.

\$\endgroup\$
0
0
\$\begingroup\$

Trilangle, 104 (program) + 48 + 82 + 175 + 175 (outputs) = score 584

'0.<_.<.>i,S)#..\_//222*3'/."-S:2'*)<.L-3',o\.><#.(,o.""<._.......j)2<>(<#,,o@o+0"@#.,#,o'"........^oo",

Try it in the online interpreter!

The score is kinda terrible because the output is quadratic in the size of the input. This program:

  1. Collects the input and keeps track of length
                 '
                0
               < _
              < . > i
             , S ) # .
              \ _ /
    
  2. Computes triangular(3n) - 3n - 2, the amount of NOPs needed to put the work all on the bottom row of the output program
                    / 2
           2 2 * 3 ' /
            - S : 2 ' * )
    
  3. Outputs a leading \ to redirect the IP to the bottom row, all the filler NOPs, and the "end program" instruction
          "
         <   L - 3 ' , o \
          > < # . ( , o . "
       " <   _
                        , o @
    
  4. Repeats the input in a format that Trilangle can understand it. This relies on implementation-defined behavior; it works in my reference interpreter as of v1.6.2.
      j ) 2 < > ( < # ,
     o + 0 " @ # . , # , o ' "
                    ^ o o " , .
    
\$\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.