77
\$\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\$
  • 21
    \$\begingroup\$ Ahem: Is this message anything to do with the challenge? :-) \$\endgroup\$ – wizzwizz4 Oct 18 '16 at 18:46
  • 12
    \$\begingroup\$ T​I​L 4​2​ ​= 8 \$\endgroup\$ – ETHproductions 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
  • 1
    \$\begingroup\$ So that's what Lisp code looks like \$\endgroup\$ – caird coinheringaahing Dec 17 '17 at 18:35

97 Answers 97

4
\$\begingroup\$

Dyalog APL, 14 bytes

⊃{⍺,1⌽')(',⍵}/

this is an atop of and { }/

(get first element) will be applied after { }/ (reduction of a lambda)

⍺,1⌽')(',⍵ - the left argument () concatenated with (,) the rotation by one element to the left (1⌽) of the string ')(' concatenated with (,) the right argument ()

reduction in APL folds from right to left, as required here

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

Perl, 36 bytes (34 + 2 for -lpflag)

Thanks to Dada for pointing out a bug and saving one byte (in total)!

Splits the string into an array, then joins it with the (delimiter. We directly add the closing )since lengthreturns the length of the string before the join.

$_=(join"(",split//).")"x(y///c-1)

Try it here!

\$\endgroup\$
  • \$\begingroup\$ Sure you don't need -l flag? I doesn't seem to work when I try it... Or maybe I missed something? \$\endgroup\$ – Dada Oct 18 '16 at 20:49
  • \$\begingroup\$ Also, you can write y///c-1 instead of -1+length to save 2 bytes. \$\endgroup\$ – Dada Oct 18 '16 at 20:51
  • \$\begingroup\$ @Dada indeed, -l is needed when you run this with the terminal. I'm always doing these things on Ideone and it's not needed there... Editing! (and thanks for the tip!) \$\endgroup\$ – Paul Picard Oct 18 '16 at 20:54
  • \$\begingroup\$ You could also do $_=(join"(",@a=split//).")"x(@a-1) which is a bit more verbose and the same number of bytes as the y///c-1. Or well, depends on the definition of verbose. \$\endgroup\$ – simbabque Oct 18 '16 at 21:25
  • 2
    \$\begingroup\$ You can again drop the -l option by demanding that the input string is entered without final newline, echo -n Hello | program \$\endgroup\$ – Ton Hospel Oct 19 '16 at 4:55
3
\$\begingroup\$

Perl 5, 44 33 bytes (31 + 1 for -l + 1 for -p)

saved 11 bytes thanks to Dada

s/([\w ])([\w ]+)/$1($2)/&&redo

Can be run from the command line with the -p and -e options.

$ perl -ple 's/([\w ])([\w ]+)/$1($2)/&&redo' <<< 'Hello'

Output:

H(e(l(l(o))))
\$\endgroup\$
  • 1
    \$\begingroup\$ You can use -l instead of chomp to save 5 bytes. Also, since -p surround the code with a while, you can do s/../../&&redo instead of 0while s/../../. As it happens, this regex is shorter : s/([\w ])([\w ]+)/$1($2)/. \$\endgroup\$ – Dada Oct 18 '16 at 20:38
  • \$\begingroup\$ Another thing : usually, when you really need to chomp, you can chop instead to save one byte ;) \$\endgroup\$ – Dada Oct 18 '16 at 20:49
  • \$\begingroup\$ @Dada thanks, didn't think about the redo and got caught up building a complicated regex. I need to understand that golf is not obfuscation. ;) \$\endgroup\$ – simbabque Oct 18 '16 at 21:06
  • 1
    \$\begingroup\$ You code wasn't that bad! It just takes time and practice! And even after that, Ton Hospel will always find a shorter way than everybody else! ;-) \$\endgroup\$ – Dada Oct 18 '16 at 21:16
  • 1
    \$\begingroup\$ You are supposed to support all printable ASCII so you need [^()] instead of [\w ]. The first one in fact only needs [^(] \$\endgroup\$ – Ton Hospel Oct 19 '16 at 5:09
3
\$\begingroup\$

Brachylog, 35 28 25 bytes

l-L,")":LjkC,?:"("zckc:Cc

Try it online!

Explanation

l-L,          # L is length of input - 1
")":LjkC,     # C is ")" repeated L-1 times
              # output is
?:"("z        # input zipped with "("
      ckc     # flattened to a string with the last element removed
         :Cc  # concatenated with C
\$\endgroup\$
3
\$\begingroup\$

Java 82 81

Thanks to Olivier Grégoire for the correction leading to 1byte less.

Solution

I forced myself in using a String a not a char[] so this is a bit more verbose :/

String n(String s){return s.length()>1?s.charAt(0)+"("+n(s.substring(1))+")":s;}

A simple recursive function.

Test

public static void main(String[] a){
    System.out.println(n("test"));
    System.out.println(n("Hello world!"));
}

t(e(s(t)))

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

\$\endgroup\$
  • 1
    \$\begingroup\$ For Java 7, did you notice that the last character is duplicated? For Java 8, it won't compile and work because you have to define a recursive function like this: n=s->...n.apply(...) instead of s->...n(...), also there are some other issues which make your answer don't work. \$\endgroup\$ – Olivier Grégoire Oct 21 '16 at 9:30
  • 1
    \$\begingroup\$ Thanks, indeed I missed that ... I just made the correction and gain a byte, thanks :) . I removed the Java 8 part since I can't test it here and don't have enought experience to do it blindly ;) \$\endgroup\$ – AxelH Oct 21 '16 at 9:45
  • \$\begingroup\$ Well, actually a recursive function can't work in Java 8. You always get a "self-reference in intializer" error. \$\endgroup\$ – Olivier Grégoire Oct 21 '16 at 9:55
  • \$\begingroup\$ @OlivierGrégoire Never used Lambda for complex code, mainly for small validation process. But thanks for the info, I will dig into this. \$\endgroup\$ – AxelH Oct 21 '16 at 9:56
3
\$\begingroup\$

Brain-Flak, 118 84 + 1 = 85 bytes

Try it online

([[]]<{({}<>)((((()()()()()){}){}){})<>}>()){({}()<(<>({})<>())>)}{}<>{}{({}<>)<>}<>

This requires the -fc flag to run giving it an extra byte. -f flag is standard for passing input.


Explanation

([[]]<        #Store a copy of the stack height before hand in the scope
 {            #While there is something on the stack...
  ({}<>)      #Move something over and...
  ((((()()()()()){}){}){}) #Put a paren on top
  <>          #Swap back
}
>())          #Put the 1-stack height down
{             #While that is not zero
 ({}()<       #Add one and
  (<>({})<>())#Silently move a copy of the top of the other stack over (close paren)
 >)
}{}
<>{}          #Remove extra open paren
{({}<>)<>}<>  #Combine the two stacks
\$\endgroup\$
2
\$\begingroup\$

Lua, 88 bytes

Probably not nearly as short as it could be.

x=""y=...for i=1,#y-1 do x=x..y:sub(i,i).."("end print(x..y:sub(-1,-1)..(")"):rep(#y-1))

Takes input from the command line.

\$\endgroup\$
  • \$\begingroup\$ Here's even better! y=...print(y:gsub('.','%1(',#y-1)..(')'):rep(#y-1)) 51 bytes I also made variations for repeat until and while end but they were longer than yours even though as minified as possible. \$\endgroup\$ – ascx Oct 20 '16 at 12:38
  • \$\begingroup\$ @ascx In here, you're not allowed to edit his answer just to golf it further. Let the author did that. \$\endgroup\$ – Akangka Oct 23 '16 at 14:33
  • \$\begingroup\$ @ascx meta.codegolf.stackexchange.com/a/1619/46245 \$\endgroup\$ – Akangka Oct 23 '16 at 14:35
2
\$\begingroup\$

C, 102 89 bytes

Maybe this can be golfed more? I'm just happy to answer in C! :D

i=0,j=0;f(char*a){while(*a)putchar(*a),*++a?putchar(40),i++:0;while(j<i)putchar(41),j++;}
\$\endgroup\$
  • 1
    \$\begingroup\$ 79 bytes \$\endgroup\$ – ceilingcat Oct 17 at 20:31
  • \$\begingroup\$ @ceilingcat braver than me. \$\endgroup\$ – cat Oct 18 at 4:58
2
\$\begingroup\$

Ruby, 41 29 bytes

->s{s.split("").join(?()+?)*(s.length-1)}

->s{(s.chars*?()+?)*~-s.size}

Thanks @ValueInk

\$\endgroup\$
  • \$\begingroup\$ chars is more efficient than split, and I believe you want s.length-1 \$\endgroup\$ – Lee W Oct 18 '16 at 19:16
  • \$\begingroup\$ size is more efficient than length, and multiplying an array by a string does an implicit join. And finally, (x-1) can be substituted to ~-x. Combining with Lee W suggestions, you end up with ->s{(s.chars*?()+?)*~-s.size} for 29 bytes! \$\endgroup\$ – Value Ink Oct 19 '16 at 0:36
  • 2
    \$\begingroup\$ And then I realize that these standard optimizations causes it to be exactly like @m-chrzan's answer, and now this is a tad awkward \$\endgroup\$ – Value Ink Oct 19 '16 at 0:38
2
\$\begingroup\$

Turtlèd, 25 27 bytes

(original didn't work for single char inputs ;_;)

This is what Turtlèd ended up being for even though it as originally ascii art stuff.

!-l[*+.r'(r_]l-_[*-')r_]"  [2 trailing spaces]

Try it online!

Explanation:

put the input on to the cells with ( after each char

!                        Take a string as input
 -                       decrement the string pointer, so it points at last char
  l                      move left
   [*       ]            while the current cell is not *
     +.r                 increment string pointer and write the pointed char, move right
        '(r              write (, move right
           _             write * if pointed char is last char, else " "


Write the terminating parens, the first one overwriting the last open paren

             l-           move left, decrement string pointer
               _          write * if pointed char is last char, else " "
                [*     ]  while the current cell is not *
                  -')r    decrement string pointer, write ), move right
                      _   write * if pointed char is last char, else " "

                        "[2 spaces]  Remove the last *, or two *s if input is one char
\$\endgroup\$
2
\$\begingroup\$

SWI-Prolog, 82 bytes

q([H],[H]).
q([H|T],[H,40|S]):-q(T,R),append(R,[41],S).
X*Y:-q(X,Z),atom_codes(Y,Z).

Called like: `Hello World!`*X.

Online interpreter

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

Mathematica, 45 43 bytes

#2<>"("<>#<>")"&~Fold~Reverse@Characters@#&
\$\endgroup\$
  • \$\begingroup\$ You can use # instead of #1. And infix notation ~Fold~ should also work. \$\endgroup\$ – Martin Ender Oct 19 '16 at 8:42
2
\$\begingroup\$

k, 16 bytes

This is an anonymous function composition

{y,"(",x,")"}/|:

Example

k){y,"(",x,")"}/|:"hello world"
"h(e(l(l(o( (w(o(r(l(d))))))))))"
\$\endgroup\$
2
\$\begingroup\$

Pyth, 10 characters

+j\(Q*\)tl

Try it online!

Joins the input on (, and appends length - 1 closing parens afterwards.

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

CJam, 12 11 bytes

One byte saved by Martin Ender.

q_'(*\,(')*

Try it online

\$\endgroup\$
  • 1
    \$\begingroup\$ You can save a byte by avoiding the second \: q_'(*\,(')* \$\endgroup\$ – Martin Ender Oct 21 '16 at 12:01
2
\$\begingroup\$

Scala, 58 bytes

"Hello world!"match{case s =>s.mkString("(")+")"*s.length}

Could be shorter

\$\endgroup\$
  • \$\begingroup\$ I think you meant (s:String)=>s.mkString("(")+")"*s.length (40 bytes) (no need for match case here) \$\endgroup\$ – Jacob May 28 '18 at 7:22
  • \$\begingroup\$ Also - I think it's not correct. You'll need *(s.length-1) \$\endgroup\$ – Jacob May 28 '18 at 7:26
2
\$\begingroup\$

Actually, 10 bytes

lD')*ß'(j+

Try it online!

Explanation:

lD')*ß'(j+
lD')*       ")"*(len(input)-1)
     ß'(j   insert a "(" between every pair of characters in the input
         +  append the closing parens
\$\endgroup\$
2
\$\begingroup\$

V, 9 bytes

$òys$)hhl

Try it online!

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

Mathematica, 35 27 bytes bytes

Saved 8 bytes on adding the appropriate number of ")" to the end thanks to alephalpha

#~Riffle~"("<>Most[0#+")"]&

Input is a list of characters. Riffles "(" between each character, then adds that many ")" minus 1 to the end. Specifically, multiplies the input by 0, adds ")" and then takes Most of the list.

e.g.

#~Riffle~"("<>Most[0#+")"]&[{"H","e","l","l","o"}]

{"H","e","l","l","o"}~Riffle~"("<>Most[0{"H","e","l","l","o"}+")"]

{"H","(","e","(","l","(","l","(","o"}<>Most[{0,0,0,0,0}+")"]

{"H","(","e","(","l","(","l","(","o"}<>Most[{")",")",")",")",")"}]

{"H","(","e","(","l","(","l","(","o"}<>{")",")",")",")"}

"H(e(l(l(o))))"
\$\endgroup\$
  • 1
    \$\begingroup\$ #~Riffle~"("<>Most[0#+")"]& \$\endgroup\$ – alephalpha Jan 11 '17 at 14:30
2
\$\begingroup\$

PHP, 51 60 68 63 bytes

Why not just do what´s asked for instead of emulating it? Recurse!

function n($s){return$s[1]>""?"$s[0](".n(substr($s,1)).")":$s;}
\$\endgroup\$
  • \$\begingroup\$ why not change $s[1]>"" into just $s[1]? 3 chars less. \$\endgroup\$ – nl-x Oct 24 '16 at 13:40
  • \$\begingroup\$ @nl-x because the 0 character evaluates to false \$\endgroup\$ – Titus Oct 24 '16 at 13:43
  • \$\begingroup\$ @nl-x ... but I learned something just as long in the meantime. \$\endgroup\$ – Titus Mar 7 '17 at 23:53
  • \$\begingroup\$ Please do explain what you did there... \$\endgroup\$ – nl-x Mar 8 '17 at 7:26
  • \$\begingroup\$ @nl-x I messed it up. I intended a shorter check on the second character using bitwise arithmetics, but checked the string for emptiness instead. Rolled back. \$\endgroup\$ – Titus Mar 8 '17 at 13:02
2
\$\begingroup\$

QBIC, 64 bytes

Way too large. Posted as an incentive to get my butt moving again on the QBIC project.

;_LA|[a-1|Z=Z+$mid$|(A,b,1)+@(|]Z=Z+$right$|(A,1)[a-1|Z=Z+@)|]?Z

All those $mid$| and $right$|s should be turned into QBIC commands, but to do that I first need to solve a problem with nesting function calls...


EDIT: Got my butt moving. Now in 48 bytes:

_L;|[a-1|Z=Z+_sA,b,1|+@(`]Z=Z+_sA,-1|[a-1|Z=Z+@)
\$\endgroup\$
  • \$\begingroup\$ Huh. QBIC looks interesting. Is there a github project I could follow? Or a README describing what it is? \$\endgroup\$ – DJMcMayhem Nov 28 '16 at 18:11
  • \$\begingroup\$ @DrMcMoylex I swear, the day I figure out how Github works ... The project lives in a shared folder on a Google Drive, link in the header. Some info o getting started here and here. \$\endgroup\$ – steenbergh Nov 28 '16 at 18:23
  • \$\begingroup\$ Why is QBIC not on TIO? \$\endgroup\$ – MD XF Nov 10 '17 at 18:36
  • \$\begingroup\$ @MDXF Well, QBIC code is converted into QBasic code, which is run in Dosbox. I do not believe that such an environment can be easily set up for use on the web... I am taking suggestions however :) \$\endgroup\$ – steenbergh Nov 10 '17 at 20:19
  • \$\begingroup\$ @steenbergh Ah, that's true. I'm actually looking into ways to get QBasic / ABASIC / Applesoft Basic onto TIO. Right now it's looking like I'm going to need to write my own interpreters. >.< \$\endgroup\$ – MD XF Nov 11 '17 at 4:55
2
\$\begingroup\$

R, 56 bytes

function(s)c(paste(s,collapse="("),rep(")",length(s)-1))

Try it online!

Plain old R. Recursive solution below. Both input and output are vectors of characters.

R, 57 bytes

f=function(s)"if"(length(s)>1,c(s[1],"(",f(s[-1]),")"),s)

Try it online!

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

Stax, 8 6 bytes

-2 thanks to @recursive!

çΔ \Γ]

Run and debug it at staxlang.xyz!

Unpacked (7 bytes) and explanation:

Mrks:{+
M          Transpose array. This turns a string into an array of length-1 strings.
 r         Reverse string.
  k        Fold array using the rest of the program as a block:
   s         Swap. This puts the accumulator on top of the current element.
    :{       Wrap in parentheses.
      +      Concatenate.
           Implicit print at end of program!
\$\endgroup\$
  • \$\begingroup\$ If you transpose the input string, you can get rid of the stringifications, and pack down to 6. Mrks:{+ \$\endgroup\$ – recursive May 24 '18 at 17:03
  • \$\begingroup\$ @recursive Ah. That's what I was looking for. Definitely beats {]m for the same functionality! \$\endgroup\$ – Khuldraeseth na'Barya May 25 '18 at 19:57
2
\$\begingroup\$

Forth (gforth), 66 58 bytes

: f over 1 type 1 -1 d+ dup 0> if ." ("recurse ." )"then ;

Try it online!

-8 bytes by switching to a recursive solution

Explanation

Prints the first character of the string. If it's not the last character in the string, print an open parentheses, recursively call on the remainder of the string, and print a close parentheses.

Code Explanation

: f             \ start a new word definition
  over 1 type   \ print the first character of the string
  1 -1 d+       \ remove the first character of the string
  dup           \ duplicate the string length value
  0> if         \ check if remaining string length is greater than 0
    ." ("       \ print an open parentheses
    recurse     \ call recursively on remainder of string
    ." )"       \ print a close parentheses
  then          \ end the if block
;               \ end the word definition            
\$\endgroup\$
1
\$\begingroup\$

Pyth - 9 bytes

+j\(Qsm\)

Try it online here.

\$\endgroup\$
  • \$\begingroup\$ The output has one ) too many. \$\endgroup\$ – Neorej Oct 19 '16 at 11:40
  • \$\begingroup\$ Use +j\(Qstm\) instead. \$\endgroup\$ – Erik the Outgolfer Oct 19 '16 at 12:27
1
\$\begingroup\$

Perl 5, 27 bytes (25 + 1 for -l + 1 for -n)

This is a translation of Wheat Wizard's approach to Perl.

say$_.")"x s/.(?!$)/$&(/g

Run it like this:

perl -nlE 'say$_.")"x s/.(?!$)/$&(/g' <<< 'Hello'

Explanation:

say$_.")"x s/.(?!$)/$&(/g
           s/.(?!$)/   /g # replace every char not followed by end of string ...
                    $&    # ... with the full match (that's the one char)
                       (  # and an open parenthesis
           s/.(?!$)/$&(/g # this operates on and changes $_ and ...
                          # ... returns the number of substitutes
      ")"x                # repeat closing paren number of substitues times
     .                    # append
   $_                     # to the string that has already been changed to f(o(o
say                       # print with newline
\$\endgroup\$
  • \$\begingroup\$ That's some very nice golfing! :-) \$\endgroup\$ – Dada Oct 18 '16 at 21:31
  • \$\begingroup\$ You don't need the -l if you demand the input string is entered without final newline: echo -n Hello | program \$\endgroup\$ – Ton Hospel Oct 19 '16 at 5:14
1
\$\begingroup\$

Pyke, 9 bytes

\(JQl\)*+

Try it here!

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

Python 3, 40 chars

s=input()
print("(".join(s)+len(s)*")")
\$\endgroup\$
1
\$\begingroup\$

Zsh, 36 Bytes

z=${1:1};<<<${1[1]}${z///(}${z//?/)}

This should be possible in 34 bytes, but zsh syntax is inconsistent. $a[1] will return the first character of the string $a, but $1[1] returns the entire contents of $1 plus the string "[1]". I'd love to know if this is intended behavior, or just on a long list of zsh documentation not covering edge cases.

The logic used is

  1. Assign all but the first character of the first argument to a variable z
  2. Print the first character of the input
  3. Print z, with "the empty string replaced with (" which actually places a ( before each character of z
  4. Print z, with all of the characters replaced with )

I don't think its golfable much farther from here, even though I how many characters it takes to just split the first character from the rest of the string. There is probably a more efficient "logic" though, I just couldn't find one that synergizes with zsh or bash.

Speaking of bash, this doesn't work because the cute trick with sed-style replacing the empty string does not do anything in bash. I will edit with a solution that is better designed for bash-compatible syntax.

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

Gema, 31 13 characters

Shamelessly borrowing Titus's idea from his recursive PHP solution.

\B?=?
?#=(?#)

Sample run:

bash-4.3$ echo -n 'Hello world!' | gema '\B?=?;?#=(?#)'
H(e(l(l(o( (w(o(r(l(d(!)))))))))))
\$\endgroup\$

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.