Imagine a simple SKI calculus expression - for example, (((S α) β) γ). As you can see, each node of the rooted tree has exactly two children. Sometimes though, the parentheses are omitted and the tree is unrooted (just to make the notation clear, I believe). The challenge is to put the parentheses back, so that the tree is binary and rooted again.

The preferable way of I/O is mostly up to you; although the input and output has to at least look like the SKI calculus, and it obviously has to represent a tree.

The rule on adding parentheses is simple: α β γ becomes ((α β) γ) (bind to the left), α β γ δ becomes (((α β) γ) δ), and so on.

You may assume that the input is a correct SKI-calculus expression.

If it wasn't clear enough, you may NOT add more braces than necessary. And if it helps you in any way, you can assume that the input contains no redundant parens (like, for example, (((SK)))).


S(KS)K => ((S(KS))K)
SS(SK) => ((SS)(SK))
  • 1
    \$\begingroup\$ I'm not sure I understand the challenge completely: does using specifically SKI calculus rather than random letters affect things? \$\endgroup\$ Jun 14, 2020 at 17:13
  • \$\begingroup\$ Well - no, not really, but I'd like to ask specifically about SKI calculus. It doesn't change anything, though \$\endgroup\$ Jun 14, 2020 at 17:22
  • \$\begingroup\$ Does the program have to remove extra, unneeded parentheses? For example, what if the input is (S) or ((S))KK? \$\endgroup\$ Jun 14, 2020 at 17:40
  • \$\begingroup\$ In the second example, would answer of ((SS)((SK))) be wrong? If so, why? \$\endgroup\$
    – Abigail
    Jun 14, 2020 at 17:54
  • 1
    \$\begingroup\$ What are the nesting rules? Does A(BCDE)F become ((A(((BC)D)E))F)? \$\endgroup\$ Jun 14, 2020 at 18:24

2 Answers 2


Perl 5 -p, 37 bytes


Try it online!

  • 1
    \$\begingroup\$ very nice, "regular" expressions parsing a proper context-free language :) \$\endgroup\$
    – ngn
    Jun 15, 2020 at 0:03

Charcoal, 52 bytes


Try it online! Link is to verbose version of code. Outputs a stringified tree-like nest of lists. Explanation:


Start with an empty tree.


Loop over the input characters.


If this is a ), then...


... restore the parent node saved below, otherwise:


If the current node already has two children, then...


... remove them and put them in a first child node. (I can't wrap them in a node, since its parent is still pointing to it.)


If this is a (, then...


... save the current node, ...


... push an empty node, ...


... and set that as the current node.


Otherwise push the letter to the current node.


Stringify and output the tree.

56 bytes for pretty output:


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


Start with an empty tree.


Loop over the input characters, but add an extra I to ensure that the final result is wrapped in () if necessary. (If the result can always be wrapped in (), then this can be F⪫()θ« and the last part can be »ζ for an overall saving of 1 byte.)


Get what the bracketed expression would be.


If the current node already has two children then replace it with a node with the bracketed expression.


Switch on the current character.


If it's a ( then save the current node and start a new node.


If it's a ) then retrieve the saved node and push the bracketed expression to it.


Otherwise push the letter to the current node.


Output the desired expression.

  • \$\begingroup\$ the output is correct; well done. \$\endgroup\$ Jun 14, 2020 at 19:18

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.