86
\$\begingroup\$

To "function nest" a string, you must:

  • Treat the first character as a function, and the following characters as the arguments to that function. For example, if the input string was Hello, then the first step would be:

    H(ello)
    
  • Then, repeat this same step for every substring. So we get:

    H(ello)
    H(e(llo))
    H(e(l(lo)))
    H(e(l(l(o))))
    

Your task is to write a program or function that "function nests" a string. For example, if the input string was Hello world!, then you should output:

H(e(l(l(o( (w(o(r(l(d(!)))))))))))

The input will only ever contain printable ASCII, and you may take the input and the output in any reasonable format. For example, STDIN/STDOUT, function arguments and return value, reading and writing to a file, etc.

For simplicity's sake, you may also assume the input will not contain parentheses, and will not be empty.

Input:
Nest a string
Output:
N(e(s(t( (a( (s(t(r(i(n(g))))))))))))

Input:
foobar
Output:
f(o(o(b(a(r)))))

Input:
1234567890
Output:
1(2(3(4(5(6(7(8(9(0)))))))))

Input:
code-golf
Output:
c(o(d(e(-(g(o(l(f))))))))

Input:
a
Output:
a

Input:
42
Output:
4(2)

As usual, all of our default rules and loopholes apply, and the shortest answer scored in bytes wins!

\$\endgroup\$
9
  • 22
    \$\begingroup\$ Ahem: Is this message anything to do with the challenge? :-) \$\endgroup\$
    – wizzwizz4
    Oct 18 '16 at 18:46
  • 14
    \$\begingroup\$ T​I​L 4​2​ ​= 8 \$\endgroup\$ Oct 18 '16 at 21:48
  • \$\begingroup\$ What is maximum length for the input string? Incase of recursive methods \$\endgroup\$
    – Ferrybig
    Oct 23 '16 at 20:30
  • 1
    \$\begingroup\$ @kamoroso94 You may take the input and the output in any reasonable format. A list of characters seems perfectly reasonable to me. \$\endgroup\$
    – DJMcMayhem
    Sep 1 '17 at 15:29
  • 6
    \$\begingroup\$ So that's what Lisp code looks like \$\endgroup\$ Dec 17 '17 at 18:35

111 Answers 111

1 2 3
4
1
\$\begingroup\$

C (gcc), 97 84 bytes

Thanks to ceilingcat for -13 bytes

f(char*b){printf(*++b?"%c(":"%c",*b);*b&&f(b)+printf(")");}a[99];main(){f(gets(a));}

Try it online!

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

Keg, 22 16 15 12 bytes

?^⑷`(`⑸÷_(\)

Explained

?^⑷`(`⑸÷_(\)
#?^         Takes input and reverse it
#⑷`(`⑸÷    Maps an additional "(" to each letter
#÷_         Takes the last item and removes the extra bracket
#(\)        Appends a ")" for each item on the stack

Answer History

15 bytes

?!&("\()_^`)`&*

Try it online!

-1 byte due to some sort of stack-mechanic magic. I don't really know what I did, but it's shorter! Also, it's still ASCII only!

Explained:

?!&("\()_^`)`&*
?!&             #Take input and store the length in the register
   ("\()        #For each item on the stack, right shift and push a "("
        _^      #Pop the top and reverse
          `)`&* #Push ")" multiplied by the register (python-like string multiplication)

Answer History

16 bytes

?!&("\()'^_`)`&*

Try it online!

-6 bytes due to usage of the register rather than a custom variable. Also, that's 16 UTF-8/ASCII bytes for once.

Explained:

?!&("\()'^_`)`&*
?!&                 #Take input and store the length in the register
   ("\()            #For each item on the stack, right shift and push a "("
        '^_         #Left shift the stack, reverse and pop the top of stack
           `)`&*    #Push ")" multiplied by the register (python-like string multiplication)

22 bytes (SBCS)

?!®c("\()'^_(©c|\))^(,

Try it online!

Note that due to a newly discovered bug, TIO won't work properly, but the github interpreter will work correctly.

Explanation

#?!®c("\()'^_(©c|\))^(,
?!®c    #Get user input, and store the length in variable c
("\()   #For each item in the stack, right shift and push a "("
'^_ #Reverse the stack and pop the last most "("
(©c|\)) #For _ in range(0, var_c): append a ")"
^(, #Reverse and print the stack as characters
\$\endgroup\$
1
1
\$\begingroup\$

Wren, 54 bytes

Fn.new{|x|x.map{|i|i+"("}.join()[0..-2]+")"*~-x.count}

Try it online!

Wren, 36 bytes

I didn't write this myself. Therefore it is boring.

Fn.new{|x|x.join("(")+")"*~-x.count}

Try it online!

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

Befunge-93, 33 bytes

~# <\,"()"_v#+1:~,
         :,_@#

Try it online!

Due to the < character, the first line should be read backwards.

, : Output the most recently read character.

~ : Read a new character.

1+#v_: If there is no new character, go to the second line.

")(": Push parentheses characters onto the stack.

, : Output left parenthesis.

\ : Bury the right parenthesis deeper in the stack so it won't output until the end.

The rest of the first line is code to special-case the first character so that it gets output without creating parentheses.

The second line then simply outputs the stack until it's empty.

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

Burlesque, 16 bytes

'([]sa2./')j.*.+

Try it online!

'([]  # Insert "(" between each char
sa2./ # Find length/2
')j.* # That many ")"s
.+    # Concatenate
\$\endgroup\$
1
\$\begingroup\$

GolfScript, 12 bytes

.'('*')'@,(*

What a cute little solution!

.            #Duplicate entry string
 '('*        #Join the string with left-paren
     ')'     #Right paren string
        @    #Bring up our duplicate
         ,   #Count the number of characters
          (  #Decrease that number by 1
           * #Add that many ')' to the end

Try it online!

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

Unix TMG, 51 byte

p:parse(s)s:smark any(!<<>>)scopy s/d={2<(>1<)>}d:;

Works by recursive descent parsing.

Exploits absence of semicolons between parsing rules to make it two bytes shorter.

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

Zig, 84 bytes

fn p(q:var)[]const u8{return[_]u8{q[0]}++if(q.len>1)"("++p(q[1..q.len])++")"else"";}

Try it

tests:

fn p(q: var) []const u8 {
    return [_]u8{q[0]} ++ if (q.len > 1) "(" ++ p(q[1..q.len]) ++ ")" else "";
}

const std = @import("std");
const Test = struct { in: []const u8, out: []const u8 };
test "it works" {
    comptime const tests = [_]Test{
        .{ .in = "Hello", .out = "H(e(l(l(o))))" },
        .{ .in = "foobar", .out = "f(o(o(b(a(r)))))" },
        .{ .in = "a", .out = "a" },
    };
    inline for (tests) |i| {
        std.testing.expect(std.mem.eql(u8, comptime p(i.in), i.out));
    }
}
\$\endgroup\$
1
\$\begingroup\$

TI-Basic, 62 bytes

For(I,1,2length(Ans)-2,2
sub(Ans,1,I)+"("+sub(Ans,I+1,length(Ans)-I
End
For(I,1,.5length(Ans
Ans+")
End

Takes input in Ans. Output is stored in Ans.

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

Python 3, 51

Just a simple recursive function.

lambda s:s if len(s)<2else s[0]+"("+nest(s[1:])+")"

Try it online!

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

Underload, 18 bytes

(~*a~a:*~a*^~):()~

Try it online!

Takes input as a reversed list of characters.

Explanation

Arbitrary-length list handling is a little weird in Underload.
Typically, inputs are passed in the form (a)~(b)~(c)~^S with the assumption that there is a function on the stack. This pushes each input one at a time and then swaps them with the function, keeping the function on top, then finally executes the function and prints the top of the stack.

For arbitrary-length lists however, we need to make 2 changes.
Firstly, the function must be self-replicating, and must operate on each individual item on the stack.
Secondly, inputs must be passed in the form (a)~^(b)~^(c)~^!S
This executes the function after each input, with the expectation that after the function is run, the top of the stack will be the function. (^ pops the function from the stack before execution).

(~*a~a:*~a*^~):()~
(            )       Main function
 ~                     Swap the top two items on the stack
  *                    Concatenate them
   a                   Wrap the result in parentheses
    ~a:*~a*^~          Function self-replication.
                         Assumed that the top of the stack is the result of the function
                         and the 2nd item is the function.
                         ie for stack [f, a], produces [f, a, f]
              :()~   Duplicate function and push an empty string between them
                       Resulting stack when execution begins is
                       ['~*a~a:*~a*^~', '', '~*a~a:*~a*^~']
\$\endgroup\$
0
\$\begingroup\$

ForceLang, 132 bytes

def S set
S a io.readln()
S i 0
S b ")"
label 1
io.write a.charAt i
S i i+1
if i+-a.len
 io.write "("
 goto 1
io.write b.repeat i+-1
\$\endgroup\$
0
\$\begingroup\$

tcl, 66

puts [join [split $s ""] (][string repe ) [expr [string le $s]-1]]

Testable on http://rextester.com/live/SAXFO71660

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

Japt, 11 bytes

ç q') iUq'(

Try it online!

Takes an array of 1-length strings as input.

How it works

Uç q') iUq'(

Uç    Replace input array's every element with `undefined`
q')   Join with ")"
i     Insert to the beginning of above result...
Uq'(    Input array joined with "("

Uses a JS trick: undefined elements of an Array is converted to empty strings on join.

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

Java 10, 71 bytes

s->{var r="";for(int i=s.length;i-->1;r="("+s[i]+r+")");return s[0]+r;}

Shorter than the existing two recursive Java answers.

Input as String-array of each character.

Try it online.

s->{               // Method with String-array parameter and String return-type
  var r="";        //  Result-String, starting empty
  for(int i=s.length;i-->1; 
                   //  Loop backwards over the array, skipping the first character
    r=             //   Set the result to:
      "("          //    An opening parenthesis,
      +s[i]        //    appended with the current character,
      +r           //    appended with the current result-String,
      +")");       //    appended with a closing parenthesis
  return s[0]+r;}  //  Return the first character, appended with the result-String
\$\endgroup\$
0
\$\begingroup\$

Gol><>, 37 bytes

14a*iov
!vo$P$>:oi:P?
:>~~:?!;9sso1-:

Try it online!

Reads from stdin, outputs to stdout

Explanation:

14a*            Pushes 1 (num of characters so far) and 40 (ASCII for open paren) onto stack
    io          Reads a character and outputs it
      v         Drops to next line of golfed code

      >         Directs pointer to the right
       :o       Duplicates and outputs the (
         i      Inputs a character
!v        :P?   Drops to next line of golfed code if no more chars
  o             Outputs character
   $P$          Increments the character counter

 >              Directs pointer to the right
  ~~            Discard unneeded stack values
    :?!;        Exits if counter == 0
        9sso    Outputs closing paren
            1-  Decrement counter
:             : Duplicate counter twice (so that it isn't discarded by the '~'
\$\endgroup\$
4
  • \$\begingroup\$ ioiEH')('o$! \$\endgroup\$
    – Jo King
    Aug 28 '18 at 8:17
  • \$\begingroup\$ @JoKing well now I feel inadequate /s \$\endgroup\$
    – xornob
    Aug 28 '18 at 8:24
  • \$\begingroup\$ Well, when creating a Gol><> answer you need to check if there's an existing ><> answer you can adapt ;) \$\endgroup\$
    – Jo King
    Aug 28 '18 at 8:26
  • \$\begingroup\$ Welcome to PPCG! looks like you have too many parentheses: there should be no opening parenthese after the last letter of the string. \$\endgroup\$
    – JayCe
    Aug 28 '18 at 13:34
0
\$\begingroup\$

Japt, 11 bytes

¬q'( +UÅî')

Try it

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

Red, 59 bytes

func[s][either 1 < length? s[rejoin[s/1"("f next s")"]][s]]

Try it online!

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

Icon, 59 bytes

procedure f(s)
return(*s>1&s[1]||"("||f(s[2:0])||")")|s
end

Try it online!

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

MAWP, 33 bytes

%|_!1A[1A~;85W;~]~;1A[1A~85W1M;~]

Try it!

\$\endgroup\$
2
  • \$\begingroup\$ Hm, I thought I did this correctly. Can someone tell me what's wrong with the program? \$\endgroup\$
    – Razetime
    Aug 9 '20 at 16:48
  • 2
    \$\begingroup\$ Nothing's wrong... It's most likely an accidental downvote. I know I've done it before around here! Fwiw, it wasn't me this time. \$\endgroup\$
    – lyxal
    Aug 10 '20 at 7:04
0
\$\begingroup\$

ayr, 20 bytes

(:1},;'(',"),')'#}&#

Explained

           }&#  Length - 1
       ')'#     Repeat ')' that many times
      ,         Append to end of
(: xx)          The result of applying input to partial application xx
             Where xx is:
    '(',"  Append '(' to beginning of each char
  ,;       Convert from vec of strs to str (mix before flatten)
1}         Remove first char
\$\endgroup\$
1 2 3
4

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.