Đầu ra 2015 dưới dạng mã QR


15

Nhiệm vụ rất đơn giản. Chỉ cần xuất số 2015 dưới dạng mã QR và ghi nó vào tệp có tênnewyear.png ở định dạng PNG. Mã phải có hiệu lực bất kỳ ngày nào, vì vậy có thể bạn sẽ không sử dụng năm hiện tại.

Mã QR dưới dạng văn bản trông như thế này:

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

Kết quả được viết newyear.pngphải chứa mã QR đó với viền 5 pixel màu trắng và các chấm có kích thước một pixel. Nó không được chứa bất cứ thứ gì khác ngoài mã QR.


1
nó có thể được mã hóa cứng, hoặc bạn phải tạo mã qr?
undergroundmonorail

7
Nhiều câu trả lời sẽ đến nếu đây là đầu ra nghệ thuật ascii và không phải đầu ra hình ảnh.
Trình tối ưu hóa

6
Liệu mã phải chính xác mà không có lỗi, hoặc nó có đủ để quét chính xác không? (Mã QR có nhiều dư thừa có chủ ý và sửa lỗi, vì vậy bạn có thể lật rất nhiều pixel và chúng vẫn hoạt động.) Ngoài ra, nó phải là PNG hoặc chúng ta có thể sử dụng các định dạng hình ảnh khác không đặc biệt về PBM ở đây)?
Ilmari Karonen

Câu trả lời:


12

Tệp thô, 184 byte = tệp 173 byte + tên tệp 11 byte

Tôi hy vọng điều này không phá vỡ bất kỳ sơ hở tiêu chuẩn. Nhưng đầu ra "có độ cao và cách ngắn nhất để sản xuất nó (rất có thể) là chỉ in nó theo nghĩa đen ...".

newyear.png

Cơ sở 64 của tệp:

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

Thay vì chơi golf một chương trình, tôi đã đánh golf hình ảnh PNG. Mã QR là một định dạng rất linh hoạt, có nhiều tham số có thể được xử lý: mã hóa đầu vào, mức sửa lỗi và hình ảnh mặt nạ. Tất cả sẽ tạo ra các biểu tượng khác nhau và do đó được nén thành các tệp có kích thước khác nhau.

Vì vậy, tôi đã viết một chương trình để tạo ra tất cả các kết hợp này (kết quả là 6720 tệp), và sau đó sử dụng PNGOUT để chọn một chương trình được nén thành tệp nhỏ nhất. Hóa ra đó là một tập tin:

  • Đầu tiên viết "20" ở chế độ chữ và số
  • Sau đó viết "1" ở chế độ số
  • Sau đó viết "5" ở chế độ số
  • Sử dụng mức sửa lỗi "H" (Cao)
  • Sử dụng mặt nạ dữ liệu "110"

Điều này được gọi test-3-1-H-Diamonds.bmpnếu bạn sử dụng chương trình dưới đây. Hình ảnh này dài 175 byte sau khi chạy PNGOUT. Với mức sửa lỗi "cao" trong mã QR "phiên bản 1", chúng tôi có thể sửa đổi tối đa 8 pixel trong phần dữ liệu mà không làm hỏng dữ liệu. Với một chút thử và sửa lỗi thủ công, tôi có thể giảm nó xuống còn 173 byte được trình bày ở trên. Nó có thể nhỏ hơn nhưng làm cạn kiệt tất cả các kết hợp yêu cầu kiểm tra 208 C 8 ~ 7.5 × 10 13 mà tôi sẽ không làm;)


Chương trình Rust (0.13.0 mỗi đêm (5ba610265)) tạo ra tất cả các kết hợp:

/* 

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
Vấn đề chính tôi thấy ở đây, đó là bản thân bài dự thi của bạn không được viết bằng ngôn ngữ lập trình .
Martin Ender

4
@ MartinBüttner Đó là ý kiến ​​chủ quan của một vài người được chọn. Điều đó đang được nói, cách tập tin đã được lập trình nên tôi nói đây là một bài nộp hoàn toàn hợp lệ. Ngoài ra, đây là một cách tiếp cận tuyệt vời.
Nit

1
@Nit Đó là một bài đăng meta không có downvote, về cơ bản là cách thức đồng thuận cộng đồng hoạt động trên SE (ít nhất là trên PPCG). Nếu bạn không đồng ý, bạn có thể đánh giá thấp câu trả lời đó hoặc cung cấp giải pháp thay thế. Điều đó đang được nói, có lẽ tôi sẽ tạo một bài đăng meta riêng biệt, đặc biệt về các thách thức phức tạp của kolmogorov, vì điều này sẽ xuất hiện rất nhiều.
Martin Ender

@Nit Xong. Hãy đến để thảo luận về điều này trên meta.
Martin Ender

Chuyển đổi từ gif dường như ngắn hơn.
jimmy23013

5

Toán học, 217 177 176 166 byte

Đây là một khởi đầu:

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

Ít golf hơn:

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

Mã QR được mã hóa trong một số cơ sở 36. Tất nhiên, tôi có thể mã hóa nó trong ASCII mở rộng (cơ sở 256), nhưng điều đó sẽ chỉ rút ngắn chuỗi 30 byte và tôi không chắc mình có thể thực hiện chuyển đổi với chi phí thấp hơn nhiều.

Tất nhiên, đây là Mathicala, do đó, cũng có 63 byte

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

nhưng tôi đoán đó là một lỗ hổng tiêu chuẩn. ;) (Điều này tạo ra một mã QR khác với thử thách, vì vậy tôi đoán mã QR không phải là duy nhất?)


1
Có, có nhiều cách để mã hóa cùng một chuỗi trong mã QR, ví dụ: sử dụng các mức độ kiểm tra lỗi, sơ đồ mã hóa, mặt nạ hình ảnh khác nhau, v.v.
kennytm

Từ số? Bạn có thể sử dụng 36^^fl6ibg25c8z00uef53p4657dgd6hjzg41e5joead1qgz0l2xchqgso5r1a51v5no4zkw9v22okklg0cymmy2thay thế.
kennytm

@KennyTM oh wow, thủ thuật gọn gàng. Cảm ơn bạn :) Tôi nghĩ với điều đó, cơ sở 256 thực sự không xứng đáng (tôi cần cả hai ToCharacterCodeFromDigitssau đó.)
Martin Ender

3

Matlab 545 byte

năm mới

Hardcoding trong công việc thủ công và không có bất kỳ nén / hội thoại dựng sẵn ưa thích nào . Tôi biết nó vẫn không tốt như những câu trả lời khác nhưng tôi vẫn vui =)

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

Không thể đọc được hơn (phiên bản 545 thực tế):

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

Chúng tôi tạo ra một ma trận 31 x 31 không, nhưng truy cập vào nó như là vector để thiết lập tất cả các tế bào với các chỉ số của bđể 1. Các thủ thuật tôi đã sử dụng là ký hiệu các số nguyên liên tiếp (như [1,2,3,4] = 1:4) và loại bỏ một chữ số 100 bằng cách thêm một vô hướng vào mỗi giá trị của vectơ.

Hãy xem liệu có ai có thể đánh bại điều đó =)


Vì vậy, tôi đã không đọc từ unreadablechính xác ... chắc chắn đọc readable. đã thấy điều đó ngay sau khi đề xuất nó và hy vọng bất cứ ai đọc bản chỉnh sửa của tôi đều từ chối nó, nhưng họ đã bỏ lỡ nó quá rõ ràng. xin lỗi về chỉnh sửa xấu ...
bút danh

Không liên quan đến IMHO, chỉ muốn đưa vào phiên bản đầu tiên vì nó dễ tham khảo hơn trong phần giải thích.
flawr

2

Bash, 206 252 257 byte

Sử dụng convertlệnh được gói trong imagemagicktiết kiệm thêm 46 byte.

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

Chuyển đổi pbmhình ảnh được mã hóa base64 thành pnghình ảnh với imagemagick's convert.

Bạn có thể cần điều chỉnh decode (-d)tham số thành base64nhị phân cụ thể của mình . Đã thử nghiệm trên Ubuntu 14.04 LTS của tôi.

Đã lưu 5 byte bằng cách sử dụng <<</ here-string .

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

Phiên bản cũ (257 byte):
echo iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeAQMAAAAB/jzhAAAABlBMVEX///8AAABVwtN+AAAAX0lEQVQI12PACdi/7G9gYJFUaGBgvaIHJG6CiMvrgGJyCxoY2H/tBxJ3rgIVekxnYGCU9WtgYDokBWSFezcwMPA/ARrwZwMDA4vwUwYG1nuTYMRdP6CYjDRQ9q8fbrsBLRkaYOOP83wAAAAASUVORK5CYII=|base64 -d > newyear.png

Chỉ cần một chuỗi lệnh shell đơn giản ghi pngtệp mã hóa base64 vào stdin của base64mã đó giải mã nó vì -dcờ và ghi stdout của nó vào newyear.png.


có thể có thể tiết kiệm nhân vật với một cái gì đó giống như base64 -d>newyear.png<<<[the long string]nhưng tôi không ở một rn máy linux và tôi không biết đó là khoảng trắng là bắt buộc
undergroundmonorail

Xác nhận để làm việc với base64 -d>newyear.png<<<[base64 string]trên Ubuntu 14.04.
PurkkaKoodari

Nếu bạn định sử dụng mã được đề xuất, chỉ cần chỉnh sửa tiêu đề câu trả lời thành một cái gì đó cụ thể như Bash, Ksh hoặc Zsh. Shell nói chung (như Sh, Ash hoặc Dash tương thích POSIX) không hỗ trợ cú pháp chuỗi ở đây .
manatwork 29/12/14

Nếu chúng ta có thể sử dụng thói quen NetPBM, chúng ta có thể nuôi bitmap nén và mất 40 byte: echo UDQKMzEgMzEKAAAAAAAAAAAAAAAAAAAAAAAAAAAH95 / ABBBQQAXWV0AF0VdABdFXQAQQEEAH9V / AAAWAAAUzMUADqtLABbv0QAcMPAAH1JSAAADwAAfxbUAEFDwABdCUgAXSfAAF1W1ABBMdwAf0FUAAAAA AAAAAAAAAAAAAAAAAAAAAAA == | base64 -d | pnmtopng> newyear.png
swstephe

@manatwork Chỉ cần chỉnh sửa, sẽ hoạt động trên Bash khi tôi thử nghiệm nó trên điện thoại Android của mình.
GiantTree

1

Python 2 + PIL, 216 215

Về cơ bản là một cổng của giải pháp Mathicala.

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

Các công cụ Shell phổ biến + 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

Một chút phức tạp , nhưng ngắn hơn so với câu trả lời vỏ khác .

  • Base64 chuyển đổi từ cơ sở64 sang cơ sở 256 (ASCII mở rộng)
  • xxd chuyển đổi thành hex
  • tr làm chữ hoa hex, thích hợp cho dc
  • dc đọc hex và in chuỗi nhị phân 1s và 0
  • tr xóa \ và khoảng trắng
  • nếp gấp làm cho các dòng dài 21 ký tự (21 pixel)
  • Sản lượng này, cùng với P1\n21 21định dạng PBM P1
  • convert (Imagemagick) chuyển đổi nó thành .png với đường viền 5 pixel:

nhập mô tả hình ảnh ở đây

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.