Salida 2015 como código QR

15

La misión es simple. Simplemente envíe el número 2015 como código QR y escríbalo en el archivo denominado newyear.pngen formato PNG. El código debe ser válido cualquier día, por lo que tal vez no use el año actual.

El código QR como texto se ve así:

# # # # # # #   # # # #     # # # # # # #
#           #           #   #           #
#   # # #   #   # #     #   #   # # #   #
#   # # #   #       #   #   #   # # #   #
#   # # #   #       #   #   #   # # #   #
#           #               #           #
# # # # # # #   #   #   #   # # # # # # #
                #   # #
#   #     # #     # #     # #       #   #
  # # #   #   #   #   # #   #     #   # #
#   # #   # # #   # # # # # #   #       #
# # #         # #         # # # #
# # # # #   #   #     #     #   #     #
                      # # # #
# # # # # # #       #   # #   # #   #   #
#           #   #         # # # #
#   # # #   #         #     #   #     #
#   # # #   #     #     # # # # #
#   # # #   #   #   #   # #   # #   #   #
#           #     # #       # # #   # # #
# # # # # # #   #           #   #   #   #

El resultado escrito newyear.pngdebe contener ese código QR con bordes blancos de 5 píxeles y puntos del tamaño de un píxel. No debe contener nada más que el código QR.

Hannes Karppila
fuente
1
¿Puede estar codificado o debe generar el código qr?
undergroundmonorail
77
Se obtendrán muchas más respuestas si esto se basa en resultados de arte ascii y no en imágenes.
Optimizador
66
¿El código tiene que ser exactamente correcto sin errores, o es suficiente para que escanee correctamente? (Los códigos QR tienen mucha redundancia deliberada y corrección de errores, por lo que puede voltear muchos píxeles y seguirán funcionando). Además, ¿ tiene que ser PNG o podemos usar otros formatos de imagen? particularmente sobre PBM aquí)?
Ilmari Karonen

Respuestas:

12

Archivo sin formato, 184 bytes = archivo de 173 bytes + nombre de archivo de 11 bytes

Espero que esto no rompa ningún vacío legal estándar. Pero el resultado "tiene una alta y la forma más corta de producirlo sería (muy probablemente) imprimirlo literalmente ...".

newyear.png

Base 64 del archivo:

iVBORw0KGgoAAAANSUhEUgAAAB8AAAAfAQAAAAA31SuUAAAAdElEQVR4XnXOMQ5BQRRA0euVRFgGCq1ubIyJpSh11I
qJWIjo+fnt/JnJe55WornlycXMVAB+Qp49A7U/J8rqlIQReG5Quz6Rx8eA6VaF5R7a5arooXg2LaKvd8KGRyBPJLoy
D640pxZ3pay/creL5KnEvwcfvE46ggJMibIAAAAASUVORK5CYII=

En lugar de jugar un programa de golf, jugué la imagen PNG resultante. El código QR es un formato muy flexible, hay muchos parámetros que se pueden modificar: la codificación de la entrada, el nivel de corrección de errores y la imagen de enmascaramiento. Todos estos generarán diferentes símbolos y, por lo tanto, se comprimirán en archivos de diferentes tamaños.

Así que escribí un programa para generar todas estas combinaciones (6720 archivos resultantes), y luego uso PNGOUT para elegir el que se comprimió en el archivo más pequeño. Resulta ser un archivo que:

  • Primero escriba "20" en modo alfanumérico
  • Luego escriba "1" en modo numérico
  • Luego escriba "5" en modo numérico
  • Use el nivel de corrección de error "H" (alto)
  • Utilice el enmascaramiento de datos "110"

Esto se llama test-3-1-H-Diamonds.bmpsi utilizó el programa a continuación. Esta imagen es de 175 bytes mucho después de ejecutar PNGOUT. Con un nivel de corrección de error "alto" en el código QR de "versión 1", podemos modificar hasta 8 píxeles en la parte de datos sin arruinar los datos. Con un poco de prueba y error manual, puedo reducirlo aún más a 173 bytes presentados anteriormente. Probablemente puede ser más pequeño, pero agotar todas las combinaciones requiere 208 C 8 ~ 7.5 × 10 13 comprobaciones que no voy a hacer;)


El programa Rust (0.13.0-nightly (5ba610265)) que genera todas las combinaciones:

/* 

Also put these into your Cargo.toml: 

[dependencies]
qrcode = "0.0.3"
bmp = "0.0.3"

*/

extern crate qrcode;
extern crate bmp;

use qrcode::bits::Bits;
use qrcode::optimize::Segment;
use qrcode::types::{Version, EcLevel, Mode};
use qrcode::ec::construct_codewords;
use qrcode::canvas::{Canvas, MaskPattern, Module};

use bmp::{Image, Pixel};

use std::num::Int;

const BLACK: Pixel = Pixel { r: 0, g: 0, b: 0};
const WHITE: Pixel = Pixel { r: 255, g: 255, b: 255 };

static SEGMENT_SEPARATIONS: [&'static [(uint, uint)]; 8] = [
    &[(0, 1), (1, 2), (2, 3), (3, 4)],
    &[(0, 1), (1, 2), (2, 4)],
    &[(0, 1), (1, 3), (3, 4)],
    &[(0, 2), (2, 3), (3, 4)],
    &[(0, 1), (1, 4)],
    &[(0, 2), (2, 4)],
    &[(0, 3), (3, 4)],
    &[(0, 4)],
];

const ALL_EC_LEVELS: &'static [EcLevel] = &[EcLevel::L, EcLevel::M, EcLevel::Q, EcLevel::H];
const ALL_MODES: &'static [Mode] = &[Mode::Numeric, Mode::Alphanumeric, Mode::Byte];
const ALL_MASK_PATTERNS: &'static [MaskPattern] = &[
    MaskPattern::Checkerboard,
    MaskPattern::HorizontalLines,
    MaskPattern::VerticalLines,
    MaskPattern::DiagonalLines,
    MaskPattern::LargeCheckerboard,
    MaskPattern::Fields,
    MaskPattern::Diamonds,
    MaskPattern::Meadow,
];

fn run(ec_level: EcLevel, mask_pattern: MaskPattern, segments: &[Segment], filename: &str) {
    let version = Version::Normal(1);
    let mut bits = Bits::new(version);
    if bits.push_segments(b"2015", segments.iter().map(|s| *s)).is_err() {
        return;
    }
    if bits.push_terminator(ec_level).is_err() {
        return;
    }
    let data = bits.into_bytes();
    let (encoded_data, ec_data) = construct_codewords(&*data, version, ec_level).unwrap();
    let mut canvas = Canvas::new(version, ec_level);
    canvas.draw_all_functional_patterns();
    canvas.draw_data(&*encoded_data, &*ec_data);
    canvas.apply_mask(mask_pattern);
    let canvas = canvas;

    let width = version.width();
    let real_image_size = (width + 10) as uint;
    let mut image = Image::new(real_image_size, real_image_size);
    for i in range(0, real_image_size) {
        for j in range(0, real_image_size) {
            image.set_pixel(i, j, WHITE);
        }
    }
    for i in range(0, width) {
        for j in range(0, width) {
            if canvas.get(i, j) == Module::Dark {
                image.set_pixel((i + 5) as uint, real_image_size - (j + 6) as uint, BLACK);
            }
        }
    }
    image.save(filename);
}

fn main() {
    for (z, separations) in SEGMENT_SEPARATIONS.iter().enumerate() {
        let mut segments = separations.iter().map(|&(b, e)| Segment {
            mode: Mode::Numeric, begin: b, end: e
        }).collect::<Vec<_>>();

        let variations_count = ALL_MODES.len().pow(segments.len());
        for i in range(0, variations_count) {
            let mut var = i;
            for r in segments.iter_mut() {
                r.mode = ALL_MODES[var % ALL_MODES.len()];
                var /= ALL_MODES.len();
            }
            for ec_level in ALL_EC_LEVELS.iter() {
                for mask_pattern in ALL_MASK_PATTERNS.iter() {
                    let filename = format!("results/test-{}-{}-{}-{}.bmp", z, i, *ec_level, *mask_pattern);
                    run(*ec_level, *mask_pattern, &*segments, &*filename);
                }
            }
        }
        println!("processed {}/{}", z, 8u);
    }
}
kennytm
fuente
1
El principal problema que veo aquí es que su envío en sí no está escrito en un lenguaje de programación .
Martin Ender
44
@ MartinBüttner Esa es una opinión subjetiva de unas pocas personas seleccionadas. Dicho esto, la forma en que se obtuvo el archivo fue programada, así que diría que este es un envío completamente válido. Además, este es un enfoque increíblemente increíble.
Nit
1
@Nit Es una meta publicación sin votos negativos, que es básicamente cómo funciona el consenso de la comunidad en SE (al menos en PPCG). Si no está de acuerdo, podría rechazar esa respuesta o proporcionar una alternativa. Dicho esto, probablemente haré una meta publicación separada, específicamente sobre los desafíos de complejidad de kolmogorov, ya que esto está surgiendo mucho.
Martin Ender
@Nit hecho. Siéntase libre de venir a discutir esto en meta.
Martin Ender
La conversión de gif parecía más corta.
jimmy23013
5

Mathematica, 217 177 176 166 bytes

Aquí hay un comienzo:

"newyear.png"~Export~ImagePad[Image[IntegerDigits[36^^fl6ibg25c8z00uef53p4657dgd6hjzg41e5joead1qgz0l2xchqgso5r1a51v5no4zkw9v22okk‌​lg0cymmy2,2,441]~Partition~21],5,1]

Menos golf:

"newyear.png"~Export~ImagePad[
 Image[
  IntegerDigits[
    36^^fl6ibg25c8z00uef53p4657dgd6hjzg41e5joead1qgz0l2xchqgso5r1a51v5no4zkw9v22okk‌​lg0cymmy2,
    2,
    441
  ]~Partition~21
 ],
 5,
 1
]

El código QR está codificado en un número base 36. Por supuesto, podría codificarlo en ASCII extendido (base 256), pero eso solo acortaría la cadena en 30 bytes, y no estoy seguro de poder hacer la conversión a un costo mucho menor que eso.

Por supuesto, esto es Mathematica, así que también está el byte 63

"newyear.png"~Export~ImagePad[BarcodeImage["2015","QR",21],5,1]

pero supongo que es una escapatoria estándar. ;) (Esto produce un código QR diferente al del desafío, ¿así que supongo que el código QR no es único?)

Martin Ender
fuente
1
Sí, hay varias formas de codificar la misma cadena en el código QR, por ejemplo, utilizando diferentes niveles de verificación de errores, esquema de codificación, enmascaramiento de imágenes, etc. Sin embargo, sin considerar el código de compresión OP es uno de los más pequeños ("versión 1").
kennytm
¿De dígitos? Podrías usar 36^^fl6ibg25c8z00uef53p4657dgd6hjzg41e5joead1qgz0l2xchqgso5r1a51v5no4zkw9v22okklg0cymmy2en su lugar.
kennytm
@KennyTM oh wow, buen truco. Gracias :) Creo que con eso, la base 256 realmente no vale la pena (necesitaría ambos ToCharacterCodey FromDigitsluego.)
Martin Ender
3

Matlab 545 Bytes

Año nuevo

Codificado en un trabajo manual minucioso y sin ninguna compresión / conversación de cadena incorporada elegante . Sé que todavía no es tan bueno como las otras respuestas, pero todavía estoy feliz =)

b=[[61:67,69,71:73,75:81,92,98]+100,
    1,3:4,6,12,23,25:27,29,31:35,37,39:41,43,54,56:58,60,63:64,66,68,70:72,74,85,87:89,91,97,99]+200,
    [1:3,5,16,22,24:26,30,36,47:53,55,57,59,61:67,87:89]+300,
    [9,11,15:16,20:21,24,27,29,40,42,48:50,57,59,71,74:75,77:79,81,85,89:90]+400,
    [2,9,11:12,14:15,18,34:37,39,42:43,46:47,50:51,72,74:75,77:79,81:82,95:99]+500,
    [0:1,3:8,10:12,14:15,26,32,37,40:41,43:45,57,59:61,63,67:69,71:77,88,90:92,94,97]+600,
    [19,21:23,25,27,33,37:39,50,56,59,62,66,69,81:87,89:91,95,99:101]+700];
z=zeros(31);z(b)= 1;imwrite(~z,'newyear.png')

Más ilegible (la versión 545 real):

z=zeros(31);
z([
    [61:67, 69, 71:73, 75:81, 92, 98] + 100,
    [1, 3:4, 6, 12, 23, 25:27, 29, 31:35, 37, 39:41, 43, 54, 56:58, 60, 63:64, 66, 68, 70:72, 74, 85, 87:89, 91, 97, 99] + 200,
    [1:3, 5, 16, 22, 24:26, 30, 36, 47:53, 55, 57, 59, 61:67, 87:89] + 300,
    [9, 11, 15:16, 20:21, 24, 27, 29, 40, 42, 48:50, 57, 59, 71, 74:75, 77:79, 81, 85, 89:90] + 400,
    [2, 9, 11:12, 14:15, 18, 34:37, 39, 42:43, 46:47, 50:51, 72, 74:75, 77:79, 81:82, 95:99] + 500,
    [0:1, 3:8, 10:12, 14:15, 26, 32, 37, 40:41, 43:45, 57, 59:61, 63, 67:69, 71:77, 88, 90:92, 94, 97] + 600,
    [19, 21:23, 25,27, 33, 37:39, 50, 56, 59, 62, 66, 69, 81:87, 89:91, 95, 99:101] + 700
])= 1;
imwrite(~z,'newyear.png')

Creamos una matriz cero de 31 x 31, pero accedemos a ella como vector para establecer todas las celdas con los índices de ba 1. Los trucos que utilicé fueron la notación de enteros consecutivos (como [1,2,3,4] = 1:4) y eliminar uno de los 100 dígitos al agregar un escalar a cada valor del vector.

Veamos si alguien puede vencer eso =)

falla
fuente
así que no leí la palabra unreadablecorrectamente ... definitivamente leí readable. vi eso justo después de sugerirlo y esperaba que quien leyera mi edición lo rechazara, pero aparentemente también lo extrañaron. lo de la mala edición ...
pseudonym117
No importa realmente en mi humilde opinión, solo quería incluir la primera versión porque es más fácil hacer referencia en la explicación.
defecto
2

Bash, 206252257 bytes

El uso del convertcomando incluido imagemagickguarda 46 bytes más.

base64 -d<<<UDQKMzAgMzAKAAAAAAAAAAAAAAAAAAAAAAAAAAAH9L+ABBkggAXULoAF2S6ABdOugAQeoIAH+r+AB9zVAABIlwABHU6AAsIaAAFXS4AAD+QAB/ywAAQT5QAF3pIABd6SAAXdTgAEHBsAB/1OAAAAAAAAAAAAAAAAAAAAAAAAAAAA|convert - newyear.png

Convierte la pbmimagen codificada en base64 en una pngimagen con imagemagick's convert.

Es posible que deba ajustar el decode (-d)parámetro a su base64binario específico . Probado en mi Ubuntu 14.04 LTS.

Guardado 5 bytes usando <<</ here-string .

base64 -d>newyear.png<<<iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeAQMAAAAB/jzhAAAABlBMVEX///8AAABVwtN+AAAAX0lEQVQI12PACdi/7G9gYJFUaGBgvaIHJG6CiMvrgGJyCxoY2H/tBxJ3rgIVekxnYGCU9WtgYDokBWSFezcwMPA/ARrwZwMDA4vwUwYG1nuTYMRdP6CYjDRQ9q8fbrsBLRkaYOOP83wAAAAASUVORK5CYII=

Versión anterior (257 bytes):
echo iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeAQMAAAAB/jzhAAAABlBMVEX///8AAABVwtN+AAAAX0lEQVQI12PACdi/7G9gYJFUaGBgvaIHJG6CiMvrgGJyCxoY2H/tBxJ3rgIVekxnYGCU9WtgYDokBWSFezcwMPA/ARrwZwMDA4vwUwYG1nuTYMRdP6CYjDRQ9q8fbrsBLRkaYOOP83wAAAAASUVORK5CYII=|base64 -d > newyear.png

Solo una cadena de comandos de shell simple que escribe el pngarchivo codificado en base64 en stdin base64que lo decodifica debido a la -dbandera y escribe su stdout en newyear.png.

Árbol Gigante
fuente
probablemente pueda guardar personajes con algo así base64 -d>newyear.png<<<[the long string], pero no estoy en una máquina Linux rn y no sé lo que es obligatorio el espacio en blanco
undergroundmonorail
Confirmado para trabajar base64 -d>newyear.png<<<[base64 string]en Ubuntu 14.04.
PurkkaKoodari
Si va a utilizar el código sugerido, simplemente edite el encabezado de respuesta a algo específico como Bash, Ksh o Zsh. Shell en general (como Shix, Ash o Dash compatibles con POSIX) no admite la sintaxis here-string .
manatwork
Si podemos usar rutinas netpbm, podemos alimentar el mapa de bits comprimido y perder 40 bytes: echo UDQKMzEgMzEKAAAAAAAAAAAAAAAAAAAAAAAAAAAH95 / ABBBQQAXWV0AF0VdABdFXQAQQEEAH9V / AAAWAAAUzMUADqtLABbv0QAcMPAAH1JSAAADwAAfxbUAEFDwABdCUgAXSfAAF1W1ABBMdwAf0FUAAAAA AAAAAAAAAAAAAAAAAAAAAAA == | base64 -d | pnmtopng> newyear.png
swstephe
@manatwork Recién editado, debería funcionar en Bash como lo probé en mi teléfono Android.
GiantTree
1

Python 2 + PIL, 216 215

Básicamente un puerto de la solución de Mathematica.

from PIL import*
b=Image.new("1",[21]*2)
b.putdata(map(int,'0'*7+bin(int('FL6IBG25C8Z00UEF53P4657DGD6HJZG41E5JOEAD1QGZ0L2XCHQGSO5R1A51V5NO4ZKW9V22OKKLG0CYMMY2',36))[2:]))
ImageOps.expand(b,5,255).save("newyear.png")
PurkkaKoodari
fuente
0

Herramientas comunes de Shell + Imagemagick, 215

(echo "P1
21 21"
base64 -d<<<H95/ggoN1lduirt0VdggIP9V/ALAFMzFdVpdu/R4YeH1JSAB4H8W1goeF0JSuk+F1W1gmO/9BVA=|xxd -c99 -p|tr a-f A-F|dc -e2o16i?p|tr -d '\n\\'|fold -21)|convert -border 5 -bordercolor white - newyear.png

Un poco enrevesada , pero más corta que la otra respuesta de shell .

  • Base64 convierte de base64 a base 256 (ASCII extendido)
  • xxd se convierte en hexadecimal
  • tr hace mayúscula hexadecimal, adecuado para cc
  • dc lee hexadecimal e imprime una cadena binaria de 1s y 0s
  • tr elimina \ y espacios en blanco
  • el pliegue hace que las líneas tengan 21 caracteres (21 píxeles) de largo
  • Esta salida, junto con P1\n21 21el formato PBM P1
  • convertir (Imagemagick) convierte esto a .png con un borde de 5 píxeles:

ingrese la descripción de la imagen aquí

Trauma digital
fuente