Xác định xem một số nguyên có chia hết cho 3 không


20

Mục tiêu của bạn là xác định xem một số có chia hết cho 3 không mà không sử dụng các điều kiện. Đầu vào sẽ là một số 8 bit không dấu từ 0 đến 255. Khuyến khích sáng tạo!

Bạn CHỈ được phép sử dụng

  • Bình đẳng / bất bình đẳng ( ==, !=, >, <, >=, <=)

  • Số học ( +, -, x)

  • Toán tử logic ( !không, &&và, || hoặc)

  • Bitwise Operators ( ~không, &và, |hoặc, ^xor, <<, >>, >>>số học và logic trái và thay đổi bên phải)

  • Các hằng số (sẽ tốt hơn nếu bạn giữ các giá trị nhỏ này)

  • Phân công biến

Đầu ra 0nếu sai, 1nếu đúng.

Tiêu chuẩn quy tắc golf-golf nguyên tử áp dụng. Nếu bạn có bất kỳ câu hỏi xin vui lòng để lại trong các ý kiến. Phương pháp ví dụ ở đây . Mã thông báo là bất kỳ giá trị nào ở trên, ngoại trừ hằng và biến.


@GregHewgill Lỗi đánh máy của tôi, nó phải là số 8 bit.
qwr

2
Chúng tôi chỉ được phép sử dụng các toán tử trên? Nếu không, modulo sẽ làm cho cách này quá dễ dàng.
Jwosty

Ngoài ra, làm thế nào về tra cứu bảng?
Greg Hewgill

3
Bạn có thể làm rõ những gì bạn có nghĩa là không có điều kiện? Có bị giới hạn trong các câu lệnh IF không, hay nó cũng áp dụng cho những thứ như vòng lặp?
Ruslan

1
@Ruslan Bạn chỉ được phép sử dụng ở trên.
qwr

Câu trả lời:


31

C - 2 mã thông báo

int div3(int x) {
    return x * 0xAAAAAAAB <= x;
}

Có vẻ như để làm việc lên đến 2 31 -1.

Tín dụng zalgo("nhahtdh")cho ý tưởng nghịch đảo nhân.


1
+1. Đã gặp khó khăn một chút về cách thức <=hoạt động và nhớ rằng 0xAAAAAAAB được coi là unsigned intloại, do đó kết quả của phép nhân không được ký.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

Các nhà khai thác bất bình đẳng @DigitalTrauma được phép, không bị cấm
aditsu

@aditsu Rất tiếc! Tôi cần phải đọc kỹ hơn đôi khi! +1 câu trả lời tuyệt vời!
Chấn thương kỹ thuật số

@aditsu, xin lỗi tôi không biết, chính xác thì nó hoạt động thế nào?
Kartik_Koro

2
@Kartik_Koro 0xAAAAAAAB * 3 == 1 do tràn, vì vậy đối với mọi int x, x * 0xAAAAAAAB * 3 == x. Ngoài ra y * 3 có các giá trị khác nhau cho y khác nhau, do đó y = x * 0xAAAAAAAB phải là y duy nhất sao cho y * 3 == x. Nếu x là bội của 3, thì y phải là x / 3, nếu không thì nó phải hoạt động qua tràn. Một cách đơn giản để kiểm tra là so sánh y với x. Đồng thời xem en.wikipedia.org/wiki/Modular_multiplicative_inverse
aditsu

17

Python, 3 2 mã thông báo

Giải pháp vũ lực, nhưng nó hoạt động.

0x9249249249249249249249249249249249249249249249249249249249249249>>x&1

Cảm ơn Howard đã giảm 1 mã thông báo.


Ồ Giải pháp của bạn có lẽ là ngắn nhất (3 mã thông báo), nhưng tôi cũng muốn khuyến khích các câu trả lời khác.
qwr

11
Thậm chí còn có một giải pháp 2 mã thông báo : 0x9......>>x&1.
Howard

6

Mã thông báo C - 5 4 (?)

int div3_m2(uint32_t n) {
    return n == 3 * (n * 0xAAAAAAABull >> 33);
}

Hoạt động cho bất kỳ số 32 bit không dấu .

Mã này sử dụng phép nhân nghịch đảo modulo 2 32 của một ước số để chuyển đổi phép toán chia thành phép toán nhân.

Chỉnh sửa

Giải pháp của tôi (được đăng 2 phút sau) có cùng tinh thần với giải pháp của aditsu. Tín dụng cho anh ta để sử dụng ==đó cải thiện giải pháp của tôi thêm 1 mã thông báo.

Tài liệu tham khảo


1
Điều này thật phi thường. Tôi biết về các con số ma thuật từ thủ thuật squareroot nghịch đảo nổi tiếng, nhưng tôi không biết nó có thể được sử dụng cho một ước số tùy ý. Đây là Bull: P
qwr

Đúng, 0xAAAAAAAB = (2 ^ 33 + 1) / 3 và 171 = (2 ^ 9 + 1) / 3. Tôi chọn hằng số nhỏ nhất mà lừa. Hmm, thực ra nó cũng có vẻ hoạt động với 86 = (2 ^ 8 + 2) / 3
aditsu

Chuột, thậm chí 43 = (2 ^ 7 + 1) / 3 hoạt động, không chắc tôi đã bỏ lỡ nó như thế nào. Chỉnh sửa ngay.
aditsu

4

Mã thông báo C - 15 (?)

int div3_m1(unsigned int n) {
    n = (n & 0xf) + (n >> 4);
    n = (n & 0x3) + (n >> 2);
    n = (n & 0x3) + (n >> 2);
    return n == 0 || n == 3;
}

Vì 4 ≡ 1 (mod 3), chúng ta có 4 n ≡ 1 (mod 3). Quy tắc tổng hợp chữ số không giới hạn trong việc tính tổng các chữ số, nhưng cũng cho phép chúng tôi tùy ý chia số thành các chuỗi chữ số và tổng hợp tất cả chúng trong khi duy trì đồng quy.

Một ví dụ trong cơ sở 10, ước số = 9:

1234 12 + 34 ≡ 1 + 2 + 3 + 4 123 + 4 ≡ 1 (mod 9)

Tất cả các tuyên bố trong chương trình sử dụng tài sản này. Nó thực sự có thể được đơn giản hóa thành một vòng lặp chạy câu lệnh n = (n & 0x3) + (n >> 2);cho đến n < 4khi câu lệnh chỉ đơn giản phá vỡ số trong cơ sở-4 ở chữ số có nghĩa ít nhất và thêm 2 phần lên.


+1: điều thú vị là nó hoạt động với n lên tới 512 (thực tế là n = 590), nhưng tôi không chắc tại sao.
Paul R

@PaulR: Nó sẽ không hoạt động với số lượng lớn hơn do mang theo (lưu ý rằng tôi đã sử dụng bổ sung trong tính toán). Cũng lưu ý các dòng lặp đi lặp lại.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

Có, tôi chỉ không chắc tại sao nó hoạt động với giá trị 9 bit, vì dường như nó chỉ đang thử nghiệm 8 bit?
Paul R

đối với các số 9 bit sau lần bổ sung đầu tiên, nó trở thành tối đa 5 bit, sau lần đầu tiên n = (n & 0x3) + (n >> 2);kết quả giảm xuống còn 3 bit và việc lặp lại khiến nó chỉ còn lại 2 bit stackoverflow.com/a/3421654/995714
phuclv

1
oh tôi đã phạm sai lầm Số 5 bit + số 4 bit có thể dẫn đến số 6 bit. Nhưng nếu n <= 588 thêm 4 bit trên cùng và 2 bit dưới cùng của số 6 bit đó sẽ tạo ra tổng 4 bit duy nhất. Một lần nữa thêm kết quả đó vào một số 2 bit. 589 và 590 kết quả trong 3 bit trong tổng cuối cùng nhưng tình cờ chúng không chia hết cho 3 nên kết quả là chính xác
phuclv

2

Python (2 mã thông báo?)

1&66166908135609254527754848576393090201868562666080322308261476575950359794249L>>x

Hoặc là

1&0x9249249249249249249249249249249249249249249249249249249249249249L>>x

Hoặc là

1&0b1001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001>>x

2
Bản sao nhận xét của Howard
aditsu

@aditsu ... Những bộ óc vĩ đại nghĩ giống nhau? Tôi thề tôi đã không nhìn thấy điều đó trước khi tôi đăng bài này.
23:00

2

JavaScript - 3 mã thông báo

function div3(n) {
    var a = n * 0.3333333333333333;
    return (a | 0) == a;
}

Điều này lạm dụng thực tế là sử dụng các toán tử bitwise trên một số cắt nó thành một số nguyên trong JavaScript.


Nên là 4 thẻ: =, *, |,==
n̴̖̋h̷͉a̷̭̿h̸̡̅ẗ̵̨d̷̰ĥ̷̳

1
Tôi không nghĩ việc gán biến được tính là mã thông báo.
Tyilo

1

C - 4 mã thông báo

int div3(int x) {
    return ((x * 43) >> 7) * 3 == x;
}

Hoạt động tới 383.

Phiên bản trước (hằng số lớn hơn):

int div3(int x) {
    return ((x * 171) >> 9) * 3 == x;
}

Hoạt động đến 1535


1

bash - ???

Không chắc làm thế nào để ghi điểm này.

seq 0 85 | awk '{print $1 * 3}' | grep -w [number] | wc -l

ví dụ

$ seq 0 85 | awk '{print $1 * 3}' | grep -w 11 | wc -l
0

$ seq 0 85 | awk '{print $1 * 3}' | grep -w 12 | wc -l
1

$seq 0 85 | awk '{print $1 * 3}' | grep -w 254 | wc -l
0

$seq 0 85 | awk '{print $1 * 3}' | grep -w 255 | wc -l
1

1

Befunge 93 - 5 mã thông báo

Đã sửa lỗi - phân chia.

v      @._1.@
         \   
         0   
         +   
         3   
>&>3-:0\`|   
  ^      <   

Nhận đầu vào, tiếp tục trừ 3 cho đến khi nhỏ hơn 0, hướng con trỏ lên ('|'), sau đó thêm 3. Nếu giá trị bằng 0 thì con trỏ di chuyển sang phải (" 1. @" đầu ra '1') khác di chuyển sang trái ("@. " Đầu ra '0'). '@' Chấm dứt chương trình.


1

Batch - 7 Tokens

I think

@echo off
for /L %%a in (0,3,%1) do set a=%%a
if %a%==%1 echo 1

Returns 1 if the given number (as stdin) is divisible by three.


Are loops allowed?
sergiol

1

Ruby, 6(?) tokens

I'm really not sure how to count tokens. OP, can you score me?

I think it's 6... 1, 0, 0, *, 255, x

Note that the * is not integer multiplication.

def div3(x)
  ([1,0,0]*255)[x]
end

Wouldn't a token in the OP's sense be only one of the above listed in the question?
C5H8NNaO4

@C5H8NNaO4 So what? 0?
Not that Charles

@C5H8NNaO4 maybe 4 for constants?
Not that Charles

1

Python 0

I posted eariler but I used conditionals. Here's to using no conditionals and no tokens, just keywords

def g(x): return ([[lambda : g(sum(int(y) for y in list(str(x)))),lambda: 0][[False,True].index(x in[0,1,2,4,5,7,8])], lambda: 1][[False,True].index((lambda y: y in[3,6,9])(x))])()

uses the trick that multiple of 3s have digits which add to 3

Edit: Removed unnecessary lambda

def g(x):return([[lambda: g(sum(int(y) for y in list(str(x)))),lambda:0][[False,True].index(x in[0,1,2,4,5,7,8])], lambda:1][[False,True].index(x in[3,6,9])])()

Edit: Golfed further (117 chars) still no tokens

exec"g=`x:(((`:g(sum(int(y)for y in str(x)),`:0)[x in[0,1,2,4,5,7,8]],`:1)[x in[3,6,9]])()".replace('`','lambda ')

Killed direct access for python's nifty getitem Longer at 132 char

exec"g={0}x:((({0}:g(sum(int(y)for y in str(x))),{0}:0{1}0,1,2,4,5,7,8]),{0}:1{1}3,6,9]))()".format('lambda ',').__getitem__(x in[')

http://www.codeskulptor.org/#user34_uUl7SwOBJb_0.py


Array access [] is not allowed, though.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳


Well, the question doesn't use the rule in the tag wiki. The question has restriction on operations allowed. Note the word only.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

@n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ Well it's a good thing python has a native attribute for that too
Dylan Madisetti

0

Python - 25 tokens

To get things started, I have a lengthy solution that is a implementation of one of the answers in the link in my first post. n is input.

a = (n>>7)-((n&64)>>6)+((n&32)>>5)-((n&16)>>4)+((n&8)>>3)-((n&4)>>2)+((n&2)>>1)-(n&1)
print(a==0 or a==3)

or is equivalent to ||.


0

JavaScript - 3 Tokens

Test it on your browser's console:

a = prompt().split('');
sum = 0;

do {
  sum = a.reduce(function(p, c) {
     return parseInt(p) + parseInt(c); 
  });

  a = sum.toString().split('');

} while(a.length > 1)

alert([3, 6, 9].indexOf(+sum) > -1)

How did you come to that conclusion? I count about 37 tokens.
nyuszika7h

"A token is any of the above excluding constants and variables". How did you count 37?
William Barbosa

1
Oh, I see. The OP seems to disagree with the info page of atomic-code-golf.
nyuszika7h

Actually, now I'm not sure whether I'm right or not. My score would be 70+ according to the atomic code golf fiddle.
William Barbosa

1
The problem is not about the number of tokens, but about what operations you're using. I don't think toString, parseInt, loops, arrays, etc. are allowed.
aditsu

0

JavaScript
not sure about the token#

function mod3 (i) { return {'undefined':'100','0':'0'}[[0][i]][i.toString (3).split('').pop ()]}

or if the output for 0 is allowed to be 1;

function mod3 (i) { return '100'[i.toString (3).split('').pop ()]}


2
I have to say, I'm not sure what rules apply to this challenge. Are functioncalls and propertyaccesses allowed?
C5H8NNaO4

0

Tcl, 83 bytes

proc T n {while \$n>9 {set n [expr [join [split $n ""] +]]};expr {$n in {0 3 6 9}}}

Try it online!


Failed outgolf: 96 bytes proc T n {set n [expr [join [split [expr [join [split $n ""] +]] ""] +]];expr {$n in {0 3 6 9}}} Try it online!
sergiol

Another fail:**87 bytes** proc T n {expr {[expr [join [split [expr [join [split $n ""] +]] ""] +]] in {0 3 6 9}}} Try it online!
sergiol
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.