Tính toán tổng kiểm tra Adler-32


32

Lý lịch

Adler-32 là một tổng kiểm tra 32 bit được phát minh bởi Mark Adler vào năm 1995, là một phần của thư viện zlib được sử dụng rộng rãi (cũng được phát triển bởi Adler). Adler-32 không đáng tin cậy như kiểm tra dự phòng chu kỳ 32 bit , nhưng - ít nhất là trong phần mềm - nó nhanh hơn và dễ thực hiện hơn nhiều.

Định nghĩa

Đặt B = [b 1 , ⋯, b n ] là một mảng byte.

Tổng kiểm tra Adler-32 của B được xác định là kết quả của mức thấp + 65536 × cao , trong đó:

  • thấp: = ((1 + b 1 + ⋯ + b n ) mod 65521)

  • cao: = (((1 + b 1 ) + (1 + b 1 + b 2 ) + ⋯ (1 + b 1 + + b n )) mod 65521)

Bài tập

Đưa ra một mảng byte làm đầu vào, tính toán và trả về tổng kiểm tra Adler-32 của nó, tuân theo các điều sau đây.

  • Bạn có thể lấy đầu vào là một mảng byte hoặc số nguyên hoặc dưới dạng chuỗi.

    Trong cả hai trường hợp, chỉ các byte tương ứng với các ký tự ASCII có thể in sẽ xuất hiện trong đầu vào.

    Bạn có thể giả sử rằng độ dài của đầu vào sẽ thỏa mãn 0 <length 96 4096 .

  • Nếu bạn chọn in đầu ra, bạn có thể sử dụng bất kỳ cơ sở tích cực nào lên đến và bao gồm 256.

    Nếu bạn chọn unary, hãy đảm bảo trình thông dịch có thể xử lý tối đa 2 32 - 983056 byte đầu ra trên một máy có 16 GiB RAM.

  • Các công cụ tích hợp tính toán tổng kiểm tra Adler-32 đều bị cấm.

  • Luật tiêu chuẩn được áp dụng.

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

String:     "Eagles are great!"
Byte array: [69, 97, 103, 108, 101, 115, 32, 97, 114, 101, 32, 103, 114, 101, 97, 116, 33]
Checksum:   918816254

String:     "Programming Puzzles & Code Golf"
Byte array: [80, 114, 111, 103, 114, 97, 109, 109, 105, 110, 103, 32, 80, 117, 122, 122, 108, 101, 115, 32, 38, 32, 67, 111, 100, 101, 32, 71, 111, 108, 102]
Checksum:   3133147946

String:     "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
Byte array: [126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126]
Checksum:   68095937

String:     <1040 question marks>
Byte array: <1040 copies of 63>
Checksum:   2181038080

7
Tôi sẽ lưu ý rằng nhiều câu trả lời ở đây sẽ thất bại với các chuỗi đầu vào lớn hoặc rất lớn khi chúng tràn vào tổng số nguyên 32 hoặc 64 bit, do trì hoãn hoạt động modulo cho đến sau khi tổng được tính. Một triển khai thực sự tuân thủ sẽ cần phải thực hiện thao tác modulo ít nhất theo định kỳ để giữ cho các khoản tiền không bị tràn. Một số nguyên có chữ ký 32 bit sẽ tràn chỉ sau 4096 0xff. Số nguyên có chữ ký 64 bit sẽ tràn sau 256 MiB của 0xff.
Đánh dấu Adler

@MarkAdler Hừm, điểm công bằng. Vì tôi không xác định rằng các giải pháp sẽ phải hoạt động cho các chuỗi dài tùy ý và tôi không muốn làm mất hiệu lực các câu trả lời hiện có, tôi sẽ đặt giới hạn cho độ dài của đầu vào.
Dennis

@MarkAdler Tôi không nghĩ nó quan trọng. Tôi khá chắc chắn rằng tràn (số nguyên 32 bit đã ký) chỉ có thể xảy ra với 4104 byte trở lên, vì giá trị tối đa cao trước modulo là n * (n + 1) / 2 * 255 + n . Trên hết, thách thức hạn chế đầu vào thành byte tương ứng với các ký tự ASCII có thể in được.
Dennis

Chúng tôi cũng có thể cho phép các ngôn ngữ tràn các loại số của chúng và chỉ yêu cầu kết quả trả về là tương đương, chiếm tỷ lệ tràn, cho kết quả chính xác.
dặm

1
@PeterCordes Có, mảng ints 32 bit hoàn toàn ổn. Ít nhất theo ý kiến ​​của tôi, các bài nộp nên tập trung vào việc đánh gôn thuật toán và chú ý ít nhất có thể đến I / O.
Dennis

Câu trả lời:


3

Thạch, 19 17 byte

+\,S‘S€%65521ḅ⁹²¤

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

+\,S‘S€%65521ḅ⁹²¤    Main monadic chain. Takes array as only argument.

                     The array is shown here as [b1 b2 ... bn].
+\                   Reduce by addition (+) while returning immediate results.
                         yields [b1 b1+b2 ... b1+b2+...+bn].

  ,                  Concatenate with...
   S                 the sum of the argument.
                         yields [[b1 b1+b2 ... b1+b2+...+bn] b1+b2+...+bn].

    ‘                Increment [each].
                         yields [[1+b1 1+b1+b2 ... 1+b1+b2+...+bn] 1+b1+b2+...+bn].

     S€              Sum each list.
                         yields [[1+b1+1+b1+b2+...+1+b1+b2+...+bn] 1+b1+b2+...+bn].

       %65521        Modulo [each] by 65521.

             ḅ⁹²¤    Convert from base    65536    to integer.
              ⁹                        256
               ²                           squared

Tốt hơn nữa:⁹²¤
Dennis

1
@Dennis Tôi đã vượt qua 18 byte của bạn rồi.
Leaky Nun

1
Chà, bạn đã vượt qua ..
Leaky Nun

64

Toán học, 46 byte

{1,4^8}.Fold[##+{0,#&@@#}&,{1,0},#]~Mod~65521&

Một chức năng ẩn danh mà phải mất một mảng số nguyên và trả về Adler-32, với một số cải tiến từ dặm và Martin (xem ý kiến).

dặm cũng là 46 byte , nhưng nhanh hơn:

{1,4^8}.{Tr@#+1,Tr[Accumulate@#+1]}~Mod~65521&

37
... Bạn vừa chơi golf thuật toán nổi tiếng của riêng bạn?
Mego

25
Hãy tha thứ cho tôi nếu tôi là một ngôi sao tấn công. Không phải hàng ngày bạn thấy một tên tuổi lớn như vậy trong công nghệ phần mềm trên trang web nhỏ bé khiêm tốn của chúng tôi. Chào mừng bạn!
Mego

6
Không lớn lắm đâu.
Đánh dấu Adler

3
Nếu bạn muốn nói với tôi, đây là lần đầu tiên tôi nghĩ đến việc triển khai Adler-32 trong Mathematica.
Đánh dấu Adler

9
Hoặc có lẽ bạn đã có giải pháp này sẵn sàng kể từ khi bạn tham gia Code Golf, chỉ chờ nó được hỏi. "Cuối cùng!" ;-)
Antti Haapala

13

Julia, 73 46 byte

x->[sum(x)+1;sum(cumsum(x)+1)]%65521⋅[1;4^8]

Đây là một hàm ẩn danh chấp nhận một mảng và trả về một số nguyên. Để gọi nó, gán nó cho một biến.

Chúng tôi kết hợp sum(x) + 1sum(cumsum(x) + 1)thành một mảng, trong đó xlà mảng đầu vào và lấy từng modulo 65521. Sau đó, chúng tôi tính toán sản phẩm chấm với 1 và 4 8 , cung cấp cho chúng tôi (sum(x) + 1) + 4^8 * sum(cumsum(x) + 1), chính xác là công thức Adler-32.

Hãy thử trực tuyến! (Bao gồm tất cả các trường hợp thử nghiệm)

Đã lưu 27 byte nhờ Sp3000 và Dennis!


Wow, thật là thông minh.
con mèo

@cat Tôi có Sp3000 và Dennis để cảm ơn vì sự thông minh nhất. :)
Alex A.

11

Chức năng mã máy x86-64: 33 32 byte (hoặc 31 30 byte với int[]đầu vào thay vì char[])

Chức năng mã máy x86-32: 31 byte

Là một đoạn mã GNU C inline-asm: lưu 2B 1B (chỉ phần retin).

Nguồn bình luận và trình điều khiển thử nghiệm trên github

Phiên bản 64 bit có thể gọi trực tiếp từ C với System V x86-64 ABI tiêu chuẩn (sử dụng 2 đối số giả để nhận args trong regs tôi muốn). Các quy ước gọi điện tùy chỉnh không phải là hiếm đối với mã asm, vì vậy đây là một tính năng thưởng.

Mã máy 32 bit tiết kiệm 1B, vì hợp nhất nửa cao và thấp push16/push16 => pop32chỉ hoạt động ở chế độ 32 bit. Hàm 32 bit sẽ cần một quy ước gọi tùy chỉnh. Chúng ta không nên chống lại điều đó, nhưng gọi từ C cần có chức năng bao bọc.

Sau khi xử lý 4096 ~(ASCII 126) byte , high = 0x3f040000, low = 0x7e001. Vì vậy, highbit quan trọng nhất chưa được thiết lập. Mã của tôi lợi dụng điều này, đăng ký mở rộng eaxthành edx:eaxvới cdqnhư một cách để zeroing edx.

# See the NASM source below
0000000000401120 <golfed_adler32_amd64>:
  401120:       31 c0                   xor    eax,eax
  401122:       99                      cdq    
  401123:       8d 7a 01                lea    edi,[rdx+0x1]
0000000000401126 <golfed_adler32_amd64.byteloop>:
  401126:       ac                      lods   al,BYTE PTR ds:[rsi]
  401127:       01 c7                   add    edi,eax
  401129:       01 fa                   add    edx,edi
  40112b:       e2 f9                   loop   401126 <golfed_adler32_amd64.byteloop>
000000000040112d <golfed_adler32_amd64.end>:
  40112d:       66 b9 f1 ff             mov    cx,0xfff1
  401131:       92                      xchg   edx,eax
  401132:       99                      cdq    
  401133:       f7 f1                   div    ecx
  401135:       52                      push   rdx
  401136:       97                      xchg   edi,eax
  401137:       99                      cdq    
  401138:       f7 f1                   div    ecx
  40113a:       66 52                   push   dx      # this is the diff from last version: evil push/pop instead of shift/add
  40113c:       58                      pop    rax
  40113d:       66 5a                   pop    dx
  40113f:       c3                      ret    
0000000000401140 <golfed_adler32_amd64_end>:

0x40 - 0x20 = 32 byte.


Nguồn NASM đã nhận xét:

thủ thuật:

  • xchg eax, r32là một byte; rẻ hơn so với Mov. 8086 dữ liệu cần thiết trong rìu cho nhiều thứ hơn> = 386, vì vậy họ quyết định dành nhiều không gian opcode cho hiện tại hiếm khi được sử dụng xchg ax, r16.

  • Trộn Push64 và Push16 để hợp nhất cao và thấp vào một thanh ghi duy nhất giúp tiết kiệm các hướng dẫn di chuyển dữ liệu reg-reg trong khoảng hai divgiây. Phiên bản 32 bit của thủ thuật này hoạt động thậm chí còn tốt hơn: push16 / push16 / pop32chỉ có tổng 5B chứ không phải 6.

Vì chúng tôi đẩy / bật, điều này không an toàn cho asm nội tuyến trong SysV amd64 ABI (có vùng màu đỏ) .

golfed_adler32_amd64_v3:   ; (int dummy, const char *buf, int dummy, uint64_t len)

    ;; args: len in rcx,  const char *buf in rsi
    ;; Without dummy args, (unsigned len, const char *buf),  mov ecx, edi is the obvious solution, costing 2 bytes

    xor     eax,eax         ; scratch reg for loading bytes
    cdq                     ; edx: high=0
    lea     edi, [rdx+1]    ; edi: low=1
    ;jrcxz  .end            ; We don't handle len=0.  unlike rep, loop only checks rcx after decrementing
.byteloop:
    lodsb                   ; upper 24b of eax stays zeroed (no partial-register stall on Intel P6/SnB-family CPUs, thanks to the xor-zeroing)
    add     edi, eax        ; low += zero_extend(buf[i])
    add     edx, edi        ; high += low
    loop   .byteloop
.end:
    ;; exit when ecx = 0, eax = last byte of buf
    ;; lodsb at this point would load the terminating 0 byte, conveniently leaving eax=0

    mov     cx, 65521       ; ecx = m = adler32 magic constant.  (upper 16b of ecx is zero from the loop exit condition.  This saves 1B over mov r32,imm32)
    ;sub    cx, (65536 - 65521) ; the immediate is small enough to use the imm8 encoding.  No saving over mov, though, since this needs a mod/rm byte

    xchg    eax, edx        ; eax = high,  edx = buf[last_byte]
    cdq                     ; could be removed if we could arrange things so the loop ended with a load of the 0 byte

    div     ecx             ; div instead of idiv to fault instead of returning wrong answers if high has overflowed to negative.  (-1234 % m is negative)
    push    rdx             ; push high%m and 6B of zero padding

    xchg    eax, edi        ; eax=low
    cdq
    div     ecx             ; edx = low%m

    ;; concatenate the two 16bit halves of the result by putting them in contiguous memory
    push    dx              ; push low%m with no padding
    pop     rax             ; pop  high%m << 16 | low%m   (x86 is little-endian)

    pop     dx              ; add rsp, 2 to restore the stack pointer

    ;; outside of 16bit code, we can't justify returning the result in the dx:ax register pair
    ret
golfed_adler32_amd64_end_v3:

Tôi cũng đã xem xét việc sử dụng rcxnhư một chỉ mục mảng, thay vì có hai bộ đếm vòng lặp, nhưng adler32 (s)! = Adler32 (Reverse (s)). Vì vậy, chúng tôi không thể sử dụng loop. Đếm từ -len lên về 0 và movzx r32, [rsi+rcx]chỉ sử dụng quá nhiều byte.

Nếu chúng ta muốn xem xét việc tăng con trỏ của chúng ta, mã 32 bit có lẽ là cách để đi. Ngay cả x32 ABI (con trỏ 32 bit) là không đủ, bởi vì inc esilà 2B trên amd64, nhưng là 1B trên i386. Có vẻ khó đánh bại tổng xor eax,eax/ lodsb/ loop: 4B để đưa từng phần tử lần lượt mở rộng bằng không thành eax. inc esi/ movzx r32, byte [esi]/ looplà 5B.

scaslà một tùy chọn khác để tăng con trỏ bằng lệnh 1B ở chế độ 64 bit. ( rdi/ edithay vì rsi, vì vậy chúng tôi sẽ lấy con trỏ arg in rdi). Tuy nhiên, chúng tôi không thể sử dụng kết quả cờ từ scasnhư một điều kiện vòng lặp, vì chúng tôi không muốn giữ cho số 0 không. Phân bổ đăng ký khác nhau có thể có thể lưu một byte sau vòng lặp.


int[] đầu vào

Chức năng đầy đủ uint8_t[]là câu trả lời "chính", bởi vì đó là một thử thách thú vị hơn. Giải nén đến int[]là một điều không hợp lý để yêu cầu người gọi của chúng tôi thực hiện bằng ngôn ngữ này, nhưng nó tiết kiệm được 2B.

Nếu chúng ta lấy đầu vào của mình dưới dạng một mảng gồm các số nguyên 32 bit, chúng ta có thể dễ dàng lưu một byte (sử dụng lodsdvà thay thế xor eax,eax / cdqbằng chỉ xor edx,edx).

Chúng ta có thể lưu một byte khác bằng cách zero edx với lodsd/ cdqvà sắp xếp lại vòng lặp để nó tải phần tử 0 kết thúc trước khi thoát. (Chúng tôi vẫn cho rằng nó tồn tại, mặc dù đây là một mảng intchứ không phải chuỗi).

; untested: I didn't modify the test driver to unpack strings for this
golfed_adler32_int_array:
    ; xor   edx,edx
    lodsd                   ; first element. only the low byte non-zero
    cdq                     ; edx: high=0
    lea     edi, [rdx+1]    ; edi: low=1
    ;jrcxz  .end            ; handle len=0?  unlike rep, loop only checks rcx after decrementing
.intloop:
    add     edi, eax        ; low += buf[i]
    add     edx, edi        ; high += low
    lodsd                   ; load buf[i+1] for next iteration
    loop   .intloop
.end:
    ;; exit when ecx = 0, eax = terminating 0

    xchg    eax, edx
    ;cdq               ; edx=0 already, ready for div
    ; same as the char version

Tôi cũng đã tạo một phiên bản chưa được kiểm tra sử dụng scasd(phiên bản 1B add edi,4) và add eax, [rdi]thay vì lodsd, nhưng nó cũng có 30 byte. Các khoản tiết kiệm từ việc có hightrong eax ở cuối vòng lặp được cân bằng bởi mã lớn hơn ở nơi khác. Tuy nhiên, nó có lợi thế là không phụ thuộc vào một 0yếu tố kết thúc trong đầu vào, điều này có thể không hợp lý đối với một mảng được giải nén trong đó chúng ta cũng đưa ra độ dài một cách rõ ràng.


Trình điều khiển thử nghiệm C ++ 11

Xem liên kết github. Câu trả lời này đã trở nên quá lớn và trình điều khiển thử nghiệm có nhiều tính năng hơn với mã lớn hơn.


2
Tôi cho phép số nguyên thay vì byte chủ yếu vì nhiều ngôn ngữ thậm chí không có loại byte. Số nguyên 32 bit có thể là một lựa chọn không tự nhiên để lắp ráp, nhưng mã golf là về việc vắt kiệt byte cuối cùng trong khi vẫn tuân thủ các quy tắc. Nếu một lựa chọn "không tự nhiên" dẫn đến số byte thấp hơn, tôi sẽ nói hãy chọn nó.
Dennis

@Dennis: Tôi hiểu sự cần thiết của quy tắc đối với một số ngôn ngữ. Tôi ước có một cách để quy tắc chỉ cho phép bạn sử dụng int[]nếu cần thiết hoặc lưu hơn 4 byte mã hoặc một cái gì đó. Tôi không có vấn đề gì khi trình bày một giải pháp cho adler32(int[])vấn đề này, nhưng tôi cảm thấy rằng adler32(char[])vấn đề này thú vị hơn, vì đó là chức năng adler32 thực sự. Đó là những gì tôi thực sự muốn chơi golf trong asm. (Và tôi rất muốn lưu thêm một byte bằng cách nào đó, vì trong asm ngoài đời thực, 33 byte = 48 byte nếu hàm tiếp theo sử dụng ALIGN 16). Tôi đoán tôi sẽ tiếp tục chơi golf cả.
Peter Cordes

@Dennis: còn nữa, chúng ta có cần xử lý trường hợp len = 0 không? Tôi tiết kiệm 2B bằng cách sử dụng do{}while(--len)kiểu vòng lặp thay vì a while(len--){}.
Peter Cordes

4
Khi giải thích, càng chi tiết, càng tốt.
Dennis

3
@cat: Không, tôi không thấy đau. Tôi sẽ không dành thời gian để viết câu trả lời Stackoverflow cho câu hỏi asm / hiệu suất và cập nhật wiki thẻ x86 nếu tôi đã làm: P Nếu bạn muốn biết tại sao mã chạy chậm hay nhanh, bạn phải xem và hiểu mã asm. Khi bạn làm điều đó một lúc, bạn bắt đầu thấy khi trình biên dịch có thể tạo mã nhanh hơn ... và cuối cùng bạn bắt đầu suy nghĩ về cách trình biên dịch có thể biên dịch mã khi bạn viết nó. Tối ưu hóa cho kích thước mã thay vì hiệu suất đôi khi là một thay đổi thú vị.
Peter Cordes

8

MATL , 22 byte

tsQwYsQsh16W15-\l8Mh*s

Đầu vào có thể là một mảng các số hoặc chuỗi ASCII tương ứng.

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

Giải trình

t       % Take array or string as input. Duplicate
sQ      % Sum all its values, and add 1
wYsQs   % Swap. Cumulative sum, add 1, sum
h       % Concatenate horizontally
16W     % 2^16: gives 65536
15-     % Subtract 15: gives 65521
\       % Element-wise modulo operation
l       % Push 1
8M      % Push 65536 again
h       % Concatenate horizontally: gives array [1, 65535]
*s      % Element-wise multiplication and sum. Display

7

Trên thực tế, 36 byte

;Σu@;╗lR`╜HΣu`MΣk`:65521@%`M1#84ⁿ@q*

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

Giải trình:

;Σu@;╗lR`╜HΣu`MΣk`:65521@%`M1#84ⁿ@q*
;Σu                                   sum(input)+1
   @;╗lR                              push a copy of input to reg0, push range(1, len(input)+1)
        `╜HΣu`M                       map over range: sum(head(reg0,n))+1
               Σk                     sum, combine lower and upper into a list
                 `:65521@%`M          modulo each by 65521
                            1#84ⁿ@q*  dot product with [1,4**8]

7

Java, 84 byte

long a(int[]i){long a=1,b=0;for(int p:i)b=(b+(a=(a+p)%(p=65521)))%p;return b<<16|a;}

Nếu các giải pháp Java luôn được coi là mã có thể biên dịch hoàn chỉnh, vui lòng cho tôi biết.

Ung dung

long a(int[] i) {
    long a = 1, b = 0;
    for (int p : i) b = (b + (a = (a + p) % (p = 65521))) % p;
    return b << 16 | a;
}

chú thích

Bạn sẽ phải chuyển đổi đầu vào Stringthành int[]( int[]ngắn hơn một byte so với byte[]hoặc char[]).

Đầu ra

String:     "Eagles are great!"
Byte Array: [69, 97, 103, 108, 101, 115, 32, 97, 114, 101, 32, 103, 114, 101, 97, 116, 33]
Checksum:   918816254
Expected:   918816254

String:     "Programming Puzzles & Code Golf"
Byte Array: [80, 114, 111, 103, 114, 97, 109, 109, 105, 110, 103, 32, 80, 117, 122, 122, 108, 101, 115, 32, 38, 32, 67, 111, 100, 101, 32, 71, 111, 108, 102]
Checksum:   3133147946
Expected:   3133147946

String:     "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
Byte Array: [126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126]
Checksum:   68095937
Expected:   68095937

String:     "?????????...?"
Byte Array: [63, 63, 63, 63, 63, 63, 63, 63, 63, ...,63]
Checksum:   2181038080
Expected:   2181038080

1
Câu trả lời tốt đẹp, và chào mừng đến với trang web! Ngoài ra, các giải pháp không đầy đủ và có thể biên dịch được là tốt, trừ khi thách thức nói rõ rằng đó phải là một chương trình đầy đủ. Đây là một chức năng đầy đủ, vì vậy nó tính.
DJMcMayhem

6

Piet, 120 Codel mã hóa 1

Với codelize 20:

mã hóa 20

Ghi chú / Làm thế nào nó hoạt động?

  • Vì không thể sử dụng một mảng hoặc chuỗi làm đầu vào, chương trình này hoạt động bằng cách lấy một loạt các số nguyên (đại diện cho các ký tự ascii) làm đầu vào. Tôi đã nghĩ về việc sử dụng đầu vào ký tự lúc đầu nhưng đấu tranh để tìm một giải pháp tốt cho việc chấm dứt, vì vậy bây giờ nó chấm dứt khi bất kỳ số nào nhỏ hơn 1 được nhập. Ban đầu nó chỉ là giá trị âm cho việc chấm dứt, nhưng tôi đã phải thay đổi khởi tạo sau khi viết chương trình, vì vậy bây giờ tôi không thể phù hợp với yêu cầu 2, chỉ một 1(26/45 trên hình ảnh dấu vết). Điều này không quan trọng mặc dù theo quy tắc thử thách, chỉ cho phép các ký tự ascii có thể in được.

  • Gặp khó khăn trong một thời gian dài với việc nhập lại vòng lặp, mặc dù cuối cùng tôi đã tìm thấy giải pháp thanh lịch. Không pointerhoặc switchhoạt động, chỉ có trình thông dịch chạy vào tường cho đến khi nó chuyển trở lại vào bảng mã màu xanh lá cây để đọc đầu vào (43-> 44 trên hình ảnh dấu vết).

  • Chấm dứt vòng lặp được thực hiện bằng cách nhân đôi đầu vào, thêm 1 và sau đó kiểm tra xem nó có lớn hơn 1. Nếu đúng, trình chọn mã hóa được kích hoạt và tiếp tục thực hiện ở đường dưới. Nếu không, chương trình sẽ nằm bên trái (codel màu vàng sáng, 31/50 trên hình ảnh dấu vết).

  • Kích thước đầu vào được hỗ trợ phụ thuộc vào việc thực hiện trình thông dịch, mặc dù có thể hỗ trợ đầu vào lớn tùy ý với trình thông dịch phù hợp (ví dụ: giả sử trình thông dịch Java sử dụng BigIntegerlàm giá trị bên trong)

  • Chỉ cần thấy rằng thiết lập bao gồm một không cần thiết DUPCC(7-> 8-> 9 trong hình ảnh dấu vết). Không biết làm thế nào điều đó xảy ra. Đây thực sự là một noop, nó bật tắt trình chọn codel 16 lần mà kết quả là không thay đổi.

Hình ảnh dấu vết của Npiet

Thiết lập và vòng lặp đầu tiên:

khởi đầu

Kết thúc vòng lặp, đầu ra và thoát:

kết thúc

Đầu ra

Hãy tha thứ cho tôi nếu tôi chỉ bao gồm một đầu ra, chỉ mất một thời gian dài để nhập: ^)

String: "Eagles are great!"

PS B:\Marvin\Desktop\Piet> .\npiet.exe adler32.png
? 69
? 97
? 103
? 108
? 101
? 115
? 32
? 97
? 114
? 101
? 32
? 103
? 114
? 101
? 97
? 116
? 33
? -1
918816254

Theo dõi Npiet cho [65, -1]

trace: step 0  (0,0/r,l nR -> 1,0/r,l dR):
action: push, value 4
trace: stack (1 values): 4

trace: step 1  (1,0/r,l dR -> 2,0/r,l dB):
action: duplicate
trace: stack (2 values): 4 4

trace: step 2  (2,0/r,l dB -> 3,0/r,l nM):
action: multiply
trace: stack (1 values): 16

trace: step 3  (3,0/r,l nM -> 4,0/r,l nC):
action: duplicate
trace: stack (2 values): 16 16

trace: step 4  (4,0/r,l nC -> 5,0/r,l nY):
action: duplicate
trace: stack (3 values): 16 16 16

trace: step 5  (5,0/r,l nY -> 6,0/r,l nM):
action: duplicate
trace: stack (4 values): 16 16 16 16

trace: step 6  (6,0/r,l nM -> 7,0/r,l nC):
action: duplicate
trace: stack (5 values): 16 16 16 16 16

trace: step 7  (7,0/r,l nC -> 8,0/r,l nY):
action: duplicate
trace: stack (6 values): 16 16 16 16 16 16

trace: step 8  (8,0/r,l nY -> 9,0/r,l lB):
action: switch
trace: stack (5 values): 16 16 16 16 16
trace: stack (5 values): 16 16 16 16 16

trace: step 9  (9,0/r,l lB -> 10,0/r,l dM):
action: multiply
trace: stack (4 values): 256 16 16 16

trace: step 10  (10,0/r,l dM -> 11,0/r,l nR):
action: multiply
trace: stack (3 values): 4096 16 16

trace: step 11  (11,0/r,l nR -> 12,0/r,l lY):
action: multiply
trace: stack (2 values): 65536 16

trace: step 12  (12,0/r,l lY -> 13,0/r,l lM):
action: duplicate
trace: stack (3 values): 65536 65536 16

trace: step 13  (13,0/r,l lM -> 14,0/r,l nM):
action: push, value 3
trace: stack (4 values): 3 65536 65536 16

trace: step 14  (14,0/r,l nM -> 15,0/r,l dM):
action: push, value 2
trace: stack (5 values): 2 3 65536 65536 16

trace: step 15  (15,0/r,l dM -> 16,0/r,l lC):
action: roll
trace: stack (3 values): 16 65536 65536

trace: step 16  (16,0/r,l lC -> 17,0/r,l nB):
action: sub
trace: stack (2 values): 65520 65536

trace: step 17  (17,0/r,l nB -> 18,0/r,l dB):
action: push, value 1
trace: stack (3 values): 1 65520 65536

trace: step 18  (18,0/r,l dB -> 19,0/r,l dM):
action: add
trace: stack (2 values): 65521 65536

trace: step 19  (19,0/r,l dM -> 19,1/d,r dC):
action: duplicate
trace: stack (3 values): 65521 65521 65536

trace: step 20  (19,1/d,r dC -> 18,1/l,l lC):
action: push, value 1
trace: stack (4 values): 1 65521 65521 65536

trace: step 21  (18,1/l,l lC -> 17,1/l,l nC):
action: push, value 1
trace: stack (5 values): 1 1 65521 65521 65536

trace: step 22  (17,1/l,l nC -> 16,1/l,l dB):
action: sub
trace: stack (4 values): 0 65521 65521 65536

trace: step 23  (16,1/l,l dB -> 15,1/l,l lB):
action: push, value 1
trace: stack (5 values): 1 0 65521 65521 65536

trace: step 24  (15,1/l,l lB -> 13,2/l,l dG):
action: in(number)
? 65
trace: stack (6 values): 65 1 0 65521 65521 65536

trace: step 25  (13,2/l,l dG -> 12,2/l,l dR):
action: duplicate
trace: stack (7 values): 65 65 1 0 65521 65521 65536

trace: step 26  (12,2/l,l dR -> 11,2/l,l lR):
action: push, value 1
trace: stack (8 values): 1 65 65 1 0 65521 65521 65536

trace: step 27  (11,2/l,l lR -> 10,2/l,l lY):
action: add
trace: stack (7 values): 66 65 1 0 65521 65521 65536

trace: step 28  (10,2/l,l lY -> 9,2/l,l nY):
action: push, value 1
trace: stack (8 values): 1 66 65 1 0 65521 65521 65536

trace: step 29  (9,2/l,l nY -> 8,1/l,r nB):
action: greater
trace: stack (7 values): 1 65 1 0 65521 65521 65536

trace: step 30  (8,1/l,r nB -> 7,1/l,r lY):
action: switch
trace: stack (6 values): 65 1 0 65521 65521 65536
trace: stack (6 values): 65 1 0 65521 65521 65536

trace: step 31  (7,1/l,l lY -> 6,2/l,l nY):
action: push, value 2
trace: stack (7 values): 2 65 1 0 65521 65521 65536

trace: step 32  (6,2/l,l nY -> 5,3/l,l dB):
action: pointer
trace: stack (6 values): 65 1 0 65521 65521 65536

trace: step 33  (5,3/r,l dB -> 7,4/r,l dM):
action: add
trace: stack (5 values): 66 0 65521 65521 65536

trace: step 34  (7,4/r,l dM -> 8,4/r,l dC):
action: duplicate
trace: stack (6 values): 66 66 0 65521 65521 65536

trace: step 35  (8,4/r,l dC -> 9,3/r,l lC):
action: push, value 3
trace: stack (7 values): 3 66 66 0 65521 65521 65536

trace: step 36  (9,3/r,l lC -> 10,3/r,l nC):
action: push, value 2
trace: stack (8 values): 2 3 66 66 0 65521 65521 65536

trace: step 37  (10,3/r,l nC -> 11,3/r,l dY):
action: roll
trace: stack (6 values): 0 66 66 65521 65521 65536

trace: step 38  (11,3/r,l dY -> 12,3/r,l dG):
action: add
trace: stack (5 values): 66 66 65521 65521 65536

trace: step 39  (12,3/r,l dG -> 13,3/r,l lG):
action: push, value 2
trace: stack (6 values): 2 66 66 65521 65521 65536

trace: step 40  (13,3/r,l lG -> 14,3/r,l nG):
action: push, value 1
trace: stack (7 values): 1 2 66 66 65521 65521 65536

trace: step 41  (14,3/r,l nG -> 15,3/r,l dR):
action: roll
trace: stack (5 values): 66 66 65521 65521 65536
trace: white cell(s) crossed - continuing with no command at 17,3...

trace: step 42  (15,3/r,l dR -> 17,3/r,l lB):

trace: step 43  (17,3/r,l lB -> 13,2/l,l dG):
action: in(number)
? -1
trace: stack (6 values): -1 66 66 65521 65521 65536

trace: step 44  (13,2/l,l dG -> 12,2/l,l dR):
action: duplicate
trace: stack (7 values): -1 -1 66 66 65521 65521 65536

trace: step 45  (12,2/l,l dR -> 11,2/l,l lR):
action: push, value 1
trace: stack (8 values): 1 -1 -1 66 66 65521 65521 65536

trace: step 46  (11,2/l,l lR -> 10,2/l,l lY):
action: add
trace: stack (7 values): 0 -1 66 66 65521 65521 65536

trace: step 47  (10,2/l,l lY -> 9,2/l,l nY):
action: push, value 1
trace: stack (8 values): 1 0 -1 66 66 65521 65521 65536

trace: step 48  (9,2/l,l nY -> 8,1/l,r nB):
action: greater
trace: stack (7 values): 0 -1 66 66 65521 65521 65536

trace: step 49  (8,1/l,r nB -> 7,1/l,r lY):
action: switch
trace: stack (6 values): -1 66 66 65521 65521 65536
trace: stack (6 values): -1 66 66 65521 65521 65536

trace: step 50  (7,1/l,r lY -> 6,1/l,r dY):
action: pop
trace: stack (5 values): 66 66 65521 65521 65536

trace: step 51  (6,1/l,r dY -> 4,1/l,r lY):
action: push, value 3
trace: stack (6 values): 3 66 66 65521 65521 65536

trace: step 52  (4,1/l,r lY -> 3,1/l,r nY):
action: push, value 2
trace: stack (7 values): 2 3 66 66 65521 65521 65536

trace: step 53  (3,1/l,r nY -> 2,1/l,r nM):
action: duplicate
trace: stack (8 values): 2 2 3 66 66 65521 65521 65536

trace: step 54  (2,1/l,r nM -> 1,1/l,r dG):
action: pointer
trace: stack (7 values): 2 3 66 66 65521 65521 65536

trace: step 55  (1,1/r,r dG -> 2,2/r,r lR):
action: roll
trace: stack (5 values): 65521 66 66 65521 65536

trace: step 56  (2,2/r,r lR -> 2,3/d,l nR):
action: push, value 1
trace: stack (6 values): 1 65521 66 66 65521 65536

trace: step 57  (2,3/d,l nR -> 2,4/d,l lC):
action: switch
trace: stack (5 values): 65521 66 66 65521 65536
trace: stack (5 values): 65521 66 66 65521 65536

trace: step 58  (2,4/d,r lC -> 2,5/d,r nM):
action: mod
trace: stack (4 values): 66 66 65521 65536

trace: step 59  (2,5/d,r nM -> 4,5/r,r dM):
action: push, value 3
trace: stack (5 values): 3 66 66 65521 65536

trace: step 60  (4,5/r,r dM -> 6,5/r,r lM):
action: push, value 2
trace: stack (6 values): 2 3 66 66 65521 65536

trace: step 61  (6,5/r,r lM -> 7,5/r,r nC):
action: roll
trace: stack (4 values): 65521 66 66 65536

trace: step 62  (7,5/r,r nC -> 8,5/r,r dM):
action: mod
trace: stack (3 values): 66 66 65536

trace: step 63  (8,5/r,r dM -> 11,5/r,r lM):
action: push, value 3
trace: stack (4 values): 3 66 66 65536

trace: step 64  (11,5/r,r lM -> 12,5/r,r nM):
action: push, value 1
trace: stack (5 values): 1 3 66 66 65536

trace: step 65  (12,5/r,r nM -> 13,5/r,r dC):
action: roll
trace: stack (3 values): 66 65536 66

trace: step 66  (13,5/r,r dC -> 14,5/r,r nB):
action: multiply
trace: stack (2 values): 4325376 66

trace: step 67  (14,5/r,r nB -> 15,5/r,r nM):
action: add
trace: stack (1 values): 4325442

trace: step 68  (15,5/r,r nM -> 16,5/r,r dB):
action: out(number)
4325442
trace: stack is empty
trace: white cell(s) crossed - continuing with no command at 19,5...

trace: step 69  (16,5/r,r dB -> 19,5/r,r nM):

5

C89, 70 byte

h,l,m=65521;A(char*B){h=0;l=1;while(*B)h+=l+=*B++;return h%m<<16|l%m;}

Để kiểm tra (biên dịch với gcc -std=c89 -lm golf.c):

#include <stdio.h>
int main(int argc, char** argv) {
    printf("%u\n", A("Eagles are great!"));
    printf("%u\n", A("Programming Puzzles & Code Golf"));
    printf("%u\n", A("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"));
    return 0;
}

Đó là cách các zlibnguồn trông? Hừm ...
con mèo

1
Việc triển khai này đã tạo ra một điểm khởi đầu tốt đẹp cho phiên bản x86 asm của tôi.
Peter Cordes

Có thể lưu 1 byte bằng cách sử dụng forthay vì while:for(h=0,l=1;*B;)h+=l+=*B++;
ninjalj

5

Mê cung , 37 36 32 31 byte

}?"{655:}21:}%=}){%{{36*+!
:++)

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

Nhập dưới dạng danh sách các số nguyên. Chương trình kết thúc với một lỗi (có thông báo lỗi chuyển đến STDERR).

Giải trình

Mê cung mồi:

  • Labyrinth có hai ngăn xếp các số nguyên tùy ý chính xác, chínhaux (iliary), được điền ban đầu với một (ngầm) số lượng vô hạn các số không.
  • Mã nguồn giống như một mê cung, trong đó con trỏ lệnh (IP) đi theo hành lang khi nó có thể (thậm chí quanh các góc). Mã bắt đầu ở ký tự hợp lệ đầu tiên theo thứ tự đọc, tức là ở góc trên cùng bên trái trong trường hợp này. Khi IP đến bất kỳ hình thức giao nhau nào (tức là một số ô liền kề ngoài một ô mà nó xuất phát), nó sẽ chọn một hướng dựa trên đỉnh của ngăn xếp chính. Các quy tắc cơ bản là: rẽ trái khi âm, tiếp tục đi về phía trước khi số 0, rẽ phải khi dương. Và khi một trong những điều này là không thể bởi vì có một bức tường, thì IP sẽ đi theo hướng ngược lại. IP cũng quay vòng khi nhấn vào ngõ cụt.
  • Các chữ số được xử lý bằng cách nhân đỉnh của ngăn xếp chính với 10 và sau đó thêm chữ số. Để bắt đầu một số mới, bạn có thể đẩy số không bằng _.

Mặc dù mã bắt đầu bằng một "phòng" 4x2, nhưng thực tế đó là hai vòng hai nhân hai riêng biệt được ép với nhau. IP chỉ xảy ra dính vào một vòng lặp tại một thời điểm do các giá trị ngăn xếp.

Vì vậy, mã bắt đầu bằng một vòng lặp 2x2 (theo chiều kim đồng hồ) để đọc đầu vào trong khi tính tổng tiền tố:

}   Move last prefix sum over to aux.
?   Read an integer from STDIN or push 0 on EOF, which exits the loop.
+   Add current value to prefix sum.
:   Duplicate this prefix sum.

Bây giờ chúng ta đã có tất cả các khoản tiền tiền tố trên aux chồng, cũng như một bản sao của tổng khắp các giá trị và các 0từ EOF trên chính . Cùng với đó, chúng ta nhập một vòng lặp 2x2 (theo chiều kim đồng hồ) khác để tính tổng tất cả các tổng tiền tố để tính toán HIGH.

"   No-op. Does nothing.
{   Pull one prefix sum over from aux. When we're done, this fetches a 0,
    which exits the loop.
)   Increment prefix sum.
+   Add it to HIGH.

Ngăn xếp chính bây giờ có LOW - 1HIGHkhông, ngoại trừ chúng ta chưa lấy modulo. Phần còn lại của mã là hoàn toàn tuyến tính:

655      Turn the zero into 655.
:}       Make a copy and shift it over to aux.
21       Turn the copy on main into 65521.
:}       Make a copy and shift it over to aux.
%        Take HIGH mod 65521.
=        Swap HIGH with the other copy of 65521 on aux.
}){      Move 65521 back to aux, increment LOW-1 to LOW, 
         move 65521 back to main.
%        Take LOW mod 65521.
{        Move HIGH back to main.
{        Move the other copy of 655 back to main.
36       Turn it into 65536.
*        Multiply HIGH by that.
+        Add it to LOW.
!        Print it.

IP bây giờ đã đi vào ngõ cụt và quay lại. Các +*về cơ bản là không-ops, do số không ở ngăn xếp dưới. Các 36hiện trở đầu chính vào 63, nhưng hai {{kéo hai số không từ aux trên đầu trang của nó. Sau đó %cố gắng chia cho số 0 kết thúc chương trình.

Lưu ý rằng Labyrinth sử dụng các số nguyên có độ chính xác tùy ý để trì hoãn modulo cho đến khi kết thúc tổng sẽ không gây ra vấn đề với tràn số nguyên.


5

Python 2, 60 58 byte

H=h=65521
l=1
for n in input():l+=n;h+=l
print h%H<<16|l%H

Một cách tiếp cận khá đơn giản. Đây là một chương trình đầy đủ có một danh sách các số nguyên thông qua STDIN, ví dụ [72, 105, 33].

(Cảm ơn @xnor về mẹo khử răng cưa / khởi tạo tuyệt vời)


2
Bạn có thể làm H=h=65521để khởi tạo htrong khi đặt bí danh 65521.
xnor

4

J, 30 byte

+/(+65536&*)&(65521|+/)&:>:+/\

Điều này có lẽ có thể được cô đọng nhiều hơn với một chuyến tàu khác.

Sử dụng

Ở đây x $ ytạo ra một danh sách với các xbản sao của y.

   f =: +/(+65536&*)&(65521|+/)&:>:+/\
   f 69 97 103 108 101 115 32 97 114 101 32 103 114 101 97 116 33
918816254
   f 80 114 111 103 114 97 109 109 105 110 103 32 80 117 122 122 108 101 115 32 38 32 67 111 100 101 32 71 111 108 102
3133147946
   f (32 $ 126)
68095937
   f (1040 $ 63)
2181038080
   f (4096 $ 255)
2170679522

Giải trình

+/(+65536&*)&(65521|+/)&:>:+/\
f (           g           ) h     Monad train (f g h) y = (f y) g (h y)
+/                                Sum the input list
                           +/\    Sum each prefix of the input, forms a list
x     f   &   g   &:   h    y     Composed verbs, makes (g (h x)) f (g (h y))
                         >:       Increment the sum and increment each prefix sum
               (m f g) y          Hook, makes m f (g y)
                    +/            Sum the prefix sums
              65521|              Take the sum and prefix total mod 65521
    (f g) y                       Hook again
    65536&*                       Multiply the prefix total by 65536
                                  This is a bonded verb, it will only multiply
                                  using a fixed value now
   +                              Add the sum and scaled prefix total

4

Octave, 52 50 byte

Đã lưu 2 byte nhờ @LuisMendo

@(B)mod([sum(S=cumsum(B)+1),S(end)],65521)*[4^8;1]

Lấy một mảng các số nguyên làm đầu vào.

mức thấp được lấy từ phần tử cuối cùng của mức cao (trước khi tính tổng) thay vì tính tổng một cách rõ ràng, tiết kiệm tổng cộng ... 1 byte !

Mẫu chạy trên ideone .


@LuisMendo Ooh, tôi quên mất +B. Tôi đoán thông số kỹ thuật đầu vào nói rằng bạn có thể lấy số nguyên, vì vậy có lẽ tôi sẽ làm điều đó.
cốc

3

CJam, 30 29 byte

q~{1$+}*]:)_W>]1fb65521f%2G#b

Nhập dưới dạng danh sách các số nguyên.

Kiểm tra nó ở đây.

Giải trình

q~       e# Read and evaluate input.
{        e# Fold this block over the list, computing prefix sums.
  1$+    e#   Copy the last prefix and add the current element.
}*
]        e# Wrap the prefix sums in an array.
:)       e# Increment each. This will sum to HIGH.
_W>      e# Copy the list and truncate to only the last element, i.e.
         e# the sum of the entire input plus 1. This is LOW.
]        e# Wrap both of those lists in an array.
1fb      e# Sum each, by treating it as base 1 digits.
65521f%  e# Take each modulo 65521.
2G#b     e# Treat the list as base 65536 digits, computing 65536*HIGH + LOW.

3

Perl 6 , 60 byte

{(.sum+1)%65521+65536*((sum(1,*+.shift...->{!$_})-1)%65521)}

Giải trình:

{
  # $_ is the implicit parameter for this lambda because this block doesn't have
  # an explicit parameter, and @_ isn't seen inside of it.
  # ( @_ takes precedence over $_ when it is seen by the compiler )

  # .sum is short for $_.sum
  ( .sum + 1 ) % 65521 + 65536
  *
  (
    (
      sum(

        # generate a sequence:

        1,         # starting with 1
        * + .shift # lambda that adds previous result (*) with $_.shift
        ...        # generate until:
        -> { !$_ } # $_ is empty

        # ^ I used a pointy block with zero parameters
        # so that the block doesn't have an implicit parameter
        # like the surrounding block

        # this is so that $_ refers to the outer $_

      ) - 1        # remove starting value
    ) % 65521
  )
}

Kiểm tra:

#! /usr/bin/env perl6
use v6.c;
use Test;

# give the lambda a name
my &Adler32 = {(.sum+1)%65521+65536*((sum(1,*+.shift...->{!$_})-1)%65521)}

my @tests = (
  (  918816254,  'Eagles are great!'),
  ( 3133147946,  'Programming Puzzles & Code Golf'),
  (   68095937,  '~' x 32,     "'~' x 32"),
  ( 2181038080,  63 xx 1040,   "'?' x 1040"),
);

plan +@tests;

for @tests -> ($checksum, $input, $gist? ) {
  my @array := do given $input {
    when Str { .encode.Array }
    default { .Array }
  }

  is Adler32(@array), $checksum, $gist // $input.perl
}
1..4
ok 1 - "Eagles are great!"
ok 2 - "Programming Puzzles \& Code Golf"
ok 3 - '~' x 32
ok 4 - '?' x 1040

3

Python 3 (79 byte)

Dựa trên giải pháp của R. Kap.

lambda w,E=65521:(1+sum(w))%E+(sum(1+sum(w[:i+1])for i in range(len(w)))%E<<16)

Tôi đã thay thế phép nhân bằng một ca và loại bỏ một cặp dấu ngoặc.

Bởi vì tôi không thể đăng bình luận, tôi đã trả lời mới.


3

Lược đồ, 195 byte

(define(a b)(+(let L((b b)(s 1))(if(=(length b)0)s(L(cdr b)(modulo(+ s(car b))65521))))(* 65536(let H((b b)(s 1)(t 0))(if(=(length b)0)t(let((S(+ s(car b))))(H(cdr b)S(modulo(+ t S)65521))))))))

Nếu nó không dành cho tất cả các dấu ngoặc đơn đó ...


3

Haskell, 54 50 byte

m=(`mod`65521).sum
g x=m(-1:scanl(+)1x)*4^8+m(1:x)

Ví dụ sử dụng: g [69,97,103,108,101,115,32,97,114,101,32,103,114,101,97,116,33]->918816254 .

scanlbao gồm giá trị bắt đầu (-> 1) trong danh sách (-> [1,1+b1,1+b1+b2,..]), do đó, giá trị sumnày bị tắt 1, được cố định bằng cách thêm vào -1danh sách trước khi tính tổng.

Chỉnh sửa: Cảm ơn @xnor cho 4 byte.


Có vẻ như bạn có thể trích xuất tổng kết vào m: m=(`mod`65521).sum g x=m(-1:scanl(+)1x)*4^8+m(1:x). Có lẽ có một cách tốt hơn để sửa chữa các khoản tiền hơn là trả trước.
xnor

3

JavaScript (ES7), 52 50 byte

a=>a.map(b=>h+=l+=b,h=0,l=1)&&l%65521+h%65521*4**8

ES6 mất 51 byte (thay thế 4 ** 8 bằng 65536). Nếu bạn muốn có một phiên bản chuỗi, thì với 69 byte:

s=>[...s].map(c=>h+=l+=c.charCodeAt(),h=0,l=1)&&l%65521+h%65521*65536

Chỉnh sửa: Đã lưu 2 byte nhờ @ user81655.


3

Chấp nhận chức năng ARM Thumb-2 uint8_t[] : 40 byte (36B cho ABI không chuẩn vàint[] )

Các tính năng: modulo không hoãn, vì vậy đầu vào kích thước tùy ý là tốt. Không thực sự sử dụng hướng dẫn phân chia, vì vậy nó không chậm. (err, ít nhất là không vì lý do đó: P)

Tiết kiệm từ các quy tắc ít nghiêm ngặt hơn:

  • -2B nếu chúng ta không phải lưu các thanh ghi trước khi sử dụng chúng.
  • -2B để yêu cầu người gọi giải nén byte thành một uint32_t[]mảng.

Vì vậy, trường hợp tốt nhất là 36B.

// uint8_t *buf in r0,  uint32_t len in r1
00000000 <adler32arm_golf2>:
   0:   b570            push    {r4, r5, r6, lr} //
   2:   2201            movs    r2, #1          // low
   4:   2300            movs    r3, #0          // high
   6:   f64f 75f1       movw    r5, #65521      ; 0xfff1 = m
0000000a <adler32arm_golf2.byteloop>:
   a:   f810 4b01       ldrb.w  r4, [r0], #1    // post-increment byte-load
   e:   4422            add     r2, r4          // low += *B
  10:   4413            add     r3, r2          // high += low
  12:   42aa            cmp     r2, r5          // subtract if needed instead of deferred modulo
  14:   bf28            it      cs
  16:   1b52            subcs   r2, r2, r5
  18:   42ab            cmp     r3, r5
  1a:   bf28            it      cs              // Predication in thumb mode is still possible, but takes a separate instruction
  1c:   1b5b            subcs   r3, r3, r5
  1e:   3901            subs    r1, #1          // while(--len)
  20:   d1f3            bne.n   a <.byteloop2>
  22:   eac2 4003       pkhbt   r0, r2, r3, lsl #16   // other options are the same size: ORR or ADD.
  26:   bd70            pop     {r4, r5, r6, pc}  // ARM can return by popping the return address (from lr) into the pc; nifty
00000028 <adler32arm_end_golf2>:

0x28 = 40 byte


Ghi chú:

Thay vì log%mở cuối, chúng tôi làm if(low>=m) low-=mtrong vòng lặp. Nếu chúng ta làm thấp trước khi cao, chúng ta biết rằng không thể vượt quá 2*m, vì vậy modulo chỉ là vấn đề trừ hay không. A cmpsubđược cung cấp chỉ là 6B trong chế độ Thumb2. Thành ngữ tiêu chuẩn cho% là 8B trong chế độ Thumb2:

UDIV R2, R0, R1         // R2 <- R0 / R1
MLS  R0, R1, R2, R0     // R0 <- R0 - (R1 * R2 )

adler(char *)Phiên bản độ dài ẩn có cùng kích thước mã với độ dài rõ ràngadler(uint8_t[], uint32_t len) . Chúng ta có thể đặt cờ cho điều kiện thoát vòng lặp bằng một lệnh 2B.

Phiên bản độ dài ẩn có lợi thế là hoạt động chính xác với chuỗi trống, thay vì cố gắng lặp 2 ^ 32 lần.


lắp ráp / biên dịch với:

arm-linux-gnueabi-as --gen-debug -mimplicit-it=always -mfloat-abi=soft -mthumb adler32-arm.S

hoặc là

arm-linux-gnueabi-g++ -Wa,-mimplicit-it=always -g -static -std=gnu++14 -Wall -Wextra -Os -march=armv6t2 -mthumb -mfloat-abi=soft test-adler32.cpp -fverbose-asm adler32-arm.S -o test-adler32
qemu-arm ./test-adler32

Không -static, quá trình chạy dưới qemu-armkhông tìm thấy nó là trình liên kết động. (Và có, tôi cài đặt một ARM thiết lập cross-devel chỉ dành riêng cho câu trả lời này, bởi vì tôi nghĩ ý tưởng xác-trừ tôi là gọn gàng.) Trên amd64 Ubuntu, cài đặt gcc-arm-linux-gnueabi, g++-arm-linux-gnueabi. Tôi tìm thấy gdb-arm-none-eabiloại hầu như không làm việc kết nối vớiqemu-arm -g port .

Nguồn bình luận:

// There's no directive to enable implicit-it=always

// gcc uses compiler uses these in its output
.syntax unified
.arch armv8-a
.fpu softvfp

.thumb      @ aka .code 16

.p2align 4
.globl adler32arm_golf    @ put this label on the one we want to test

.thumb_func
adler32arm_golf:
adler32arm_golf2:   @ (uint8_t buf[], uint32_t len)
        @ r0 = buf
        @ r1 = len
        push    {r4, r5, r6, lr}   @ even number of regs keeps the stack aligned.  Good style? since there's no code-size saving

        movs    r2, #1          @ r2: low
        movs    r3, #0          @ r3: high
                                @ r4 = tmp for loading bytes
        movw    r5, #65521      @ r5: modulo constant

adler32arm_golf2.byteloop2:
        ldrb    r4, [r0], #1    @ *(buf++) post-increment addressing.  4B encoding
        @ldrb    r4, [r0, r1]   @ 2B encoding, but unless we make the caller pass us buf+len and -len, it needs extra code somewhere else
        @ldmia   r0!, {r4}      @ int[] version:  r4 = [r0]; r0+=4;  post-increment addressing.  2B encoding.

        add     r2, r2, r4      @ low += tmp
        add     r3, r3, r2      @ high += low;   // I think it's safe to do this before the modulo range-reduction for low, but it would certainly work to put it after.

        cmp     r2, r5
        subhs   r2, r5          @ if(low>=m) low-=m;   @ 6B total for %.  predicated insns require an IT instruction in thumb2

        cmp     r3, r5
        subhs   r3, r5          @ if(high>=m) high-=m;  // equivalent to high %= m.

        @sub    r1, #1          @ 4B encoding: sub.w to not set flags with immediate
        subs    r1, #1          @ len-- and set flags.  2B encoding
        @cmp    r4, #0          @ null-termination check. 2B encoding
        bne     adler32arm_golf2.byteloop2

@        udiv    r0, r2, r5            @ normal way to do one of the modulos
@        mls     r2, r5, r0, r2         @ r2 = low % m.  8B total for %

        PKHBT   r0, r2, r3, lsl #16     @ 4B   r0 = [ high%m <<16  |   low%m  ]
        @orr     r0, r0, r4, lsl #16    @ 4B
        @orr     r0, r0, r4             @ 4B
        @add     r0, r2, r3, lsl #16    @ 4B
        @add     r0, r0, r4             @ 2B
        pop     {r4, r5, r6, pc}        @ ARM can return by popping the return address (saved from lr) into pc.  Nifty
adler32arm_end_golf2:

test-adler32.cppcó cùng trường hợp kiểm tra và main()đối với câu trả lời x86-64 của tôi, nhưng bắt đầu theo cách này:

#include <stdint.h>
uint32_t adler32_simple(const uint8_t *B) {
  const uint32_t m=65521;

  uint32_t h=0, l=1;
  do {
    l += *B++;        // Borrowed from orlp's answer, as a simple reference implementation
    h += l;
    l %= m; h %= m;   // with non-deferred modulo if this is uncommented
  } while(*B);

  return h%m<<16|l%m;
}


#include <stdio.h>
//#include <zlib.h>
#include <string.h>
#include <assert.h>
#include <string>   // useful for the memset-style constructors that repeat a character n times


extern "C" {
    unsigned golfed_adler32_amd64(int /*dummy1*/, const char *buf, int /*dummy2*/, unsigned len);
    unsigned adler32arm_golf(const char *buf, unsigned len);
}
#ifdef __amd64__
#define golfed_adler32(buf, len)   golfed_adler32_amd64(1234, buf, 1234, len)
#elif  __arm__
#define golfed_adler32(buf, len)   adler32arm_golf(buf, len)
#else
#error "no architecture"
#endif

static void test_adler(const char *str)
{
    unsigned len = strlen(str);
//    unsigned zlib = zlib_adler(len, str);
    unsigned reference = adler32_simple((const uint8_t*)str);
    unsigned golfed = golfed_adler32(str, len);

    printf("%s: c:%u asm:%u\n", str, reference, golfed);
    assert(reference == golfed);
}

// main() to call test_adler() unchanged from my amd64 answer, except that the comments about length limits don't apply

3

Hàm mã máy x86 16 bit: 32 byte sử dụng quy ước gọi tùy chỉnh

Các đối số trong các thanh ghi, và không bảo toàn các reg khác ngoài bp (và sp).

Trong mã 16 bit, chúng tôi trả về giá trị 32 bit trong dx:axcặp đăng ký. Điều này có nghĩa là chúng tôi không phải sử dụng bất kỳ hướng dẫn nào để hợp nhất highlowvàoeax . (Điều này cũng sẽ lưu byte trong mã 32 và 64 bit, nhưng chúng tôi chỉ có thể biện minh cho việc giảm tải công việc này cho người gọi bằng mã 16 bit.)

Nguồn nhận xét và trình điều khiển thử nghiệm trên github (cho x86 16, 32 và 64 bit và ARM).

### const char *buf in SI,  uint16_t len in CX
## returns in dx:ax
## also clobbers bx and di.
00000100 <adler32_x16_v6>:
 100:   31 c0                   xor    ax,ax         # set up for lods
 102:   99                      cwd                  # dx= high=0
 103:   bf 01 00                mov    di,0x1        # di= low=0
 106:   bb f1 ff                mov    bx,0xfff1     # bx= m
00000109 <adler32_x16_v6.byteloop>:
 109:   ac                      lods
 10a:   01 c7                   add    di,ax         # low+=buf[i]. modulo-reduce on carry, or on low>=m
 10c:   72 04                   jc     112 <adler32_x16_v6.carry_low>
 10e:   39 df                   cmp    di,bx
 110:   72 02                   jb     114 <adler32_x16_v6.low_mod_m_done>
00000112 <adler32_x16_v6.carry_low>:
 112:   29 df                   sub    di,bx
00000114 <adler32_x16_v6.low_mod_m_done>:
 114:   01 fa                   add    dx,di         # high+=low
 116:   0f 92 d0                setb   al            # store the carry to set up a 32bit dividend.
 119:   92                      xchg   dx,ax
 11a:   f7 f3                   div    bx            # high (including carry) %= m, in dx.  ax=0 or 1 (so we're set for lods next iteration)                                                         
 11c:   e2 eb                   loop   109 <adler32_x16_v6.byteloop>
 11e:   97                      xchg   di,ax         # 
 11f:   c3                      ret    
00000120 <adler32_x16_v6_end>:

0x120 - 0x100 = 32 byte

Đã kiểm tra bằng cách lắp ráp cùng một mã cho chế độ 32 bit, vì vậy tôi có thể gọi nó (với chức năng bao bọc) từ C được biên dịch với -m32. Đối với tôi, chế độ 16 bit có phần thú vị, các cuộc gọi hệ thống DOS thì không. Tất cả các hướng dẫn có toán hạng rõ ràng, ngoại trừlooplodsb, do đó, việc lắp ráp cho chế độ 32 bit sử dụng tiền tố kích thước toán hạng. Cùng một hướng dẫn, mã hóa khác nhau. Nhưnglodsb ở chế độ 32 bit sẽ sử dụng[esi] , vì vậy phiên bản thử nghiệm này hoạt động với các con trỏ 32 bit (vì chúng tôi không thực hiện bất kỳ phép toán / so sánh tăng / so sánh địa chỉ nào).

Không phù hợp. Khai thác thử nghiệm của tôi in một tin nhắn nếu có sự không phù hợp.

$ yasm -felf32 -Worphan-labels -gdwarf2 adler32-x86-16.asm -o adler32-x86-16+32.o &&
   g++ -DTEST_16BIT -m32 -std=gnu++11 -O1 -g -Wall -Wextra -o test-adler32-x16  adler32-x86-16+32.o  test-adler32.cpp -lz &&
   ./test-adler32-x16
Eagles are great! (len=17): zlib:0x36c405fe  c:0x36c405fe golfed:0x36c405fe
Programming Puzzles & Code Golf (len=31): zlib:0xbac00b2a  c:0xbac00b2a golfed:0xbac00b2a
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (len=32): zlib:0x040f0fc1  c:0x040f0fc1 golfed:0x040f0fc1
?????????????????????????????????????????????????? (len=1040): zlib:0x82000000  c:0x82000000 golfed:0x82000000
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (len=4096): zlib:0xb169e06a  c:0xb169e06a golfed:0xb169e06a
(0xFF repeating) (len=4096): zlib:0x8161f0e2  c:0x8161f0e2 golfed:0x8161f0e2
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (len=5837): zlib:0x5d2a398c  c:0x5d2a398c golfed:0x5d2a398c
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (len=5838): zlib:0x97343a0a  c:0x97343a0a golfed:0x97343a0a
(0xFF repeating) (len=9999): zlib:0xcae9ea2c  c:0xcae9ea2c golfed:0xcae9ea2c
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (len=65535): zlib:0x33bc06e5  c:0x33bc06e5 golfed:0x33bc06e5

Với các thanh ghi 16 bit, chúng ta không thể trì hoãn việc giảm modulo cho đến sau vòng lặp. Có một sự khác biệt thú vị giữa 16 bit và các kích thước toán hạng khác: m = 65521( 0xFFF1) là hơn một nửa 65536. Trừm khi mang theo giữ giá trị dưới 2 * m, ngay cả khi high=0xFFF0 + 0xFFF0. Sau vòng lặp, phép so sánh và phép trừ sẽ thực hiện thủ thuật, thay vìdiv .

Tôi đã đưa ra một kỹ thuật mới để giảm modulo sau khi một add có thể tạo ra một carry . Thay vì bỏ nửa trên của đầu vào div, hãy sử dụng setc dlđể tạo cổ tức 32 bit giữ kết quả cộng không bị cắt bớt ( dhđã bị xóa 0). ( divkhông phân chia 32b / 16b => 16 bit.)

setcc(3 byte) đã được giới thiệu với 386. Để chạy cái này trên 286 hoặc sớm hơn, tốt nhất tôi đã nghĩ ra bằng cách sử dụng hướng dẫn không có giấy tờ salc(đặt AL từ carry) . Đó là một opcode một byte cho sbb al,al, vì vậy chúng ta có thể sử dụng salc/ neg altrước khi thực hiện xchg ax, dx(cái mà chúng ta cần dù sao). Không có salc, có một chuỗi 4B: sbb dx,dx/ neg dx. Chúng tôi không thể sử dụng 3B sbb dx,dx/ inc dx, vì điều đó sẽ mô phỏng setncchứ không phải setc.


Tôi đã thử sử dụng kích thước toán hạng 32 bit thay vì xử lý carry, nhưng đó không chỉ là các addhướng dẫn cần tiền tố kích thước toán hạng. Các hướng dẫn thiết lập các hằng số, v.v cũng cần các tiền tố kích thước toán hạng, vì vậy nó không phải là nhỏ nhất.



2

Perl 5, 43 byte

42 byte, cộng thêm 1 cho -aE thay vì-e

Đầu vào là số nguyên thập phân, phân tách không gian.

map$h+=$.+=$_,@F;say$.%65521+$h%65521*4**8

Một chiếc mũ của tôi để Sp3000 , từ đó tôi lấy ý tưởng cho câu trả lời này.

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

  1. Bởi vì -a, $. bắt đầu từ 1 và @Flà mảng đầu vào. $hbắt đầu từ 0. $_được sử dụng bởimap như một trình giữ chỗ cho mỗi phần tử của một mảng.
  2. map$h+=$.+=$_,@F có nghĩa là cho mỗi phần tử trong @F chúng ta thêm phần tử đó vào $.và sau đó thêm $.vào $h.
  3. Sau đó, chúng tôi thực hiện số học mô-đun $.%65521+$h%65521*4**8(nghĩa là ($. % 65521) + ( ($h % 65521) * (4**8) )say(in) kết quả.

1

Yếu tố, 112 109 103 byte

Hiện nay , đây là một bản dịch nghĩa đen của thuật toán trong câu hỏi ... bây giờ tôi thực sự đã thực hiện nó, bạn biết, chính xác.

[ [ sum 1 + ] [ [ dup length [1,b] reverse v. ] [ length ] bi + ] bi [ 65521 mod ] bi@ 16 shift bitor ]

Ung dung:

: adler-32 ( seq -- n )
  [ sum 1 + ] 
  [ 
    [ dup length [1,b] reverse v. ] 
    [ length ] bi + 
  ] bi 
  [ 65521 mod ] bi@ 
  16 shift bitor 
  ;

Yêu cầu bất kỳ chuỗi số hoặc chuỗi (không khác biệt nhiều, mặc dù về mặt kỹ thuật chúng không giống nhau).

Tôi không biết điều này sẽ hoạt động như thế nào cho giới hạn đã cho trên một phiên bản Factor được biên dịch với kích thước từ 32 bit, nhưng trên máy 6 GHz 64 bit 64 bit của tôi:

IN: scratchpad 1040 63 <array>

--- Data stack:
{ 63 63 63 63 63 63 63 63 63 63 63 63 63 63 ~1026 more~ }
IN: scratchpad [ adler-32 ] time
Running time: 7.326900000000001e-05 seconds

--- Data stack:
2181038080
IN: scratchpad 10,000 63 <array> 

--- Data stack:
2181038080
{ 63 63 63 63 63 63 63 63 63 63 63 63 63 63 ~9986 more~ }
IN: scratchpad [ adler-32 ] time
Running time: 0.000531669 seconds

1

Ruby, 91 byte

->s{b=s.bytes;z=i=b.size
b.inject(1,:+)%65521+b.map{|e|e*(1+i-=1)}.inject(z,:+)%65521*4**8}

1

Clojure, 109 byte

Dựa trên giải pháp của @Mark Adler .

(fn f[s](->> s(reduce #(mapv + %(repeat %2)[0(first %)])[1 0])(map #(rem % 65521))(map *[1 65536])(apply +)))

Ung dung

(fn f [s]
  (->> s
       (reduce #(mapv + % (repeat %2) [0 (first %)]) [1 0])
       (map #(rem % 65521))
       (map * [1 65536])
       (apply +)))

Sử dụng

=> (def f (fn f[s](->> s(reduce #(mapv + %(repeat %2)[0(first %)])[1 0])(map #(rem % 65521))(map *[1 65536])(apply +))))
=> (f [69 97 103 108 101 115 32 97 114 101 32 103 114 101 97 116 33])
918816254
=> (f [80 114 111 103 114 97 109 109 105 110 103 32 80 117 122 122 108 101 115 32 38 32 67 111 100 101 32 71 111 108 102])
3133147946
=> (f (repeat 32 126))
68095937
=> (f (repeat 1040 63))
2181038080
=> (f (repeat 4096 255))
2170679522

1

Javascript (130 ký tự được đánh gôn)

Ung dung

function a(b)
{
    c=1
    for(i=0;i<b.length;i++)
    {
        c+=b[i]
    }
    d=c%65521
    f=""
    e=0
    k=""
    for(j=0;j<b.length;j++)
    {
        k+= "+"+b[j]
        f+= "(1"+k+")"
        e= ((eval(f)))
        if(j!=b.length-1){f+="+"}
    }
    g=e%65521
    h=d+65536*g
    console.log(h)
}

Chơi gôn

a=b=>{for(c=1,k=f="",y=b.length,i=0;i<y;i++)c+=x=b[i],f+="(1"+(k+="+"+x)+")",i<y-1&&(f+="+");return z=65521,c%z+65536*(eval(f)%z)}

Dán vào Bảng điều khiển dành cho nhà phát triển và sau đó cung cấp cho nó một mảng Byte EG:

[69, 97, 103, 108, 101, 115, 32, 97, 114, 101, 32, 103, 114, 101, 97, 116, 33]

Và nó sẽ trả lại tổng kiểm tra cho giao diện điều khiển


1

TMP, 55 byte

3a1.3b0.1;4+a>T8%a>xFFF14+b>a8%b>xFFF11~5<b>164|b>a2$b$

Triển khai trong Lua có thể được tìm thấy ở đây: http://preview.ccode.gq/projects/TMP.lua


1
Chào mừng bạn đến với Câu đố lập trình và Code Golf! Liệu ngôn ngữ này đáp ứng định nghĩa của chúng tôi về ngôn ngữ lập trình ?
con mèo

@cat Tôi tin là có, nhưng tôi không chắc liệu nó có thực sự hỗ trợ "tuples?"
brianush1

BrainFuck cũng không, vì vậy bạn có thể ổn. Nếu nó hoàn tất, có thể tìm thấy các số nguyên tố và có thể làm những điều cơ bản mà bất kỳ ngôn ngữ nào khác có thể làm (và nó có thể), nó sẽ hoạt động :) CSS không phải là ngôn ngữ lập trình riêng và cũng không phải là HTML mà là CSS3 + HTML là hoàn chỉnh và có thể tìm thấy số nguyên tố.
con mèo

Vì vậy, sử dụng trong CodeGolf có ổn không?
brianush1

Tôi nghĩ vậy - tôi biết cả TMP và Lua, vì vậy một lời giải thích về mã này sẽ là một trợ giúp tuyệt vời (và sẽ làm cho đây là một câu trả lời tuyệt vời). : D
con mèo

1

Python 3.5, 82 byte:

( -1 byte nhờ Neil ! )

( -1 byte nhờ mathmandan ! )

( -4 byte nhờ Dennis ! )

lambda w:((1+sum(w))%65521)+4**8*(sum(1+sum(w[:i+1])for i in range(len(w)))%65521)

Một lambdachức năng ẩn danh . Chấp nhận một mảng byte, áp dụng toàn bộ thuật toán cho mảng và đưa ra kết quả. Đã làm việc thành công cho tất cả các trường hợp thử nghiệm. Bạn gọi nó bằng cách gán một biến cho nó, và sau đó gọi biến đó giống như bạn sẽ gọi một hàm bình thường. Nếu bạn đang sử dụng shell, thì cái này sẽ xuất ra mà không có chức năng in. Tuy nhiên, nếu bạn không phải, thì bạn phải gói chức năng gọi trongprint() hàm để thực sự thấy đầu ra.

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


(E+15)thực sự là một byte dài hơn 65536.
Neil

@Neil Cảm ơn vì tiền boa. Bây giờ nó đã được sửa.
R. Kap

@ Sp3000 Vậy sao? Sẽ rất có vấn đề nếu họ thêm một số byte, nhưng thực tế là họ không thêm byte nào phù hợp với tôi.
R. Kap

4**8là một byte ngắn hơn 65536.
mathmandan

Bạn có thể lưu 4 byte bằng cách thả dấu ngoặc quanh trình tạo và lặp từ 0 đến len (w) . 6 byte khác có thể được lưu bằng cách khai thác ưu tiên toán tử.
Dennis

1

Phân hạch , 324 byte

          /   M
       R_MZ  |S
      D ]    |S
 /?V?\} {}/  |S /    \
R{/A  Z$[/   |S/     {\
  } J{\      |S      ;_
 \^  /       |S   R'~++Y++~'L
 /    /      |S       }Y;
 \  \        ;^/
 /  /         +\+ R'~++A++~'L
 \  <Z________________/
    ;\X       //
              \Y/
               *

Cảnh báo công bằng, việc triển khai duy nhất tôi đã thử nghiệm này là cổng ngôn ngữ của riêng tôi tới F #. Nó không được đánh gôn, chủ yếu là vì tôi thấy dễ dàng hơn trong một vài lần chạy dài trong khi hằng số cơ bản của tôi nguội dọc theo đáy, vì vậy tôi có thể quay lại và điều chỉnh nó.

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

  • Các R'~++Y++~'L khối cầu chì một hằng số 256 và ra mắt nó xuống, thiết lập số nhân khối lượng của lò phản ứng trực tiếp dưới nó.
  • Các R'~++A++~'Akhối cầu chì khác 256 và ra mắt nó lên đối với lò phản ứng ở trên, mà phân hạch hạt thành hai bội khối lượng65536 khối lượng mỗi, tung ra họ trái và bên phải (nơi hạt ngay lập tức bị phá hủy bởi terminator).
  • Hạt trái đập vào một lò phản ứng khác và trải qua quá trình phân hạch, tách thành hai hạt có khối lượng bằng nhau hướng lên xuống.
  • Năng lượng di chuyển lên của hai hạt đi qua thao tác khối lượng bằng không, phản xạ sang trái, sau đó thiết lập hệ số nhân khối lượng của lò phản ứng nhiệt hạch. Lò phản ứng này sẽ là cách chúng tôi nhân khối H.
  • Các hạt di chuyển xuống phản xạ về bên trái và giảm khối lượng trong thời gian dài, cuối cùng đạt đến một khối lượng 65521 (nguyên tố lớn của chúng ta).
  • Gương quay ( Z) ở cuối quá trình chạy làm cho hạt nhân đôi số nguyên tố, gửi một trở lại bên phải nơi cuối cùng đặt khối lượng được lưu trữ của lò phản ứng phân hạch (^ ). Đây là cách chúng tôi sẽ áp dụng toán tử mô đun cho khối H.
  • Bản sao thứ hai được phản ánh trở lại, trong đó nó thực hiện chức năng tương tự cho lò phản ứng phân hạch ( <) chúng tôi sẽ sử dụng cho khối L.
  • Bây giờ các hằng số của chúng ta đã được đặt đúng chỗ, chúng ta tham gia vào các shenanigans ở phía trên bên trái để đọc đầu vào của chúng ta và tạo hai danh sách của chúng ta. Thành thật mà nói, tôi quên cách chúng hoạt động, nhưng đối với chuỗi trống, tôi phải làm chậm hạt tổng hợp khối H, điều này giải thích |S"tháp giải nhiệt".
  • \Y/ hợp nhất khối L (đi qua kênh bên trái) và khối H (đi qua kênh bên phải), sau đó đưa chúng vào một bộ kết thúc đặt mã thoát thành khối hợp nhất.

Trừ khi tôi mắc lỗi ở đâu đó, điều này dường như không hoạt động với trình thông dịch chính thức ( liên kết ). Tôi có thể lấy cổng của bạn đến F # ở đâu?
Dennis

@Dennis Tôi đang cố gắng tìm hiểu xem lỗi có phải là kết thúc của tôi hay không, nhưng tôi cũng không thể khiến trình thông dịch hoạt động được. Tôi sẽ xem nếu tôi có thể làm cho nó hoạt động sau đó cập nhật câu trả lời của tôi nếu cần.
Andrew Coonce

@Dennis Dường như trình thông dịch trực tuyến không xử lý việc hủy bỏ mã lỗi *, đó là cách tôi trả lại đầu ra. Tôi sẽ xem liệu tôi có thể tìm một thông dịch viên khác để xác minh đầu ra vào ngày mai không.
Andrew Coonce
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.