El último desafío ( Pixel-art, episodio 1: mostrar Super Mario ) fue solo un entrenamiento ... (y lo completaron de manera increíble, ¡gracias!)
Esta vez, tienes que trabajar un poco más. Tienes que mostrar todo el primer mapa del mundo de Super Mario bros en NES, sin enemigos y sin Mario.
Su programa o función debe mostrar todos los píxeles de la siguiente imagen O producir un archivo de imagen similar (BMP, PNG o GIF).
Su programa no debe acceder a Internet de ninguna manera.
La salida se puede ampliar si lo desea, y los píxeles pueden ser elementos ASCII o HTML si lo desea, siempre que tengan el color correcto.
Aquí está el modelo que debes seguir:
Toda la imagen: http://i.stack.imgur.com/2kfVc.png
El conjunto de fichas (si lo necesita): http://img.ctrlv.in/img/14/10/19/5443f44c7eb78.png
Puede producir su propio conjunto de fichas, subconjunto o superconjunto de este.
Puede usar su conjunto de mosaicos como un archivo de imagen separado o incluirlo en su código (por ejemplo, en base64). Si está separado, agregue su tamaño en bytes a su puntaje.El mapa con coordenadas: http://goo.gl/c8xJIx o http://img.ctrlv.in/img/14/10/19/544373adc9f64.png
Los colores:
Azul cielo: # 5C94FC Negro: # 000000 Rosa: # FCBCB0 (para los bloques y el castillo) Marrón: # C84C0C (para los bloques y el castillo) Naranja: # FC9838 (para el bloque "?") Verde claro: # 80D010 (para arbustos, montañas, asta de bandera, urdimbre) Verde oscuro: # 00A800 (para arbustos, montañas, asta de bandera, urdimbre) Blanco: #FCFCFC (nubes) Azul claro: # 3CBCFC (nubes)
La respuesta más corta gana.
EDITAR: Habrá dos tablas de puntuación, una donde las puntuaciones se cuentan en bytes y otra donde se cuentan en caracteres.
¡Buena suerte!
PD: Aquí hay algunas notas que podrían ayudarlo a optimizar su programa:
- Las nubes, arbustos y montañas tienen un patrón repetitivo (cada 48 columnas)
- Los bloques voladores solo están presentes en las líneas 4 y 8
- Cada mosaico o sprite del mapa usa como máximo 4 colores (incluido azul o transparente, dependiendo de cómo lo vea)
- Los arbustos son simplemente "la parte superior de las nubes" con una paleta de colores diferente
- Los arbustos / nubes simples, dobles y triples se pueden formar fácilmente usando el mismo mini juego de piezas de 16x16px. Esto también es cierto para las montañas simples y triples
Respuestas:
Código de máquina x86,
1729161914681382 bytesCómo funciona: los mosaicos se generan mediante una combinación de compresión RLE, imágenes de 2 bits y código de procedimiento. Una vez que los mosaicos se generan en la memoria, el programa crea una matriz de índices de mosaicos. Esto se carga primero con el fondo de repetición. Después de eso, las tuberías, los bloques flotantes, las pirámides y el asta de la bandera se dibujan de forma procesal. Las tuberías, colinas, arbustos y pirámides pueden extenderse por debajo del suelo, pero se cubren cuando las tejas de roca se escriben a continuación. Finalmente, los valores de mosaico del castillo simplemente se copian en la ubicación correcta. Para generar el archivo de imagen, el encabezado BMP y la paleta se almacenan en el archivo como datos, y se escriben primero. Luego, el programa se ejecuta a través de la matriz, escribiendo la fila apropiada del mosaico correspondiente para cada posición.
Uso: Ejecute mario.com, generará "m.bmp", un archivo de imagen BMP estándar. El archivo se crea como un archivo oculto, ya que terminó siendo menos bytes.
Descargue un archivo ZIP que contenga el código fuente y el binario, más la salida.
Código de ensamblaje para generar el archivo ejecutable:
fuente
Javascript minificado (*):
1285 1258 1253 1205 11861171 caracteres(*) Minified usando Closure, RegPack y ObfuscaTweet, como lo sugiere xem
La versión Unicode tiene un tamaño de 4549 bytes, sin ObfuscaTweet (solo Closure y Regpack), el tamaño es de 2251 bytes.
Historia:
1285 -> 1258: variable
A
para 48 (thx @hsl), fusionó algunos de losfor
bucles, fusionómt()
ymu()
, utilizando índices de mosaico en lugar de cadenas de mosaico, optimizó png con PNGOUT1258 -> 1253: fusionó algunos
for
bucles más ; renombradomt()
ar()
; eliminó llaves innecesarias; variableB
para 16; definir 16 sprites CSS no utilizados (reemplaza 32 conA
); mostrando 1 fila no utilizada (reemplaza 14 conB
); función eliminadae()
; acortadot()
,g()
,c()
; usando enfor(i=0;i<n;)f(i++)
lugar defor(i=0;i<n;i++)f(i)
donde sea posible1253 -> 1205: movió el estilo del cuerpo a la parte CSS en lugar de
<body style=...>
; reemplazó algunosfor
bucles conf
llamadas; funciones optimizadasr
,q
;</head><body>
parece ser innecesario<html><head>
también; funciónt(i)
para mapeo CSS eliminada; Nombres CSSb0
... enb31
lugar dea
...z
,aa
...ff
1205 -> 1186: función
n
renombrada aN
; nueva funciónn
que opera en una matriz con codificación delta1186 -> 1171: las colinas y las urdimbres pueden dibujarse "grandes" en cualquier momento, las partes inferiores quedan sobregiradas por bloques de piedra; utilizar
d
tanto para nubes como para arbustos; eliminado algunos puntos y comas innecesariosEste es un intento de procedimiento. Hay patrones en todas partes, uno de los números mágicos es 48 (espacio entre las nubes, los arbustos y las montañas). El mosaico se codifica como una cadena de URL de datos Base64 y se usa como una hoja de estilo CSS. En Javascript, la matriz 212x14
m
está llena de índices de mosaico. Vea la versión comentada no minificada para más detalles.Funciona en Chrome 38 (Ctrl + T para la nueva pestaña, Ctrl + Shift + J para la consola de JavaScript, pegue el código allí) y Firefox 33 (si está envuelto con etiquetas HTML de JavaScript). También hay una versión JS bin .
Todavía hay espacio para optimizaciones, publicaré actualizaciones y sería bueno si algunas personas de JS / CSS / HTML pudieran sugerir optimizaciones / correcciones.
Minified:
Sin minificar y comentado:
fuente
function l(i,j,s){for(k=0;k<j;k++)n(i+k*W,s);}
se puede acortar extrayendo k ++ a la función, creo? Entonces, ¿puede la siguiente línea con j.Python3
1638157616161513 bytes581 código + 932 datos
↑ Este top es el nivel original. En el medio está el PPM generado por este script. ¡En la parte inferior hay una diferencia, y esto muestra que la paleta y el mapa no están exactamente de acuerdo! Lo puse en falla de datos y no en mi script;)
(bytes contados sin comentarios, línea sin envolver y sangría de segundo nivel
\t
)Datos (codificados en base64 para ser pegados; decodificar y guardar como un archivo llamado "i"):
El archivo de datos es un formato personalizado que hice para este problema y se almacena como LZMA.
Primero se serializan los 32 mosaicos. Hay 9 colores en la paleta, y esto toma 8219 bytes sin comprimir. (Descubrí que tratar de comprimir los mosaicos a 4 bits por píxel no ayudó en absoluto a la compresión. No intenté forzar con fuerza bruta el mejor orden de los mosaicos, y probablemente pierda algunos puntos aquí).
Hay 212x14 = 2968 bloques que componen el mapa.
Entonces las instrucciones para recrear el mapa ahora están codificadas.
Primero viene una sección de comandos "poner" que colocan una secuencia de mosaicos de la paleta de mosaicos en el mapa en un determinado x, y. Como hay 32 mosaicos, especifico una ejecución del mismo mosaico usando un número mayor que 32 en lugar del índice de mosaico.
Luego viene una sección de comandos "copiar" que copia algún rectángulo del mapa actual a otro lugar. Hay una máscara de bits especial que marca si la copia debe reflejarse.
Un breve ejemplo de búfer de comando:
(Dije corto , pero en realidad es casi la mitad del búfer de comando total necesario para hacer todo el mapa; la gran mayoría de los bytes en los datos son los 32 mosaicos de origen)
Luego viene una segunda sección de comandos "poner" y finalmente otra sección de comandos "copiar".
Debido a que estos pueden sobrescribirse entre sí, puedo construir partes de copia que luego borro o cambio.
Puedo sin duda afeitado unos cuantos más bytes fuera de él por - por ejemplo - convirtiendo pone en pequeños ejemplares y al hacer el
eval
truco en una fuente de código gzip, o jugar con PNG (que es DESINFLE con filtros específicas en la imagen) también. Pero me gustan las cosas detalladas como son.fuente
3,11
parece que falta el mosaico en la paleta. Parece que hay algo de ruido en el mapa20,12
y el contorno general de los árboles y las nubes puede ser una falla de alineación de la paleta. Solo hay 9 colores, por lo que no puede ser ningún tipo de artefacto de mezcla.Javascript,
106910721024 caracteres (1957 bytes)RegPacked y Obfuscatweeted
Código no ofuscado
Escondí este código porque hay un código no protegido debajo.
Mostrar fragmento de código
Código sin golf
Primero convertí los mosaicos en sprites con el URI de datos minificados de @ schnaader.
0 ~ v
(que es 0 ~ 31 en la base 31) representa cada mosaico.Y convertí el mapa en mosaicos a mano. Estos datos tienen 212 caracteres por fila.
Luego reemplacé el carácter repetitivo (como
7
(cielo) y1
(suelo)) conrepeat()
.Encontré
7
sy algunos bloques, y7
se repite otro patrón. Entonces hice otra función para hacerlo compacto. Puede verlo en el código fuente no ofuscado.Finalmente, RegPacked, y Obfuscatweeted mi código de golf de 2341 bytes.
Fue un desafío muy divertido. ¡Gracias! Y gracias a @xem por más trucos.
fuente
JavaScript:
3620 (ay)34293411Actualizaciones
Actualización n. ° 1: se eliminaron las
var
definiciones y se colocaron las declaraciones de variables entre corchetes de primer uso. EliminadogetElementById()
ya que también está disponible en carga como una variable por ID. Usando encloneNode()
lugar decreateElement('CANVAS')
. Renombrado principal dexMx
aM
. Se eliminó la función de escala :(, (todavía disponible en el ejemplo ) .Se agregaron algunos comentarios al código expandido. (Ese código no se actualiza con las eliminaciones. La siguiente línea, ("Mini código") , es).
Actualización n. ° 2: se eliminó la función principal
M()
en su conjunto y dejó que el código se ejecutara en raíz . Esto requeriría que el código se coloque dentro de un contenedor de carga o al final del documento.Actualización n. ° 3: estadísticas agregadas.
Mini código:
Bla bla:
- Demo al final de la publicación.
Usando el lienzo como base para un intento de resolver esto. Terminé con alrededor de 6000 caracteres, pero después de un poco de violín (y una compresión personalizada, con violín y ajustes también) ahora estoy en el número indicado. Sigue siendo alta, pero la calidad es buena ;-).
También incluye una opción de escala, primer argumento para el
xMx()
, también conocido como "principal" . 1 = tamaño normal (como en mosaicos de 16 bits). No hay mucho espacio para ajustar, por lo que si uno usa fracciones, algunas de las fichas no encajan mejor. En números enteros debería estar bien. [1]Pero: advertir, subir, rápidamente consume recursos y se convierte en un gran lienzo. (Todo está pintado de una vez.) Cuando el ancho original es de 3392 píxeles, rápidamente se vuelve enorme. [1]
[1] A partir de la actualización # 1, esto se ha eliminado. Está presente en la demo.
Estadísticas:
Main code : 870
Compression:
Main data : 2176 (17,480 bits)
Key : 128 ( 1,024 bits)
Code : 236
Whole she bang : 2540
Decompressed data : 5608 (44,864 bits)
Total : 3410
[1][1]: +1 byte, ";", entre el código principal / de datos.
Los datos comprimidos son una matriz, Å, y un "objeto" , Ø. Donde Å está sosteniendo la colocación de los azulejos y el Ø sosteniendo los datos para pintar los azulejos. El Ø también debería haber sido una matriz, pero como mi código comenzó con algo como esto:
Terminó como está. Quizás vea si no puedo arreglar esto. Lo ideal sería haberlo analizado con JSON en lugar de eval (), pero eso no sería un punto en un concurso como este. Como es ahora, no se puede analizar JSON debido a las comillas faltantes alrededor de las partes de identificación.
Manifestación
Aquí hay un violín donde se puede ver el código en acción. El código en el violín me expandí un poco (y agregué algunos estilos HTML / CSS en todo el mundo, pero la imagen de sí mismo es autosuficiente):
MUNDO MARIOS
Código ampliado:
Código ampliado y (un poco) reordenado:
fuente
var
para declarar variables; se declaran automáticamente cuando los define, por lo que debería poder eliminarlosvar D,C,c,S,s,R,F,Z,
de su código. (también se puede reemplazar/.{2}/
con/../
).var
pero lo dejé porque tenía que correr cuando lo publiqué. Hecho ahora. El RegExp fue agradable, de alguna manera no logró ver eso;)ev(a|i)l
rutina). Si es "legal", entonces está bien.eval(unescape(escape('𨑬𩑲𭀨𘣆𘠩').replace(/uD./g,'')))
funciona según lo previsto. Y sí, su puntaje se cuenta en caracteres, por lo que puede usar totalmente trucos como la compresión Unicode y eval.¡Podría tener un puntaje cercano a 1750 con eso!Pitón
133113261314127212681217 bytes(código:
219214202186182, datos:362 + 750 = 1112363 + 723 = 1086346 + 689 = 1035)La idea aquí es que primero genero un mapa un 16º del tamaño en cada dimensión, donde cada píxel está coloreado por el índice en el mapa de mosaico. Para asegurar que se usara la misma paleta, primero combiné el mapa de mosaico dado y el mapa en una sola imagen. De esto y del mapa de mosaico (ambos png minificados) ahora podemos regenerar el mapa original. (El código para este proceso se puede ver debajo del código de envío). Cabe señalar que guardé el mapa de mosaico como un archivo "t" y el mapa generado como una imagen "m"
EDITAR: comencé a explorar cómo el orden de los mosaicos influía en la compresión, y en aras de la exploración generé 10000 permutaciones aleatorias y las comprimí con este resultado: todo esto fue con los mosaicos en una línea, ya que eso redujo el código bastante poco. Intenté cosas similares con diferentes configuraciones (2 * 16, 4 * 8), pero ninguna con un mejor resultado promedio.
Suponiendo que png se comprimiría mejor con regiones similares continuas más grandes, construí una herramienta que me permitiría mover los mosaicos, y usando lo que percibí como una imagen más continua obtuve la imagen de mosaico a 723 desde 750b.
EDIT2: después de mucho (mucho) más análisis sobre cómo funciona realmente png, y muchos experimentos (aún en curso), las imágenes ahora se han comprimido aún más. Enlace a continuación actualizado. Escribiré más sobre este análisis más adelante cuando esté completo.
Las nuevas imágenes utilizadas están aquí: http://imgur.com/a/RgkXx
Aquí están las otras imágenes generadas en el proceso: http://imgur.com/a/HXTGA , aunque algunas están un poco desactualizadas debido a la edición anterior.
El script que escribí para reducir el mapa es bastante burdo, pero aquí va (también podría estar desactualizado debido a los cambios anteriores):
fuente
Perl 5 + PNG: 689 + 593 = 1282
Un intento fallido de reemplazar el mapa de mosaico comprimido PNG de la solución de Christian con el código Perl. Al final es 65 bytes más largo. Toma los mismos mosaicos PNG en la entrada y genera un PNG en la salida.
Uso:
perl mario.pl <tiles.png >world.png
fuente
JS:
40123921 caracteresJS se usa para desempaquetar muchos caracteres Unicode y escribir una etiqueta img cuya src es la imagen dada en el OP, guardada como PNG, comprimida, codificada en base64 y recortada.
Demostración: http://jsbin.com/fojidejoco/1/
PD: Sé que es un poco engañoso (incluso si las reglas lo permiten), pero al menos, nos da un objetivo: hacerlo en menos de 4012 caracteres.
Herramientas utilizadas:
fuente