Después de pasar un tiempo en Stack Exchange, puedo reconocer la mayoría de los sitios en Hot Network Questions por su pequeño ícono (que también es su favicon ), pero ciertamente no todos. ¡Escribamos un programa que pueda! Debe escribir el código que determina el sitio, dado uno de los 132 favicons (actualmente), incluido Stack Overflow en japonés (que todavía está en beta privada):
He subido un archivo ZIP con todas estas imágenes como PNG en GitHub . Haga clic en el botón "Sin procesar" para descargarlo. El orden de los iconos anteriores es el orden alfabético de los nombres de archivo en el archivo zip.
Los nombres de sitio correspondientes (en este orden) son:
Notas:
- He eliminado el
®
deLEGO® Answers
yExpressionEngine® Answers
, para que no tenga que preocuparse por Unicode. - He usado nombres en inglés para los desbordamientos de pila en japonés y portugués por la misma razón.
- Los íconos de la Ciencia de la Tierra y el idioma español son indistinguibles. Por lo tanto, dado uno de estos íconos, su código puede devolver cualquiera de esos sitios (de su elección). Lo mismo ocurre con Magento y las artes marciales .
Reglas
Puede escribir un programa o función que
- recibe el nombre de archivo (local) de la imagen a través de STDIN, argumento de línea de comando o argumento de función o recibe el contenido del archivo de imagen a través de STDIN
- devuelve o imprime a STDOUT el nombre del sitio, como se indica arriba.
Su código debe reconocer los 132 sitios correctamente (con la excepción mencionada anteriormente).
No puede hacer suposiciones sobre el nombre del archivo (así se llama codegolf.png
). Puede suponer que la imagen tiene dimensiones 16x16, y que de hecho será una de las 132 imágenes de arriba. Las imágenes anteriores son todas PNG, pero puede usar cualquier otro formato de gráficos de trama conveniente, pero tendrá que convertir las imágenes usted mismo. No debe hacer suposiciones sobre el flujo de bytes real del archivo de imagen, aparte de eso es una imagen válida en cualquier formato que elija. En particular, si hay múltiples formas de codificar la misma imagen en su formato (por ejemplo, agregando campos irrelevantes a la sección de encabezado), su código debe funcionar para todos ellos. En resumen, su código solo debe basarse en los valores de píxeles en sí mismos, sin detalles del archivo que lo codifica.
Como de costumbre, no puede obtener ningún dato de Internet. Tienes que determinar el sitio solo a partir de la imagen.
Puede usar funciones integradas o de terceros para leer el archivo de imagen y obtener una lista de valores de color, pero no debe usar ninguna otra función de procesamiento de imágenes existente.
Este es el código de golf, por lo que gana la respuesta más corta (en bytes).
fuente
pngcrush
no existirá.Respuestas:
Python 3.x + Almohada,
230118941878 bytesLa idea es hacer un hash de la imagen y encontrar la cadena correspondiente de un diccionario (al igual que otras respuestas).
El código clave es este:
Abrimos el archivo y luego lo convertimos en una cadena de 1024 bytes de valores RGBA. Con un poco de experimentación, encontramos que la suma de verificación ADLER-32 de cada sexto byte de esta cadena de bytes es única para estas 132 imágenes. Y luego más pruebas muestran que, tomar el módulo de 2003 de la suma de verificación da el diccionario más pequeño.
El diccionario original se ve así:
Notamos que todos los nombres de sitios no contienen números. Por lo tanto, podríamos concatenar todo el diccionario en una sola cadena:
Y luego use la expresión regular, por ejemplo,
1969(\D+)
para extraer el nombre del sitio. Esta enorme cadena se comprime para ahorrar espacio (deje que el motor de compresión note las múltiples ocurrencias del "Idioma") y finalmente se codifica en base-85.Como ahora también está etiquetado como kolmogorov-complex , aquí hay una solución de 2394 bytes que no usa compresión (zlib todavía se importa para adler32).
fuente
.tobytes()
obtiene los datos de píxeles (16 × 16 × 4 = 1024), por lo que se basa en la imagen. Sin embargo, el archivo debe estar en RGBA.C #, 2760 bytes
Mi solución no utiliza hashing, en realidad examina los píxeles individuales de la imagen y decide en función de eso. Descubrí que era suficiente examinar el componente azul de la imagen del módulo 9. La idea es dividir repetidamente en función del valor de pixel.B% 9, así:
Utilizando un script, generé el siguiente programa monstruoso (5197 bytes) que resuelve el problema usando un árbol de decisión binario:
Algunas personas han utilizado funciones de compresión integradas en sus soluciones. Hice el mío, escribiendo un script que identifica subcadenas comunes y las reemplaza por shorthands de un solo carácter. El código se comprime en la siguiente cadena de 2502 bye:
El diccionario necesario para la descompresión es de solo 108 bytes:
El diccionario usa punto y coma como delimitador, y contiene caracteres individuales seguidos de su descompresión. Entonces, para descomprimir, ":" primero sería reemplazado por "&", luego "<" por "%!", "|" por "ic", y así sucesivamente. La descompresión de una cadena c se puede expresar de una manera bastante concisa:
Luego, después de la descompresión, uso un poco de magia negra de reflexión para compilar el código sobre la marcha y ejecutarlo:
Tenga en cuenta que los ejemplos utilizados aquí para la explicación son ligeramente diferentes de los utilizados en la solución de 2876 bytes.
fuente
Node.js,
3178313026672608 bytesCalcula el hash SHA1 de los datos de imagen de cada archivo y, utilizando los bytes 16 a 19 del resumen hexadecimal, indexa los nombres de los sitios.
Usando los bytes 12 a 16 del resumen hexadecimal del hash SHA1 de cada archivo, indexa los nombres de los sitios. Puede haber una combinación más corta usando solo 3 bytes del resumen hexadecimal.fuente
h="17352368".match(/.{4}/g)
(los hashes de 4 caracteres, divididos en una matriz),s="MathOverflow;StackOverflow in Portuguese".split(";")
(nombres separados por a;) y luego vuelva a poner todo junto:t={}h.forEach(function(k,i){t[k]=s[i]})
(da como resultado el mismo objeto que su código). Hay 132 puntos y comas, por lo que incluso si cambia a un carácter de 2 bytes (OP dice que no debe haber unicode en los nombres del sitio), ahorrará espacio. Además, puede agregar la optimización de @manatwork además de ese ahorro adicional.split()
s: us una sola cadena como "1234Site; 5678Other". Luego, suponiendo que no haya conflicto entre los fragmentos hash y los nombres de los sitios, uno solomatch()
lo hará:function $(e){r=require;return"8d4fAcademia;3a6dAndroid Enthusiasts;5caeAnime & Manga;804cAsk Different;bef3Arduino".match(r("crypto").createHash("sha1").update(r("fs").readFileSync(e)).digest("hex").slice(12,16)+"([^;]+)")[1]}
Python 2.7,
19061889 bytesEsta solución utiliza CRC32 en los datos de píxeles para crear un identificador único de base 95 de 2 dígitos. El índice del identificador se utiliza para buscar la cadena de respuesta.
Lo complicado fue encontrar una combinación de funciones de estilo hash que daría como resultado 132 (o 131) etiquetas pequeñas pero únicas. Probé algunas opciones antes de decidirme por esta. Parece bastante compacto.
El programa usa Python PIL para leer los datos de píxeles del archivo.
Python 2.7 2150 bytes
Esta es una versión sin usar bibliotecas de compresión o codificación. La lista de intercambio de pila se comprime con un método de intercambio simple. Los caracteres que no se usan en el texto:
se utilizan para mantener segmentos de cadena comunes. El texto no está comprimido con la
for k,v in [(v[0],v[1:]) for v in K.split('|')]:T=T.replace(k,v)
línea. La tabla de indexación de dos caracteres es la misma que en el programa anterior.fuente
C #, 2672 bytes
La tabla (cadena) de etiquetas y hashes SHA parciales se comprime para guardar algunos bytes. El diccionario original se ve así:
fuente
var
debería guardar un par de bytes. 2) ¿Qué pasa con el generador de cadenas? No lo veo usado. 3)StreamReader.ReadToEnd
podría ayudar un poco también.