Take the 2-minute tour ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

In the esoteric programming language Curly, programs consist solely of curly braces {} and semicolons ;. Despite this humble toolset, Curly has literals that can represent any nonnegative integer. The format is a little hard for the uninitiated to read, though, so let's write some code to do the conversion for us.

Format of numbers

Curly numbers are structured according to the following rules:

  1. Adding a semicolon adds one to the number.
  2. A number enclosed in curly braces is multiplied by four.
  3. Curly-brace groups may be nested but not concatenated. Braces must match properly.
  4. Semicolons outside a set of curly braces must come afterward, not before.
  5. To avoid ambiguity in parsing, a number must always start with a curly brace.

Some examples:

{;;}     2*4 = 8
{{;};};  (1*4+1)*4+1 = 21
{};;;    0*4+3 = 3

(Note that rule 5 means the numbers 0 to 3 must start with an empty pair of curly braces.)

And some invalid examples:

{{;}{;;}}  Curly brace groups side-by-side, not nested
{;}}       Unmatched brace
{;{;}}     Semicolon before curly-brace group
;;;        Number does not start with curly brace

Here's a BNF grammar for Curly numbers:

<number> ::= "{" <inner> "}" <semis>
<inner>  ::= <semis>
           | <number>
<semis>  ::= ";" <semis>
           | ""

Numbers like {;;;;} (more than 3 semicolons in a row) or {{};} (unnecessary empty brace groups) are called improper Curly numbers. They obey the above grammar and can be evaluated in the usual way, but they are also capable of shorter representations (for the above examples, {{;}} and {;} respectively).

The challenge

Write a program or function that inputs/receives a string. If the string is a nonnegative decimal integer, output/return the proper (i.e. shortest possible) Curly representation for that integer. If the string is a Curly number, output/return its decimal representation.

Input can be received via STDIN, command-line argument, or function parameter. It must be a string; that is, you may not write a function that accepts strings for Curly numbers but integers for decimal numbers.

Output can be printed to STDOUT or returned from the function. A function may return an integer when appropriate, or it may return strings in all situations.

Your program does not have to handle bad input (Curly numbers that break the formatting rules, floating point numbers, negative integers, random text), and it is not required to handle improper Curly numbers (but see below). Input will consist only of printable ASCII characters.

Scoring

The shortest code in bytes wins. If your program can do both of the following:

  1. correctly handle improper Curly numbers, and
  2. when given a Curly number, ignore any extra characters that aren't {};

then subtract 10% from your score. (Integer input will never have extraneous characters, even for the bonus.)

Test cases

Input       Output
{;;}        8
{{;};};     21
{};;;       3
{{{{;}}};}  260
{}          0
4           {;}
17          {{;}};
1           {};
0           {}
96          {{{;};;}}

For the bonus:

{};;;;;     5
{{;;;;};;}  72
c{u;r;l}y;! 9
42{;} ;;;;  8

Note: Curly is not yet implemented. But if this question does well, I may develop it further.

share|improve this question
    
how it should handle case if you have not matching number of parenthesis ? or shall i assume it will never happened? –  user902383 1 hour ago
    
@user902383 You can assume that non-matching curly braces will never happen. –  DLosc 1 hour ago

6 Answers 6

CJam, 51 47 44 41 bytes

r_'{-_@={i4bYUe[';f*{{}s@*\+}*}{'}/:,4b}?

Try it online: sample run | test suite

How it works

r        e# Read a token from STDIN.
_'{-     e# Remove all left curly brackets from a copy of the token.
_@       e# Copy the modified token and rotate the original on top of it.
=        e# Check for equality.
{        e# If the strings were equal:
  i4b    e#   Convert to integer, then to base 4.
  YUe[   e#   Left-pad the resulting array with zeroes to a length of 2.
  ';f*   e#   Replace each digit with that many semicolons.
  {      e#   For each string of semicolons but the first:
    {}s  e#     Push the string "{}".
    @    e#     Rotate the first string or the result of the previous 
         e#     iteration on top of the stack.
    *    e#     Join, i.e., surround the string with curly brackets.
    \+   e#     Append the current string of semicolons to the result.
  }*     e#
}{       e# Else:
  '}/    e#   Split the modified input at right curly brackets.
  :,     e#   Replace each run of 0 to 3 semicolons by its length.
  4b     e#   Convert from base 4 to integer.
}?       e#
share|improve this answer

Python 2, 167 characters

d=lambda x:("{"+d(x//4)+"}"if x>3 else"")+";"*(x%4)
c=lambda n:"{}"*(int(n)<4)+d(int(n))if n.isdigit()else reduce(lambda x,y:x*4+y,[x.count(";")for x in n.split("}")])

In this implementation, c is the function that satisfies the requirements. It returns a string if given an nonnegative integer as input, or an integer if given a curly number as input.

share|improve this answer
    
Nice work! Your answer also gets the -10% bonus. –  DLosc 14 hours ago

CJam, 87 bytes 80.1 score (89 bytes - 10% bonus)

Update version that qualifies for the bonus while growing by 2 bytes:

l_'{#){VX@{";{}"#)" _@+\ 4* 4/"S/=~}/;}{i_4<{"{}"\';*}{{4md\_{F'{\+'}+}{;L}?\';*+}:F~}?}?

Try it online

First time I used recursion in CJam! The whole thing may look kind of lengthy, but the two completely separate conversions add up.

I used a completely separate case for converting numbers smaller than 4 to Curly. It's probably possible to avoid that, but folding the special case handling into the recursive function wouldn't be entirely trivial. And adding the extra {} as a post-processing step didn't really look any better, even though I should try again if it might be slightly shorter.

share|improve this answer
    
Wouldn't your score be 80.1? –  Pietu1998 11 hours ago
3  
@Pietu1998 Thanks. Not only are my solutions too long, apparently I also fail at basic arithmetic... –  Reto Koradi 10 hours ago

Pyth, 35 32 bytes - 10% = 28.8

.x.U+jb`HZ*R\;.[Z2jsz4i/R\;cz\}4

Try it online: Demonstration or Test Suite

edit: As it turned out, I accidentally can also handle improper Curly Numbers. Wasn't planned at all. ;-)

Explanation:

There are two expressions in the code. The first one converts a number into a Curly Number, and the second one converts a Curly Number into a regular number. .x handles, which expression gets printed. It will try to print the first expression. If there are any non-digits in the input, the first expression fails (via Exception). .x catches the Exception and prints the second one.

.U+jb`HZ*R\;.[Z2jsz4   # number to Curly Number
                 sz    read the input and converts it to an int
                j  4   convert to base 4
            .[Z2       pad zeros on the left, until length is >= 2
        *R\;           convert each digit to ";"s
                       lets call this list of ";"s Y
.U                     reduce this list, start with b=Y[0], 
                       Z iterates over Y[1], Y[2], ..., 
                       update b in each step with:
   jb`H                   put b into curly brackets
  +    Z                  and append Z

i/R\;cz\}4             # Curly Number to regular number
     cz\}              split the input by "}"
 /R\;                  count the ";"s in each string
i        4             convert this list from base 4 to base 10
share|improve this answer
2  
Fastest gun in the west :( I had this exact solution except I had forgotten that the .[Z2 was necessary. –  orlp 6 hours ago

C#, 163 bytes

With bonus: 197 - 10% = 177.3

This does no validation and only looks for ; and } characters. It assumes all { characters come before any ; characters.

Line breaks and indents for clarity:

string C(string a){
    int n;
    if(int.TryParse(a,out n))
        a="{"+(n>3?C(""+n/4):"")+"}"+new string(';',n%4);
    else{
        foreach(char c in a)
            n=c==';'?n+1:c=='}'?n*4:n;
        a=""+n;
    }
    return a;
}

Going for the bonus took more effort than worth. The hardest thing I found was to not insert a {} in the middle of a Curly number.

Line breaks and indents for clarity:

string C(string a){
    int n;
    if(int.TryParse(a,out n))
        a="{"+(n>3?(a=C(""+n/4)).Substring(a[1]=='}'?2:0):"")+"}"+new string(';',n%4);
    else{
        foreach(char c in a)
            n=c==';'?n+1:c=='}'?n*4:n;
        a=""+n;
    }
    return a;
}
share|improve this answer
    
You can save one Byte by using var instead of char in the foreach loops. –  raznagul 2 hours ago
    
Unfortunately, output such as {{};} is invalid even without the bonus: on integer input, your program must output a proper Curly number, without the extra {} in the middle. Fortunately, your bonus solution works correctly and is eligible for the bonus. –  DLosc 1 hour ago

Java 326 bytes - 10% = 294 bytes

It is complete program written in java,

public class a{static String c(long a,int v){if(a==0)return v==0?"{}":"";String x="";for(int i=0;i<a%4;i++)x+=";";return "{"+c(a/4,v+1)+"}"+x;}public static void main(String[]c){try{System.out.println(c(Long.parseLong(c[0]),0));}catch(Exception e){System.out.println(c[0].chars().reduce(0,(a,b)->b==';'?a+1:b=='}'?a*4:a));}}}

I'm sure it can be much shorter but i cant have much time now to optimize it

share|improve this answer
    
You're halfway there, but this doesn't appear to properly convert integer input to Curly numbers. For an input of "16", I got 0 (should have been "{{;}}"). –  DLosc 53 mins ago
    
@DLosc damn, right, and thought i can have a nice result with java:( –  user902383 49 mins ago
    
also: common optimisation on java is to avoid the public before class –  masterX244 3 mins ago

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.