Chia hết cho 1000003? Dễ dàng, chỉ cần nhân số cuối cùng với 300001 và thêm!


16

Với một số nguyên tố Plớn hơn 10, chương trình hoặc hàm của bạn phải tìm ra quy tắc chia hết của nó x, được định nghĩa là số nguyên có giá trị tuyệt đối nhỏ nhất mang lại bội số của số nguyên tố ban đầu khi nhân với chữ số cuối của số nguyên tố và được thêm vào phần còn lại của số nguyên tố nguyên tố.

Thí dụ

Cho một đầu vào 31, chữ số cuối cùng là 1và phần còn lại của số là 3. Do đó, chương trình của bạn phải tìm số nguyên xcó giá trị tuyệt đối tối thiểu sao cho 1*x + 3là bội số của 31. Trong trường hợp này, x=-3hoạt động, vì vậy chương trình hoặc chức năng sẽ trở lại -3.

Cho một đầu vào 1000003, chữ số cuối cùng là 3và phần còn lại của số là 100000. Do đó, chương trình của bạn sẽ tìm thấy x=300001bởi vì 3*300001+100000 = 1000003đó là bội số của 1000003.

Bối cảnh toán học

Giá trị của xcó thể được sử dụng như một thử nghiệm chia hết. Nếu một số Nchia hết cho P, thì việc xnhân số chữ số cuối cùng Nvới phần còn lại Nsẽ mang lại bội số của Pnếu và chỉ khi Nchia hết cho Pvị trí đầu tiên.

Đối với P=11, chúng tôi nhận được x=-1, tương đương với quy tắc chia hết được biết đến cho 11: một số chia hết cho 11các chữ số khác nhau của nó là chia hết cho 11.

Quy tắc

  • Đầu ra có thể ở bất kỳ dạng nào mã hóa rõ ràng cả dấu hiệu và giá trị của đầu ra.
  • Số nguyên tố đầu vào sẽ nằm trong khoảng từ 10 đến 2 ^ 30.
  • Bạn không cần phải xử lý nếu đầu vào không phải là số nguyên tố hoặc không nằm trong phạm vi.
  • Bạn không cần phải xử lý nếu cả hai x-xlà đầu ra hợp lệ (không nên xảy ra).
  • Lực lượng vũ phu được cho phép, nhưng các giải pháp sáng tạo hơn được đánh giá cao.
  • Đây là , vì vậy mã ngắn nhất trong mỗi ngôn ngữ sẽ thắng! Đừng để câu trả lời trong các ngôn ngữ chơi gôn ngăn cản bạn đăng bài bằng các ngôn ngữ khác.

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

Input   Output
11  -1
13  4
17  -5
19  2
23  7
29  3
31  -3
37  -11
41  -4
43  13
47  -14
53  16
59  6
61  -6
67  -20
71  -7
73  22
79  8
83  25
89  9
97  -29
101 -10
103 31
107 -32
109 11
113 34
127 -38
131 -13
1000003 300001
2000003 600001
2999999 300000
9999991 -999999

3
Một đơn giản hóa hữu ích: chúng tôi đang tìm kiếm xgiá trị nhỏ nhất tuyệt đối trong đó 10*x-1chia hết cho đầu vào.
xnor

Bất cứ ai cũng có thể cung cấp một gợi ý tại sao (3 / (n % 5 * 2 - 5) * n + 1) / 10(n % 5 * 2 - 5^2) * n / 10 + 1có thể tìm thấy một giá trị tuyệt đối tối thiểu cho một cái gì đó như thế này? Trực giác đầu tiên của tôi sẽ là tính toán bội số chung nhỏ nhất bằng cách sử dụng ước số chung lớn nhất được tính toán bằng thuật toán của Euclid.
David Foerster

1
@DavidFoerster Cho một số, bạn có thể xóa chữ số cuối cùng, nhân số đó với một số x, thêm nó vào và vẫn nhận được một số chia hết cho n. Nếu sau đó chúng ta nhân số mới với 10 và trừ số ban đầu thì nó vẫn chia hết cho n. Nhận xét của xnor sau đó theo một số đại số. Bước tiếp theo là sắp xếp lại công thức sao cho phù xhợp n: x = (k*n+1)/10. Chúng tôi muốn tuyệt đối nhỏ nhất x, bởi vậy chúng tôi muốn tuyệt đối nhỏ k, và điều này phải bất cứ một trong những -3, -1, 1hoặc 3(tùy thuộc vào n's chữ số cuối cùng) mà làm cho các bộ phận chính xác.
Neil

Câu trả lời:


14

JavaScript (ES6), 32 25 23 byte

f=
n=>(3/(n%5*2-5)*n+1)/10
<input type=number min=1 oninput=o.textContent=this.value%5*(this.value%2)?f(this.value):``><pre id=o>

3/(n%5*2-5)sẽ được viết 9/n(mod -10)nếu tôi có quyền truy cập vào phân chia modulo cân bằng. Chỉnh sửa: Đã lưu 2 byte nhờ @EgorSkriptunoff


3
Bạn có thể lưu 2 byte bằng cách thay thế n=>((n%10*2%14-3)*n+1)/10bằngn=>(3/(n%5*2-5)*n+1)/10
Egor Skriptunoff


@KevinCruijssen Có lẽ là một polyglot gần như bỏ lỡ cho Java 8 quá ... oh chờ đã, tôi thấy câu trả lời của bạn ngay bây giờ!
Neil

@Neil Bạn nói đúng. Tôi thường đăng câu trả lời Java, vì vậy tôi đã làm việc trên một cổng của xnor khi tôi thấy câu trả lời của bạn. Đăng nó theo cách nào đó như là một cổng nhàm chán tín dụng bạn.
Kevin Cruijssen

8

Python 2 , 27 byte

lambda n:(n%5*2-5^2)*n/10+1

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

Các hoạt động được thực hiện từ trái sang phải : (((n%5)*2)-5)^2.

Tôi đã sử dụng trình giả mạo số học của mình để tìm biểu thức n%5*2-5^2để thực hiện {1:-1,3:3,2:-3,4:1}[k], đưa nghịch đảo âm của phần dư 5 vào phạm vi [-2..2].


Là bác sĩ vũ phu số học này có sẵn công khai ở đâu đó không?
Lynn

Đó có phải là biểu thức duy nhất mà nó tìm thấy hay nó chỉ in biểu thức đầu tiên có độ dài nhất định? ( 3/(n%5*2-5)có cùng độ dài với (n%5*2-5^2).)
Neil

@Lynn Không, tôi có thể dọn dẹp và đăng nó khi có thời gian.
xnor

1
@Neil Nó chỉ tìm thấy tương đương và n%5*2-6^3. Tôi chỉ nhìn lên chiều dài mặc dù biểu thức không có parens, trong khi đó 3/(n%5*2-5)là hai ký tự dài hơn nhưng tiết kiệm được các parens bên ngoài do được ưu tiên. Tìm kiếm biểu thức của độ dài này sẽ mất một thời gian. Ca sử dụng này đề xuất một tùy chọn chỉ tìm các biểu thức có thể được sử dụng trong ngữ cảnh cụ thể thông qua hoạt động ngoài cùng của chúng có mức độ ưu tiên đủ cao.
xnor





5

Japt , 16 9 byte

Cách lưu quá nhiều byte nhờ một quan sát của @xnor

_*AÉ vU}c

Kiểm tra nó trực tuyến! Có thể mất một vài giây trên đầu vào lớn hơn.

Giải trình

_  *AÉ  vU}c    Implicit: U = input integer
Z{Z*A-1 vU}c    Ungolfed
Z{        }c    Loop through each integer Z in [0, -1, 1, -2, ...] and yield the first where
  Z*A             Z times 10
     -1           minus 1
        vU        is divisible by the input.
                Implicit: output result of last expression




1

Python 2 , 44 43 byte

(Bỏ qua 44 vẫn là 44.) Cảm ơn Fireflame241 vì đã tiết kiệm một byte!

P=input();i=P/3
while i*10%P-1:i-=1
print i

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

Có chính xác một số giữa 0P-1đó là một số nghịch đảo 10. Nhưng nếu nghịch đảo đó uxảy ra lớn hơn P/2, thì đó (u-P)cũng là nghịch đảo và có giá trị tuyệt đối nhỏ hơn u. Vì vậy, hóa ra chúng ta thực sự đang tìm kiếm số duy nhất xgiữa -P/2P/2đó là số nghịch đảo 10.

Đoạn mã trên thực hiện chính xác điều đó, bắt đầu từ (tầng của) P/2và bước xuống dưới cho đến khi đạt được nghịch đảo. Điều này phải xảy ra đối với một số số lớn hơn -P/2miễn Plà số nguyên tố lớn hơn 10. Chính xác hơn, nó sẽ chấm dứt nếu và chỉ khi Plà đồng thời 10.

Chỉnh sửa: Thực tế hóa ra xlà được đảm bảo ở giữa -P/3P/3, vì vậy phiên bản hiện tại bắt đầu từ P/3và bước xuống từ đó. Xem phần có nhãn Giới hạn được cải thiện để biết giải thích về điều này.

Giải thích toán học

Nó không rõ ràng ngay lập tức với tôi tại sao thử nghiệm phân chia hoạt động. Đây là một lời giải thích, trong trường hợp bất cứ ai khác đang tự hỏi.

Hãy Plà một số nguyên tố, lớn hơn 10, có chữ số cuối cùng b. Như vậy

P = 10a + b

ở đâu a > 0, và 0 <= b < 10. Trong thực tế blà một trong hai 1, 3, 7, hoặc 9, bởi vì một lớn hơn thủ hơn 10phải kết thúc bằng một trong các chữ số.

Bây giờ giả sử bx + a = 0 (mod P). Sau đó

a = -bx (mod P)

10a + b = 10(-bx) + b (mod P)

0 = 10(-bx) + b (mod P)

0 = b(1 - 10x) (mod P)

Plà số nguyên tố, các số nguyên mod Plà một miền tích phân . Vì vậy, hoặc b = 0 (mod P), hoặc 1 - 10x = 0 (mod P).

Chúng tôi biết 0 <= b < 10 < P, vì vậy nếu b = 0 (mod P)sau đó b = 0. Nhưng chúng tôi đã nói bđược một trong hai 1, 3, 7, hoặc 9, vì vậy đây là không thể. Do đó 1 - 10x = 0 (mod P), vì vậy 10x = 1 (mod P). Nói cách khác, xlà nghịch đảo của 10modulo P.

Bây giờ giả sử Nlà một số nguyên không âm có chữ số cuối cùng d, vì vậy N = 10c + d. chúng tôi có một chuỗi các câu lệnh tương đương:

10c + d = 0 (mod P)

<==> 10xc + dx = 0 (mod P)

<==> c + dx = 0 (mod P)

QED.

Hữu ích?

Tôi cũng đã tự hỏi liệu thử nghiệm chia hết (được đưa ra N = 10c + d, thay thế Nbằng dx + c) có thực sự hiệu quả trong thực tế hay không. Hoặc ít nhất, nó có đáng tin cậy thay thế Nbằng một số nhỏ hơn N(về giá trị tuyệt đối) không?

Giả sử N = 10c + d, ở đâu c >= 00 <= d < 10. Do đó 10c = N - d <= N. Theo bất đẳng thức tam giác,

|c + dx| <= |c| + |dx| = c + d|x| <= N/10 + d|x|

< N/10 + 10|x| <= N/10 + 10P/2 = N/10 + 5P

Như vậy 5P <= 9N/10, nếu , sau đó |c + dx| < N.

Đặc biệt, nếu N >= 6P, sau đó |c + dx| < N. Như vậy, cho Pchúng ta bắt đầu bằng cách tính toán 2P, 3P, ..., 6P, cùng với x. Sau đó, cho N, chúng tôi chạy thử nghiệm chia hết liên tục cho đến khi chúng ta đạt được một số nhỏ hơn hoặc bằng đến 6P, và kiểm tra xem kết quả là bất kỳ con số 0, P, 2P, ..., 6P.

(Tất nhiên, bất cứ khi nào chúng ta đạt đến một số âm, chúng ta sẽ thay thế nó bằng giá trị tuyệt đối của nó, điều này là tốt vì qnó chia hết cho Pkhi và chỉ khi (-q)là.)

Giới hạn được cải thiện

Tôi nhận thấy rằng |x|/Pdường như không bao giờ gần gũi 1/2. Trên thực tế, có vẻ như nó luôn nhỏ hơn 1/3... hoặc khi kiểm tra kỹ hơn, nó luôn ở rất gần 1/10hoặc3/10 . Lớn nhất nó từng có vẻ là 4/13(xảy ra khi P=13x=4). Tại sao điều này sẽ được?

Hãy ulà một số nguyên và giả sử rằng 10u = kP + 1đối với một số nguyên k, uthì nghịch đảo của 10modulo P. Sau đó, chúng ta cũng biết rằng ktương đối chính10 , vì k(-P)tương đương với 1modulo 10.

Bây giờ, chúng ta biết rằng tất cả các nghịch đảo của 10modulo Pđều khác nhau theo bội số P, vì vậy chúng ta có thể lấy số nguyên uvà cộng hoặc trừ bội số của Pý chí, và kết quả sẽ luôn là nghịch đảo của 10modulo P. Giả sử chúng ta chọn để trừ Ptừ u: chúng tôi nhận

10(u - P) = 10u - 10P = kP + 1 - 10P

10(u - P) = (k - 10)P + 1

Nói cách khác, giảm (tương ứng, tăng) ubởi Ptương ứng với giảm (tăng) kbởi 10. Chúng tôi muốn thêm / bớt bội số củaP từ ucho đến khi phía bên trái tay được giảm thiểu về giá trị tuyệt đối; nhưng phía bên trái tay được giảm thiểu một cách chính xác khi phía bên tay phải được giảm thiểu, và vì vậy chúng tôi muốn thêm / bớt 10từ kcho đến khi phía bên tay phải được giảm thiểu về giá trị tuyệt đối.

Nhưng chúng ta biết rằng điều này sẽ xảy ra khi klà giữa -55, và do đó (vì klà tố cùng nhau với 10) phương tiện này klà một trong hai -3, -1,1 , hoặc 3. (Đây là nội dung bình luận của @ Neil trong OP. Cảm ơn, Neil! )

Vì vậy khi |u|được giảm thiểu (ví dụ u=x), chúng tôi sẽ có x/P = u/P = k/10 + 1/(10P), nơi klà một trong hai -3, -1, 1, hoặc3 . Do đó |x|/P <= 3/10 + 1/(10P). Tương đương , |x| <= (3P + 1)/10.

Hơn nữa, sự bất bình đẳng này là nghiêm ngặt tại P=11, bởi vì tại P=11chúng ta có x=-1k=-1. Nhỏ nhấtP mà bình đẳng giữ là P=13(ở đâu x=4k=3).

Do đó, số tiền lớn nhất |x|/Ptừng có là 3/10 + 1/(10*13)bởi vì đây P=13là số nguyên tố đầu tiên mà chúng ta có k=3và trong số đó có k=3số hạng 1/(10P)lớn nhất khi Pnhỏ nhất (ví dụ: tại P=13). Do đó, đối với tất cả P, chúng ta cũng có |x|/P <= 3/10 + 1/130 = 4/13 < 1/3. Điều này giải thích tại sao trong đoạn mã trên chúng ta có thể khởi tạo i = P/3thay vì phải bắt đầu tại P/2.

Hơn nữa, các giới hạn trong phần Hữu ích ở trên có thể được cải thiện.

Bổ đề : Hãy để N = 10c + dnơi c > 00 <= d <= 9. Sau đó c + d|x| < N/10 + 9(3P + 1)/10. (Lưu ý sự bất bình đẳng nghiêm ngặt.)

Bằng chứng bổ đề: bằng các trường hợp. Trường hợp I : d = 0, vì vậy N = 10c. Sau đó c + d|x| = c = N/10 < N/10 + 9(3P + 1)/10.

Trường hợp II : 0 < d <= 9. Sau đó10c = N - d < N , vì vậy c < N/10. Do đó c + d|x| < N/10 + d|x| <= N/10 + 9|x| <= N/10 + 9(3P + 1)/10. QED.

Như vậy, nếu N > 3P(và N = 10c + dnhư trước), thì

3P + 1 <= N

9(3P + 1)/10 <= 9N/10

N/10 + 9(3P + 1)/10 <= N

c + d|x| < N/10 + 9(3P + 1)/10 <= N

Vì thế nếu N > 3P sau đó c + d|x| < N.

Do đó, chúng ta chỉ phải tìm P, 2P3P, cùng với x. Cho N > 0, trong khi N > 3P, chúng tôi thay thế Nbởi |c + dx|, mà giảm N. Cuối cùng, chúng tôi sẽ nhận được N <= 3P; tại thời điểm đó, chúng tôi dừng lại và kiểm tra xem Nlà tương đương với bất kỳ con số 0, P,2P , hoặc 3P.

Chúng ta không thể làm tốt hơn 3Pnói chung. Ví dụ, giả sử P = 13N = 39, vì vậy x = 4. Sau đó thay thế Nbằng dx + c = 9(4) + 3Nkhông đổi.


Giải thích rất hay! Bạn có thể lưu một byte bằng cách di chuyển -1bên ngoài dấu ngoặc đơn: 43 byte
fireflame241

@ fireflame241 Cảm ơn bạn rất nhiều! Tôi có thể tuyên bố rằng tôi đã để nó ở tuổi 44 chỉ để tôi có thể gạch bỏ nó (mặc dù đây sẽ là một lời nói dối).
mathmandan

1

Khoảng trắng , 92 byte

Lưu ý rằng cú pháp của ngôn ngữ này chỉ bao gồm khoảng trắng , do đó, mỗi ký tự khoảng trắng đã được thêm tiền tố ở đây với S, T hoặc L (tương ứng với Space, Tab và Linefeed). Chúng có thể được gỡ bỏ mà không làm mất chức năng, nhưng chúng được bao gồm ở đây để hiển thị chính xác.

S S S L
T   L
T   T   S S S L
T   T   T   S L
S S S S T   T   L
T   S S L
S L
T   S S S T S T L
T   S T T   S L
S T S S S S S S T   S T L
T   S S T   T   S T S S S S T   L
T   S S S S S S T   S T S L
T   S T S T L
S T L
L
L
.

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




0

Excel, 27 byte

=0.3/(MOD(A1,5)*2-5)*A1+0.1

Có thể được nhập vào Cell như

=.3/(MOD(A1,5)*2-5)*A1+.1

cho 25 byte, nhưng tự động cập nhật Excel.


Trên thực tế tôi nghĩ rằng bạn được phép yêu cầu số byte bạn cần nhập (nhưng tôi quá lười để kiểm tra meta).
Neil
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.