Java 7, 725 байт
f(int)( 325 байт ):
String f(int i){String s="";for(int j=0,e=0;e<i;e+=v(s))s=Integer.toBinaryString(j++);return"["+s.replace("1","[").replace("0","]")+"]";}int v(String s){for(;!s.isEmpty();s=s.replaceFirst("1","").replaceFirst("0",""))if(s.replace("1","").length()!=s.replace("0","").length()|s.charAt(0)<49|s.endsWith("1"))return 0;return 1;}
g(String)( 75 + 325 байт ):
int g(String s){int r=0;for(String i="10";!i.equals(s);i=f(++r));return r;}
Так как метод gиспользует метод fдля вычисления своего результата, перебирая возможный список пустот, пока не найдет тот, который равен введенному, байтыf считаются дважды (так как оба метода должны иметь возможность работать без другого для этой задачи).
Объяснение:
В общем случае метод fпросто перебирает все двоичные String-представления целых чисел и увеличивает счетчик каждый раз, когда найден действительный. Допустимые двоичные строки для этой задачи соответствуют следующим правилам: они начинаются с a 1и заканчиваются a 0; они имеют равное количество единиц и нулей; и каждый раз, когда вы удаляете первое 1и 0снова проверяете то, что осталось, эти два правила все еще применяются. После того, как счетчик равен входному значению, он преобразует эту двоичную строку в список пустых строк, заменяя все 1на [и все 0на ].
Что касается метода g: мы начинаем с "[]"(представляющего void-list 0), а затем продолжаем использовать метод f, увеличивая целое число, пока оно не будет соответствовать input-String.
String f(int i){ // Method `f` with integer parameter and String return-type
String s=""; // Start with an empty String
for(int j=0,e=0;e<i; // Loop as long as `e` does not equal the input
e+=v(s)) // And append increase integer `e` if String `s` is valid
s=Integer.toBinaryString(j++);
// Change `s` to the next byte-String of integer `j`
// End of loop (implicit / single-line body)
return"["+ // Return the result String encapsulated in "[" and "]"
s.replace("1","[").replace("0","]")+"]";
// after we've replaced all 1s with "[" and all 0s with "]"
} // End of method `f`
int v(String s){ // Separate method with String parameter and integer return-type
for(;!s.isEmpty(); // Loop as long as String `s` isn't empty
s=s.replaceFirst("1","").replaceFirst("0",""))
// After each iteration: Remove the first "1" and "0"
if(s.replace("1","").length()!=s.replace("0","").length()
// If there isn't an equal amount of 1s and 0s
|s.charAt(0)<49 // or the String doesn't start with a 1
|s.endsWith("1")) // or the String doesn't end with a 0
return 0; // Return 0 (String is not valid)
// End of loop (implicit / single-line body)
return 1; // Return 1 (String is valid)
} // End of separate method
int g(String s){ // Method `g` with String parameter and integer return-type
int r=0; // Result integer
for(String i="[]";!i.equals(s);
// Loop as long as `i` does not equal the input String
i=f(++r)); // After each iteration: Set `i` to the next String in line
return r; // Return the result integer
} // End of method `g`
Примеры случаев ввода и вывода:
Попробуй это здесь. (ПРИМЕЧАНИЕ. В последние несколько тестов это происходит довольно медленно. На все это уйдет около 10-15 секунд.)
0 <-> []
1 <-> [[]]
2 <-> [[][]]
3 <-> [[[]]]
4 <-> [[][][]]
5 <-> [[][[]]]
6 <-> [[[]][]]
7 <-> [[[][]]]
8 <-> [[[[]]]]
9 <-> [[][][][]]
10 <-> [[][][[]]]
11 <-> [[][[]][]]
12 <-> [[][[][]]]
13 <-> [[][[[]]]]
14 <-> [[[]][][]]
50 <-> [[[][[[]]]]]
383 <-> [[[][]][[[][]]]]