Java 7, 725 bytes
f(int)( 325 bytes ):
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 bytes ):
int g(String s){int r=0;for(String i="10";!i.equals(s);i=f(++r));return r;}
Como el método gusa el método fpara calcular su resultado, recorre la posible lista vacía hasta que encuentra el igual al ingresado, los bytes def se cuentan dos veces (ya que ambos métodos deberían poder ejecutarse sin el otro para este desafío).
Explicación:
En general, el método fsimplemente recorre todas las representaciones de cadenas binarias de enteros y aumenta un contador cada vez que se encuentra uno válido. Las cadenas binarias válidas para este desafío cumplen con las siguientes reglas: comienzan con a 1y terminan con a 0; tienen el mismo número de 1s y 0s; y cada vez que elimine el primero 1y 0valide lo que queda nuevamente, estas dos reglas aún se aplican. Después de que el contador es igual a la entrada, convierte esa cadena binaria en una lista vacía de cadena, reemplazando todas 1con [y todas 0con ].
En cuanto al método g: comenzamos con "[]"(que representa la lista vacía 0), y luego continuamos usando el método fmientras aumentamos un entero, hasta que coincida con la cadena de entrada.
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`
Ejemplos de casos de entrada y salida:
Pruébalo aquí (NOTA: es bastante lento para los últimos casos de prueba. Tomará alrededor de 10-15 segundos para todos ellos).
0 <-> []
1 <-> [[]]
2 <-> [[][]]
3 <-> [[[]]]
4 <-> [[][][]]
5 <-> [[][[]]]
6 <-> [[[]][]]
7 <-> [[[][]]]
8 <-> [[[[]]]]
9 <-> [[][][][]]
10 <-> [[][][[]]]
11 <-> [[][[]][]]
12 <-> [[][[][]]]
13 <-> [[][[[]]]]
14 <-> [[[]][][]]
50 <-> [[[][[[]]]]]
383 <-> [[[][]][[[][]]]]