Tạo chuỗi còn lại tối thiểu


21

Mỗi số có thể được biểu diễn bằng một chuỗi còn lại dài vô hạn. Ví dụ: nếu chúng ta lấy số 7 và thực hiện 7mod2, sau 7mod3đó 7mod4, v.v., chúng ta sẽ nhận được 1,1,3,2,1,0,7,7,7,7,.....

Tuy nhiên, chúng ta cần phần còn lại ngắn nhất có thể vẫn có thể được sử dụng để phân biệt với tất cả các số thấp hơn. Sử dụng 7 lần nữa, [1,1,3]là lần tiếp theo ngắn nhất, bởi vì tất cả các lần trước đó không bắt đầu bằng [1,1,3]:

0: 0,0,0,0...
1: 1,1,1,1...
2: 0,2,2,2...
3: 1,0,3,3...
4: 0,1,0,4...
5: 1,2,1,0...
6: 0,0,2,1...

Lưu ý rằng [1,1] không hoạt động để đại diện cho 7, bởi vì nó cũng có thể được sử dụng để đại diện cho 1. Tuy nhiên, bạn nên xuất ra [1]với đầu vào là 1.

Đầu ra đầu vào

Đầu vào của bạn là một số nguyên không âm. Bạn phải xuất một chuỗi hoặc danh sách các chuỗi còn lại có độ dài tối thiểu như được xác định ở trên.

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

0: 0
1: 1
2: 0,2
3: 1,0
4: 0,1
5: 1,2
6: 0,0,2
7: 1,1,3
8: 0,2,0
9: 1,0,1
10: 0,1,2
11: 1,2,3
12: 0,0,0,2
30: 0,0,2,0
42: 0,0,2,2
59: 1,2,3,4
60: 0,0,0,0,0,4
257: 1,2,1,2,5,5
566: 0,2,2,1,2,6,6
1000: 0,1,0,0,4,6,0,1
9998: 0,2,2,3,2,2,6,8,8,10
9999: 1,0,3,4,3,3,7,0,9,0

Dưới đây là 10.000 chuỗi đầu tiên , trong trường hợp bạn quan tâm (số dòng bị tắt bởi 1).

Đây là một , vì vậy hãy làm cho nó ngắn nhất có thể bằng ngôn ngữ yêu thích của bạn. Điểm thưởng giả cho bất kỳ câu trả lời nhanh chóng!



@nimi chúng tôi đã nói về điều đó trong trò chuyện, và tôi đã quyết định rằng các chuỗi cần dài ít nhất 1 yếu tố.
Nathan Merrill

1
Tôi hơi ngạc nhiên khi bạn không giới hạn nó ở phần còn lại chính.
Neil

Có ổn không nếu đầu ra được trả về trong một danh sách?
R. Kap

@neil, tôi cũng đã xem xét điều đó, nhưng vì phần còn lại khác với số tổng hợp, tôi đã bỏ phiếu để giữ nó
Nathan Merrill

Câu trả lời:


5

Toán học, 60 53 byte

#~Mod~FirstCase[2~Range~#&/@Range[#+2],x_/;LCM@@x>#]&

Hơi nhanh (nó xử lý 10000 trong ~ 0,1 giây, nhưng có thể sẽ hết bộ nhớ trong 100000).

Mã ném một lỗi nhưng tính toán kết quả chính xác.

Giải trình

Chúng tôi đã tìm thấy trước đó trong cuộc trò chuyện rằng các ước số được yêu cầu luôn có thể được xác định là danh sách ngắn nhất {1, 2, ..., n}có bội số chung nhỏ nhất vượt quá đầu vào. Một lập luận ngắn cho lý do đó là: nếu LCM nhỏ hơn đầu vào, thì việc trừ LCM khỏi đầu vào sẽ khiến tất cả các ước số không thay đổi, do đó biểu diễn không phải là duy nhất. Tuy nhiên, đối với tất cả các đầu vào nhỏ hơn LCM, phần dư sẽ là duy nhất, nếu không, sự khác biệt giữa hai số có phần dư bằng nhau sẽ là bội số nhỏ hơn của tất cả các ước.

Đối với mã ... như thường lệ, thứ tự đọc của Mathicala được đánh gôn là một chút buồn cười.

Range[#+2]

Điều này cho chúng tôi một danh sách [1, 2, 3, ..., n+2]cho đầu vào n. Các +2là để đảm bảo rằng nó hoạt động một cách chính xác cho 01.

2~Range~#&/@...

Bản đồ 2~Range~#(cú pháp đường cho Range[2,#]) trong danh sách này, vì vậy chúng tôi nhận được

{{}, {2}, {2,3}, ..., {2,3,...,n+2}}

Đây là những danh sách chia cho ứng viên (tất nhiên nói chung là nhiều hơn chúng ta cần). Bây giờ chúng tôi tìm thấy một trong số họ đầu tiên có LCM vượt quá đầu vào với:

FirstCase[...,x_/;LCM@@x>#]

Thêm cú pháp: x_là một mẫu phù hợp với bất kỳ danh sách nào và gọi nó x. Các /;điều kiện gắn liền với mô hình đó. Điều kiện này là LCM@@x>#nơi @@ áp dụng chức năng cho danh sách, nghĩa LCM@@{1,2,3}LCM[1,2,3].

Cuối cùng chúng ta chỉ đơn giản nhận được tất cả số còn lại, làm cho việc sử dụng thực tế là ModListable, tức là nó tự động bản đồ trên một danh sách nếu một trong số các đối số là một danh sách (hoặc nếu cả hai trong số đó là danh sách các độ dài tương tự):

#~Mod~...

5

Thạch , 14 byte

‘Ræl\>iṠ2»2r⁸%

Điều này sử dụng thực tế một giải pháp (nếu có) của một hệ thống đồng quy tuyến tính là mô đun duy nhất LCM của mô đun. Hãy thử trực tuyến! hoặc xác minh tất cả các trường hợp thử nghiệm .

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

‘Ræl\>iṠ2»2r⁸%  Main link. Argument: n

‘               Increment; yield n+1.
 R              Range; yield [1, ..., n+1].
  æl\           Cumulatively reduce by LCM.
                This yields [LCM(1), ..., LCM(1, ..., n+1)].
     >          Compare all LCMs with n.
      iṠ        Find the first index of sign(n).
                This yields the first m such that LCM(2, ..., m) > n if n > 0, and
                0 if n == 0.
        2»      Take the maximum of the previous result and 2, mapping 0 to 2.
          2r    Yield the range from 2 up to and including the maximum.
            ⁸%  Compute n modulo each integer in that range.

5

MATL , 24 byte

Cảm ơn @nimi đã chỉ ra một lỗi trong phiên bản trước của câu trả lời này (hiện đã được sửa)

Q:qtQ!\t0Z)tb=YpsSP2):Q)

Điều này hết bộ nhớ trong trình biên dịch trực tuyến cho hai trường hợp thử nghiệm lớn nhất (nhưng nó hoạt động trên máy tính có RAM 4 GB).

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

Giải trình

Điều này áp dụng định nghĩa một cách đơn giản. Đối với đầu vào nnó sẽ tính toán một mảng 2D chứa mod(p,q)với ptừ 0để nqtừ 1đến n+1. Mỗi cái plà một cột, và mỗi cái qlà một hàng. Ví dụ, với đầu vào n=7mảng này là

0 0 0 0 0 0 0 0
0 1 0 1 0 1 0 1
0 1 2 0 1 2 0 1
0 1 2 3 0 1 2 3
0 1 2 3 4 0 1 2
0 1 2 3 4 5 0 1
0 1 2 3 4 5 6 0
0 1 2 3 4 5 6 7

Bây giờ cột cuối cùng, chứa phần còn lại của n, là phần tử so với từng cột của mảng này. Sản lượng này

1 1 1 1 1 1 1 1
0 1 0 1 0 1 0 1
0 1 0 0 1 0 0 1
0 0 0 1 0 0 0 1
0 0 1 0 0 0 0 1
0 1 0 0 0 0 0 1
1 0 0 0 0 0 0 1
0 0 0 0 0 0 0 1

trong đó 1chỉ ra sự bình đẳng. Cột cuối cùng rõ ràng là bằng chính nó và do đó chứa tất cả những cái. Chúng ta cần tìm cột có số lượng lớn nhất của cột đầu tiên , ngoài cột cuối cùng và lưu ý số lượng cột ban đầu đó , m. (Trong trường hợp này, đó là cột thứ hai, chứa cột m=3đầu tiên). Để kết thúc này, chúng tôi tính toán sản phẩm tích lũy của từng cột:

1 1 1 1 1 1 1 1
0 1 0 1 0 1 0 1
0 1 0 0 0 0 0 1
0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 1

sau đó tổng của mỗi cột

1 3 1 2 1 2 1 8

và sau đó sắp xếp không ngày càng tăng và lấy giá trị thứ hai, đó là 3. Đây là mong muốn m, cho biết chúng ta cần chọn bao nhiêu phần còn lại.

Q:q    % take input n implicitly. Generare row array [0 1 ... n]
tQ!    % duplicate. Transform into column array [1; 2; ...; n-1]
\      % modulo, element-wise with broadcast. Gives the 2D array
t0Z)   % duplicate. Take last column
tb     % duplicate, bubble up
=      % test for equality, element-wise with broadcast
Yp     % cumumative product of each column
s      % sum of each column. This gives the number of initial coincidences
SP2)   % sort in decreasing order and take second value: m
:Q     % generate range [2 3 ... m+1]
)      % apply as index into array of remainders of n. Implicitly display

4

Thạch , 13 11 byte

r¬µ%€R‘$ḟ/Ṫ

Điều này sẽ không giành được bất kỳ điểm brownie vận tốc nào ... Hãy thử trực tuyến! hoặc xác minh các trường hợp thử nghiệm nhỏ hơn .

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

r¬µ%€R‘$ḟ/Ṫ  Main link. Argument: n

r¬           Range from n to (not n).
             This yields [n, ..., 0] if n > 0 and [0, 1] otherwise.

  µ          Begin a new, monadic chain. Argument: A (range)

       $     Combine the previous two links into a monadic chain:
     R         Range; turn each k in A into [1, ..., k] or [] if k == 0.
      ‘        Increment to map k to [2, ..., k+1].
   %€        Take each k in A modulo all the integers in the 2D list to the right.
        ḟ/   Reduce by filter-not; sequentially remove all remainder sequences of
             n-1, ..., (not n) from the remainder sequences of n.
          Ṫ  Tail; take the last remainder sequence.
             This gives the shortest sequence for descending A and the longest one
             (i.e., [0]) for ascending A.

Tại sao bạn bao gồm hai câu trả lời ???
Erik the Outgolfer

Bởi vì chúng là hai cách tiếp cận hoàn toàn khác nhau. Mặc dù cái này ngắn hơn 3 byte, nhưng cái kia thực sự đủ nhanh để tính toán tất cả các trường hợp thử nghiệm.
Dennis

Nếu tôi là bạn, tôi sẽ không làm điều đó ... ngoại trừ nếu đó là một điều bỏ phiếu lên / xuống.
Erik the Outgolfer


3

Python 3.5, 117 95 78 byte

import sympy
r=lambda n,m=2,M=1,*l:M>n and l or r(n,m+1,sympy.lcm(m,M),*l,n%m)

Yêu cầu Python 3.5 và sympy ( python3 -m pip install --user sympy). Tín dụng cho @Dennis để thông báo cho tôi rằng Python 3.5 cho phép *llừa với các đối số mặc định.


Với SymPy 0.7.5, bạn có thể rút ngắn M>n and ltới l*(M>n).
Dennis

3

Python 2, 73 70 69 65 byte

i=l=1
n=input()
while l<=n|1:
 i+=1;a=l;print n%i
 while l%i:l+=a

Một chương trình đầy đủ. @Dennis đã lưu 4 byte bằng cách cải thiện cách xử lý zero.


3

Haskell, 66 60 51 50 byte

f i=mod i<$>[2..2+sum[1|l<-scanl1 lcm[2..i],l<=i]]

Ví dụ sử dụng: f 42-> [0,0,2,2]. Đó là thuật toán được mô tả trong câu trả lời của @Martin Büttner .

Tôi sẽ giữ phiên bản trước để tham khảo, vì nó khá nhanh:

Haskell, 51 byte

f i=mod i<$>[[2..x]|x<-[2..],foldl1 lcm[2..x]>i]!!0

Phải mất 0,03 giây cho f (10^100)máy tính xách tay năm tuổi của tôi.

Chỉnh sửa: @xnor tìm thấy một byte để lưu. Cảm ơn!


Lưu một byte bằng cách đếm các chỉ số cho đến khi lcm tăng quá cao:h i=mod i<$>[2..2+sum[1|l<-scanl1 lcm[2..i],l<=i]]
xnor

2

Pyth, 51 byte 66 byte

IqQZ[Z).q)IqQ1[1))IqQ2,0 1))FdhhQJu/*GHiGHtUd1I>JQVQ aY%QhN)<tYd.q

Hãy thử nó!

Phiên bản 39 byte tốc độ cao hơn nhiều (không hoạt động trong 0-2):

FdhhQJu/*GHiGHtUd1I>JQVtd aY%QhN)<tYd.q

Nó dường như hoạt động với số lượng lớn vô lý như 10 10 3

Lưu ý: câu trả lời này không hoạt động cho 0, 1 và 2. Đã sửa !


2

JavaScript (ES6), 81 77 byte

f=(n,r=[n%2],l=i=2,g=(j,k)=>j?g(k%j,j):k)=>l>n?r:f(n,[...r,n%++i],i/g(i,l)*l)

Điều này đệ quy xây dựng câu trả lời cho đến khi LCM vượt quá số ban đầu. GCD cũng được tính toán đệ quy, tất nhiên.

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


@ user81655 Đó chỉ là đồ lót ...
Neil

2

Ruby, 52 byte

->n{m=t=1;a=[];(a<<n%m)until n<t=t.lcm(m+=1);a<<n%m}

Giải pháp này kiểm tra mọi khả năng mbắt đầu từ 2 là phần còn lại làm cho chuỗi duy nhất. Điều làm nên sự mđộc đáo cuối cùng không phải là phần còn lại, mà mlà thành viên cuối cùng của phạm vi nhỏ nhất (2..m)trong đó bội số chung (LCM) ít nhất của phạm vi đó lớn hơn n. Điều này là do Định lý còn lại của Trung Quốc, trong đó để xác định duy nhất số nào nvới số lượng còn lại, LCM của các phần còn lại phải lớn hơn n(nếu chọn ntừ (1..n); nếu chọn ntừ a..b, LCM chỉ cần lớn hơn b-a)

Lưu ý: Tôi đặt a<<n%mở cuối mã bởi vì until n<t=t.lcm(m+=1)các mạch ngắn trước đó ađã nhận được phần tử cuối cùng để làm cho nó là duy nhất.

Nếu bất cứ ai có bất kỳ đề nghị chơi golf, xin vui lòng cho tôi biết trong các ý kiến ​​hoặc trong trò chuyện PPCG .

Ungolfing:

def remainder_sequence(num)
  # starting with 1, as the statements in the until loop immediately increments divisor
  divisor = 1
  # starts with 1 instead of 2, as the statements in the until loop
  # immediately change product to a new lcm
  product = 1
  remainders = []

  # this increments divisor first then checks the lcm of product and divisor
  # before checking if num is less than this lcm
  until num < (product = product.lcm(divisor = divisor + 1))
    remainders << num % divisor
  end

  # until always short circuits before the last element is entered
  # so this enters the last element and returns
  return remainders << num % divisor
end


1

Python 3.5, 194 181 169 152 149 146 byte:

( Cảm ơn @ Sherlock9 vì 2 byte! )

def r(o,c=0):
 y=[[j%i for i in range(2,100)]for j in range(o+1)]
 while 1:
  c+=1;z=y[-1][:c]
  if z not in[f[:c]for f in y[:-1]]:break
 print(z)

Hoạt động hoàn hảo, và cũng khá nhanh chóng. Tính toán cho chuỗi 100000đầu ra còn lại tối thiểu [0, 1, 0, 0, 4, 5, 0, 1, 0, 10, 4, 4]và chỉ mất khoảng 3 giây. Nó thậm chí còn có thể tính toán chuỗi cho đầu vào 1000000(1 triệu), đầu ra [0, 1, 0, 0, 4, 1, 0, 1, 0, 1, 4, 1, 8, 10, 0, 9]và mất khoảng 60 giây.

Giải trình

Về cơ bản những gì chức năng này thực hiện được trước hết là tạo ra một danh sách, yvới tất cả các j mod inơi jlà mỗi số nguyên trong phạm vi 0=>7(bao gồm 7) và ilà mỗi số nguyên trong phạm vi 0=>100. Chương trình sau đó đi vào một whilevòng lặp vô hạn và so sánh cùng một số lượng nội dung của từng danh sách con trong danh sách con thứ nhất đến thứ hai của danh sách con y( y[:-1:]) với cùng số lượng mục trong danh sách con cuối cùng ( y[-1]) của danh sách y. Khi sublist y[-1]khác nhau hơn bất kỳ sublist khác, vòng lặp được chia ra, và trình tự còn lại tối thiểu đúng được trả về.

Chẳng hạn, nếu đầu vào là 3, ysẽ là:

[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2], [1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3]]

Sau đó, khi nó đi vào vòng lặp while, nó sẽ so sánh từng danh sách con trong danh sách y[:-1:]với cùng số lượng mục trong danh sách phụ y[-1]. Ví dụ, đầu tiên nó sẽ so sánh [[0],[1],[0]][1]. Vì danh sách con cuối cùng nằm trong phần còn lại y, nên nó sẽ tiếp tục và sau đó so sánh [[0,0],[0,1],[0,2]][1,0]. Vì [1,0]bây giờ KHÔNG ở phần còn lại của y thứ tự cụ thể đó, đó là chuỗi nhắc nhở tối thiểu, và do đó, [1,0]sẽ được trả lại chính xác.


Để lưu byte, y[:c:]giống nhưy[:c]
Sherlock9

0

C89, 105 byte

g(a,b){return b?g(b,a%b):a;}main(n,m,M){scanf("%d",&n);for(m=M=1;(M=++m*M/g(m,M))<=n;)printf("%d ",n%m);}

Biên dịch (có cảnh báo) bằng cách sử dụng gcc -std=c89. Lấy một số duy nhất trên stdin và đưa ra chuỗi các phần dư được phân tách bằng khoảng trắng trên thiết bị xuất chuẩn.


1
Điều này không in bất cứ điều gì khi n = 0
xsot

0

C, 89 byte

a,i=2;main(l,n){for(n=atoi(gets(n))?:!puts(n);n/l;printf("%d ",n%i++))for(a=l;l%i;l+=a);}

Biên dịch với gcc. Dùng thử trực tuyến: n = 59 , n = 0 .

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.