Phép nhân Nim


17

Lý lịch

Nếu bạn chơi golf nhiều mã, bạn có thể biết về hoạt động XOR bitwise . Cho hai số nguyên, nó cho một số nguyên khác có 1s trong các bit có hai đầu vào khác nhau. Vì vậy, ví dụ , 1010 XOR 0011 = 1001.

Nó hóa ra rất hữu ích trong lý thuyết trò chơi, nơi nó được gọi là "nim sum". Nếu bạn có tổng hai trò chơi (nghĩa là bạn đang thực hiện di chuyển trong một trò chơi cùng một lúc), giá trị của vị trí là tổng số giá trị của các vị trí trong mỗi trò chơi riêng lẻ.

Nhưng chúng ta có thể tiến thêm một bước này. Với phép cộng nim và một định nghĩa thích hợp về phép nhân nim , chúng ta có thể tạo thành một trường từ các số nguyên không âm. Vì vậy, thách thức là nhân rộng golf nim.

Định nghĩa

Phép nhân Nim tuân theo các quy tắc sau:
Sản phẩm nim của Fermat 2-power n = (2 ^ (2 ^ k)) với bất kỳ số nhỏ hơn là sản phẩm thông thường.
Sản phẩm nim của Fermat 2-power n với chính nó là 3n / 2.
Phép nhân nim phân phối trên phép cộng nim.
Phép nhân nim là giao hoán và kết hợp (như là phép cộng nim).
Nhận dạng nhân là 1 (và danh tính cộng là 0).

Bất kỳ số nguyên không âm nào cũng có thể được viết dưới dạng tổng nim của các lũy thừa riêng biệt của hai và bất kỳ lũy thừa nào của hai có thể được viết là tích của các số Fermat riêng biệt, vì vậy điều này là đủ để xác định phép nhân nim cho tất cả các số nguyên không âm.

Thí dụ

Đó là tất cả khá trừu tượng, vì vậy hãy làm việc qua một ví dụ. Tôi sẽ sử dụng +để biểu thị phép cộng nim (XOR) và *cho phép nhân nim.

6 * 13
= (4 + 2) * (8 + 4 + 1)
= (4 + 2) * ((4 * 2) + 4 + 1)
= (4 * 4 * 2) + (4 * 2 * 2) + (4 * 4) + (4 * 2) + (4 * 1) + (2 * 1)
= (6 * 2) + (4 * 3) + 6 + 8 + 4 + 2
= ((4 + 2) * 2) + 12 + 6 + 8 + 4 + 2
= (4 * 2) + (2 * 2) + 12 + 6 + 8 + 4 + 2
= 8 + 3 + 12 + 6 + 8 + 4 + 2
= 15

Các trường hợp kiểm tra bổ sung

4, 4 -> 6
4, 3 -> 12
4, 7 -> 10
2, 4 -> 8
2, 3 -> 1
1, 42 -> 42

Thử thách

Viết chương trình hoặc hàm, cho hai số nguyên không âm trong bất kỳ dạng thuận tiện nào, tính toán sản phẩm nim của chúng.

Đây là , vì vậy bài nộp ngắn nhất sẽ thắng.


1
Trong trường hợp không rõ ràng với độc giả, điều này khác với phép nhân XOR (không mang theo) và do đó không phải là một bản sao của thách thức đó.
xnor

1
Các bảng nhân Nim trong OEIS: A051775 , A051776 , A051910 , A051911 .
Arnauld

Cũng lưu ý rằng không có cách trực quan để hiểu phép nhân nimber (theo bài đăng đó).
dùng202729

Các số Fermat có dạng 2 ^ (2 ^ k) +1, vì vậy những gì bạn gọi là số Fermat thực sự là ít hơn một.
Kelly Lowder

@KellyLowder Vâng, đó thực sự là Fermat 2-power.

Câu trả lời:


8

Nim , 120 byte

proc f(a,b:int):int=
 var s={0..a*b}
 for i in 0..<a*b:s=s-{f(i%%a,i/%a)xor f(a,i/%a)xor f(i%%a,b)}
 for i in s:return i

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

OK, điều này có thể là điên rồ, nhưng ai đó đã phải thực hiện phép nhân Nim trong Nim ...

Đây là thuật toán tiêu chuẩn từ Wikipedia. Vấn đề là tôi không biết ngôn ngữ, vì vậy phải học những điều cơ bản một cách nhanh chóng. Đặc biệt, tôi đã rất ngạc nhiên -=minkhông làm việc cho các bộ, và cách tốt nhất tôi tìm được để trích xuất tối thiểu là sử dụng trình lặp và trả về giá trị đầu tiên. Hy vọng, các chuyên gia của Nim sẽ giúp tôi cải thiện điều này.


2
Tôi đã tự hỏi khi ai đó sẽ thử điều này.


4

Thạch , 16 byte

p’ß/;ß"^/ʋ€ṭ‘ḟ$Ṃ

Sử dụng công thức đệ quy xy = mex ({ay ⊕ xb ⊕ ab: a <x, b <y}) để nhân nimber .

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

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

p’ß/;ß"^/ʋ€ṭ‘ḟ$Ṃ  Main link. Left argument: x. Right argument: y.

p                 Cartesian product; yield the array of all pairs [a, b] such that
                  0 < a ≤ x and 0 < b ≤ y.
 ’                Decrement, changing the conditions to 0 ≤ a < x and 0 ≤ b < y.
          ṭ       Tack; yield [y, x].
        ʋ€        Combine the four links to the left into a dyadic chain. Call it
                  with right argument [y, x] and each of the [a, b] as left one.
  ß/                  Reduce [a, b] by the main link, computing the product ab.
     ß"               Zip [a, b] with [y, x] using the main link, computing the
                      array of products [ay, xb].
    ;                 Concatenate, yielding [ab, ay, xb].
       ^/             Reduce by bitwise XOR, yielding ab ⊕ ay ⊕ xb.
                  All that's left is to compute the minimum excluded (mex) non-
                  negative integer.
             $    Combine the two links to the left into a monadic chain.
           ‘          Increment the XOR sums.
            ḟ         Filterfalse; remove all incremented sums that appear in the
                      original sums.
              Ṃ  Take the minimum if the resulting array is non-empty or yield 0.
                 If x = 0 or y = 0, the array of sums is empty and Ṃ yields 0.
                 If x > 0 and y > 0, since 0 is among the sums, this finds the
                 smallest non-sum n+1 such that n ≥ 0 is a sum.
                 In either case, Ṃ yields xy.

4

CGSuite ,52 39 22 byte

(a,b)->a.NimProduct(b)

Không nhận ra nó có nội dung này và "thủ tục" ẩn danh.

Phiên bản gốc, 36 byte:

(a,b)->*a.ConwayProduct(*b).NimValue

Hoặc 25 byte nếu đầu vào / đầu ra có thể nhanh hơn:

(a,b)->a.ConwayProduct(b)

Vâng, tôi đã hy vọng *a**b/ a*bđể làm việc, nhưng nó không.


Chắc chắn là công cụ phù hợp cho công việc.

3

Bình thường , 21 byte

Mf-TsmmxxgkdgkHgGdGH0

Trình diễn

Sử dụng công thức phần tử loại trừ tối thiểu của phép nhân nim, như được đưa ra ở đây .

Hai bản đồ lồng nhau được sử dụng để lặp lại trên tất cả các giá trị nhỏ hơn ( mm ... GH), sau đó kết quả được làm phẳng ( s). Phần thông minh đi kèm f-T ... 0, trong đó chúng tôi lặp lại các số nguyên trở lên từ 0 để tìm phần đầu tiên không có trong tập hợp được đề cập ở trên. Bằng cách thực hiện theo cách này, chúng ta không cần tính toán giới hạn trên, tiết kiệm một vài byte.

Cuối cùng, hàm gtính toán sản phẩm nim.


3

JavaScript (ES6), 142 128 byte

f=(x,y,z=Math.log2,v=x&-x,t=z(x),u=z(y),s=t&u,r=s&-s)=>x<2|y<2?x*y:x>v?f(v,y)^f(x^v,y):y&y-1?f(y,x):r?f(f(x>>r,y>>r),3<<r-1):x*y
<div oninput=o.textContent=f(x.value,y.value)><input id=x><input id=y><pre id=o>

Bước đầu tiên là phân chia cả hai xythành một XOR quyền hạn 2, lấy các sản phẩm nim cặp của họ và sau đó XOR kết quả (vì sản phẩm nim phân phối trên XOR). Khi chúng ta đã đệ quy trường hợp xycả hai lũy thừa của 2, chúng ta lưu ý rằng các lũy thừa Fermat nhân với nhau bằng số học thông thường, do đó chúng ta có thể nhân tố xythành các lũy thừa Fermat. Nếu xykhông chia sẻ một sức mạnh Fermat, chúng ta có thể đảo ngược quá trình và chỉ cần quay lại x * y. Tuy nhiên, nếu họ chia sẻ một sức mạnh Fermat, thì chúng ta chia cả hai xybằng sức mạnh đó, tính toán sản phẩm nim, sau đó lấy sản phẩm nim với bình phương nim của sức mạnh Fermat đó. Ung dung:

function nimprod(x, y) {
    if (x < 2 || y < 2) return x * y;
    var v = x & -x;
    if (x > v) return nimprod(v, y) ^ nimprod(x ^ v, y); // nimprod distributes over ^
    if (y & (y - 1)) return nimprod(y, x); // x is a power of 2 but y is not
    var t = Math.log2(x);
    var u = Math.log2(y);
    var s = t & u;
    if (!s) return x * y; // x and y do not share a Fermat power
    var r = s & -s;
    return nimprod(nimprod(x >> r, y >> r), 3 << r - 1); // square the Fermat power
}

1

Ngôn ngữ Wolfram (Mathicala) , 81 byte

x_±y_:=Min@Complement[Range[0,x*y],##&@@Array[BitXor[x±#2,#±y,±##]&,{x,y},0]]

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

Sử dụng công thức:

αβ=mex({αβ+αβ+αβ:α<α,β<β}).

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.