Escriba un programa que genere el número total de caracteres y la frecuencia de cada carácter en su fuente y su salida. Debe seguir el formato ilustrado en el ejemplo.
Ejemplo
Si tu código fuera
abb1
Su salida tendría que ser
My source has 4 characters.
1 is "a"
2 are "b"
1 is "1"
Besides unquoted numbers, my output has 383 characters.
34 are "
"
79 are " "
63 are """
2 are "'"
2 are ","
4 are "."
2 are "1"
2 are "B"
2 are "I"
2 are "M"
39 are "a"
4 are "b"
6 are "c"
4 are "d"
38 are "e"
3 are "g"
5 are "h"
4 are "i"
4 are "m"
3 are "n"
8 are "o"
3 are "p"
2 are "q"
38 are "r"
12 are "s"
8 are "t"
7 are "u"
3 are "y"
It's good to be a program.
(La salida debe ir a stdout).
Observe, por ejemplo, que la salida contiene dos m en mayúscula. Uno para My
y otro para 2 are "M"
. Esto debe ser cierto para todos los caracteres para que la salida no se contradiga de ninguna manera.
Los números sin comillas se ignoran en la salida para evitar conjuntos de frecuencias insatisfactorios. Por ejemplo, 1 is "1"
es incorrecto si se cuentan ambos 1. Debería leer 2 are "1"
, pero solo hay uno 1 nuevamente.
Aclaraciones de formato
"is" debe usarse para ocurrencias de un solo carácter.
"are" debe usarse para ocurrencias de múltiples caracteres.
"is" nunca debería aparecer en la lista de caracteres de salida porque sería superfluo.
1 is 'Z'
se refiere a la Z en sí misma, por lo que se puede eliminar toda la línea.Las tres frases completas deben aparecer en orden con las listas de frecuencia de caracteres entre ellas (como muestra el ejemplo). Entonces su salida comenzará
My source...
y terminará con...be a program.
. Tenga en cuenta que no hay una nueva línea al final de la salida.Las listas de frecuencia de caracteres pueden estar en cualquier orden.
Las nuevas líneas cuentan como un carácter (en caso de que sean \ r \ n).
Comprobador de formato
El siguiente script de Python toma su código y su salida como cadenas y afirma que la salida no tiene contradicciones. Proporciona un mensaje de error útil si algo está mal. Puede ejecutarlo en línea en http://ideone.com/6H0ldu bifurcándolo, reemplazando las cadenas CODE y OUTPUT y luego ejecutándolo. Nunca dará falsos positivos o negativos (suponiendo que esté libre de errores).
#Change the CODE and OUTPUT strings to test your program
CODE = r'''abb1'''
OUTPUT = r'''My source has 4 characters.
1 is "a"
2 are "b"
1 is "1"
Besides unquoted numbers, my output has 383 characters.
34 are "
"
79 are " "
63 are """
2 are "'"
2 are ","
4 are "."
2 are "1"
2 are "B"
2 are "I"
2 are "M"
39 are "a"
4 are "b"
6 are "c"
4 are "d"
38 are "e"
3 are "g"
5 are "h"
4 are "i"
4 are "m"
3 are "n"
8 are "o"
3 are "p"
2 are "q"
38 are "r"
12 are "s"
8 are "t"
7 are "u"
3 are "y"
It's good to be a program.'''
#######################################################
import re
amountPattern = r'(\d+) (is|are) "(.)"\n'
class IntrospectionException(Exception):
pass
def getClaimedAmounts(string, errorOnIs):
groups = re.findall(amountPattern, string, re.DOTALL)
for amount, verb, char in groups:
if verb == 'is':
if errorOnIs:
raise IntrospectionException('\'1 is "%s"\' is unnecessary' % char)
elif amount != '1':
raise IntrospectionException('At "%s", %s must use "are"' % (char, amount))
elif verb == 'are' and amount == '1':
raise IntrospectionException('At "%s", 1 must use "is"' % char)
amounts = {}
for amount, verb, char in groups:
if char in amounts:
raise IntrospectionException('Duplicate "%s" found' % char)
amounts[char] = int(amount)
return amounts
def getActualAmounts(string):
amounts = {}
for char in string:
if char in amounts:
amounts[char] += 1
else:
amounts[char] = 1
return amounts
def compareAmounts(claimed, actual):
for char in actual:
if char not in claimed:
raise IntrospectionException('The amounts list is missing "%s"' % char)
for char in actual: #loop separately so missing character errors are all found first
if claimed[char] != actual[char]:
raise IntrospectionException('The amount of "%s" characters is %d, not %d' % (char, actual[char], claimed[char]))
if claimed != actual:
raise IntrospectionException('The amounts are somehow incorrect')
def isCorrect(code, output):
p1 = r'^My source has (\d+) characters\.\n'
p2 = r'Besides unquoted numbers, my output has (\d+) characters\.\n'
p3 = r"It's good to be a program\.$"
p4 = '%s(%s)*%s(%s)*%s' % (p1, amountPattern, p2, amountPattern, p3)
for p in [p1, p2, p3, p4]:
if re.search(p, output, re.DOTALL) == None:
raise IntrospectionException('Did not match the regex "%s"' % p)
claimedCodeSize = int(re.search(p1, output).groups()[0])
actualCodeSize = len(code)
if claimedCodeSize != actualCodeSize:
raise IntrospectionException('The code length is %d, not %d' % (actualCodeSize, claimedCodeSize))
filteredOutput = re.sub(r'([^"])\d+([^"])', r'\1\2', output)
claimedOutputSize = int(re.search(p2, output).groups()[0])
actualOutputSize = len(filteredOutput)
if claimedOutputSize != actualOutputSize:
raise IntrospectionException('The output length (excluding unquoted numbers) is %d, not %d' % (actualOutputSize, claimedOutputSize))
splitIndex = re.search(p2, output).start()
claimedCodeAmounts = getClaimedAmounts(output[:splitIndex], False)
actualCodeAmounts = getActualAmounts(code)
compareAmounts(claimedCodeAmounts, actualCodeAmounts)
claimedOutputAmounts = getClaimedAmounts(output[splitIndex:], True)
actualOutputAmounts = getActualAmounts(filteredOutput)
compareAmounts(claimedOutputAmounts, actualOutputAmounts)
def checkCorrectness():
try:
isCorrect(CODE, OUTPUT)
print 'Everything is correct!'
except IntrospectionException as e:
print 'Failed: %s.' % e
checkCorrectness()
Puntuación
Este es el código de golf. La presentación con la menor cantidad de personajes gana. Las presentaciones deben pasar el verificador de formato para que sea válido. Se aplican las lagunas estándar, aunque puede leer su propio código fuente y / o codificar su salida .
r'''CODE'''
).Respuestas:
CJam - 189
Pruébalo en http://cjam.aditsu.net/
Salida:
fuente
Ruby, 269 (311, 367) caracteres
Tengo tres soluciones diferentes para este desafío. Cada uno de ellos usa un conjunto diferente de trucos:
Solución "adecuada", 367 caracteres:
La solución más larga es más o menos solo una prueba de concepto de que es posible resolver este desafío sin ningún truco, y no está casi totalmente desarrollado. Es una verdadera quine (es decir, genera su propio código fuente en lugar de leerlo de un archivo) y en realidad calcula todos los números que imprime (longitud del código, longitud de salida, ocurrencias de caracteres). Debido a la forma en que funciona el quine, todo el código debe estar en una sola línea y dentro de un literal de cadena.
Salida parcialmente codificada, 311 caracteres:
La siguiente solución más corta usa dos trucos, pero sigue siendo una verdadera quine: - Ningún carácter aparece exactamente una vez en el código fuente. De esa manera, no necesito decidir si debo imprimir
is
oare
en la primera mitad de la salida. También hace que sea un poco más fácil calcular el tamaño de salida total (aunque en realidad no necesito hacer eso). - El tamaño de salida total está codificado. Como esto solo depende del número de caracteres distintos en el código fuente (y en el caso general, cuántos de esos caracteres aparecen solo una vez), es fácil calcularlo por adelantado.Tenga en cuenta que el código está precedido por dos líneas nuevas muy importantes, que StackExchange no mostraría en el bloque de código. Por esa razón, he agregado una línea adicional al frente si esas líneas nuevas, que no es parte del código.
Solución más corta, 269 caracteres:
La solución más corta codifica adicionalmente su propia longitud de fuente. Al usar nombres de variables que son / no son ya parte del código fuente, es posible encontrar un "punto fijo" donde todos los caracteres en el código fuente (¡incluidos los dígitos de las longitudes codificadas!) Aparecen al menos dos veces.
Esta solución también guarda algunos caracteres más simplemente leyendo su propio código fuente del archivo de código, en lugar de generarlo. Como un efecto secundario agradable, esto hace que el código sea mucho más "legible" (pero a quién le importa el código legible en un código-golf ...), ya que ahora el código ya no tiene que estar dentro de una cadena literal.
También modifiqué un poco el script de prueba para reducir el pegado de copias necesario para verificar el código. Al reemplazar las definiciones de
CODE
yOUTPUT
conel script ahora ejecuta automáticamente mi código, lee su salida y toma el código fuente del archivo de código.
Aquí está la salida generada por el código más corto:
fuente