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

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\$
2
\$\begingroup\$

Vyxal, 7 bytes

L‹k(*sY

Try it Online!

Get gamed on @emanresuA

Explained

L‹k(*sY
L‹      # Push the length of the input, but decremented
  k(    # Push "()"
    *   # and repeat it ↑↑ times
     s  # sort that
      Y # and interleave it with the input
\$\endgroup\$
1
  • \$\begingroup\$ Ugh, that builtin. Nice job :P \$\endgroup\$
    – emanresu A
    Nov 2 '21 at 19:08
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\$
2
  • \$\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\$

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\$
1
\$\begingroup\$

Scala, 46 bytes

(s:String)=>(s.init:\(""+s.last))(_+"("+_+")")

Explanation:

(s:String)=>    //define a function
  (s.init       //take everything but the last char
   :\           //foldRight
   (""+s.last)    //with the last char as a string as a start
  )(              //combine the chars right to left with this function:
    _+"("+_+")"   //take the char, append "(", append everything we've got so far, append ")"
  )
\$\endgroup\$
1
\$\begingroup\$

Groovy, 38 36 Bytes thanks to @manatwork

{it.reverse().inject{r,i->i+"($r)"}}

Yeah, the C&P messed up the first time.

\$\endgroup\$
5
  • \$\begingroup\$ I think your code was destroyed on copy paste, as is neither functional and is far from your byte count. BTW, no need for braces around simple variables in expansion. \$\endgroup\$
    – manatwork
    Oct 19 '16 at 19:14
  • \$\begingroup\$ @manatwork was missing a brace, the braces are for string interpolation and you're right I effed the byte-count, forgot it needed reverse. \$\endgroup\$ Oct 19 '16 at 19:41
  • \$\begingroup\$ I use lettercount.com for groovy byte count, NO IDEA what was going on. I thought 68 seemed high... \$\endgroup\$ Oct 19 '16 at 19:42
  • 1
    \$\begingroup\$ Cool. But you still have extra braces in interpolation: "(${r})""($r)". At least Groovy 2.4.5 is happy without them too. \$\endgroup\$
    – manatwork
    Oct 19 '16 at 19:51
  • \$\begingroup\$ @manatwork most of my experience is with Groovy on Grails and $ notation isn't accepted in views AFAIK. \$\endgroup\$ Oct 19 '16 at 19:52
1
\$\begingroup\$

Python 2, 60 57 51 Bytes

def c(s):if(len(s)==1):return s;return s[0]+"("+c(s[1:])+")"

After some clarification on the rules from @manatwork on white space,

def c(s):return s if(len(s)==1)else s[0]+"("+c(s[1:])+")"

Thanks again @manatwork

def c(s):return s[0]+"("+c(s[1:])+")"if s[1:]else s

Ungolfed:

def c(s):
    if(len(s)==1):
        return s;
    return s[0]+"("+c(s[1:])+")"

Recursively calls itself and adds to the string.

c("CodeGolf") = 'C(o(d(e(G(o(l(f)))))))'
\$\endgroup\$
5
  • 3
    \$\begingroup\$ This doesn't work. You can't have if statements in one line. SyntaxError \$\endgroup\$
    – Blue
    Oct 19 '16 at 19:00
  • \$\begingroup\$ I just put in on the one line to show it concisely without whitespace. You actually run the ungolfed version \$\endgroup\$
    – bioweasel
    Oct 19 '16 at 19:23
  • 1
    \$\begingroup\$ Sorry, @bioweasel, but the spaces needed for the code to run have to be counted. Better refactor it to have a single statement inside the function: def c(s):return s if(len(s)==1)else s[0]+"("+c(s[1:])+")". \$\endgroup\$
    – manatwork
    Oct 19 '16 at 20:02
  • \$\begingroup\$ Ah, gotcha. Sorry, this is my first time and I wasn't quite sure on the rules 100%, especially with Python and the whitespace \$\endgroup\$
    – bioweasel
    Oct 19 '16 at 20:09
  • \$\begingroup\$ You could use that s[1:] syntax in the condition too: def c(s):return s[0]+"("+c(s[1:])+")"if s[1:]else s. \$\endgroup\$
    – manatwork
    Oct 19 '16 at 20:24
1
\$\begingroup\$

Python 50 49 bytes

saved 1 byte (actually 3) thanks to @ETHproductions

This is my recursive version written in Python. Would probably be shorter the iterative aproach.. but I simply like recursion :)

F=lambda s:s[0]+'('+F(s[1:])+')'if len(s)>1else s
\$\endgroup\$
5
  • \$\begingroup\$ If a function entry needs to call itself, you must include the assignment (i.e. F=) in the byte count. Also, I think you can do s at the end instead of s[0], as the string's length is already 1. \$\endgroup\$ Oct 21 '16 at 13:05
  • \$\begingroup\$ ups, I actually had it like that but forgot to copy it.. thanks! \$\endgroup\$
    – Stefan
    Oct 21 '16 at 14:58
  • \$\begingroup\$ Quite similar to bioweasel's Python solution. \$\endgroup\$
    – manatwork
    Oct 21 '16 at 15:05
  • \$\begingroup\$ Indeed, didn't see his solution.. \$\endgroup\$
    – Stefan
    Oct 21 '16 at 15:16
  • \$\begingroup\$ Possible 48 bytes. \$\endgroup\$ Aug 28 '18 at 16:20
1
\$\begingroup\$

Dart 44 bytes

p(s)=>s.split("").join("(")+")"*~-s.length;

I tried to be clever, but nothing beat this simple version. Notable mention:

r(s,[x=0])=>s[x++]+(x<s.length?"(${r(s,x)})":"");
q(s)=>s[0]+((s=s.substring(1))==""?s:"(${q(s)})");

but they drowned in necessary parentheses.

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

Java, 72 bytes

(a,s,l)->{l=a.length;s=""+a[--l];for(;l>0;)s=a[--l]+"("+s+")";return s;}

Ungolfed

public class Main {

  interface X {
    String f(char[]a,String s,int l);
  }

  static X x = (a,s,l) -> {
    l = a.length;
    s = "" + a[--l]; // start with the last character
    for (;l>0;)
      s = a[--l] + "(" + s +")"; // wrap in parentheses and prepend with the previous letter.
    return s;
  };

  public static void main(String[] args) {
    System.out.println(x.f("Hello World!".toCharArray(),"",0));
  }
}
\$\endgroup\$
1
\$\begingroup\$

C, 84 82 76 70 68 66 Bytes

i;f(char*s){for(i=1;*s+~i;putchar(*s?i&1?*s++:40:41),i+=*s?1:-2);}

Now using just one for loop and one putchar...

Test is like this

main(c,v)char**v;
{
    f(v[1]);puts("");
    f("foobar");puts("");     
    f("code-golf");puts("");     
}

output

H(e(l(l(o( (W(o(r(l(d))))))))))
f(o(o(b(a(r)))))
c(o(d(e(-(g(o(l(f))))))))
\$\endgroup\$
1
\$\begingroup\$

JavaScript, 36 bytes

([...v])=>v.join`(`+v.fill``.join`)`

I can't seem to beat the top score of 34 bytes, but I thought I would share my different approach.

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

Clojure, 94 60 59 48 bytes

-34 by making it a actual recursive solution. The biggest saving here was getting rid of the repeat part to generate the end brackets.

-1 by rearranging it, eliminating a conditional.

-11 bytes thanks to NikoNyrh. Now deconstructs the parameter directly.

(defn n[[f & r]](if(str f(if r(str\((n r)\))))))

Recursive. Basically (str head "(" (recur tail) ")"), with the brackets being added only if a tail exists.

Uses unoptimized recursion. Can handle strings up to around 5235 characters long.

Ungolfed:

(defn nest [[f & r]]
    (if f ; When it exists, construct string and recur, else, base-case
      (str f (if r (str \( (nest r) \))))))
\$\endgroup\$
2
  • \$\begingroup\$ I guess you could merge function definition and let to (defn n[[f & r]](if f(str f(if r(str\((n r)\))))) :) \$\endgroup\$
    – NikoNyrh
    Jan 11 '17 at 0:38
  • \$\begingroup\$ @NikoNyrh You're right! I hate deconstructing in the parameter list in real code, but that certainly helps here. Thanks! \$\endgroup\$ Jan 11 '17 at 0:39
1
\$\begingroup\$

Python 3, 43 bytes

lambda x:print(*x,sep='(',end=')'*~-len(x))

Longer than shortest Python submission, but it is fairly different, so I thought I should post it. It is a function, but prints to STDOUT.

\$\endgroup\$
2
  • \$\begingroup\$ This prints one extra close paren each time. Try ~-len(x) rather than len(x) \$\endgroup\$
    – Wheat Wizard
    Jan 11 '17 at 2:16
  • \$\begingroup\$ @WheatWizard Thank you, I don't know how I missed that. \$\endgroup\$
    – nedla2004
    Jan 11 '17 at 12:49
1
\$\begingroup\$

Haskell, 38 30 bytes

8 bytes saved thanks to @JanDvorak

f[x]=[x]
f(x:s)=x:'(':f s++")"

This is my first attempt at a haskell golf, probably not optimal yet.

Explanation

We define a function f. If this function receives input that matches the pattern [x], that is a length 1 string, we return the input. If we receive anything else as input we return the x:'(':f s++")", or the first character plus the rest result of f on the rest of the string all enclosed in parentheses.

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

Groovy, 46 bytes

{it.reverse().inject{r,i->")$r($i"}.reverse()}
\$\endgroup\$
1
\$\begingroup\$

Swift 3.1,  85  83 bytes

This is an anonymous function accepting an Array of Strings and returning a String.

{$0.joined(separator:"(")+String(repeating:")",count:$0.count-1)}as([String])->String

Try it here!

Swift 3.1,  88 87  86 bytes

This is a named function accepting an Array of Strings and printing a String.

func f(n:[String]){print(n.joined(separator:"(")+(1..<n.count).map{_ in")"}.joined())}

Try it here!

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

Ly, 50 bytes

iyspr1[1[=!["("o1$]p1$]1[=[pp2$]p1$]o]l1-[")"o1-];

Try it online!

This is ridiculous. Ly is lacking severely in the string manipulation department.

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

Java 8 (63 82 bytes)

"s" is a char[]

s->{String r="",p=r;for(char c:s){r+="("+c;p+=")";}return r+p;}

s->{String r="",p=r;for(char c:s){if(r==p)r+=c;else{r+="("+c;p+=")";}}return r+p;}

Edit: I didn't realise there aren't parentheses around the whole string.

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

Implicit, 24 23 bytes

~@~.(0-1@40@~.);;(0@41;

Try it online!

Ungolfed/explained:

~@~.     # read first character, print, read second, increment
(0       # do-while top of stack truthy
 -1      #  decrement top of stack
 @40     #  print open parenthesis (ASCII 40)
 @       #  print top of stack
 ~.      #  read char and increment
)        # while top of stack truthy
;;       # pop top two values (EOF, last char)

(0       # do-while top of stack truthy
 @41     #  print close parenthesis (ASCII 41)
 ;       #  pop top of stack
¶        # (implicit) forever

Test cases:

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

foobar
f(o(o(b(a(r)))))

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

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

a
a

42
4(2)
\$\endgroup\$
1
\$\begingroup\$

SNOBOL4 (CSNOBOL4), 111 bytes

	INPUT LEN(1) . O REM . N
	W =SIZE(N)
N	N LEN(1) . X REM . N	:F(O)
	O =O '(' X	:(N)
O	OUTPUT =O DUPL(')',W)
END

Try it online!

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

Canvas, 8 bytes

(*;L╷)×+

Try it here!

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

Python 3.6+, 39 bytes

z=lambda x,*y:x+f'({z(*y)})'if y else x

Takes each character as an individual argument (can be used like z(*'asdf')). This uses recursion with iterable unpacking and f-string interpolation.


Note: This is almost non-competing. Python 3.6 was released after this challenge was posted, but was feature-frozen in beta on 2016-09-12, so this feature was available before the challenge was posted.


Though it turns out you can do it in the same number of bytes with %-interpolation (this works on more Python versions):

z=lambda x,*y:x+'(%s)'%z(*y)if y else x
\$\endgroup\$
1
\$\begingroup\$

Whitespace, 132 bytes

[S S S N
_Push_0][N
S S N
_Create_Label_LOOP][S N
S _Duplicate][S N
S _Duplicate][T N
T   S _Read_characters_as_STDIN][T  T   T   _Retrieve][S S S T  S T S S T   N
_Push_41_)][T   S S T   _Subtract][N
T   S S N
_If_0_Jump_to_Label_PRINT_TRAILING][S N
S _Duplicate][N
T   S T N
_If_0_Jump_to_Label_SKIP][S S S T   S T S S S N
_Push_40_(][T   N
S S _Print_as_character][N
S S T   N
_Create_Label_SKIP][S N
S _Duplicate][T T   T   _Retrieve][T    N
S S _Print_as_character][S S S T    N
_Push_1][T  S S S _Add][N
S N
N
_Jump_to_Label_LOOP][N
S S S N
_Create_Label_PRINT_TRAILING][S S S T   N
_Push_1][T  S S T   _Subtract][S N
S _Duplicate][N
T   S S S N
_If_0_Jump_to_Label_EXIT][S S S T   S T S S T   N
_Push_41_)][T   N
S S _Print_as_character][N
S N
S N
_Jump_to_Label_PRINT_TRAILING]

Letters S (space), T (tab), and N (new-line) added as highlighting only.
[..._some_action] added as explanation only.

Try it online (with raw spaces, tabs and new-lines only).

Since Whitespace's STDIN don't know when the input is done since it can only read a single character or number at a time, the input will need a trailing ) to indicate we're done inputting (which is possible since the challenge rules state: "For simplicity's sake, you may also assume the input will not contain parentheses").

Explanation in pseudo-code:

Integer n = 0
Start LOOP:
  Character c = read character from STDIN
  If(c == ')'):
    Jump to function PRINT_TRAILING
  If(n != 0)
    Print '(' to STDOUT
  Print c to STDOUT
  n = n + 1
  Jump to next iteration of LOOP

function PRINT_TRAILING:
  n = n - 1
  If(n == 0)
    Stop program
  Print ')' to STDOUT
  Jump to function PRINT_TRAILING
\$\endgroup\$
1
\$\begingroup\$

J, 29 bytes

f=:(')'#~<:@#),~}.@,@('(',.])

Try it online!

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

C++, 66 bytes

[&](string s){return s[1]?s.substr(0,1)+"("+f(s.substr(1))+")":s;}

Try it Online

Matlab, 45 bytes

@(s)fold(@(x,y)strcat(y,'(',x,')'),fliplr(s))

Try it Online!

The problem with this is that octave in try it online doesn't really support the fold function which of course exists in Matlab. Let me know if I should delete this solution since we can't test it on tio.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Being able to test a submission on TIO is not a requirement, so your MATLAB answer is just fine. It's preferable to post different solutions in different answers though, so they can be voted on independently. \$\endgroup\$
    – Dennis
    Aug 28 '18 at 14:18
  • \$\begingroup\$ Octave implementation of fold() \$\endgroup\$
    – ceilingcat
    Oct 16 '19 at 5:22
1
\$\begingroup\$

Racket 195 bytes

(let p((r "")(l(reverse(string->list s)))(i 0))(cond[(= i(length l))r][(= i 0)(set! r(string(list-ref l i)))
(p r l(+ 1 i))][(set! r(string-append(string(list-ref l i))"("r")" ))(p r l(+ 1 i))]))

Ungolfed:

(define (f s)
  (let loop ((r "")
             (l (reverse (string->list s)))
             (i 0))
    (cond
      [(>= i (length l)) r] 
      [(= i 0) (set! r (string (list-ref l i)))
               (loop r l (add1 i))]
      [else (set! r (string-append (string (list-ref l i)) "(" r ")" ))
            (loop r l (add1 i))]
      )))

Testing:

(f "Hello")

Output:

"H(e(l(l(o))))"

Edit: 2 bytes saved following suggestion by @JonathanFrech (add1 to + 1)

\$\endgroup\$
1
  • \$\begingroup\$ + 1 is shorter than add1. \$\endgroup\$ Aug 28 '18 at 16:15
1
\$\begingroup\$

Gol><>, 21 bytes

TiE!tlF`(}}|~l2,R`)rH

Try it online!

24 bytes

TiE!trlF}8ss}|r~l2,R`)rH

It's hideous, I know. I am going to golf this profusely.

Try it online!

\$\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.