17
\$\begingroup\$

Mission is simple. Just output number 2015 as QR code and write it to file named newyear.png in PNG format. Code must be valid any day, so maybe you shall not use current year.

QR code as text looks like this:

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

The result written in newyear.png must contain that QR code with white 5 pixel borders and one pixel sized dots. It must not contain anything else than QR code.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ can it be hardcoded, or must you generate the qr code? \$\endgroup\$ Dec 29, 2014 at 11:14
  • 7
    \$\begingroup\$ Much more answers will come if this is ascii art output based and not image output. \$\endgroup\$
    – Optimizer
    Dec 29, 2014 at 11:37
  • 6
    \$\begingroup\$ Does the code have to be exactly correct with no errors, or is it enough that it scans correctly? (QR codes have a lot of deliberate redundancy and error correction, so you can flip a lot of pixels and they'll still work.) Also, does it have to be PNG, or can we use other image formats (I'm thinking particularly about PBM here)? \$\endgroup\$ Dec 30, 2014 at 1:49

8 Answers 8

15
\$\begingroup\$

Raw file, 184 bytes = 173-byte file + 11-byte filename

I hope this does not break any standard loopholes. But the output "has a high and the shortest way to produce it would (most likely) be to just print it literally...".

newyear.png

Base 64 of the file:

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

Instead of golfing a program I golfed the resulting PNG image. QR code is a very flexible format, there are many parameters that can be fiddled: the encoding of the input, the error correction level, and the masking image. These will all generate different symbols and thus compressed to files of different sizes.

So I have written a program to generate all these combinations (resulting 6720 files), and then use PNGOUT to pick the one which compressed to the smallest file. It turns out to be a file that:

  • First write "20" in alphanumeric mode
  • Then write "1" in numeric mode
  • Then write "5" in numeric mode
  • Use the "H" (High) error correction level
  • Use the "110" data masking

This is called test-3-1-H-Diamonds.bmp if you used the program below. This image is 175-byte long after running PNGOUT. With "high" error correction level in "version 1" QR code, we can modify up to 8 pixels in the data part without ruining the data. With a bit of manual trial-and-error I can reduce it further to 173 bytes presented above. It can probably be smaller but exhausting all combinations requires 208C8 ~ 7.5 × 1013 checks which I'm not going to do ;)


The Rust (0.13.0-nightly (5ba610265)) program that generates all combinations:

/* 

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);
    }
}
\$\endgroup\$
8
  • 1
    \$\begingroup\$ The main problem I see here, is that your submission itself is not written in a programming language. \$\endgroup\$ Dec 30, 2014 at 0:12
  • 4
    \$\begingroup\$ @MartinBüttner That's a subjective opinion of a selected few people. That being said, the way the file was obtained was programmed so I'd say this is a completely valid submission. Also, this is a frigging awesome approach. \$\endgroup\$
    – Etheryte
    Dec 30, 2014 at 1:21
  • 1
    \$\begingroup\$ @Nit It's a meta post without downvotes, which is basically how community consensus works on SE (at least on PPCG). If you disagree, you could downvote that answer or provide an alternative. That being said, I'll probably make a separate meta post, specifically about kolmogorov complexity challenges, as this is coming up a lot. \$\endgroup\$ Dec 30, 2014 at 9:58
  • \$\begingroup\$ @Nit Done. Feel free to come discuss this on meta. \$\endgroup\$ Dec 30, 2014 at 10:33
  • \$\begingroup\$ Converting from gif seemed shorter. \$\endgroup\$
    – jimmy23013
    Dec 31, 2014 at 10:09
5
\$\begingroup\$

Mathematica, 217 177 176 166 bytes

Here is a start:

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

Less golf:

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

The QR code is encoded in a base 36 number. Of course, I could encode it in extended ASCII (base 256), but that would only shorten the string by 30 bytes, and I'm not sure I can do the conversion at the cost of much less than that.

Of course, this is Mathematica, so there's also the 63-byte

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

but I guess that's a standard loophole. ;) (This produces a different QR code than the one in the challenge, so I guess the QR code isn't unique?)

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Yes there are multiple ways to encode the same string in QR code, e.g. using different levels of error checking, encoding scheme, masking image, etc. Not considering compression OP's code is one of the smallest ("version 1") nevertheless. \$\endgroup\$
    – kennytm
    Dec 29, 2014 at 13:11
  • \$\begingroup\$ FromDigits? You could use 36^^fl6ibg25c8z00uef53p4657dgd6hjzg41e5joead1qgz0l2xchqgso5r1a51v5no4zkw9v22okklg0cymmy2 instead. \$\endgroup\$
    – kennytm
    Dec 30, 2014 at 0:06
  • \$\begingroup\$ @KennyTM oh wow, neat trick. Thank you :) I think with that, base 256 is really not worth it (I'd need both ToCharacterCode and FromDigits then.) \$\endgroup\$ Dec 30, 2014 at 0:09
5
+200
\$\begingroup\$

Python 3, 261 bytes

from PIL import Image
h=Image.new("1",[21]*2)
h.putdata([int(u)for u in list("".join(format(ord(i),"08b")for i in'\x01\x0c\x03ï¯\x91MD\x8bª$]Q>þø\x05P\x1féÿY\x99ÔU-\x12 \\<ððVÖÿðü\x07IO¯\x0fEíj-\x83ÑT\x94û8\x80\x17Õ'))])
h.save("newyear.png")

Needs a better way of encoding

Explanation

from PIL import Image    # Import the Pillow library for images
ima = Image.new("1", [21, 21])    # Create a new 21x21 Image in B/W mode
ima.putdata(    # Function to write a sequence to the pixels
    [int(u) for u in list(    # convert string into list of bits to write
        "".join(    # join into single string
            format(ord(byte),"08b"    # format a unicode character into list of bits
                )for byte in'\x01\x0c\x03ï¯\x91MD\x8bª$]Q>þø\x05P\x1féÿY\x99ÔU-\x12 \\<ððVÖÿðü\x07IO¯\x0fEíj-\x83ÑT\x94û8\x80\x17Õ'    # Loop through encoded qr data
        )
    )]
)
ima.save("newyear.png")    # Save image
\$\endgroup\$
1
  • \$\begingroup\$ Use [*map(int,...)], instead of list comprehension, get rid of list(...)call as strings are iterables and use a format string literal instead of a format call: 245 bytes \$\endgroup\$
    – movatica
    Aug 6, 2021 at 12:25
3
\$\begingroup\$

Matlab 545 Bytes

newyear

Hardcoded in painstaking manual work and without any fancy builtin string compression/conversation. I know it still is not as good as the other answers but I am still happy=)

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

More unreadable (the actual 545 version):

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

We create a 31 x 31 zero matrix, but access it as vector to set all cells with the indices of b to 1. The tricks I used were the notation of consecutive integers (like [1,2,3,4] = 1:4) and removing one the 100-digit by adding a scalar to every value of the vector.

Let's see if anyone can beat that=)

\$\endgroup\$
2
  • \$\begingroup\$ so i didnt read the word unreadable correctly... definitely read readable. saw that right after suggesting it and was hoping whoever read my edit rejected it, but they missed it too apparently. sorry about the bad edit... \$\endgroup\$ Dec 29, 2014 at 18:42
  • \$\begingroup\$ Does not relly matter IMHO, just wanted to include the first version because it is easier to refer to in the explaination. \$\endgroup\$
    – flawr
    Dec 29, 2014 at 19:35
2
\$\begingroup\$

Python 2 + PIL, 216 215

Basically a port of the Mathematica solution.

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")
\$\endgroup\$
2
  • \$\begingroup\$ -4 bytes using a Python3 format string literal: f"{int('FL6IBG25C8Z00UEF53P4657DGD6HJZG41E5JOEAD1QGZ0L2XCHQGSO5R1A51V5NO4ZKW9V22OKKLG0CYMMY2',36):0441b}" \$\endgroup\$
    – movatica
    Aug 6, 2021 at 12:32
  • \$\begingroup\$ @movatica Thanks for the idea! However, f-strings were added in Python 3.6, and even the first mention is from July 2015, so I prefer to limit the answer to what was possible in 2014. \$\endgroup\$ Aug 6, 2021 at 14:34
2
\$\begingroup\$

Bash, 206 252 257 Bytes

Using the convert command bundled in imagemagick saves 46 more bytes.

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

Converts the base64-encoded pbm image to a png image with imagemagick's convert.

You may need to adjust the decode (-d) parameter to your specific base64 binary. Tested on my Ubuntu 14.04 LTS.

Saved 5 bytes by using <<</here-string.

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

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

Just a simple shell command chain that writes the base64 encoded png file into stdin of base64 that decodes it because of the -d flag and writes its stdout to newyear.png.

\$\endgroup\$
10
  • \$\begingroup\$ can probably save characters with something like base64 -d>newyear.png<<<[the long string] but i'm not at a linux machine rn and i don't know which whitespace is mandatory \$\endgroup\$ Dec 29, 2014 at 16:32
  • \$\begingroup\$ Confirmed to work with base64 -d>newyear.png<<<[base64 string] on Ubuntu 14.04. \$\endgroup\$ Dec 29, 2014 at 16:54
  • \$\begingroup\$ If you are going to use the suggested code, just edit the answer heading to something specific like Bash, Ksh or Zsh. Shell in general (like POSIX compatible Sh, Ash or Dash) does not support the here-string syntax. \$\endgroup\$
    – manatwork
    Dec 29, 2014 at 17:00
  • \$\begingroup\$ If we can use netpbm routines, we can feed the compressed bitmap and lose 40 bytes: echo UDQKMzEgMzEKAAAAAAAAAAAAAAAAAAAAAAAAAAAH95/ABBBQQAXWV0AF0VdABdFXQAQQEEAH9V/ AAAWAAAUzMUADqtLABbv0QAcMPAAH1JSAAADwAAfxbUAEFDwABdCUgAXSfAAF1W1ABBMdwAf0FUAAAAA AAAAAAAAAAAAAAAAAAAAAAA==|base64 -d|pnmtopng>newyear.png \$\endgroup\$
    – swstephe
    Dec 29, 2014 at 17:14
  • \$\begingroup\$ @manatwork Just edited, should work on Bash as I tested it on my Android phone. \$\endgroup\$
    – GiantTree
    Dec 29, 2014 at 17:27
1
\$\begingroup\$

HTML (Stack Snippet), 367

Edit: Oops! I forgot about the filename requirement. This makes a download link that prompts the user to download newyear.png. Due to browser security, I'm pretty sure I can't bypass that prompt.

I tested this on Firefox, but FYI, the closing </a> tag doesn't seem to be required for this to still work:

<a href="data:png;base64,iVBORw0KGgoAAAANSUhEUgAAAB8AAAAfCAYAAAAfrhY5AAAAs0lEQVRIie2U4QrAIAiEff+Xdn9FPD1ta7AljJHhfVqm6IsmB37gqqoiAr9on42j4RN/O64S8xVbP4KjuFvgGfQbcNY/jRt3O/ovd3tlqPHaOpW49XXWSKeEWzH2qKNkUVIpHAlnU455FTQcZVz5O31Ad7utIDpeZp+Cd2xScQpn32vWG36/Bc/8j9+5F8ygWXLtO2fg0YDZUnk1aB69cw/xPpQ8De9MMJ/cUuW77MD/B78AsoJkRZwIeDUAAAAASUVORK5CYII=" download="newyear.png">a

Original answer that just displays the png:

<img src="data:png;base64,iVBORw0KGgoAAAANSUhEUgAAAB8AAAAfCAYAAAAfrhY5AAAAs0lEQVRIie2U4QrAIAiEff+Xdn9FPD1ta7AljJHhfVqm6IsmB37gqqoiAr9on42j4RN/O64S8xVbP4KjuFvgGfQbcNY/jRt3O/ovd3tlqPHaOpW49XXWSKeEWzH2qKNkUVIpHAlnU455FTQcZVz5O31Ad7utIDpeZp+Cd2xScQpn32vWG36/Bc/8j9+5F8ygWXLtO2fg0YDZUnk1aB69cw/xPpQ8De9MMJ/cUuW77MD/B78AsoJkRZwIeDUAAAAASUVORK5CYII=">

\$\endgroup\$
0
\$\begingroup\$

Common Shell tools + 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

A bit convoluted, but shorter than the other shell answer.

  • Base64 converts from base64 to base 256 (extended ASCII)
  • xxd converts to hex
  • tr makes hex uppercase, suitable for dc
  • dc reads hex and prints binary string of 1s and 0s
  • tr removes \ and whitespace
  • fold makes lines 21 chars (21 pixels) long
  • This output, along with P1\n21 21 is the PBM P1 format
  • convert (Imagemagick) converts this to .png with a 5 pixel border:

enter image description here

\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.