Lấy cảm hứng từ cả thử thách "Unique is Cheap" của @Laikoni , trong đó điểm số dựa trên chính thử thách, cũng như câu trả lời JavaScript (ES6) của @ETHproductions cho thử thách "Nén Palindrom" , trong đó anh ta sử dụng một thử thách khá hay phương pháp nén cho cờ palindrom, chữ hoa / chữ thường và chữ cái.
Thử thách:
Bạn sẽ tạo hai chương trình / chức năng: chương trình / chức năng nén và chương trình / chức năng giải nén.
Nén chương trình / chức năng:
Với các nhân vật sử dụng trong mã nguồn của riêng bạn (cả mã nén và giải nén nguồn kết hợp) như chỉ đầu vào có thể, sử dụng bất kỳ loại phương pháp bit nén của sự lựa chọn và đầu ra của bạn kết quả 0
s và 1
s của bit-nén của đầu vào này .
Số lượng bit ( 0
s và 1
s) xuất ra phải càng ngắn càng tốt và số tiền này sẽ là số điểm của câu trả lời của bạn .
Ý tưởng là có sự cân bằng tốt giữa các loại ký tự khác nhau được sử dụng trong mã nguồn của riêng bạn, kích thước của các chương trình / chức năng của bạn và loại nén bit mà bạn đã sử dụng. Hoặc để trích dẫn @RobertFraser trong bình luận này :
Đây là một ví dụ tuyệt vời về các nguyên tắc cơ bản của kỹ thuật. Lấy một mô tả vấn đề, suy nghĩ về các cách khác nhau để giải quyết nó và tạo ra sự đánh đổi giữa các yêu cầu (nghĩa là có bao nhiêu bit để dành cho các phong cách khác nhau), v.v.
Quy tắc thử thách:
- Chương trình / chức năng nén và giải nén phải cùng ngôn ngữ lập trình.
- Bạn phải cung cấp cả chương trình / chức năng nén và giải nén, và số lượng
0
s và1
s đầu ra chương trình nén của bạn cho cả hai chương trình / chức năng được kết hợp (được che giấu) vì đầu vào sẽ là điểm số của bạn. - Việc nén phải - rõ ràng - hoạt động đối với tất cả các ký tự được sử dụng trong mã nguồn của cả chương trình / chức năng nén và giải nén của bạn, theo bất kỳ thứ tự hoặc số tiền nào. (Nó có thể có hành vi không xác định cho bất kỳ ký tự nào không có trong mã nguồn của bạn.)
- Kiểu đầu vào không nhất thiết phải là một chuỗi. Nó cũng có thể là một danh sách / mảng / luồng ký tự và nó có thể là đối số chương trình, STDIN, v.v. Cuộc gọi của bạn.
Áp dụng tương tự cho đầu ra. Có thể được trả về từ một chức năng hoặc in ra STDOUT. Có thể là một chuỗi đơn, mảng số nguyên, v.v. - Chương trình nén của bạn phải xuất ít nhất một
0
hoặc1
(vì vậy mộtcat
chương trình trống cho cả chương trình nén và giải nén là không thể). - Mã nguồn của bạn có thể không chỉ chứa
0
s và1
s, ngoại trừ no-op (để ngăn các ngôn ngữ lập trình in mã nguồn của riêng chúng theo mặc định, trong đó cả hai chương trình nén và giải nén có thể là một0
hoặc1
một phần và không có op để ngăn chặn hành vi này với một bình luận không được sử dụng, xin lỗi các ngôn ngữ lập trình dựa trên nhị phân chỉ sử dụng0
s và1
s làm mã nguồn). - Mặc dù bạn sẽ phải hỗ trợ đầu vào từ 0 hoặc nhiều nhóm ký tự được sử dụng trong các chương trình / chức năng của mình, bạn không phải hỗ trợ đầu vào trống. Vì vậy, bạn có thể giả sử mỗi đầu vào sẽ có ít nhất 1 ký tự.
- Một đầu vào có thể có thể lớn hơn kích thước nén và giải nén của bạn cộng lại.
- Nếu vì bất kỳ lý do gì, phương pháp nén của bạn phụ thuộc vào thứ tự và có đầu ra ngắn hơn khi đầu vào của bạn
DecompressionProgramCompressionProgram
thay vìCompressionProgramDecompressionProgram
, bạn được phép chọn thứ tự che giấu các chương trình / chức năng cho điểm số của mình.
Thí dụ:
Giả sử chương trình nén là ABC
và chương trình giải nén là 123aBc
. Đối với bất kỳ đầu vào nào chứa 0 hoặc nhiều nhóm ký tự 123ABCab
, nó có thể nén chính xác các ký tự đó thành 0
s và 1
s, và có thể giải nén các 0
s và 1
s này trở lại thành các ký tự chính xác. Một số ví dụ đầu vào hợp lệ cho hai chương trình này có thể là: ABC123aBc
(tất nhiên); A
; 1Ca
; 22222b1121221b
; Vân vân.
Quy tắc chung:
- Các quy tắc chuẩn áp dụng cho câu trả lời của bạn, vì vậy bạn được phép sử dụng STDIN / STDOUT, các hàm / phương thức với các tham số thích hợp, các chương trình đầy đủ. Cuộc gọi của bạn.
- Lỗ hổng mặc định bị cấm.
- Nếu có thể, vui lòng thêm một liên kết với một bài kiểm tra cho mã của bạn.
- Ngoài ra, xin vui lòng thêm một lời giải thích nếu cần thiết.
Ví dụ về câu trả lời:
Java 8, điểm số 1440 bit, 180 (87 + 93) byte
Đây là một triển khai rất tệ trong Java 8, trong đó mỗi ký tự được in đơn giản là Chuỗi nhị phân 8 bit.
Chức năng nén:
Đầu vào được cung cấp như
java.util.stream.IntStream
.s->s.forEach(c->System.out.print("".format("%8s",Long.toString(c,2)).replace(' ','0')))
Chức năng giải nén:
Đầu vào được cung cấp như
String
.s->{for(Integer i=0;i<s.length();System.out.printf("%c",i.parseInt(s.substring(i,i+=8),2)));}
if input==compr_code+decompr_code then return 0 else return binary charcodes of input
, bộ giải nén-> if input==0 then return compr_code+decompr_code else convert binary codes to characters and return them
. Điểm cuối cùng: 1 (thấp nhất có thể). Các chương trình sẽ không tầm thường để viết, nhưng với một số thủ thuật từ các câu hỏi, chúng chắc chắn có thể thực hiện được.