Dây golf


22

Tôi luôn không đưa ra câu trả lời cho thách thức đòi hỏi phải nén chuỗi, lý do chính là tôi không biết sử dụng các công cụ nén chuỗi hiệu quả như tôi nên làm .

Vì lý do này, tôi đã đăng câu hỏi này. Không giống như các câu hỏi về mẹo khác của tôi, đây không phải là ngôn ngữ cụ thể mà nếu bạn có thể nghĩ ra bất kỳ lời khuyên nào bằng ngôn ngữ của mình, thì bạn có thể đăng nó (miễn là bạn chỉ định ngôn ngữ). Lời khuyên chung cũng được đánh giá cao.

Vì vậy, làm thế nào tôi có thể sử dụng các công cụ nén chuỗi để đạt hiệu quả tối đa của chúng?

Câu trả lời:


9

Chuyển đổi cơ sở (CJam)

Một cách dễ dàng để mã hóa các chuỗi ASCII không bắt đầu bằng byte null là chuyển đổi từ cơ sở 128 sang số nguyên, sau đó sang cơ sở 256:

128b256b:c              e# Prints encoded string.
128b256b:c`"256b128b:c" e# Prints encoded string with decoder.

Điều này sử dụng 7 bit để mã hóa mỗi ký tự ASCII.

Nếu chuỗi ban đầu chỉ bao gồm, ví dụ, các chữ cái viết thường và không bắt đầu bằng a , chúng ta có thể bắt đầu bằng cách ánh xạ "a...z"tới [0 ... 25], sau đó tiến hành như trên:

'afm26b256b:c               e# Prints encoded string.
'afm26b256b:c`"256b26b'af+" e# Prints encoded string with decoder.

Cuối cùng, nếu chuỗi gốc chỉ có một vài ký tự duy nhất (phổ biến trong nghệ thuật ASCII), thì tốt hơn là chỉ định rõ ràng bảng chữ cái.

Ví dụ:

" +-/\|"f#6b256b:c                       e# Prints encoded string.
" +-/\|"f#6b256b:c`"256b6b"" +-/\|"`"f=" e# Prints encoded string with decoder.

Theo nguyên tắc thông thường, bạn muốn ký tự đầu tiên của chuỗi gốc là ký tự thứ hai của bảng chữ cái, ký tự phân biệt tiếp theo của chuỗi gốc là ký tự đầu tiên của bảng chữ cái, ký tự phân biệt tiếp theo của chuỗi gốc là ký tự thứ ba của bảng chữ cái, ký tự phân biệt tiếp theo của chuỗi gốc là ký tự thứ tư của bảng chữ cái, v.v.

Bộ mã hóa của ví dụ cuối hoạt động như sau:

" +-/\|"f# e# Replace each character by its index in that string.
6b256b     e# Convert from base 6 (length of the alphabet) to base 256.
:c         e# Cast each digit to character.

Bộ giải mã của ví dụ cuối hoạt động như sau:

256b6b     e# Convert from base 256 to base 6.
" +-/\|"f= e# Replace each digit by the corresponding character of the alphabet.

2
Tôi sẽ nói cụ thể hơn: theo quy tắc ngón tay cái, bạn muốn ký tự đầu tiên của chuỗi gốc là ký tự thứ hai của bảng chữ cái, ký tự riêng biệt tiếp theo của chuỗi gốc là ký tự đầu tiên của bảng chữ cái, ...
Peter Taylor

@PeterTaylor Đã thêm. Cảm ơn!
Dennis

9

Các câu hỏi phức tạp Kolmogorov lớn hơn với một số cấu trúc nhưng không có công thức đơn giản (ví dụ như lời bài hát) thường sẽ được hưởng lợi từ cách tiếp cận dựa trên ngữ pháp. Về bản chất, bạn trích xuất các chuỗi con lặp đi lặp lại và mã hóa chúng bằng cách nào đó. Đây là những gì Lempel-Ziv làm, sử dụng một lớp ngữ pháp khá hạn chế; nếu bạn sử dụng các ngữ pháp chung hơn thì bạn phải tìm ra cách mã hóa các quy tắc. Ví dụ, một cách tiếp cận ở đây là "mã hóa bù", trong đó bạn bù từng byte nguồn theo số quy tắc ( n), gán byte 1cho nquy tắc, sử dụng 0byte để tách quy tắc và liên tục thay thế byte ibằng quy tắc được đánh giá i. Cuối cùng, bạn hoàn tác phần bù bằng cách trừ đi ntừng byte.

Tôi thực sự đã viết một chương trình Java thực hiện các cách tiếp cận khác nhau:

Hầu hết các phương pháp tiếp cận theo một quá trình hai giai đoạn. Trong giai đoạn đầu tiên, chuỗi được chuyển đổi thành một ngữ pháp tạo ra nó; trong giai đoạn thứ hai, ngữ pháp được chuyển đổi thành chương trình GolfScript. Việc triển khai giai đoạn đầu chủ yếu dựa trên Charikar, Lehman, Liu, Panigrahy, Mitchhakaran, Sahai, & Shelat (2005) Vấn đề ngữ pháp nhỏ nhất , Lý thuyết thông tin, Giao dịch của IEEE trên, 51 (7), 2554-2576.

Nó cũng bao gồm một cách tiếp cận Lempel-Ziv, một cách tiếp cận mã hóa cơ sở và một cách tiếp cận mã hóa runlength, và xác định một phương pháp đưa ra chương trình ngắn nhất.


0

Stax

Trong ngôn ngữ chơi gôn mã Stax , có một công cụ nhỏ hữu ích được gọi là máy nén chuỗi ký tự . Tôi không biết làm thế nào nó hoạt động, chính xác, nhưng có một nơi tôi làm biết làm thế nào nó hoạt động. Nó chuyển đổi chuỗi thành số, sau đó thành Cơ sở 256. Đó là CP437 , với 0x00 và 0xFF được chuyển đổi để sao chép. Đó là PackedStax. Bạn có thể chuyển đổi chuỗi của mình với trình nén chuỗi ký tự sau đó Đóng gói chuỗi đó, để nén tốt.

Sử dụng quy trình này, chuỗi "Chuỗi này có ba mươi hai byte" có thể được chuyển đổi thành v * "A] - | W4]} 3"% (chuỗi được nén thường được bao quanh bởi các backticks để cho biết sự khác biệt giữa một chuỗi bình thường trong Stax ) và cuối cùng là üvìë! [qJu ← α để nén / giảm 18 byte, hơn một nửa.

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.