Hãy giải mã con số này!


8

Thử thách này đặt ra một thuật toán để mã hóa một số nguyên ndưới dạng một số nguyên khác r. Điều gì sau đây là một lời giải thích ngắn gọn về thuật toán đó, sử dụng n=60làm ví dụ.

Thuật toán gốc

  • Đầu tiên, chúng tôi mã hóa số dưới dạng một chuỗi dấu ngoặc.

    • Nếu n = 1, trả về một chuỗi trống.
    • Mặt khác, chúng tôi thực hiện nphân tách nguyên tố được sắp xếp tăng dần và thay thế từng phần tử bằng chỉ mục chính của nó (được lập chỉ mục 1) trong ngoặc.60 = 2*2*3*5 => [1][1][2][3]
    • Làm điều này đệ quy cho đến khi tất cả chúng ta có dấu ngoặc. [1][1][2][3] => [][][[1]][[2]] => [][][[]][[[1]]] => [][][[]][[[]]]
  • Khi chúng tôi có chuỗi dấu ngoặc của mình, chúng tôi chuyển đổi nó thành một số nguyên với quy trình sau.

    • Chuyển đổi từng khung mở sang a 1và mỗi khung đóng thành a 0.[][][[]][[[]]] => 10101100111000
    • Hủy bỏ tất cả dấu vết 0và cuối cùng 1.10101100111000 => 1010110011
    • Chuyển đổi chuỗi cuối cùng của 0s và 1s từ nhị phân thành một số nguyên.1010110011 => 691

Giải mã mã hóa này

Một tính chất thú vị của thuật toán này là nó không phải là tính từ. Không phải mọi số nguyên có thể là kết quả của mã hóa này.

  • Thứ nhất, biểu diễn nhị phân của kết quả r, phải balance-ableở chỗ số 0s không bao giờ vượt quá số 1s. Một trường hợp thử nghiệm falsey ngắn là 4, đó là 100trong nhị phân.
  • Thứ hai, dấu ngoặc trong biểu diễn nhị phân phải là sorted ascendingkhi dấu cuối cùng 1và dấu cuối 0được nối thêm một lần nữa. Một trường hợp thử nghiệm falsey ngắn là 12 <= 1100 <= 110010 <= (())().

Tuy nhiên, chỉ cần xác định nếu một số có thể giải mã theo cách này sẽ tạo ra một thách thức ngắn. Thay vào đó, thách thức là liên tục giải mã một đầu vào nhất định cho đến khi đạt được số không thể giải mã hoặc đạt được chu kỳ và trả về chuỗi số kết quả .

Các thách thức

  • Cho một số 1 <= r <= 2**20 = 1048576, trả lại chuỗi các con sốr liên tiếp giải mã thành, bắt đầu với rbản thân và kết thúc với một số un-decode-thể hoặc một chu kỳ.
  • Nếu một số không thể giải mã được đưa ra làm đầu vào, chẳng hạn như 4hoặc 12, sẽ trả về một danh sách chỉ chứa đầu vào.
  • Một chuỗi kết thúc bằng một chu kỳ nên được chỉ ra một cách nào đó, hoặc bằng cách phụ thêm hoặc thêm vào trước một dấu hiệu (chọn bất kỳ số nguyên không tích cực, chuỗi, danh sách, vv như một dấu hiệu, nhưng giữ cho nó phù hợp), hoặc bằng cách lặp đi lặp lại chu kỳ trong một cách nào đó (lặp lại yếu tố đầu tiên, lặp lại toàn bộ chu kỳ, lặp lại vô hạn, v.v.).
  • Nếu bạn có bất kỳ chuỗi nào là vô hạn (chẳng hạn như tăng mãi mãi), hãy xem xét nó là hành vi không xác định.
  • Đây là mã golf. Số byte nhỏ nhất sẽ thắng.

Một ví dụ hoạt động của giải mã

   1 -> 1 -> 1100 -> [[]] -> [2] -> 3
-> 3 -> 11 -> 111000 -> [[[]]] -> [[2]] -> [3] -> 5
-> 5 -> 101 -> 101100 -> [][[]] -> 2*[2] -> 2*3 -> 6
-> 6 -> 110 -> 110100 -> [[][]] -> [2*2] -> [4] -> 7
-> 7 -> 111 -> 11110000 -> [[[[]]]] -> [[[2]]] -> [[3]] -> [5] -> 11
-> 11 -> 1011 -> 10111000 -> [][[[]]] -> 2*[[2]] -> 2*[3] -> 2*5 -> 10
-> 10 -> 1010 -> 101010 -> [][][] -> 2*2*2 -> 8
-> 8 -> 1000  ERROR: Unbalanced string

Các trường hợp thử nghiệm

4 -> [4]
12 -> [12]
1 -> [1, 3, 5, 6, 7, 11, 10, 8]
2 -> [2, 4]
13 -> [13, 13]    # cycle is repeated once
23 -> [23, 22, 14, 17]
51 -> [51, 15, 31, 127, 5381]
691 -> [691, 60]
126 -> [126, 1787, 90907]
1019 -> [1019, 506683, 359087867, 560390368728]

Đề xuất và phản hồi cho thách thức này được chào đón nhất. Chúc may mắn và chơi golf tốt!



Làm thế nào để 1cho 3?
Nữ tu rò rỉ

@LeakyNun 1- (nối các 1số 0 ở cuối) -> 1100-> [[]]-> [[1]]-> [2]->3
Colera Su

6-> 110-> 110100không hợp lệ, phải không? Vậy nên 1cho đầu vào [1,3,5,6]?
dyl Nam

Và cho 7: 7-> 111-> 11110000-> [[[[]]]]-> 4 số nguyên tố = 7? Có lẽ tôi không hiểu thuật toán
dylnan

Câu trả lời:


4

Python 3 , 379 358 339 337 327 310 304 byte

Phỏng đoán: Là 13số duy nhất sẽ dẫn đến một chu kỳ? (Không có ngoại lệ nhỏ hơn 10 6. )

Đã sửa lỗi và -7 byte nhờ Sherlock9 .
-3 byte nhờ Jonathan Frech .
-16 byte nhờ vào các lò nướng .
-6 byte nhờ ông Xcoder .

Nếu có một chu kỳ, nó sẽ lặp lại toàn bộ chu kỳ.

def p(a,x=0,n=1):
 while a:x+=1;a-=n%x;n*=x*x
 return x
def g(a):
 c=i=0
 for v in a:
  c+=int(v)*2-1
  if c<0:return 0,0
  if c<1:break
  i+=1
 if a:x=p(g(a[1:i])[0]);b,c=g(a[i+1:]);return(x>c>0)*(0,0)or(x*b,x)
 return 1,0
def f(a):
 x=a,
 while(x.count(a)<3)*a:a,t=g(bin(a-~a)[2:]);x+=a,
 return x[:-1]

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

Giải trình:

def p(a,x=0,n=1):     # return the a-th prime
 while a:             # magical way to enumerate primes
  x+=1
  a-=n%x
  n*=x*x
 return x

def g(a):             # decode a 0/1 string
 c=i=0
 for v in a:
  c+=int(v)*2-1       # +1 if 1, -1 if 0
  if c<0: return(0,0) # c<0: unbalanced parentheses
  if c<1: break       # first outermost parentheses
  i+=1
 if a:
   x=p(g(a[1:i])[0])  # recursive solve those inside the parentheses ...
   b,c=g(a[i+1:])     # and the remaining
   if x>c and c:      # if not ascending
    return (0,0)
   return (x*b,x)     # return (result, value of first closed parentheses)
 return (1,0)         # empty string

def f(a):
 x=a,
 while a and x.count(a)<3: # detect non-decodable or cycle
  a,t=g(bin(a-~a)[2:])     # a-~a is a*2+1
  x+=a,
 return x[:-1]

1

Bình thường, 62 byte

L?b**FKme.fP_Zyd)bSIK1fTseB.u.xyvs@L,"],"\[++JjN2 1m0h-/J1/J00

Bộ kiểm tra

Cho biết một chu kỳ bằng cách lặp lại số cuối cùng.

L?b**FKme.fP_Zyd)bSIK1    Define y to decode from list format. 0 if invalid.

fTseB.u.xyvs@L,"],"\[++JjN2 1m0h-/J1/J00
     .u                                     Repeat the following until it cycles
                                            Collecting the values in a list.
                     ++JjN2 1m0h-/J1/J0     Convert the number to expanded binary
            @L,"],"\[                       Map 0 to "],", 1 to "["
           s                                Flatten to a string.
          v                                 Evaluate as a Python object.
       .x                              0    If evaluation fails, return 0.
         y                                  Otherwise decode.
  seB                                       Duplicate the final number
fT                                          Remove all 0s.
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.