Uscita 2015 come codice QR


15

La missione è semplice. Basta inviare il numero 2015 come codice QR e scriverlo nel file denominato newyear.pngin formato PNG. Il codice deve essere valido in qualsiasi giorno, quindi forse non dovrai utilizzare l'anno corrente.

Il codice QR come testo appare così:

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

Il risultato scritto newyear.pngdeve contenere quel codice QR con bordi bianchi di 5 pixel e punti di una dimensione di pixel. Non deve contenere altro che un codice QR.


1
può essere hardcoded o devi generare il codice qr?
undergroundmonorail

7
Molte più risposte arriveranno se si tratta di output di arte ASCII e non di output di immagini.
Ottimizzatore

6
Il codice deve essere esattamente corretto senza errori o è sufficiente che lo scannerizzi correttamente? (I codici QR hanno molta ridondanza deliberata e correzione degli errori, quindi puoi capovolgere molti pixel e continueranno a funzionare.) Inoltre, deve essere PNG o possiamo usare altri formati di immagine (sto pensando in particolare su PBM qui)?
Ilmari Karonen,

Risposte:


12

File non elaborato, 184 byte = file a 173 byte + nome file a 11 byte

Spero che ciò non rompa eventuali scappatoie standard. Ma l'output "ha un'alta e il modo più breve per produrlo sarebbe (molto probabilmente) stamparlo letteralmente ...".

newyear.png

Base 64 del file:

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

Invece di giocare a golf un programma ho golf l'immagine PNG risultante. Il codice QR è un formato molto flessibile, ci sono molti parametri che possono essere manipolati: la codifica dell'input, il livello di correzione dell'errore e l'immagine di mascheramento. Questi genereranno tutti simboli diversi e quindi compressi in file di dimensioni diverse.

Quindi ho scritto un programma per generare tutte queste combinazioni (risultanti 6720 file), e quindi usare PNGOUT per scegliere quello che è stato compresso nel file più piccolo. Risulta essere un file che:

  • Scrivi prima "20" in modalità alfanumerica
  • Quindi scrivere "1" in modalità numerica
  • Quindi scrivere "5" in modalità numerica
  • Utilizzare il livello di correzione degli errori "H" (alto)
  • Utilizzare il mascheramento dei dati "110"

Questo si chiama test-3-1-H-Diamonds.bmpse hai usato il programma qui sotto. Questa immagine è lunga 175 byte dopo l'esecuzione di PNGOUT. Con un livello di correzione degli errori "alto" nel codice QR "versione 1", possiamo modificare fino a 8 pixel nella parte dati senza rovinare i dati. Con un po 'di tentativi ed errori manuali posso ridurlo ulteriormente a 173 byte presentati sopra. Probabilmente può essere più piccolo ma esaurire tutte le combinazioni richiede 208 C 8 ~ 7,5 × 10 13 controlli che non ho intenzione di fare;)


Il programma Rust (0.13.0-nightly (5ba610265)) che genera tutte le combinazioni:

/* 

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);
    }
}

1
Il problema principale che vedo qui è che la tua stessa presentazione non è scritta in un linguaggio di programmazione .
Martin Ender,

4
@ MartinBüttner Questa è un'opinione soggettiva di poche persone selezionate. Detto questo, il modo in cui il file è stato ottenuto è stato programmato, quindi direi che questo è un invio completamente valido. Inoltre, questo è un approccio fantastico da brivido.
Nit

1
@Nit È un meta post senza voti negativi, che è sostanzialmente il modo in cui il consenso della comunità funziona su SE (almeno su PPCG). Se non sei d'accordo, potresti sottovalutare quella risposta o fornire un'alternativa. Detto questo, probabilmente farò un meta post separato, in particolare sulle sfide della complessità di kolmogorov, poiché questo sta arrivando molto.
Martin Ender,

@Nit Fatto. Sentiti libero di venire a discuterne su meta.
Martin Ender,

La conversione da GIF sembrava più breve.
jimmy23013,

5

Mathematica, 217 177 176 166 byte

Ecco un inizio:

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

Meno golf:

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

Il codice QR è codificato in un numero 36 di base. Certo, potrei codificarlo in ASCII esteso (base 256), ma ciò accorcerebbe solo la stringa di 30 byte e non sono sicuro di poter fare la conversione al costo di molto meno.

Naturalmente, questo è Mathematica, quindi c'è anche il 63 byte

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

ma immagino che sia una scappatoia standard. ;) (Questo produce un codice QR diverso da quello della sfida, quindi immagino che il codice QR non sia univoco?)


1
Sì, ci sono diversi modi per codificare la stessa stringa nel codice QR, ad esempio usando diversi livelli di controllo degli errori, schema di codifica, immagine di mascheramento, ecc. Non considerare la compressione Il codice OP è comunque uno dei più piccoli ("versione 1").
kennytm,

FromDigits? 36^^fl6ibg25c8z00uef53p4657dgd6hjzg41e5joead1qgz0l2xchqgso5r1a51v5no4zkw9v22okklg0cymmy2Invece potresti usare .
kennytm,

@KennyTM oh wow, trucco pulito. Grazie :) Penso che la base 256 non ne valga davvero la pena (avrei bisogno di entrambi ToCharacterCodee FromDigitspoi.)
Martin Ender il

3

Matlab 545 byte

nuovo anno

Hardcoded in scrupoloso lavoro manuale e senza alcuna compressione / conversazione di stringhe incorporate . So che non è ancora buono come le altre risposte, ma sono ancora felice =)

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')

Più illeggibile (l'attuale versione 545):

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')

Creiamo una matrice zero 31 x 31, ma accediamo come vettore per impostare tutte le celle con gli indici di ba 1. I trucchi che ho usato sono stati la notazione di numeri interi consecutivi (come [1,2,3,4] = 1:4) e la rimozione di una delle 100 cifre aggiungendo uno scalare a ogni valore del vettore.

Vediamo se qualcuno può battere quello =)


quindi non ho letto la parola unreadablecorrettamente ... sicuramente letto readable. l'ho visto subito dopo averlo suggerito e speravo che chiunque avesse letto la mia modifica lo avesse respinto, ma a quanto pare lo mancava troppo. scusatemi per la modifica errata ...
pseudonimo117,

Non importa davvero, ho voluto solo includere la prima versione perché è più facile fare riferimento nella spiegazione.
flawr

2

Bash, 206252257 byte

L'uso del convertcomando in bundle imagemagickconsente di risparmiare 46 byte in più.

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

Converte l' pbmimmagine codificata in base64 in pngun'immagine con imagemagick's convert.

Potrebbe essere necessario adattare il decode (-d)parametro al proprio base64binario specifico . Testato su Ubuntu 14.04 LTS.

5 byte salvati usando <<</ here-string .

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

Vecchia versione (257 byte):
echo iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeAQMAAAAB/jzhAAAABlBMVEX///8AAABVwtN+AAAAX0lEQVQI12PACdi/7G9gYJFUaGBgvaIHJG6CiMvrgGJyCxoY2H/tBxJ3rgIVekxnYGCU9WtgYDokBWSFezcwMPA/ARrwZwMDA4vwUwYG1nuTYMRdP6CYjDRQ9q8fbrsBLRkaYOOP83wAAAAASUVORK5CYII=|base64 -d > newyear.png

Solo una semplice catena di comandi della shell che scrive la base64 codificata png file in stdin di base64quello lo decodifica a causa della -dbandiera e scrive il suo stdout su newyear.png.


posso probabilmente salvare personaggi con qualcosa del genere base64 -d>newyear.png<<<[the long string]ma non sono su una macchina Linux e non so quale spazio bianco sia obbligatorio
undergroundmonorail

Confermato per funzionare con base64 -d>newyear.png<<<[base64 string]Ubuntu 14.04.
PurkkaKoodari,

Se stai per usare il codice suggerito, modifica l'intestazione della risposta in qualcosa di specifico come Bash, Ksh o Zsh. La shell in generale (come compatibile con POSIX Sh, Ash o Dash) non supporta la sintassi here-string .
arte

Se siamo in grado di usare le routine netpbm, siamo in grado di alimentare il bitmap compressa e perdere 40 byte: echo UDQKMzEgMzEKAAAAAAAAAAAAAAAAAAAAAAAAAAAH95 / ABBBQQAXWV0AF0VdABdFXQAQQEEAH9V / AAAWAAAUzMUADqtLABbv0QAcMPAAH1JSAAADwAAfxbUAEFDwABdCUgAXSfAAF1W1ABBMdwAf0FUAAAAA AAAAAAAAAAAAAAAAAAAAAAA == | base64 -d | pnmtopng> newyear.png
swstephe

@manatwork Appena modificato, dovrebbe funzionare su Bash mentre l'ho provato sul mio telefono Android.
GiantTree

1

Python 2 + PIL, 216 215

Fondamentalmente un porto della soluzione 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")

0

Strumenti Shell comuni + 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 po 'contorto , ma più breve dell'altra risposta della shell .

  • Base64 converte da base64 a base 256 (ASCII estesa)
  • xxd converte in esadecimale
  • tr rende esadecimale maiuscolo, adatto per cc
  • dc legge hex e stampa una stringa binaria di 1s e 0s
  • tr rimuove \ e spazi bianchi
  • piega rende le linee lunghe 21 caratteri (21 pixel)
  • Questa uscita, insieme P1\n21 21al formato PBM P1
  • convert (Imagemagick) converte questo in .png con un bordo di 5 pixel:

inserisci qui la descrizione dell'immagine

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.