Literales de cadena de Python de golf

21

Fondo

Python 3 tiene muchos tipos de literales de cadena. Por ejemplo, la cadena this 'is' an exa\\m/plese puede representar como:

'this \'is\' an exa\\\\m/ple'
"this 'is' an exa\\\\m/ple"
r"this 'is' an exa\\m/ple"
'''this 'is' an exa\\\\m/ple'''
"""this 'is' an exa\\\\m/ple"""
r'''this 'is' an exa\\m/ple'''
r"""this 'is' an exa\\m/ple"""

Como puede ver, el uso de diferentes delimitadores para cadenas puede alargar o acortar cadenas al cambiar el escape necesario para ciertos caracteres. Algunos delimitadores no se pueden usar para todas las cadenas: r'falta arriba (ver más adelante para una explicación) Conocer sus cuerdas es muy útil en el golf de código.

También se pueden combinar múltiples literales de cadena en uno:

'this \'is\' an ''''exa\\\\m/ple'''
"this 'is' an "r'exa\\m/ple'

Reto

El desafío es, dada una cadena ASCII imprimible, generar su representación literal más corta en Python.

Detalles sobre la mecánica de cuerdas

Las cadenas pueden estar delimitados usando ', ", '''y """. Una cadena termina cuando el delimitador inicial se golpea nuevamente sin escapar.

Si un literal de cadena comienza con '''o """se consume como delimitador. De lo contrario 'o "se utiliza.

Los personajes se pueden escapar colocando un \antes de ellos. Esto inserta el carácter en la cadena y elimina cualquier significado especial que pueda tener. Por ejemplo, en 'a \' b'el medio 'se escapa y, por lo tanto, no termina el literal, y la cadena resultante es a ' b.

Opcionalmente, uno de ro Rpuede insertarse antes del delimitador de inicio. Si se hace esto, el escape \aparecerá en el resultado. Por ejemplo, r'a \' b'evalúa a a \' b. Por eso a ' bno se puede delimitar por r'.

Para escapar '''o """, uno solo necesita escapar de uno de los personajes.

Estos literales se pueden concatenar juntos, lo que concatena sus contenidos.

Reglas

  • La entrada es la cadena de golf. Solo ASCII imprimible, por lo que no hay líneas nuevas u otros caracteres especiales.
  • La salida es el literal de cadena golfed. Si hay varias soluciones, envíe una.
  • Para simplificar el desafío, en las no rcadenas, cualquier escape excepto \\, \'y \"se considera inválido. No deben usarse en la salida, aunque '\m'sea ​​igual que '\\m'en Python. Esto elimina la necesidad de procesar códigos de escape especiales como \n.
  • Los builtins para golf de cuerdas de Python no están permitidos. Python represtá permitido, ya que es horrible de todos modos.
  • Aplican reglas estándar de .

Ejemplo de entradas / salidas

Hice todo lo posible para verificar esto, pero avíseme si hay errores. Si hay varios resultados válidos para los casos, todos se enumeran debajo de la entrada.

test
 -> 'test'
 -> "test"
te\st
 -> 'te\\st'
 -> "te\\st"
 -> r'te\st'
 -> r"te\st"
te'st
 -> "te'st"
te"st
 -> 'te"st'
t"e"s't
 -> 't"e"s\'t'
te\'st
 -> "te\\'st"
 -> r'te\'st'
 -> r"te\'st"
te\'\"st
 -> r'te\'\"st'
 -> r"te\'\"st"
t"'e"'s"'t"'s"'t"'r"'i"'n"'g
 -> """t"'e"'s"'t"'s"'t"'r"'i"'n"'g"""
 -> '''t"'e"'s"'t"'s"'t"'r"'i"'n"'g'''
t"\e"\s"\t"\s'\t"\r"\i"\n"\g
 -> r"""t"\e"\s"\t"\s'\t"\r"\i"\n"\g"""
 -> r'''t"\e"\s"\t"\s'\t"\r"\i"\n"\g'''
t"""e"""s"""'''t'''s'''"""t"""r"""'''i'''n'''g
 -> 't"""e"""s"""'"'''t'''s'''"'"""t"""r"""'"'''i'''n'''g"
t\"""e\"""s\"""'''t'''s'''\"""t\"""r\"""'''i'''n'''g
 -> r"""t\"""e\"""s\"""'''t'''s'''\"""t\"""r\"""'''i'''n'''g"""
t"e"s"t"s"t"r"i"n"g"\'\'\'\'\'\'\'\
 -> r't"e"s"t"s"t"r"i"n"g"\'\'\'\'\'\'\'''\\'
 -> r't"e"s"t"s"t"r"i"n"g"\'\'\'\'\'\'\''"\\"
"""t"'e"'s"'t"'s"'t"'r"'i"'n"'g'''
 -> """\"""t"'e"'s"'t"'s"'t"'r"'i"'n"'g'''"""
 -> '''"""t"'e"'s"'t"'s"'t"'r"'i"'n"'g''\''''

Gracias a Anders Kaseorg por estos casos adicionales:

\\'"\\'\
 -> "\\\\'\"\\\\'\\"
''"""''"""''
 -> '''''"""''"""'\''''
PurkkaKoodari
fuente
¿Qué pasa con las cadenas que comienzan o terminan con "o '-> """t"'e"'s"'t"'s"'t"'r"'i"'n"'g'''
Rod
@ Rod Agregaré eso como un caso de prueba.
PurkkaKoodari
55
Buen ejemplo de un buen desafío con una etiqueta de idioma.
Adám
¿Qué hay de u'y b'?
caird coinheringaahing
@cairdcoinheringaahing No proporcionan ninguna característica útil para jugar al golf, y bni siquiera se pueden combinar con cuerdas regulares, así que las dejé fuera.
PurkkaKoodari

Respuestas:

7

Python 3 , 264 262 bytes

f=lambda s,b='\\',r=str.replace:min(sum([['r'+d+s+d,d+r(r(s[:-1],b,b+b),d,d[1:]+b+d[0])+b*(s[-1:]in[b,d[0]])+s[-1:]+d][d in r(r(s+d[1:],b+b,'x'),b+d[0],b)or r(s,b+b,'')[-1:]==b:]for d in["'",'"',"'''",'"""']],[f(s[:k])+f(s[k:])for k in range(1,len(s))]),key=len)

Pruébalo en línea!

Esto funciona pero es muy lento sin memorización, que puede agregar con

import functools
f=functools.lru_cache(None)(f)

Encontró una solución mejorada para uno de los casos de prueba:

t"e"s"t"s"t"r"i"n"g"\'\'\'\'\'\'\'\
 -> 't"e"s"t"s"t"r"i"n"g"'r"\'\'\'\'\'\'\'"'\\'
 -> r't"e"s"t"s"t"r"i"n"g"\'\'\'\'\'\'\'''\\'

Las versiones anteriores de esta respuesta arrojaron resultados incorrectos en lo siguiente, que podrían agregarse como casos de prueba:

\\'"\\'\
 -> "\\\\'\"\\\\'\\"
''"""''"""''
 -> '''''"""''"""'\''''
Anders Kaseorg
fuente
1
¡Buen trabajo! Gracias por el caso de prueba, lo he corregido en el desafío.
PurkkaKoodari