Literais de string de golfe em Python


21

fundo

O Python 3 possui muitos tipos de literais de string. Por exemplo, a sequência this 'is' an exa\\m/plepode ser representada 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 você pode ver, o uso de diferentes delimitadores para cadeias de caracteres pode aumentar ou diminuir as cadeias alterando a fuga necessária para determinados caracteres. Alguns delimitadores não podem ser usados ​​para todas as strings: r'está ausente acima (veja a explicação mais adiante). Conhecer suas strings é muito útil no código de golfe.

Também é possível combinar vários literais de string em um:

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

Desafio

O desafio é, dada uma string ASCII imprimível, produzir sua menor representação literal em Python.

Detalhes sobre mecânica de cordas

Strings podem ser delimitados usando ', ", '''e """. Uma sequência termina quando o delimitador inicial é atingido novamente sem escape.

Se um literal de cadeia começar com '''ou """for consumido como delimitador. Caso contrário, 'ou "é usado.

Os caracteres podem ser escapados colocando um \antes deles. Isso insere o caractere na string e elimina qualquer significado especial que possa ter. Por exemplo, no 'a \' b'meio 'é escapado e, portanto, não termina o literal, e a sequência resultante é a ' b.

Opcionalmente, um de rou Rpode ser inserido antes do delimitador inicial. Se isso for feito, o escape \aparecerá no resultado. Por exemplo, r'a \' b'avalia como a \' b. É por isso a ' bque não pode ser delimitado por r'.

Para escapar '''ou """, basta escapar de um dos personagens.

Esses literais podem ser concatenados juntos, o que concatena seu conteúdo.

Regras

  • A entrada é a sequência de golfe. Somente ASCII imprimível, portanto, não há novas linhas ou outros caracteres especiais.
  • A saída é a literal da sequência de golfe. Se houver várias soluções, imprima uma.
  • Para simplificar o desafio, em não- rseqüências de caracteres qualquer escape exceto \\, \'e \"é considerado inválido. Eles não devem ser usados ​​na saída, mesmo que '\m'sejam iguais '\\m'em Python. Isso elimina a necessidade de processar códigos de escape especiais, como \n.
  • Builtins para jogar strings em Python não são permitidos. O Python repré permitido, já que é ruim de qualquer maneira.
  • Aplicam-se as regras padrão de .

Exemplo de entradas / saídas

Eu tentei o meu melhor para verificar isso, mas deixe-me saber se há erros. Se houver várias saídas válidas para os casos, todas elas serão listadas abaixo da 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''\''''

Agradecemos a Anders Kaseorg por esses casos adicionais:

\\'"\\'\
 -> "\\\\'\"\\\\'\\"
''"""''"""''
 -> '''''"""''"""'\''''

E quanto a strings que começam ou terminam com "ou '-> """t"'e"'s"'t"'s"'t"'r"'i"'n"'g'''
Rod

@ Rod Vou adicionar isso como um caso de teste.
PurkkaKoodari

5
Bom exemplo de um bom desafio com uma tag de idioma.
Adám

Que tal u'e b'?
caird coinheringaahing

@cairdcoinheringaahing Eles não fornecem nenhum recurso útil para jogar golfe e bnem podem ser combinados com cordas regulares, então eu os deixei de fora.
PurkkaKoodari

Respostas:


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)

Experimente online!

Isso funciona, mas é muito lento sem memorização, que você pode adicionar com

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

Ele encontrou uma solução aprimorada para um dos casos de teste:

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"\'\'\'\'\'\'\'''\\'

Versões anteriores desta resposta retornaram resultados incorretos, que podem ser adicionados como casos de teste:

\\'"\\'\
 -> "\\\\'\"\\\\'\\"
''"""''"""''
 -> '''''"""''"""'\''''

1
Bom trabalho! Obrigado pelo caso de teste, eu o corrigi no desafio.
PurkkaKoodari
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.