76
\$\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
  • 11
    \$\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
  • \$\begingroup\$ Is the output the execution of said function, or merely the string itself? \$\endgroup\$ – nl-x Oct 24 '16 at 12:24
  • 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

91 Answers 91

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\$
  • \$\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\$ – Magic Octopus Urn 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\$ – Magic Octopus Urn 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\$ – Magic Octopus Urn Oct 19 '16 at 19:52
1
\$\begingroup\$

Bash / sed, 74 bytes

y=$(echo $1|sed "s/./\0(/g");z=$(echo $1|sed "s/./)/g");echo ${y%?}${z%?}
  • Puts a parenthesis after each characters in y.
  • Puts a parenthesis for each characters in z.
  • Print x and z truncated of one character.

To test, put this code into a file, and run the shell script with any arguments.

\$\endgroup\$
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\$
  • 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\$

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\$
  • \$\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\$ – Carcigenicate 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\$
  • \$\begingroup\$ This prints one extra close paren each time. Try ~-len(x) rather than len(x) \$\endgroup\$ – Sriotchilism O'Zaic 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\$

Kotlin, 83 63 bytes

-20 bytes using toList; thanks to 12Me21 tipping me off this could be shorter.

{s:String->s.toList().joinToString("(")+")".repeat(s.length-1)}

Try it online!

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

Forth (gforth), 66 bytes

: f 1- 2dup 0 ?do dup 1 type ." ("') over c! 1+ loop 1 type type ;

Try it online!

Explanation

Prints each character of the string (except the last) followed by an open parenthesis, then overwrites the string and replaces the character with a close parenthesis. At the end, prints the last character, and then prints the string (now consisting of all close-parentheses).

Code Explanation

: f             \ start a new word definition
  1- 2dup       \ subtract one from the string length and duplicate the string identifier
  0 ?do         \ loop from 0 to string length - 2
    dup         \ duplicate the current string address
    1 type      \ output the character at the current address
    ." ("       \ output an open parenthesis
    ') over c!  \ get the char-code for a close-parenthesis, then write to the current address
    1+          \ add 1 to the current address
  loop          \ end the loop
  1 type type   \ output the last character, then output the string of parenthesis
;               \ end the word definition
\$\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\$
  • 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
0
\$\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\$
  • \$\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\$ – ETHproductions 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\$ – Jonathan Frech Aug 28 '18 at 16:20
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\$

Canvas, 8 bytes

(*;L╷)×+

Try it here!

\$\endgroup\$
0
\$\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\$
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\$
  • \$\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\$

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.