Nén nghệ thuật ASCII mất mát


21

Lý lịch

PICASCII là một công cụ gọn gàng chuyển đổi hình ảnh thành nghệ thuật ASCII.

Nó đạt được các mức độ sáng khác nhau bằng cách sử dụng mười ký tự ASCII sau:

@#+';:,.` 

Chúng ta sẽ nói rằng các charxels này (các yếu tố nhân vật) có độ sáng từ 1 (tại dấu) đến 10 (không gian).

Dưới đây, bạn có thể thấy kết quả của việc chuyển đổi một ít mã, cờ xứ Wales, một hình chữ thập quá tay, một con cá hồi lớn và một ít golf, được hiển thị với phông chữ chính xác:

Nghệ thuật ASCII

Bạn có thể xem hình ảnh trong fiddle này và tải chúng từ Google Drive .

Bài tập

Mặc dù kết quả cuối cùng của PICASCII rất dễ chịu, nhưng tất cả năm hình ảnh được kết hợp có trọng lượng 153.559 byte. Những hình ảnh này có thể được nén bao nhiêu nếu chúng ta sẵn sàng hy sinh một phần chất lượng của chúng?

Nhiệm vụ của bạn là viết một chương trình chấp nhận hình ảnh nghệ thuật ASCII như các hình ảnh trên và chất lượng tối thiểu làm đầu vào và in một hình ảnh nén bị mất - dưới dạng một chương trình đầy đủ hoặc một hàm trả về một chuỗi - đáp ứng yêu cầu chất lượng.

Điều này có nghĩa là bạn không được viết một bộ giải nén riêng; nó phải được tích hợp vào mỗi hình ảnh nén.

Hình ảnh gốc sẽ bao gồm các charxels có độ sáng trong khoảng từ 1 đến 10, được phân tách bằng các đường kẻ thành các đường có cùng độ dài. Hình ảnh nén phải có cùng kích thước và sử dụng cùng một bộ ký tự.

Đối với hình ảnh không nén bao gồm n charxels, chất lượng của phiên bản nén của hình ảnh được xác định là

công thức chất lượng

Trong đó c i là độ sáng của charxel thứ i của đầu ra của hình ảnh nén và u i độ sáng của charxel thứ i của hình ảnh không nén.

Chấm điểm

Mã của bạn sẽ được chạy với năm hình ảnh ở trên dưới dạng cài đặt chất lượng đầu vào và tối thiểu là 0,50, 0,60, 0,70, 0,80 và 0,90 cho mỗi hình ảnh.

Điểm của bạn là giá trị trung bình hình học của kích thước của tất cả các hình ảnh nén, nghĩa là gốc thứ hai mươi lăm của sản phẩm có độ dài của tất cả hai mươi lăm hình ảnh nén.

Điểm thấp nhất sẽ thắng!

Quy tắc bổ sung

  • Mã của bạn phải hoạt động đối với các hình ảnh tùy ý, không chỉ các hình ảnh được sử dụng để ghi điểm.

    Dự kiến ​​bạn sẽ tối ưu hóa mã của mình đối với các trường hợp thử nghiệm, nhưng một chương trình thậm chí không cố nén các hình ảnh tùy ý sẽ không nhận được sự hỗ trợ từ tôi.

  • Máy nén của bạn có thể sử dụng máy nén luồng byte tích hợp (ví dụ: gzip), nhưng bạn phải tự thực hiện chúng cho các hình ảnh nén.

    Bulit-in thường được sử dụng trong bộ giải nén luồng byte (ví dụ: chuyển đổi cơ sở, giải mã độ dài chạy) được cho phép.

  • Máy nén và hình ảnh nén không phải ở cùng một ngôn ngữ.

    Tuy nhiên, bạn phải chọn một ngôn ngữ cho tất cả các hình ảnh nén.

  • Đối với mỗi hình ảnh nén, áp dụng quy tắc golf mã tiêu chuẩn.

xác minh

Tôi đã tạo một tập lệnh CJam để dễ dàng xác minh tất cả các yêu cầu chất lượng và tính điểm của bài nộp.

Bạn có thể tải xuống trình thông dịch Java từ đây hoặc tại đây .

e# URLs of the uncompressed images.
e# "%s" will get replaced by 1, 2, 3, 4, 5.

"file:///home/dennis/codegolf/53199/original/image%s.txt"

e# URLs of the compressed images (source code).
e# "%s-%s" will get replaced by "1-50", "1-60", ... "5-90".

"file:///home/dennis/codegolf/53199/code/image%s-%s.php"

e# URLs of the compressed images (output).

"file:///home/dennis/codegolf/53199/output/image%s-%s.txt"

e# Code

:O;:C;:U;5,:)
{
    5,5f+Af*
    {
        C[IQ]e%g,X*:X;
        ISQS
        [U[I]e%O[IQ]e%]
        {g_W=N&{W<}&}%
        _Nf/::,:=
        {
            {N-"@#+';:,.` "f#}%z
            _::m2f#:+\,81d*/mq1m8#
            _"%04.4f"e%S
            @100*iQ<"(too low)"*
        }{
            ;"Dimension mismatch."
        }?
        N]o
    }fQ
}fI
N"SCORE: %04.4f"X1d25/#e%N

Thí dụ

Bash → PHP, điểm số 30344.0474

cat

Đạt 100% chất lượng cho tất cả các đầu vào.

$ java -jar cjam-0.6.5.jar vrfy.cjam
1 50 1.0000 
1 60 1.0000 
1 70 1.0000 
1 80 1.0000 
1 90 1.0000 
2 50 1.0000 
2 60 1.0000 
2 70 1.0000 
2 80 1.0000 
2 90 1.0000 
3 50 1.0000 
3 60 1.0000 
3 70 1.0000 
3 80 1.0000 
3 90 1.0000 
4 50 1.0000 
4 60 1.0000 
4 70 1.0000 
4 80 1.0000 
4 90 1.0000 
5 50 1.0000 
5 60 1.0000 
5 70 1.0000 
5 80 1.0000 
5 90 1.0000 

SCORE: 30344.0474

Tôi gặp một số khó khăn khi hiểu phần này: Nếu ai đó chọn q = 0,5, thì mỗi char trong tệp đầu vào sẽ được thay thế bằng char với một nửa độ sáng ở đầu ra, phải không? Rõ ràng loại trừ khoảng trắng vì điều đó sẽ làm rối tung toàn bộ hình ảnh.
Nicolás Siplis 16/07/2015

1
Tất cả quá khó hiểu và loopholey. Làm thế nào để bạn dừng một mục mattmahoney.net/dc/barf.html ? Bộ giải nén có thể đọc bất kỳ tập tin nào ngoài hình ảnh nén không? Bạn có thể cung cấp một kịch bản python hoặc một cái gì đó thực sự kiểm tra chất lượng của một hình ảnh và tính toán điểm số để không thể có sự phân biệt trên mặt trận đó không? Vv
Will

1
@ Sẽ khó hiểu? Có lẽ. Nhưng tôi không nghĩ đó là loopholey. Mỗi hình ảnh nén phải là một chương trình hoặc chức năng, vì vậy những trò đùa không tưởng như BARF sẽ tự động bị loại trừ. Tôi không biết Python, nhưng tôi sẽ nghĩ ra một cái gì đó để xác minh đơn giản.
Dennis

8
"Tôi đã tạo một tập lệnh CJam để dễ dàng xác minh tất cả các yêu cầu chất lượng và tính điểm của bài nộp." Có phải mọi người thực sự sử dụng điều này để làm kịch bản bình thường? Chúa ơi ...
Fatalize 16/07/2015

Câu trả lời:


4

Java → CJam, điểm 4417,89

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import net.aditsu.cjam.CJam;

public class Compress {
    protected static final char[] DIGITS = "0123456789ABCDEFGHIJK".toCharArray();
    protected static final String CHARS = "@#+';:,.` ";
    protected static final char[] CHR = CHARS.toCharArray();

    private static class Img {
        public final int rows;
        public final int cols;
        public final int[][] a;

        public Img(final int rows, final int cols) {
            this.rows = rows;
            this.cols = cols;
            a = new int[rows][cols];
        }

        public Img(final List<String> l) {
            rows = l.size();
            cols = l.get(0).length();
            a = new int[rows][cols];
            for (int i = 0; i < rows; ++i) {
                for (int j = 0; j < cols; ++j) {
                    a[i][j] = CHARS.indexOf(l.get(i).charAt(j));
                }
            }
        }

        public static Img read(final Reader r) {
            try {
                final BufferedReader br = new BufferedReader(r);
                final List<String> l = new ArrayList<>();
                while (true) {
                    final String s = br.readLine();
                    if (s == null || s.isEmpty()) {
                        break;
                    }
                    l.add(s);
                }
                br.close();
                return new Img(l);
            }
            catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

        public static Img read(final File f) {
            try {
                return read(new FileReader(f));
            }
            catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

        public Img scaleDown(final int fr, final int fc) {
            final int r1 = (rows + fr - 1) / fr;
            final int c1 = (cols + fc - 1) / fc;
            final Img x = new Img(r1, c1);
            final int[][] q = new int[r1][c1];
            for (int i = 0; i < rows; ++i) {
                for (int j = 0; j < cols; ++j) {
                    x.a[i / fr][j / fc] += a[i][j];
                    q[i / fr][j / fc]++;
                }
            }
            for (int i = 0; i < r1; ++i) {
                for (int j = 0; j < c1; ++j) {
                    x.a[i][j] /= q[i][j];
                }
            }
            return x;
        }

        public Img scaleUp(final int fr, final int fc) {
            final int r1 = rows * fr;
            final int c1 = cols * fc;
            final Img x = new Img(r1, c1);
            for (int i = 0; i < r1; ++i) {
                for (int j = 0; j < c1; ++j) {
                    x.a[i][j] = a[i / fr][j / fc];
                }
            }
            return x;
        }

        public Img crop(final int r, final int c) {
            if (r == rows && c == cols) {
                return this;
            }
            final Img x = new Img(r, c);
            for (int i = 0; i < r; ++i) {
                for (int j = 0; j < c; ++j) {
                    x.a[i][j] = a[i][j];
                }
            }
            return x;
        }

        public Img rescale(final int fr, final int fc) {
            return scaleDown(fr, fc).scaleUp(fr, fc).crop(rows, cols);
        }

        public double quality(final Img x) {
            if (x.rows != rows || x.cols != cols) {
                throw new IllegalArgumentException();
            }
            double t = 0;
            for (int i = 0; i < rows; ++i) {
                for (int j = 0; j < cols; ++j) {
                    final int y = a[i][j] - x.a[i][j];
                    t += y * y;
                }
            }
            t /= 81 * rows * cols;
            t = 1 - Math.sqrt(t);
            return Math.pow(t, 8);
        }

        @Override
        public String toString() {
            final StringBuilder sb = new StringBuilder();
            for (int i = 0; i < rows; ++i) {
                for (int j = 0; j < cols; ++j) {
                    sb.append(CHR[a[i][j]]);
                }
                sb.append('\n');
            }
            return sb.toString();
        }

        public Array toArray() {
            final Array x = new Array(rows * cols);
            int k = 0;
            for (int i = 0; i < rows; ++i) {
                for (int j = 0; j < cols; ++j) {
                    x.a[k++] = a[i][j];
                }
            }
            return x;
        }

        public String compress(final double quality) {
            int bi = 1;
            int bj = 1;
            int bs = rows * cols;
            Img bx = this;

            for (int i = 1; i < 3; ++i) {
                for (int j = 1; j < 3; ++j) {
                    Img x = rescale(i, j);
                    if (quality(x) >= quality) {
                        x = scaleDown(i, j);
                        if (x.rows * x.cols < bs) {
                            bi = i;
                            bj = j;
                            bs = x.rows * x.cols;
                            bx = x;
                        }
                    }
                }
            }

            Array a = bx.toArray();
            int bf = 0;
            for (int i = 1; i <= 20; ++i) {
                final int t = a.rle11(i).n;
                if (t < bs) {
                    bs = t;
                    bf = i;
                }
            }

            int b = 10;
            if (bf > 0) {
                b = 11;
                a = a.rle11(bf);
            }

            String s = null;
            for (int i = 92; i < 97; ++i) {
                for (char c = ' '; c < '$'; ++c) {
                    final String t = a.cjamBase(b, i, c);
                    boolean ok = true;
                    for (int j = 0; j < t.length(); ++j) {
                        if (t.charAt(j) > '~') {
                            ok = false;
                            break;
                        }
                    }
                    if (!ok) {
                        continue;
                    }
                    if (s == null || t.length() < s.length()) {
                        s = t;
                    }
                }
            }

            if (bf > 0) {
                s += "{(_A={;()";
                if (bf > 1) {
                    s += DIGITS[bf] + "*";
                }
                s += "\\(a@*}&\\}h]e_";
            }
            if (bi * bj == 1) {
                return s + '"' + CHARS + "\"f=" + cols + "/N*";
            }
            s += bx.cols + "/";
            if (bi > 1) {
                s += bi + "e*";
                if (rows % 2 == 1) {
                    s += "W<";
                }
            }
            if (bj > 1) {
                s += bj + "fe*";
                if (cols % 2 == 1) {
                    s += "Wf<";
                }
            }
            return s + '"' + CHARS + "\"ff=N*";
        }

        public void verify(final String s, final double quality) {
            final String t = CJam.run(s, "");
            final Img x = read(new StringReader(t));
            final double q = quality(x);
            if (q < quality) {
                throw new RuntimeException(q + " < " + quality);
            }
//          System.out.println(q + " >= " + quality);
        }
    }

    private static class Array {
        public final int[] a;
        public final int n;

        public Array(final int n) {
            this.n = n;
            a = new int[n];
        }

        public Array(final int[] a) {
            this.a = a;
            n = a.length;
        }

        public String join() {
            final StringBuilder sb = new StringBuilder();
            for (int x : a) {
                sb.append(x).append(' ');
            }
            sb.setLength(sb.length() - 1);
            return sb.toString();
        }

//      public String cjamStr() {
//          final StringBuilder sb = new StringBuilder("\"");
//          for (int x : a) {
//              sb.append(DIGITS[x]);
//          }
//          sb.append("\":~");
//          return sb.toString();
//      }

        public String cjamBase(final int m, final int b, final char c) {
            final boolean zero = a[0] == 0;
            String s = join();
            if (zero) {
                s = "1 " + s;
            }
            s = CJam.run("q~]" + m + "b" + b + "b'" + c + "f+`", s);
            s += "'" + c + "fm" + b + "b" + DIGITS[m] + "b";
            if (zero) {
                s += "1>";
            }
            return s;
        }

        public Array rle11(final int f) {
            final int[] b = new int[n];
            int m = 0;
            int x = -1;
            int k = 0;
            for (int i = 0; i <= n; ++i) {
                final int t = i == n ? -2 : a[i];
                if (t == x && m < 11 * f) {
                    m++;
                }
                else {
                    if (m >= f && m > 3) {
                        b[k++] = 10;
                        b[k++] = m / f - 1;
                        b[k++] = x;
                        for (int j = 0; j < m % f; ++j) {
                            b[k++] = x;
                        }
                    }
                    else {
                        for (int j = 0; j < m; ++j) {
                            b[k++] = x;
                        }
                    }
                    m = 1;
                    x = t;
                }
            }
            return new Array(Arrays.copyOf(b, k));
        }
    }

    private static void score() {
        double p = 1;
        for (int i = 1; i < 6; ++i) {
            final File f = new File("image" + i + ".txt");
            final Img img = Img.read(f);
            final int n = (int) f.length();
            for (int j = 5; j < 10; ++j) {
                final double q = j / 10.0;
                final String s = img.compress(q);
                System.out.println(f.getName() + ", " + q + ": " + n + " -> " + s.length());
                img.verify(s, q);
                p *= s.length();
            }
        }
        System.out.println(Math.pow(p, 1 / 25.0));
    }

    public static void main(final String... args) {
        if (args.length != 2) {
            score();
            return;
        }
        final String fname = args[0];
        final double quality = Double.parseDouble(args[1]);
        try {
            final Img img = Img.read(new File(fname));
            final String s = img.compress(quality);
            img.verify(s, quality);
            final FileWriter fw = new FileWriter(fname + ".cjam");
            fw.write(s);
            fw.close();
        }
        catch (IOException e) {
            throw new RuntimeException();
        }
    }
}

Yêu cầu bình CJam trong đường dẫn lớp. Nếu bạn cung cấp cho nó 2 đối số dòng lệnh (tên tệp và chất lượng), nó sẽ thêm ".cjam" vào tên tệp và ghi hình ảnh nén vào đó. Mặt khác, nó tính điểm của nó trên 5 hình ảnh thử nghiệm, được cho là nằm trong thư mục hiện tại. Chương trình cũng xác minh mọi hình ảnh nén tự động. Bạn có thể muốn kiểm tra lại cách tính điểm trong trường hợp có sự khác biệt.

Các kỹ thuật được sử dụng (cho đến nay) là: chia tỷ lệ thành một nửa (theo chiều ngang, chiều dọc hoặc cả hai) nếu nó không làm giảm chất lượng quá nhiều, RLE được mã hóa tùy chỉnh và chuyển đổi cơ sở để đóng gói thêm dữ liệu vào mỗi ký tự trong khi vẫn còn trong phạm vi ASCII có thể in.


Bạn có thể cho tôi một cái nhìn tổng quan ngắn gọn về cách chạy này? Tôi đã biên dịch nó (thành công, tôi nghĩ vậy) với javac -cp cjam-0.6.5.jar Compress.java, nhưng java -cp cjam-0.6.5.jar Compressnói Error: Could not find or load main class Compressjava Compresskhông tìm thấy lớp CJam.
Dennis

@Dennis Bạn cần thêm thư mục chứa Compress. Class vào classpath (-cp). Nếu nó có trong thư mục hiện tại, hãy sử dụng -cp .:cjam-0.6.5.jar(trong Windoze tôi nghĩ bạn cần một dấu chấm phẩy thay vì dấu hai chấm)
aditsu

Đó là mẹo, cảm ơn bạn.
Dennis

2

Python 3.5 (chính và đầu ra) (hiện không lọc)

Chúc mừng sinh nhật, Thử thách! Đây là món quà của bạn: một câu trả lời!

EDIT: Đã chuyển đổi đầu ra thành mã python, tốc độ nén được cải thiện (một chút) EDIT2: Làm cho nó được in thô khi sizelà 1. Điểm được cải thiện, nhưng điểm cần phải được tính lại. EDIT3: @Dennis chỉ ra rằng tôi vẫn sửa lỗi, vì vậy tôi đã đánh dấu câu trả lời là không thể xóa

Mã số:

import sys
LIST = [' ','`','.',',',':',';',"'",'+','#','@']

def charxel_to_brightness(charxel):
    return LIST.index(charxel)

def brightness_to_charxel(bright):
    return LIST[bright]

def image_to_brightness(imagetext):
    return [list(map(charxel_to_brightness,line)) for line in imagetext.split("\n")]

def brightness_to_image(brightarray):
    return '\n'.join([''.join(map(brightness_to_charxel,line)) for line in brightarray])

def split_into_parts(lst,size):
    return [lst[x:x+size] for x in range(0, len(lst), size)]

def gen_updown(startxel,endxel,size):
    return [[int((size-r)*(endxel-startxel)/size+startxel) for c in range(size)] for r in range(size)]

def gen_leftright(startxel,endxel,size):
    return [[int((size-c)*(endxel-startxel)/size+startxel) for c in range(size)] for r in range(size)]

def gen_tlbr(startxel,endxel,size):
    return [[int((2*size-r-c)/2*(endxel-startxel)/size+startxel) for c in range(size)] for r in range(size)]

def gen_bltr(startxel,endxel,size):
    return [[int((size-r+c)/2*(endxel-startxel)/size+startxel) for c in range(size)] for r in range(size)]

def gen_block(code,startxel,endxel,size):
    if code==0:return gen_updown(startxel,endxel,size)
    if code==1:return gen_leftright(startxel,endxel,size)
    if code==2:return gen_bltr(startxel,endxel,size)
    if code==3:return gen_tlbr(startxel,endxel,size)

def vars_to_data(code,startxel,endxel):
    acc=endxel
    acc+=startxel<<4
    acc+=code<<8
    return acc

def data_to_vars(data):
    code=data>>8
    startxel=(data>>4)&15
    endxel=data&15
    return code,startxel,endxel

def split_into_squares(imgarray,size):
    rows = split_into_parts(imgarray,size)
    allsquares = []
    for rowblock in rows:
        splitrows = []
        for row in rowblock:
            row = split_into_parts(row,size)
            splitrows.append(row)
        rowdict = []
        for row in splitrows:
            for x in range(len(row)):
                if len(rowdict)<=x:
                    rowdict.append([])
                rowdict[x].append(row[x])
        allsquares.append(rowdict)
    return allsquares

def calc_quality(imgarray,comparray):
    acc=0
    for row in range(len(imgarray)):
        for col in range(len(imgarray[row])):
            acc+=pow(imgarray[row][col]-comparray[row][col],2)
    return (1-(acc/81.0/sum([len(row) for row in imgarray]))**.5)**8

def fuse_squares(squarray):
    output=[]
    counter=0
    scounter=0
    sqrow=0
    while sqrow<len(squarray):
        if scounter<len(squarray[sqrow][0]):
            output.append([])
            for square in squarray[sqrow]:
                output[counter].extend(square[scounter])
            scounter+=1
            counter+=1
        else:
            scounter=0
            sqrow+=1
    return output

def main_calc(imgarray,threshold):
    imgarray = image_to_brightness(imgarray)
    size = 9
    quality = 0
    compimg=[]
    datarray=[]
    testdata = [vars_to_data(c,s,e) for c in range(4) for s in range(10) for e in range(10)]
    while quality<threshold:
        squares = split_into_squares(imgarray,size)
        compimg = []
        datarray = []
        testblock = [gen_block(c,s,e,size) for c in range(4) for s in range(10) for e in range(10)]
        for row in squares:
            comprow = []
            datrow=[]
            for square in row:
                quality_values = [calc_quality(square,block) for block in testblock]
                best_quality = quality_values.index(max(quality_values))
                comprow.append(testblock[best_quality])
                datrow.append(testdata[best_quality])
            compimg.append(comprow)
            datarray.append(datrow)
        compimg = fuse_squares(compimg)
        quality = calc_quality(imgarray,compimg)
        print("Size:{} Quality:{}".format(size,quality))
        size-=1
    return brightness_to_image(compimg),datarray,size+1

template = '''def s(d,s,e,z):
 x=range(z)
 return d<1 and[[int((z-r)*(e-s)/z+s)for c in x]for r in x]or d==1 and[[int((z-c)*(e-s)/z+s)for c in x]for r in x]or d==2 and[[int((2*z-r-c)/2*(e-s)/z+s)for c in x]for r in x]or d>2 and[[int((z-r+c)/2*(e-s)/z+s)for c in x] for r in x]
i=lambda a:'\\n'.join([''.join(map(lambda r:" `.,:;'+#@"[r],l))for l in a])
def f(a):
 o=[];c=0;s=0;r=0
 while r<len(a):
  if s<len(a[r][0]):
   o.append([])
   for q in a[r]:
    o[c].extend(q[s])
   s+=1;c+=1
  else:
   s=0;r+=1
 return o
t={};z={}
print(i(f([[s(D>>8,(D>>4)&15,D&15,z)for D in R]for R in t])))'''

template_size_1 = '''print("""{}""")'''   

def main(filename,threshold):
    print(filename+" "+str(threshold))
    file = open(filename,'r')
    compimg,datarray,size = main_calc(file.read(),threshold)
    file.close()
    textoutput = open(filename.split(".")[0]+"-"+str(threshold*100)+".txt",'w')
    textoutput.write(compimg)
    textoutput.close()
    compoutput = open(filename.split(".")[0]+"-"+str(threshold*100)+".py",'w')
    datarray = str(datarray).replace(" ","")
    code = ""
    if size==1:
        code = template_size_1.format(compimg)
    else:
        code= template.format(datarray,str(size))
    compoutput.write(code)
    compoutput.close()
    print("done")

if __name__ == "__main__":
    main(sys.argv[1],float(sys.argv[2]))

Câu trả lời này có thể sử dụng rất nhiều cải tiến, vì vậy có lẽ tôi sẽ làm việc với nó nhiều hơn vào cuối tuần.

Cách thức hoạt động:

  • Chia hình ảnh thành các khối có kích thước size.
  • Tìm khối phù hợp nhất
    • Các khối có thể có độ dốc ngay bây giờ!
  • Tính chất lượng (theo công thức) cho toàn bộ hình ảnh.
  • Nếu đúng, ghi hình ảnh nén vào tập tin.
  • Nếu không, giảm dần sizevà thử lại.

Thuật toán này hoạt động tốt đối với chất lượng thấp (0,5, 0,6) nhưng không hoạt động quá tốt trên các hình ảnh chất lượng cao hơn (thực sự tăng cao). Nó cũng thực sự chậm.

Ở đây tôi có tất cả các tệp được tạo, vì vậy bạn sẽ không phải tạo lại chúng.


Cuối cùng, một câu trả lời! Mặc dù về mặt kỹ thuật, nó không cạnh tranh, vì tôi đã tạo ra Bubblegum sau khi đăng thử thách này ... Tôi sẽ chạy tập lệnh chấm điểm sau đó và có thể chuyển nó sang ngôn ngữ ít bí truyền hơn.
Dennis

@Dennis Ah, cũng không quá khó để chuyển đầu ra sang tập lệnh python. Cảm ơn bạn đã sẵn sàng
Blue

Tôi vừa đọc lại thử thách của mình (sau một năm, tôi hơi mơ hồ về các chi tiết) và nó nói Máy nén của bạn có thể sử dụng máy nén luồng byte tích hợp (ví dụ: gzip), nhưng bạn phải tự thực hiện chúng cho hình ảnh nén. Điều đó có nghĩa là Bubblegum đã ra ngoài.
Dennis

Cuối cùng tôi đã nhớ rằng tôi đã hứa sẽ ghi điểm này; xin lỗi về sự chậm trễ. Mã của bạn dường như có một lỗi đánh máy ( compingnên là compimg), mà tôi đã sửa để chạy chương trình. Trừ khi tôi mắc lỗi khi chạy mã của bạn, kích thước của một số hình ảnh được tạo không chính xác (ví dụ: image2.txtcó 33.164 byte, nhưng image2-50.0.txtcó 33.329) và khác không tạo cùng một tệp khi chạy các chương trình được tạo ( image3-50.0.txtcó chất lượng 0,5110 , nhưng chạy chương trình được tạo ra có chất lượng 0.4508 ).
Dennis

Phụ lục: Tôi đã tải xuống image3-50.0.pytừ Dropbox của bạn và nó khớp với tệp tôi đã tạo.
Dennis
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.