Khám phá không gian xors


14

Không gian xors của một tập hợp số nguyên là tập hợp tất cả các số nguyên có thể thu được bằng cách kết hợp các số nguyên bắt đầu với toán tử xor bitwise ( ^) thông thường . Ví dụ: không gian xors (8, 4)(0, 4, 8, 12): 0 là 4 ^ 4, 12 là 4 ^ 8 và không có số nào khác có thể đạt được. Lưu ý rằng các số bắt đầu luôn được bao gồm, theo định nghĩa này (ví dụ: 4 là 4 ^ 4 ^ 4).

Mục tiêu của bạn là viết chương trình ngắn nhất lấy danh sách các số nguyên không âm làm đầu vào và xuất số lượng phần tử trong không gian xors của chúng.

  • Sơ hở tiêu chuẩn bị cấm.
  • Đầu vào và đầu ra có thể ở bất kỳ định dạng thông thường nào . Đầu vào được đảm bảo là hợp lệ, không trống và không trùng lặp.
  • Mã của bạn sẽ có thể xử lý tất cả các trường hợp thử nghiệm trong vòng chưa đầy một ngày .

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

Input: 0
Output: 1

Input: 6
Output: 2

Input: 8 4
Ouput: 4

Input: 0 256
Output: 2

Input: 256 259 3
Output: 4

Input: 60 62 94 101 115
Output: 32

Input: 60 62 94 101 115 40 91
Output: 32

Input: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
Output: 64

Input: 1 2 4 8 16 32 64 128 256 512 1024 2048 4096 8192 16384
Output: 32768

Câu trả lời:


2

Bình thường, 8 byte

lu{+xM*Q

Bộ kiểm tra

Giải trình:

Để tạo không gian xors, chúng tôi tìm điểm cố định lấy xor của mỗi cặp số, thêm vào mỗi số và lặp lại. Sau đó, chúng tôi lấy chiều dài của kết quả. Điều này chạy trong 20 giây (chỉ ngoại tuyến) trên trường hợp thử nghiệm cuối cùng.

lu{+xM*Q
lu{+xM*QGGQ    Implicit variable introduction
 u        Q    Find the fixed point of the following, starting with the input,
               where the current value is G.
      *QG      Form the Cartesian product of Q (input) and G (current)
    xM         Take the xor of every pair
   +           Add the current values
  {            Deduplicate
l              Output the length of the result.

Gói Pyth , 7 byte

Hexdump:

0000000: d9d7 dabf 1355 51                        .....UQ

Giống như trên, với mã hóa ASCII 7 bit.

Đặt ở trên trong một tệp với xxd -rvà chạy nó như sau:

py packed-pyth.py xorspace.ppyth '[256, 259, 3]'

Tôi nghĩ bạn có thể làm l{mxFdy.
xnor

@xnor yáp dụng cho trường hợp thử nghiệm 1 đến 63 là quá chậm. Tôi không có 2 ^ 63 bộ nhớ.
isaacg

10

MATL , 11 byte

t"G!Z~Ghu]n

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

Trường hợp thử nghiệm cuối cùng không chạy trong trình thông dịch trực tuyến vì giới hạn bộ nhớ, nhưng chạy ngoại tuyến trong chưa đầy 2 giây trên máy tính hiện đại.

Giải trình

Đối với đầu vào có kích thước n, điều này thực hiện như sau:

  1. Bắt đầu kết quả để đầu vào.
  2. Lặp lại nthời gian:
    1. Áp dụng XOR bitwise cho tất cả các cặp mục nhập từ kết quả hiện tại và đầu vào.
    2. Đính kèm các giá trị đầu vào vào kết quả.
    3. Khử trùng lặp.
  3. Đầu ra là số phần tử của kết quả cuối cùng.

Mã nhận xét.

t      % Implicit input: row vector. Duplicate
"      % For each (i.e. do as many times as the input size)
  G!   %   Push input as a column vector
  Z~   %   Bitwise XOR with broadcast, i.e. for all pairs of entries of the
       %   two arguments. The first argument is the accumulated result
       %   from the previous iteration, the second is the input vector
  G    %   Push input again
  h    %   Postpend
  u    %   Unique values. Gives a row vector
]      % End
n      % Number of entries. Implicitly display

Thí dụ

Các kết quả trung gian (bước 2.1 và 2.3) cho đầu vào [256 259 3]là:

Lặp lại đầu tiên: [256 259 3]với [256 259 3]: tính toán tất cả các cặp bitwise-XOR đưa ra ma trận

  0   3 259
  3   0 256
259 256   0

Đính kèm [256 259 3]và sao chép

0 3 259 256

Lặp lại thứ hai: kết quả hiện tại [0 3 259 256]với [256 259 3]. Sau khi lặp lại điều này một lần nữa cho

0 3 259 256

Lặp lại lần thứ ba: một lần nữa

0 3 259 256

Vì vậy, đầu ra là 4(số lượng mục kết quả).


Xin giải thích? Bạn không thể sử dụng O (2 ^ n).
Erik the Outgolfer

Tôi không biết nó hoạt động như thế nào, nhưng chắc chắn không phải là O (2 ^ n). Nó thực sự giải quyết trường hợp thử nghiệm (1 2 3 Vấu 63) khá nhanh, mặc dù đó là trường hợp xấu nhất đối với phương pháp vũ phu.
Grimmy

2
Làm thế nào là nhanh như vậy? Tôi đã cố gắng thực hiện khá nhiều điều tương tự trong Jelly, nhưng lần thử đầu tiên đã bị giết sau 19 phút ... (Bây giờ đang cố gắng với nhiều RAM hơn.)
Dennis

2
Tôi tin rằng đây trường hợp xấu nhất O (2ⁿ); Chỉ là trong bài kiểm tra thực hiện nó, n chỉ mới 15, nên chương trình vẫn chạy khá nhanh.

2
@ ais523 Các số trung gian thu được từ bitwise-XOR không bao giờ có thể nhận được lớn hơn số tối đa trong đầu vào, hãy gọi đó M. Vì vậy, kích thước của vectơ kết quả trung gian không bao giờ vượt quá Mvà độ phức tạp là O ( M*M). OP đã nói rằng định nghĩa chính xác về nvấn đề không quan trọng, vì vậy nếu tôi xác định nnhư Mtôi có thể khẳng định đây là O ( n*n).
Luis Mendo

8

Haskell , 64 byte

f lấy một danh sách các số nguyên và trả về một số nguyên.

import Data.Bits
f l|m<-maximum l,m>0=2*f(min<*>xor m<$>l)|0<1=1

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

Điều này không xử lý một danh sách trống, mà bạn có thể nhưng $0:thay vào đó là không gian saumaximum .

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

  • Nếu tối đa m của danh sách bằng 0, trả về 1.
  • Mặt khác, xors mọi phần tử với mức tối đa.
    • Nếu kết quả nhỏ hơn phần tử, phần tử được thay thế bởi phần tử.
    • Điều này nhất thiết phải thay đổi bit quan trọng nhất được đặt ở bất kỳ đâu trong danh sách.
    • Sau đó đệ quy trên danh sách kết quả, nhân đôi kết quả của đệ quy.
  • Quá trình này về cơ bản thực hiện loại bỏ Gaussian (mặc dù các hàng cuối cùng bằng cách đặt chúng thành 0) modulo 2, trên ma trận có các hàng là các biểu diễn bit của danh sách các số. Tập hợp các biểu diễn bit của "xorspace" là không gian vectơ modulo 2 được kéo dài bởi các hàng của ma trận này và có số phần tử bằng 2 với sức mạnh của thứ hạng hàng của ma trận.
  • Thuật toán này là thời gian đa thức, vì vậy chắc chắn nên tốt hơn O (2 ^ n).

Về cơ bản, đây là thuật toán mà tôi đã nghĩ đến (để đánh bại các giới hạn phức tạp), mặc dù đây là một cách đặc biệt tao nhã để thể hiện nó. Thật tuyệt khi thấy nó trong một câu trả lời đúng.

4

Toán học, 52 byte

2^MatrixRank[PadLeft@IntegerDigits[#,2],Modulus->2]&

Tại sao bạn xóa câu trả lời Pari / GP của bạn? Nó dường như đang làm việc tốt. EDIT: nevermind, nó đã thất bại một số trường hợp thử nghiệm thực sự.
Grimmy

@Grimy Tại sao bạn chấp nhận câu trả lời của tôi? Đây là một môn đánh gôn, mã ngắn nhất sẽ thắng.
alephalpha

Xin lỗi, tôi đã thay đổi câu trả lời được chấp nhận thành 7 byte được đóng gói Pyth.
Grimmy

3

05AB1E , 8 byte

vDy^ìÙ}g

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

Tất cả các trường hợp thử nghiệm kết thúc dưới 1 phút trên TIO.


Điều này không thành công tiêu chí cuối cùng: «Mã của bạn sẽ có thể xử lý tất cả các trường hợp thử nghiệm trong vòng chưa đầy một ngày (không có công cụ O (2 ** n)). »
Grimmy

@Grimy: Không đọc 2^nphần: /
Emigna

@Grimy: Bây giờ được cập nhật để hoàn thành tất cả các trường hợp thử nghiệm trong vòng dưới 1 phút (và sử dụng ít byte hơn)
Emigna

Đã suy nghĩ âü^Ùgcho đến khi tôi thấy bạn có thể xor nhiều lần, giải pháp tốt đẹp.
Bạch tuộc ma thuật Urn

@carusocomputing: Điều đó tiết kiệm một byte, nhưng tôi không chắc về sự phức tạp.
Emigna


2

Thạch , 9 8 byte

0œ|⁺^¥/L

Kết thúc tất cả các trường hợp thử nghiệm dưới 8 giây trên TIO, với yêu cầu bộ nhớ không đáng kể.

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

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

0œ|⁺^¥/L  Main link. Argument: A (array)

0œ|       Perform multiset union with 0, prepending 0 if A doesn't contain it.
      /   Reduce A by the link to the left.
     ¥      Combine the previous two links into a dyadic chain.
            Left argument: V (array). Right argument: n (integer)
    ^           Bitwise XOR each element in V with n.
   ⁺            This quick refers to the previous link, making it a shorthand for
                the link 'œ|'. Thus, it performs multiset union on V and the array
                of bitwise XORs.
       L  Compute the length of the result.

1

Python, 113 byte

def f(x):
 u,s=[0],{0}
 while u:
	a=u.pop()
	for b in x:
	 c=a^b
	 if c not in s:u+=[c]
	 s.add(c)
 return len(s)

Nó hoạt động, nhưng tôi đang đếm 113 byte; tôi có bỏ lỡ điều gì không?
Grimmy

@totallyhuman có lẽ vì bạn đang tính các bảng là 8 byte, thay vì một byte đơn.
Grimmy

Nếu vết lõm đầu tiên là một khoảng trắng, thì cái tiếp theo là một tab và cái cuối cùng là một tab + một khoảng
trắng

@Grimy Trên thực tế, mỗi tab có 4 khoảng không 8.
Erik the Outgolfer

Một chương trình đầy đủ sẽ ngắn hơn, vì nó tiết kiệm được một ít vết lõm. Ngoài ra, vòng lặp for có thể được cô đọng thành một dòng duy nhất, u+=[c][c in s:]tương đương với ifcâu lệnh của bạn .
Dennis
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.