Thuật toán tính toán nếu một số là bội số của 3


13

Khi làm phép tính tâm thần người ta có thể làm:

  • Cho một số nguyên k, tổng tất cả các chữ số (trong cơ sở 10) và nếu kết quả là bội số của 3, thì k là bội số của 3.

Bạn có biết bất kỳ thuật toán nào hoạt động tương tự nhưng hoạt động trên các chữ số nhị phân (bit) không?

  • Lúc đầu, tôi đã nghĩ đến việc sử dụng các hàm đã sẵn sàng của ngôn ngữ chuyển đổi số nguyên sang ascii để thực hiện việc hội tụ từ cơ sở 2 sang cơ sở 10, sau đó áp dụng thủ thuật tính toán tinh thần. Nhưng tất nhiên sau đó tôi cũng có thể tự mã hóa cơ sở hội tụ 2 đến 10. Tôi chưa làm được, nhưng tôi sẽ thử.

  • Sau đó, tôi đã nghĩ về sự phân chia eidianidian trong cơ sở 2 ...

Tuy nhiên tôi tự hỏi nếu có các phương tiện, thuật toán khác.


Câu trả lời:


22

Hãy xem xét hai quan sát sau đây (còn lại như một bài tập cho người đọc):

  1. Sức mạnh chẵn của hai là 1 modulo 3.
  2. Sức mạnh lẻ của hai là -1 modulo 3.

Chúng tôi kết luận rằng một số (ở dạng nhị phân) chia hết cho ba khi và chỉ khi tổng các bit ở vị trí chẵn bằng tổng của các bit ở vị trí lẻ modulo 3.


7
Điều này giống như quy tắc chia hết cho 11 theo số thập phân.
Yuval Filmus

1
@YuvalFilmus: Chính xác. Tôi sẽ thêm một bài tập khác cho người đọc nhưng đã quyết định chống lại nó.
mhum

3
OK, làm thế nào về việc tìm ra nếu một số được viết bằng thập lục phân chia hết cho 17 (thập phân)? Hoặc 15 (thập phân) cho vấn đề đó? ;-)
vonbrand

33

Điều gì về một máy tự động nhà nước hữu hạn cho công việc?

nhập mô tả hình ảnh ở đây

Tất nhiên sự kỳ diệu là chỉ cần tính toán modulo 3. Thêm biểu tượng chuỗi đằng sau x phương tiện là "nhị phân giá trị" của chuỗi đi từ v một l ( x ) cho x để 2 v một l ( x ) + một cho x một . Do đó, từ trạng thái p và ký hiệu a, chúng ta chuyển sang trạng thái 2 p + a mod 3 , với p { 0 , 1 , 2axval(x)x2val(x)+axapa2p+amod3 một { 0 , 1 } . Lưu ý x { 0 , 1 } * là một chuỗi, wheras v một l ( x ) N là giá trị của nó như chuỗi nhị phân.p{0,1,2}a{0,1}x{0,1}val(x)N


1
Tôi thích ý tưởng này, hãy thử với 9. Tôi cung cấp 1001 ở dạng nhị phân. Bit đầu tiên gửi tôi đến trạng thái1, rồi trạng thái 2, rồi trạng thái1 rồi quay lại trạng thái0. Vậy state0 là bội của 3. Và độ phức tạp của thuật toán là số bit được sử dụng, không có gì hơn. Thật tuyệt vời!
Stephane Rolland

Là khái niệm này trong liên kết liên quan? Tôi nghĩ nó đơn giản hơn. geomathry.wordpress.com/2017/02/13/0-1-and-a-new-number

1
@WaqarAhmad Có, liên quan, không đơn giản. Các chuyển đổi trong một máy tự động hữu hạn cũng có thể được sử dụng để mô tả đánh giá L2R, như trong lời giải thích của bạn. Các hiệu ứng chuyển tiếp xác định , ˉ 0 1 = ˉ 1 , ˉ 1 0 = ˉ 2 , ˉ 1 1 = ˉ 0 , ˉ 2 0 = ˉ 1 , ˉ 2 1 = ˉ 20¯0=0¯0¯1=1¯1¯0=2¯1¯1=0¯2¯0=1¯2¯1=2¯. Ở đây chúng tôi có ba trạng thái, vì vậy ba biểu tượng cho các trạng thái là cần thiết. Biểu tượng của bạn là những đánh giá của số modulo 1 , 2 , 0 tương ứng, và biểu tượng đầu tiên trong việc đánh giá L2R của bạn là "nhà nước". Nếu bạn muốn thảo luận, có lẽ tốt hơn là bắt đầu một câu hỏi mới trên trang web! Θ,1,01,2,0
Hendrik

Đừng về lập trình. Điều này sẽ hiệu quả hơn trong một máy tính ternary?

4

Trong nhị phân, các số 1, 100, 10000 (= 100 × 100), 1000000 (= 100 × 100 × 100), v.v ... tất cả đều cho cùng một phần dư sau khi chia cho 11 (ba). Do đó, nếu chúng ta chia một số nhị phân thành các phần có độ dài chẵn , tổng của các phần sẽ cho phần còn lại giống như số ban đầu.

(Khi chia số, chúng tôi thêm số không cần thiết vào đầu . Ví dụ: chúng tôi sẽ chia 10111 cho các nhóm 01,01,11 hoặc 0001,0111.)

Về mặt toán học, chỉ cần chia số thành các nhóm có hai chữ số, sau đó thêm các nhóm; và lặp lại điều này cho đến khi kết quả của bạn trở thành 00 hoặc 11 = số ban đầu là bội số của ba; hoặc 01 hoặc 10 = số ban đầu không phải là bội số của ba.

Đối với chương trình máy tính, sử dụng các nhóm tám hoặc sáu hoặc ba mươi hai bit có thể nhanh hơn cho CPU của bạn. Ví dụ: nếu phép cộng tám bit là nhanh nhất, chỉ cần tạo tổng của tất cả các byte và một lần nữa, cho đến khi kết quả khớp với một byte. Sau đó sử dụng một lệnh để xác định bộ lưu giữ sau khi chia cho ba.

(Lưu ý: Chúng tôi giả sử số nguyên không dấu ở đây. Với một số đã ký, nó cần chú ý hơn một chút. Ví dụ 129 là bội của 3, nhưng -127 thì không, mặc dù các bit 10000001 có nghĩa là trước đây là một byte không dấu và cái sau như một byte đã ký.)


0

Mặc dù không phải là nhị phân cụ thể, nhưng khi nghi ngờ, phép trừ lặp đi lặp lại luôn là một cách chắc chắn để tính toán phép chia với phần dư (và do đó nếu một số là bội số của 3).


2
Lặp lại phép trừ là một ý tưởng tồi. Phân chia với phần còn lại là nhanh hơn nhiều.
Yuval Filmus

3
có lẽ thực sự rất tốn kém trong cpu, nhưng đó là một thuật toán khác :-) không xứng đáng -1 :-(
Stephane Rolland
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.