Mã hóa - Ngẫu nhiên - Giải mã


23

Thử thách

Nhiệm vụ của bạn là mã hóa một số nguyên dưới dạng một chuỗi các ký tự ASCII , sau đó giải mã thành công sau khi chuỗi đã được xáo trộn ngẫu nhiên.

Bạn sẽ viết hai chương trình / chức năng , sẽ được gọi là Bộ mã hóaBộ giải mã .

Mã hoá

  • Đầu vào: một số nguyên trong phạm vi .n[0,2311]
  • Output: một chuỗi của ASCII ký tự (không nhất thiết phải in).s

Bộ giải mã

  • Dữ liệu vào: một hoán vị ngẫu nhiên của chuỗi .ss
  • Đầu ra: số nguyên .n

Chấm điểm

Đặt là độ dài tối đa của trên tất cả các giá trị có thể có của . Nếu Bộ mã hóa hoạt động không xác định (được phép, xem bên dưới), thì sẽ là độ dài tối đa của có thể xảy ra (có thể là \ infty ).AsnAs

Đặt LEchiều dài của Bộ mã hóa theo byte và LDchiều dài của Bộ giải mã tính bằng byte.

Sau đó, điểm của bạn là A(LE+LD) .

Chiến thắng được trao cho trình nộp điểm thấp nhất .

Thời gian giới hạn

giới hạn thời gian tùy ý là 1 phút đối với thời gian thực hiện của cả Bộ mã hóaBộ giải mã cho một mẫu thử nghiệm (nghĩa là một giá trị duy nhất là ).n

Mục đích là để tránh giải pháp tìm ra rằng vũ phu mã hóa bằng cách liệt kê tất cả các chuỗi với các thuộc tính nhất định. Nếu giải pháp của bạn làm điều gì đó thông minh hơn thế, rất có thể nó sẽ phù hợp với giới hạn thời gian và sẽ được coi là hợp lệ. Tương tự, nếu nó hoạt động trên TIO đối với một số giá trị được chọn ngẫu nhiên của thì nó sẽ được coi là hợp lệ. Nếu không, tôi sẽ kiểm tra nó trên máy của mình, nhưng lưu ý rằng nếu giải pháp của bạn là vũ lực thuần túy thì gần như chắc chắn sẽ thất bại.n

Quy tắc

  • Bộ mã hóaBộ giải mã phải được viết bằng cùng một ngôn ngữ .
  • Bộ giải mã phải xuất ra số nguyên chính xác cho mọi hoán vị có thể của chuỗi trả về bởi Bộ mã hóa .nss
  • Các bộ mã hóagiải mã được không được phép chia sẻ thông tin trong bất kỳ cách nào (ví dụ bằng cách biến toàn cục hoặc các tập tin).
  • Đầu ra của bộ mã hóa cần không được xác định (có nghĩa là, cùng một đầu vào có thể tạo ra các chuỗi khác nhau nếu mã hóa được chạy nhiều lần), nhưng Decoder phải luôn luôn đoán nguyên đúng .nn
  • Bộ mã hóaBộ giải mã có thể lấy và trả về số nguyên theo bất kỳ cách thuận tiện nào (ví dụ: nếu thì đầu vào là tốt , hoặc ).nn=1414"14"[1,4]
  • Bộ mã hóa có thể xuất chuỗi bằng cách in trên hoặc bằng cách trả về chuỗi, danh sách / mảng ký tự hoặc danh sách / mảng số nguyên trong phạm vi ; lưu ý rằng Decoder sẽ nhận như là đầu vào một hoán vị của như được trả về bởi các mã hóa , vì vậy nó nên chấp nhận chuỗi trong định dạng tương tự như .sstdout [0,127]sss
  • Sơ hở tiêu chuẩn bị cấm.
  • Nếu có thể, hãy giải thích cách mã của bạn hoạt động và tại sao điểm bạn yêu cầu là chính xác.

Thí dụ

Giả sử .n=14

  • Bộ mã hóa nhận 14làm đầu vào. Nó có thể đầu ra "qwerty".
  • Bộ giải mã nhận được một hoán vị "qwerty"là đầu vào, ví dụ "tweyqr". Nó phải xuất ra 14(ở bất kỳ định dạng thuận tiện).

Bộ mã hóa cũng có thể đã trở lại [113,119,101,114,116,121], trong trường hợp đó Bộ giải mã sẽ nhận được (ví dụ) [116,119,101,121,113,114].

Lưu ý rằng chuỗi được trả về bởi Bộ mã hóa cũng có thể bao gồm các ký tự ASCII không in được (nhưng luôn nằm trong phạm vi [0x00, ..., 0x7F]).


Chắc chắn độ dài đầu ra không thể là vô hạn, bạn không thể xáo trộn một chuỗi vô hạn
H.PWiz

@ H.PWiz Không thể, nhưng chiều dài có thể không bị ràng buộc nếu Bộ mã hóa không xác định
Delfad0r

"Bộ mã hóa và Bộ giải mã không được phép chia sẻ thông tin theo bất kỳ cách nào" Điều này có bao gồm các chức năng của trình trợ giúp không? tức là Hàm tùy chỉnh tính N nhân tử cộng với ba (ví dụ ngẫu nhiên)
pizzapants184

Encoder của chúng tôi có thể trả về một chuỗi / danh sách trống không?
pizzapants184

2
@Kroppeb Có, tính đến thời điểm hiện tại, các quy tắc nói rằng bạn nên đếm byte hai lần. Mặc dù vậy, tôi rất thích xem một bài nộp với hai chương trình giống hệt nhau.
Delfad0r

Câu trả lời:


12

Jelly , (17 byte + 18 byte) × dài 6 = 210 điểm

b36 NGỤN + × 3 MạnhŒ¿b3U +
Ṣ: 3_J
% 3Uḅ3œ? Çḅ36

Hãy thử trực tuyến! (hoặc có thêm thông tin gỡ lỗi)

Đã từng đi giải quyết thử thách này nhằm vào điều kiện chiến thắng đã nêu, tôi nghĩ sẽ rất thú vị khi đi đến một điều kiện chiến thắng thay thế giả định: đưa ra độ dài tối đa có thể cho đầu ra.

Giải trình

Mã hóa

Bước đầu tiên trong mã hóa là biểu diễn đầu vào là cơ sở 36 ( b36). 36 6 = 2176782336> 2147483647, do đó, sẽ có tối đa 6 chữ số trong kết quả, mỗi chữ số nằm trong phạm vi 0 Lỗi35.

Tiếp theo, chúng tôi chuyển đổi này thành một đại diện có chứa 6 chữ số khác nhau . Có nhiều thuật toán có thể cho việc này, nhưng thuật toán được sử dụng ở đây là thêm 1 vào chữ số nhỏ nhất, 2 đến nhỏ nhất thứ hai, 3 đến nhỏ nhất thứ ba, v.v. Điều này có nghĩa là nếu hai chữ số giống nhau, một trong số chúng sẽ được coi là nhỏ hơn tùy ý, và do đó chúng sẽ trở nên khác nhau; và rõ ràng, thuật toán này không thể khiến hai chữ số khác nhau trở nên giống nhau. Để thể hiện điều này trong Jelly, chúng tôi sử dụng ("sắp xếp các chỉ mục theo các giá trị") để có được một danh sách các chỉ mục theo thứ tự được sắp xếp; một lần nữa để đảo ngược điều đó, ánh xạ hiệu quả từng phần tử của bản gốc vào vị trí của nó theo thứ tự được sắp xếp; v൅+để thêm bản gốc vào danh sách mới. Kết quả là một đại diện của số đầu vào là sáu chữ số khác nhau trong phạm vi 11441 (tối thiểu 0 + 1, tối đa 35 + 6).

Sau đó chúng tôi chia tay này vào nhưng hình thức khác: a sắp xếp danh sách các chữ số trong phạm vi 1-41, cùng với một số từ 1 đến 720 đại diện nào trong số 720 hoán vị có thể các chữ số là trong (The. Œ¿trích xuất số hoán vị và sắp xếp danh sách tương ứng.)

Cuối cùng, chúng tôi chuyển đổi số từ 1 thành 720 thành cơ sở 3 ( b3), đảo ngược nó ( U) và mã hóa sáu chữ số cơ bản 3 và sáu chữ số 14141 thông qua việc đóng gói chúng thành một ký tự ASCII duy nhất bằng cách sử dụng divmod ngược (giá trị của ký tự mod 3 là 3 chữ số cơ sở, giá trị chia cho 3 là 1 chữ số41). Phạm vi kết quả có thể là tối thiểu (1 × 3) + 0 = 3 và (41 × 3) + 2 = 125 tối đa, phù hợp với phạm vi ASCII của chúng tôi. Việc đóng gói được thực hiện thông qua ×3+, cùng với một bổ sung µđể đảm bảo rằng mọi lệnh hoạt động trên đúng bit dữ liệu. (Có một chút mẹo chơi gôn ở đây, trong đó chúng tôi thực hiện phép nhân với 3 trước khi trích xuất hoán vị; giúp tiết kiệm nhu cầu chi tiêu một byte cho một nhân vật nhóm.)

Ngẫu nhiên, lý do để đảo ngược số 3 cơ sở là vì nó có thể có ít chữ số hơn số 14141. (Không thể có nhiều hơn; số nhỏ nhất mà n !> 3 n cao hơn một chút 6.) Jelly chèn các số 0 ở cuối một cách hiệu quả khi cộng hai số có độ dài khác nhau, để làm cho chúng khớp với nhau; các số 0 ở cuối sẽ ảnh hưởng đến việc giải thích số, nhưng các số 0 đứng đầu sẽ không, do đó, việc đảo ngược được sử dụng để đảm bảo rằng các số 0 bổ sung kết thúc ở đâu đó sẽ không làm hỏng câu trả lời của chúng tôi.

Giải mã

Bước đầu tiên trong quá trình giải mã là trích xuất hai số (số 3 cơ sở và số 14141). Chúng ta có thể nhận được các chữ số của chúng đủ dễ dàng với phép chia ( :3) và modulo ( %3), nhưng làm thế nào để biết chúng theo thứ tự nào? Chà, số 14141 có các chữ số theo thứ tự được sắp xếp và các chữ số ở vị trí tương ứng của hai số được lưu trong cùng một ký tự; do đó, chúng ta có thể tìm ra thứ tự các chữ số của 1 số41 được xáo trộn (bằng cách nhìn vào các giá trị tương đối của chúng) và biết rằng các chữ số của số 3 cơ sở phải được xáo trộn theo cùng một cách. Trên thực tế, bởi vì các ký tự mã hóa ASCII của chúng tôi sắp xếp giống như các chữ số của 1 số41 (tất cả đều khác biệt và chúng quan trọng hơn số 3 số cơ sở),. Vì vậy, cả hai trích xuất bắt đầu với , tiếp theo %3hoặc :3khi thích hợp.

Trong khi các chữ số của 1 số41 vẫn theo thứ tự được sắp xếp, chúng tôi có một cách rất thuận tiện / ngắn gọn để quay lại 0 chữ số35 của cơ sở 36; chỉ trừ 1 từ thứ nhất, 2 từ thứ hai, 3 từ thứ ba, v.v. Trong Jelly, chúng ta có thể làm điều đó với _J("trừ chỉ số").

Trong khi đó, ở nhánh khác của giải mã, chúng tôi đảo ngược các chữ số của số 3 cơ sở trở lại thứ tự ( U) và chuyển đổi nó từ cơ sở 3 trở lại thành một chỉ số hoán vị với ḅ3.

Sau đó chúng ta có thể kết hợp hai nhánh với œ?Ç; œ?có nghĩa là "hoán vị cho chỉ số hoán vị này" và Çcó nghĩa là "kết quả của việc áp dụng dòng trên", nghĩa là điều gì sẽ cho Jelly chạy cả hai dòng trên cùng một đầu vào.

Những gì chúng ta có bây giờ là các chữ số của số gốc, trong cơ sở 36 (do _J) và theo thứ tự ban đầu (do œ?), vì vậy chúng ta chỉ cần thực hiện một ḅ36chuyển đổi trở lại từ cơ sở 36 thành một số nguyên duy nhất.

Bình luận

TIO! liên kết ở trên sử dụng 312699167 làm số để mã hóa. Con số này trong cơ sở 36 là [5, 6, 6, 8, 7, 35], và do đó thể hiện tất cả các khía cạnh của mã hóa: 35 kiểm tra giới hạn của phạm vi 0 Hồi127 mà chúng ta có; 6s trùng lặp kiểm tra độ phân giải của các chữ số giống hệt nhau trong cơ sở 36 ban đầu; và thực tế là các chữ số gần như (nhưng không hoàn toàn) được sắp xếp có nghĩa là số hoán vị rất nhỏ, cho nó nhiều chữ số hơn số 36 cơ sở, và do đó cho thấy cần phải đảo ngược nó trước khi thêm nó vào ban đầu.

Thật tiện lợi khi tất cả các hằng số ở đây khớp với nhau. 36 6 chỉ chỉ đủ cao để phù hợp với 2 31 , 3 6 chỉ chỉ đủ cao để phù hợp với 6 !, và (36 + 6) x 3 là chỉ chỉ đủ cao để phù hợp trong số 128 khả năng chúng ta có. (Ràng buộc cuối cùng ở đây là ít chặt chẽ nhất, bởi vì chúng ta có thể sử dụng lập chỉ mục 0 thay vì chỉ mục 1 để sử dụng các ký tự trong phạm vi 0-2. Tuy nhiên, điều đó chỉ đủ để sử dụng 37 làm cơ sở thay vì hơn 36.)


9

Jelly , ( 4 3 byte + 6 5 byte) × dài 8 = 80 64 điểm

b⁴Ä
ṢŻIḅ⁴

Hãy thử trực tuyến!

Jelly , ( 2 1 byte + 4 3 byte) × dài 10 = 60 40 điểm

Ä
ṢŻTôi

Hãy thử trực tuyến!

Giải trình

Giải pháp 1

Đây là sử dụng một thuật toán khác với hầu hết các câu trả lời khác. Chúng tôi bắt đầu bằng cách mã hóa giá trị theo hệ thập lục phân ( b⁴), như với các câu trả lời khác, sau đó lấy tổng cộng ( Ä). Mỗi đầu vào rõ ràng sẽ cung cấp một đầu ra khác nhau (vì cả hai thao tác này đều có thể đảo ngược) và cho rằng mã hóa thập lục phân sẽ chứa tối đa 8 chữ số có tối đa là 7 (đối với chữ số thứ 8 cuối cùng) và 15 (cho chữ số cuối cùng đến thứ 7- chữ số cuối cùng), số lượng tối đa trong danh sách đầu ra sẽ là 7+ (7 × 15) = 112, nhỏ hơn 127 yêu cầu của câu hỏi. Ngoài ra, đầu ra nhất thiết phải theo thứ tự được sắp xếp, cho phép chúng tôi đảo ngược việc xáo trộn.

Đối với bộ giải mã, trước tiên chúng ta đảo ngược shuffle bằng sort ( ); sau đó đảo ngược tổng tích lũy, bằng cách thêm vào số 0 ( Ż) và lấy chênh lệch của các cặp liên tiếp ( I); sau đó chuyển đổi trở lại từ thập lục phân ( ḅ⁴).

Giải pháp 2

Câu hỏi thực sự cho phép chúng ta lấy đầu vào làm danh sách các chữ số (có lẽ là số thập phân), vì vậy chúng ta có thể "gian lận" bằng cách xóa chuyển đổi cơ sở; số lượng tối đa được sử dụng trong đầu ra sau đó sẽ là 2 + (9 × 9) = 83 (thực tế là 82 vì 2999999999 nằm ngoài phạm vi, do đó, đầu vào tồi tệ nhất có thể là 1999999999). Việc mã hóa kết quả là khá khủng khiếp khi mã hóa cho vấn đề này xảy ra, nhưng nó có lợi thế là rất ngắn gọn để tạo ra, vượt xa mức độ chi tiết của mã hóa.

Câu trả lời này cảm thấy giống như gian lận đến nỗi nó không phải là giải pháp chính của tôi cho vấn đề này, nhưng có vẻ như nó đáng để thêm vào vì về mặt kỹ thuật tuân thủ các quy tắc và tạo ra điểm số cao hơn.

Bình luận

Tôi có một số thuật toán để đạt được độ dài dưới 8, nhưng có vẻ như bạn không thể thực hiện thuật toán độ dài 7 ở byte9 byte (không gian lận) hoặc byte5 byte (gian lận), do đó, bằng cách ghi điểm trong câu hỏi, điều này có khả năng là cách tốt nhất để làm điều đó. (Tuy nhiên, tôi có thể có một giải pháp cho thử thách thay thế "tối thiểu hóa độ dài của mã hóa", dù chỉ để cho vui.)

Không giống như một số giải pháp, việc sử dụng 16 làm cơ sở ở đây không quan trọng; có rất nhiều số khác sẽ hoạt động cho một giải pháp dài 8 (ví dụ 18). Tôi đã chọn 16 cho giải pháp đầu tiên đơn giản vì Jelly có cách 1 byte để thể hiện điều đó và các cơ sở khả thi khác sẽ cần sử dụng nhiều byte từ chương trình. Tất nhiên, giải pháp thứ hai cần sử dụng 10 làm cơ sở để khai thác lỗ hổng.

Cảm ơn @Dennis đã chỉ ra một số lệnh Jelly mới hơn khiến thuật toán này thậm chí còn khó viết hơn.


3
Älà chữ viết tắt +\, Żlà chữ viết tắt 0;.
Dennis

7

Ngôn ngữ lập trình Shakespeare , 10 * (264 + 494) = 8650 7910 7580

Bộ mã hóa: 264 byte

,.Ajax,.Ford,.Act I:.Scene I:.[Exeunt][Enter Ajax and Ford]Ajax:Open mind.Be you nicer zero?You be the sum ofyou the product ofthe sum ofI a big big pig the sum ofa big big big big cat a big big pig.If soSpeak thy.Ford:You are the sum ofyou a cat.If soLet usAct I.

Hãy thử trực tuyến!

Bộ giải mã: 494

,.Ajax,.Ford,.Page,.Act I:.Scene I:.[Exeunt][Enter Ajax and Ford]Ajax:Open mind.Is you nicer a pig?If soRemember you.If soLet usAct I.Scene V:.Ford:Remember I.Ajax:Recall.Is you worse the sum ofPage twice the sum ofa big big cat a cat?If soYou be the difference betweenyou Page.If soOpen heart.If notlet usScene V.Scene X:.Ford:Recall.Ajax:Be I nicer zero?If soRemember I.If soLet usScene X.[Exit Ajax][Enter Page]Ford:You be the sum ofyou twice twice the sum ofa big big cat a pig.Let usAct I.

Hãy thử trực tuyến!

Đây là một điều.

Bộ mã hóa mã hóa mỗi chữ số là chữ số cộng với chỉ số của chữ số nhân mười hai lần. Bộ giải mã lưu trữ tất cả các đầu vào trong bộ nhớ của Ford và sau đó lặp qua một bộ đếm, xuất ra sau đó xóa từng chữ số thấp hơn bộ đếm * 12 + 10.

Giải trình:

Mã hoá

,.Ajax,.Ford,.Act I:.Scene I:.      Boilerplate introducing the two characters
[Exeunt][Enter Ajax and Ford]       Enter the two characters Ajax and Ford
                                    Ford will be handling the input
                                    Ajax will be the counter
Ajax:Open mind.                     Set Ford to the next character of input
Be you nicer zero?                  Check if it is EOF
You be the sum of                   Set Ford to the sum of 
    you                             His original value (48 to 58)
    the product of                 
          the sum of               
              I                     Ajax's value
              a big big pig         Minus 4 (this handles the offset of 48)
          the sum of                Multiplied by
              a big big big big cat 2^4
              a big big pig.        + -2^2 = 12
                                    This essentially sets Ford to (F+12*(A-4))
If soSpeak thy.                      If not EOF, print Ford's value
Ford:You are the sum ofyou a cat.   Increment Ajax's value
If soLet usAct I.                   If not EOF, Repeat again.

Bộ giải mã

,.Ajax,.Ford,.Page,.Act I:.Scene I:.  Boilerplate introducing three characters
                                      Ajax is the spare stack
                                      Ford is the storage stack
                                      Puck is the counter, increasing by 12
[Exeunt][Enter Ajax and Ford]            Enter Ajax and Ford onto the stage
Ajax:Open mind.                          Get the next character of input
Is you nicer a pig?                      If not EOF
If soRemember you.                         Store the value in Ford's memory
If soLet usAct I.                          And repeat the loop
Scene V:.                                Otherwise move to the next scene
Ford:Remember I.                         Store Ford's value (initially -1 from EOF) in Ajax's memory
Ajax:Recall.                             Get the next value from Ford's memory
Is you worse the sum of                  Is the value smaller than
        Puck                                  Puck's value
        twice the sum ofa big big cat a cat?  + 10 ?
                                              i.e. is it the next digit?
If soYou be the difference betweenyou Puck.   If so, subtract Puck's value from Ford
If soOpen heart.                              And print Ford's value
If notlet usScene V.                     If that was not the digit, repeat
Scene X:.
Ford:Recall.                             Get the next value from Ajax's memory
Ajax:Be I nicer zero?                    Until the -1
If soRemember I.                         Returning the values to Ford's memory
If soLet us Scene X.                     Repeat until Ajax's memory is exhausted
[Exit Ajax][Enter Page]                  Swap Ajax and Page
Ford:You be the sum of                   Set Puck's value to
              you                        Puck +   
              twice twice the sum of     2*2*(
                           a big big cat      4
                           a pig.             -1) = 12
Let usAct I.                             And start from the beginning again, having removed one number

5

Trăn 2.7, 31 * (52 + 37) = 2759

Bộ mã hóa ( 69 52 byte):

lambda n:[chr(i)if n&(1<<i)else""for i in range(32)]

Bộ giải mã ( 41 37 byte):

lambda s:sum([1<<(ord(c))for c in s])

Lưu trữ tất cả các bit khác không trong số đầu vào dưới dạng giá trị ascii. Giá trị của ký tự ascii lưu trữ vị trí của bit set. Ví dụ: giá trị 'a' có nghĩa là bit thứ 97 được đặt.

Một vài cải tiến, nhờ @ Delfad0r

Hãy thử trực tuyến!


Chào mừng đến với PPGC! Bạn có thể bỏ e = d = ngay từ đầu - các hàm ẩn danh là hoàn toàn tốt. Ngoài ra, lưu ý rằng báo cáo sự cố nói rõ rằng Bộ mã hóa có thể trả về danh sách các số nguyên thay vì các ký tự, vì vậy bạn có thể tránh số nguyên chuyển đổi-> ký tự-> số nguyên. Hơn nữa, bạn có thể sử dụng n&(1<<i)thay vì n&(1<<i)>0và lưu 2 byte. Cuối cùng, giới hạn trên cho i(127) là quá nhiều, 32 là đủ và tiết kiệm 1 byte.
Delfad0r

1
Vui lòng cho biết điểm của bạn theo phần Ghi điểm trong báo cáo vấn đề.
Delfad0r

@ Delfad0r Việc ghi điểm có đúng không? Và cảm ơn vì lời khuyên.
Hein Wessels

Tôi nghĩ rằng điểm số là (52+37)*31=2759vì dài nhất là khi tất cả 31 bit được đặt.
Jonathan Allan

Bộ mã hóa có thể lambda n:[chr(i)*(n&1<<i>0)for i in range(32)]lưu 6 byte.
mypetlion

5

Stax , điểm 8 × (10 + 9) = 152

Bộ mã hóa, 10 byte

Ç·MÉJ'♀τ│½

Chạy và gỡ lỗi nó

16|E{i16*+m Full program, implicit input
16|E        Get hexadecimal digits
    {     m Map:
     i16*+    Add 16 * loop index
            Implicit output as string

Bộ mã hóa xuất chuỗi theo thứ tự tăng dần.

Bộ giải mã, 9 byte

üL∟n╫k∞‼9

Chạy và gỡ lỗi nó

o{16%m16|E Full program, implicit input
o          Sort string
 {16%m     Module each element by 16
      16|E Interpret as array of hex digits


5

Trăn 3 , 8 * (45 + 38) = 664

Bộ mã hóa (45 byte):

lambda n:[16*i+(n>>4*i)%16 for i in range(8)]

Bộ giải mã (38 byte):

lambda l:sum(x%16<<x//16*4 for x in l)

Hãy thử trực tuyến!


1
Bạn có thể xóa các khoảng trắng trước khi "cho", lambda l:sum(x%16<<x//16*4for x in l)hoạt động tốt :)
FatalError

4
Điều này không hoạt động. Đầu ra không phải là ASCII đơn giản (trong phạm vi 0..127)
GB

2
@GB lỗi của tôi. Tôi đã phá vỡ nó với chỉnh sửa cuối cùng của tôi. Hoàn nguyên ngay bây giờ
Curtis Bechtel

lưu 3 byte trong bộ mã hóa: lambda n:[n>>4*i&15|i<<4for i in range(8)]và 1 trong bộ giải mã: lambda l:sum(x%16<<x//16*4for x in l)với tổng số điểm là 632
Aaron

4

JavaScript (ES6), 8 * (40 + 32) = 576

0số 8

Bộ mã hóa (40 byte)

E=(n,k=0)=>n?[k|n&15,...E(n>>4,k+16)]:[]

Bộ giải mã (32 byte)

s=>s.map(c=>s|=c%16<<(c/4&~3))|s

Bản giới thiệu

Hãy thử trực tuyến!

Làm sao?

Đầu vào được chia thành 8 khối 4 bit và mỗi khối được mã hóa với 1 trong số 16 ký tự có thể. Bit quan trọng nhất của khối cuối cùng không bao giờ được đặt.

       3222222222211111111110000000000
bit:   0987654321098765432109876543210
       \_/\__/\__/\__/\__/\__/\__/\__/
block:  7  6   5   4   3   2   1   0

block #0 is encoded with char. 00 to 0F (NUL to SI)
block #1 is encoded with char. 10 to 1F (DLE to ES)
block #2 is encoded with char. 20 to 2F (' ' to '/')
block #3 is encoded with char. 30 to 3F ('0' to '?')
block #4 is encoded with char. 40 to 4F ('@' to 'O')
block #5 is encoded with char. 50 to 5F ('P' to '_')
block #6 is encoded with char. 60 to 6F ('`' to 'o')
block #7 is encoded with char. 70 to 77 ('p' to 'w')

4

Jelly , (8 + 9) byte * 8 chiều dài tối đa = 136

b⁴+J’Ɗ⁴¡

Bộ mã hóa (chân trang định dạng danh sách như Python sẽ rõ ràng)

Ṣ_J‘Ɗ⁴¡ḅ⁴

Bộ giải mã

Về mặt lý thuyết có thể có độ dài tối đa là sáu, điều đó có thể được thực hiện trong 22 byte hoặc ít hơn không?

Σtôi= =0tôi= =5(127+tôi127)= =321402081<231-1

Làm sao?

231-17fffffff[7,15,15,15,15,15,15,15][7,15,15,15,15,15,15,15] + [0,16,32,48,64,80,96,112] = [7,31,47,63,79,95,111,127]

Bộ mã hóa :

b⁴+J’Ɗ⁴¡ - Link: integer, n    e.g. 1234
 ⁴       - literal 16               16          
b        - convert to base          [4,13,2]
       ¡ - repeat...
      ⁴  - ...16 times:
     Ɗ   -   last 3 links as a monad:
   J     -     range of length        [1,2,3]     iter 2    iter 3    ...  iter 16
  +      -     add                    [5,15,5]   [5,16,7]   [5,17,9]  ...  [5,30,35]
    ’    -     decrement              [4,14,4]   [4,15,6]   [4,16,8]  ...  [4,29,34]
         -                                                                 [4,29,34]

Bộ giải mã :

Ṣ_J‘Ɗ⁴¡ḅ⁴ - Link: list of integers   e.g. [29,34,4]
Ṣ         - sort                          [4,29,34]
      ¡   - repeat...
     ⁴    - ...16 times:
    Ɗ     -   last 3 links as a monad:
  J       -     range of length           [1,2,3]
 _        -     subtract                  [3,27,31]   [3,26,29]   [3,25,27]  ...  [3,12,1]
   ‘      -     increment                 [4,28,32]   [4,27,30]   [4,26,28]  ...  [4,13,2] 
        ⁴ - literal 16                    16
       ḅ  - from base                     1234

"chữ số thập lục phân", chắc chắn. ("Các chữ số sử dụng thập lục phân đơn giản" dài hơn và riêng "chữ số" ngụ ý thập phân.)
Erik the Outgolfer

Tôi đã thay đổi nó ngay cả khi nó rõ ràng từ ngữ cảnh khi tôi ngay lập tức đề cập đến các chữ số hex.
Jonathan Allan

Tính toán của bạn bị tắt bởi một: có 321402081 kết hợp thay thế với độ dài tối đa là 5 và 7177979809 với độ dài tối đa là 6.
Anders Kaseorg

@AndersKaseorg rất tiếc, vì vậy nó có thể với độ dài tối đa là 6 ... cho 22 byte để chơi!
Jonathan Allan

4

Ngôn ngữ lập trình Shakespeare , 31 * (472 + 383 379 344) = 26505 26381 25296

Điểm trước: 16909322 * (246 + 217) = 7829016086

Điều này vẫn còn rất cao, nhưng nó là mức thấp nhất tôi có thể nghĩ đến ngay bây giờ.

Mã hoá:

,.Ajax,.Ford,.Act I:.Scene I:.[Enter Ajax and Ford]Ajax:Remember a pig.Ford:Listen tothy.Scene V:.Ajax:Remember the remainder of the quotient betweenI a big cat.Ford:You be the quotient betweenyou a big cat.Be you nicer zero?If solet usScene V.Remember a pig.Scene X:.Ajax:Recall.Ford:Am I worse zero?If notremember I.If notlet usScene X.Ajax:You zero.Scene L:.Ford:Recall.Ajax:You be the sum ofyou a cat.Am I nicer zero?If sospeak thy.Am I worse zero?If notlet usScene L.

Hãy thử trực tuyến!

Bộ giải mã:

,.Ajax,.Ford,.Page,.Act I:.Scene I:.[Exeunt][Enter Ajax and Ford]Ajax:You cat.Ford:Open mind.Remember the sum ofyou I.Scene V:.Ajax:Am I nicer a cat?If soyou be twice you.Ford:If soyou be the sum ofyou a pig.If solet usScene V.[Exit Ford][Enter Page]Page:Recall.Ajax:Am I worse a cat?If notyou be the sum ofyou Ford.If notlet usAct I.Open heart

Hãy thử trực tuyến!

Về cơ bản, nếu chuỗi chứa một ký tự có mã ASCII (n + 1), chữ số nhị phân thứ n được đặt.


344 byte cho bộ giải mã
Jo King

3

Python 3, (208 byte + 200 byte) * 6 length = 2448

Hãy thử trực tuyến! (chứa cả hai, byte bổ sung là dòng mới giữa chúng).

-4 byte (-24 điểm) bằng cách sử dụng danh sách trống (cho phép nhiều thứ hơn bắt đầu từ 0)

Bộ mã hóa (208 byte)

def E(n,h=128):
    T=lambda n,d:n*T(n+1,d-1)//d if d>1else d and n or 1
    d=l=0
    s=[]
    while n>=T(h,d):
        n-=T(h,d)
        d+=1
    for i in range(d):
        while n>=T(h-l,d+~i):
            n-=T(h-l,d+~i)
            l+=1
        s+=[l]
    return s

Bộ giải mã (200 byte)

def D(s):
    T=lambda n,d:n*T(n+1,d-1)//d if d>1else d and n or 1
    s.sort()
    l=0
    d=len(s)
    n=sum(T(128,D)for D in range(d))
    for i in s:
        for j in range(l,i):
            n+=T(128-j,d-1)
        l=i
        d-=1
    return n

Quan sát:

  • Xáo trộn có thể được đảo ngược một cách dễ dàng cho các danh sách hoàn toàn không tăng (tức là được sắp xếp).

  • Các danh sách số không tăng hoàn toàn có cùng độ dài hoàn toàn có thể được sắp xếp theo thứ tự (như chúng có trong Python).

  • Chúng tôi có thể xác định rằng danh sách được sắp xếp theo độ dài trước để tạo thành tổng thứ tự của tất cả các danh sách được sắp xếp.

  • Chúng ta có thể tạo thành một chuỗi lập chỉ mục của các danh sách này nếu chúng ta xác định rằng các giá trị chỉ có giá trị trong một danh sách là các số nguyên từ 0để 127bao gồm (tức là có tồn tại một số hữu hạn các danh sách hợp lệ với chiều dài L).

Chiến lược:

  • Bộ mã hóa: Cho một số N, tìm Ndanh sách không tăng hợp lệ.

  • Bộ giải mã: Đưa ra một danh sách hợp lệ (xáo trộn), sắp xếp nó và trả về chỉ mục của nó trong chuỗi các danh sách hợp lệ.

Giải thích mã phổ biến:

  • T=lambda n,d:n*T(n+1,d-1)//d if d>1else d and n or 1

  • Tính số nth- dfaxplex

    • Cho d=0, luôn luôn1

    • For d=1, n(số lượng chấm trong một dòng các chấm có độ dài n)

    • d=2Σtôi= =1ntôin

    • d=3Σj= =1nΣtôi= =1jtôin

Giải thích về bộ mã hóa:

  • def E(n,h=128): d=l=0, s=[]

  • nlà số đầu vào, hlà "giá trị cao" (nghĩa là số cao nhất được phép + 1), dlà độ dài đầu ra sẽ là, slà đầu ra, llà "giá trị thấp" (bắt đầu từ 0, được giải thích thêm sau)

  • while n>=T(h,d):, n-=T(h,d),d+=1

  • Có các danh sách độ T(h,d)dài hợp lệ dvà việc tính toán của chúng tôi sẽ dễ dàng hơn nếu nchỉ mục liên quan đến danh sách [0]*d(tại chỉ mục 0) thay vì chỉ mục thực tế, do đó, giảm dần ntheo. Điều này cũng điều chỉnh d(độ dài) là chính xác cho trước n.

  • for i in range(d):

  • Hiệu quả: "cho i+1số thứ trong danh sách"

    • Đây là nơi tôi sẽ giải thích l, "giá trị thấp"

    • Sau khi một số đã được đưa vào danh sách, không có số nào nhỏ hơn số đó có thể được đưa vào danh sách (để giữ cho nó được sắp xếp), đó llà số cuối cùng được thêm vào danh sách.

    • while n>=T(h-l,d+~i):, n-=T(h-l,d+~i),i+=1

    • Nếu nquá lớn để được mã hóa bằng l"chữ số" này, thì điều chỉnh cho nphù hợp và tăng dầnl

    • s+=[l]

    • Mã hóa nvới một l"chữ số" này.

    • Lúc đầu, chúng tôi có hcác tùy chọn cho "chữ số" nào để đặt tiếp theo, nhưng một khi chúng tôi đặt "chữ số" (được gán cho l), chúng tôi bị giới hạn ở h-lcác tùy chọn cho "chữ số" tiếp theo.

    • Lúc đầu, có T(h,d)các danh sách hợp lệ, nhưng chúng tôi đã thêm một "chữ số" l, giảm số "chữ số" còn lại d-1và số "chữ số" hợp lệ tiếp theo h-l, vì vậy số lượng danh sách hợp lệ sau này làT(h-l,d-1)

Giải thích về bộ giải mã:

  • def D(s):, s.sort(), l=0,d=len(s)

  • slà danh sách đầu vào (xáo trộn), vì vậy s.sort()nó; llà "giá trị thấp" ( h"giá trị cao" chỉ là chữ 128s trong mã để lưu byte), nlà số đầu ra, dlà độ dài.

  • n=sum(T(128,D)for D in range(d))

  • Điều chỉnh ntheo điểm trong chuỗi[0]*length

  • for i in s:

  • Đối với mỗi chữ số:

    • for j in range(l,i):, n+=T(128-j,d-1)

    • Điều chỉnh ntheo điểm trong chuỗi[...prevdigits, thisdigit, 0...]

      • l=i: Đặt "giá trị thấp" thành chữ số gần đây nhất

      • d-=1: Giảm độ dài kể từ khi chúng tôi sử dụng một chữ số

  • return n: Sau khi nđã được điều chỉnh cho tất cả các chữ số, đó là số đúng; trả lại.

Xin lỗi nếu điều này không rõ ràng, nhưng đây là phiên bản gỡ lỗi ban đầu của tôi Hãy thử trực tuyến! , không sử dụng danh sách trống, do đó, tắt 1 từ tất cả các số được sử dụng trong phiên bản này


3

Ruby , (36 + 29 byte) * 8, điểm 520

Mã hóa:

->n{(0..7).map{|x|(n>>x*=4)%16+x*4}}

Hãy thử trực tuyến!

Giải mã:

->a{a.sum{|x|x%16<<(x/4&28)}}

Hãy thử trực tuyến!

Làm thế nào nó hoạt động:

Số được mã hóa bằng các đoạn 4 bit và chỉ số 3 bit.

Bộ giải mã lấy mảng đầu vào và đặt mọi ngòi vào vị trí của nó một lần nữa.


3

Than , điểm 10 * (10 + 15) = 250.

Sử dụng thập phân; giải pháp dựa trên cơ sở 16 trước đó đã ghi được 328 296 264.

Có thể xuất ký tự không thể in. Cụ thể, ký tự 10 rất khó để nhập vào Than.

Bộ mã hóa, 10 byte:

⭆⮌S℅⁺Iι×χκ

Hãy thử trực tuyến! Liên kết là phiên bản dài dòng của mã.

Bộ giải mã, 15 byte:

IΣES×﹪℅ιχXχ÷℅ιχ

Hãy thử trực tuyến! Liên kết là phiên bản dài dòng của mã.

Phiên bản sử dụng danh sách các số nguyên 360 296 (cơ sở 16; số thập phân sẽ đạt 310):

Bộ mã hóa, 19 byte:

NθIE⁸⁺﹪÷θX¹⁶ι¹⁶×¹⁶ι

Hãy thử trực tuyến! Liên kết là phiên bản dài dòng của mã.

Bộ giải mã, 18 byte:

IΣEE⁸N×﹪ι¹⁶X¹⁶÷ι¹⁶

Hãy thử trực tuyến! Liên kết là phiên bản dài dòng của mã.

Phiên bản sử dụng các ký tự có thể in được điểm 360 (là 416 384 368 trong cơ sở 16):

Bộ mã hóa, 19 byte:

⭆⮌S℅⁺Iι×χ⁺κ×⁵⊕׳÷κ⁵

Hãy thử trực tuyến! Liên kết là phiên bản dài dòng của mã.

Bộ giải mã, 17 byte:

Fθ⊞υ⌈Φθ¬№υκ⭆υ﹪℅ιχ

Hãy thử trực tuyến! Liên kết là phiên bản dài dòng của mã.


2

Brachylog , 17 + 18 byte * 8 chiều dài = 280

Mã hoá:

ḃ₁₆I∧7⟧₁;Iz₁~ḃ₁₆ᵐ

Bộ giải mã:

ḃ₁₆I∧7⟧₁;Iz₁~ḃ₁₆ᵐp

Một p có thể được thêm vào cuối bộ mã hóa mà không có hiệu lực. Bộ giải mã được chạy bằng cách đặt kết quả (xáo trộn) làm đầu ra và lấy số gốc trong đầu vào.

Nếu có một vị ngữ tích lũy (được thực hiện đúng) thì điểm số có thể giảm xuống 20

Hãy thử trực tuyến!


@ Delfad0r thêm p vào bộ mã hóa sẽ làm cho nó trở thành cùng một mã để mã hóa và giải mã
Kroppeb

2

05AB1E , điểm: (2 + 2 byte ) * 11 chiều dài tối đa = 44

Bộ mã hóa (2 byte ):

Hãy thử trực tuyến.

Bộ giải mã (2 byte ):

Hãy thử trực tuyến.

Đầu vào của bộ mã hóa và đầu ra của bộ giải mã là một danh sách các chữ số.

Câu trả lời Jelly thứ 2 của @ ais523 .

Giải trình:

    # Undelta (automatically prepends a 0)
      #  i.e. [3,0,4,7,8,2,0,1,9] → [0,3,3,7,14,22,24,24,25,34]

{     # Sort
      #  i.e. [14,7,22,25,24,3,0,24,34,3] → [0,3,3,7,14,22,24,24,25,34]
 ¥    # Deltas
      #  i.e. [0,3,3,7,14,22,24,24,25,34] → [3,0,4,7,8,2,0,1,9]

Vì đặt trước 0 cho đầu ra, nên độ dài của đầu ra là độ dài của đầu vào + 1. Vì231-1 có độ dài 10 chữ số, độ dài tối đa của đầu ra là 11.


2

Gol> <> , 8 * (14 + 13) = 216

Bộ mã hóa Hãy thử trực tuyến! , 14 byte:

I8FfPSD8*L+o|;

Bộ giải mã Hãy thử trực tuyến! , 13 byte:

iEh8SD4*2$X*+

Vì điều này có thể xuất ra các ký tự ascii không thể in được, do đó gây rối cho bộ giải mã, giờ đây đã có một phiên bản sử dụng các số trong đầu ra / đầu vào:

Bộ mã hóa Hãy thử trực tuyến! , 14 byte:

I8FfPSD8*L+N|;

Bộ giải mã Hãy thử trực tuyến! , 13 byte:

IEh8SD4*2$X*+

Mã hóa:

Mã hóa hoạt động bằng cách chia số đã cho thành các khối 8 x 4 bit. Các khối này sau đó được dịch chuyển sang phải 3 bit và vị trí ban đầu của khối được gắn vào cuối là một số trong khoảng từ 0 đến 7. Do đó, mã hóa trông như thế này:

0AAAABBB
 |__|    -> the original part of the number
     |_| -> the position of the chunk inside the original number 0 = LSB and 7 = MSB

2

Perl 6 , 10 * (10 + 12) = 340 220

Mã hoá:

{^@_ Z~@_}

Bộ giải mã:

{.sort X%10}

Hãy thử trực tuyến!

Hàm mã hóa nén từng chữ số với chỉ số 0 của số. Sau đó, bộ mã hóa sắp xếp danh sách các số và lấy modulo bằng 10, nói cách khác là chữ số thứ hai của số.

Tổng cộng là 10, vì đó là độ dài tối đa 2 31 -1.


1

Haskell , 10 * (23 + 51) = 740

Đây là một chương trình mã hóa, xáo trộn, giải mã và xác nhận các giá trị: Hãy thử trực tuyến!

Bộ mã hóa, 23 byte

zipWith((+).(10*))[0..]

Hãy thử trực tuyến!

Bộ giải mã, 51 byte

map snd.sortOn fst.map(`divMod`10)
import Data.List

Hãy thử trực tuyến!

Giải trình

Vì chúng tôi được phép sử dụng đầu vào dưới dạng chữ số thập phân, nên chúng tôi sẽ sử dụng .. Bộ mã hóa ánh xạ từng chữ số xảy ra 10*index + digit, lưu ý rằng tất cả các chữ số digitsẽ ở trong [0..9]để chúng tôi có thể đảo ngược phần trên bằng cách sử dụng divMod. Sau khi khôi phục các chỉ số và các chữ số, vấn đề chỉ là sắp xếp theo các chỉ số và loại bỏ chúng.

Giải pháp dự kiến ​​sẽ hoạt động cho các giá trị lên đến 231-1= =2147483647 dài 10 chữ số, vì vậy điểm mã tối đa chúng tôi nhận được sẽ là 99= =81<128. Ngoài ra, mỗi chữ số sẽ được chuyển đổi thành "ký tự", vì vậy chúng tôi sẽ kết thúc với độ dài tối đa là 10.



1

APL (Dyalog Unicode) ,LE+LD= =36;Một= =số 8288.

d←{16n-16×⍳≢n←⍵[⍋⍵]}
e←(⊢+16×⍳∘≢)16⊥⍣¯1

Hãy thử trực tuyến! (chứa 5 byte bổ sung cho các bài tập và dòng mới).

Công dụng ⎕IO←0

Làm sao:

(⊢+16×⍳∘≢)16⊥⍣¯1  Encoder; input 1234
          16⊥⍣¯1  Convert input to base 16  4 13 2
      ⍳∘≢           [0..length of the list-1]  0 1 2
   16×              times 16  0 16 32
 ⊢+                 plus the original list  4 29 34

{16n-16×⍳≢n←⍵[⍋⍵]}  Decoder; input   34 4 29
              [⍋⍵]   Grade  up  2 0 1
                    Index  with that list  4 29 34
           n        assign that to n
      16×⍳≢          16×[0..length(n)-1]  0 16 32
    n-               subtract that from n  4 13 2
 16                 Decode from base 16  1234

1

PHP, 8 * (44 + 53) = 776

bộ mã hóa, 44 byte:

for(;$n=&$argn;$n>>=4)echo$n&15|16*$i++," ";

in không gian tách biệt danh sách các số nguyên. Chạy như ống với -nR.

tối đa 8 byte với 4 bit dữ liệu (nibble thấp hơn) và 3 bit trọng lượng (nibble trên).

Nói một cách đơn giản:
Đặt mỗi chữ số hex vào một ký tự riêng và sử dụng nửa trên của byte để lưu trữ vị trí chữ số.

thí dụ:

1457893891( 0x56e5b203) Sẽ biến thành
0x03, 0x10, 0x22, 0x3b, 0x45, 0x5e, 0x66, 0x75
3 16 34 59 69 94 102 117

bộ giải mã, 53 byte:

while($i++<8)$n+=(15&$x=$argv[$i])<<($x>>4)*4;echo$n;

hoặc là

while($i++<8)$n+=(15&$x=$argv[$i])<<($x/4&~3);echo$n;

hoặc là

for(;$i<9;$x=$argv[++$i])$n+=$x%16<<($x/4&~3);echo$n;

lấy số nguyên từ các đối số dòng lệnh. Chạy với -nr.


Hãy thử chúng trực tuyến .


0

Con trăn 2 , 10 * (68 + 54) = 1220

e=lambda n:"".join(chr(int(`i`+j))for i,j in enumerate(`n`)if j<'L')
d=lambda s:int("".join(`ord(c)%10`for c in sorted(s)))

Hãy thử trực tuyến!

EDIT: Cảm ơn Jo King vì những gợi ý - không chắc tại sao tôi lại bù đắp cho 32, khi nhìn lại.

Mã hóa vị trí và giá trị của mỗi nơi dưới dạng một ký tự, bắt đầu bằng [dấu cách] (vị trí 0, giá trị 0) byte NUL 0x0.

Giải mã bằng:

  • sắp xếp chuỗi (Python sẽ sắp xếp các ký tự theo giá trị thứ tự của chúng)
  • chuyển đổi mỗi ký tự thành giá trị thứ tự của nó
  • lấy chữ số cuối cùng của mỗi số nguyên
  • nối các số nguyên thành một chuỗi
  • chuyển đổi chuỗi tham gia trở lại thành một int

Bạn có cần sự 32bù đắp? Ngoài ra, [-1]có thể %10thay vào đó, ở đúng nơi
Jo King

0

C (gcc) , 10 * 112 = 1120

c,i;e(i,s)char*s;{for(c=1;i;c+=10,i/=10)*s++=c+i%10;*s=0;}
d(char*s){for(i=0;c=*s++;i+=--c%10*pow(10,c/10));s=i;}

Hãy thử trực tuyến!

Tôi có các biến toàn cục, nhưng chúng không thực sự chuyển bất kỳ thông tin nào giữa hai hàm. Khai báo biến cho cđược sử dụng trong cả hai hàm tiết kiệm cho tôi 2 byte chiều dài mã.

Một phiên bản chỉ sử dụng ASCII có thể in được cho hình phạt 3 5 byte có tại đây:

c,i;e(i,s)char*s;{for(c=32;i;c+=10,i/=10)*s++=c+i%10;*s=0;}
d(char*s){for(i=0;c=*s++;i+=(c-=32)%10*pow(10,c/10));s=i;}

Cảm ơn @ceilingcat đã cải thiện 70 điểm.

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.