ตรวจสอบว่าจำนวนเต็มหารด้วย 3 หรือไม่


20

เป้าหมายของคุณคือพิจารณาว่าตัวเลขหารด้วย 3 โดยไม่ใช้เงื่อนไขหรือไม่ อินพุตจะเป็นตัวเลข 8 บิตที่ไม่ได้ลงนามตั้งแต่ 0 ถึง 255 สนับสนุนให้ใช้ความคิดสร้างสรรค์!

คุณได้รับอนุญาตเท่านั้นที่จะใช้

  • ความเท่าเทียมกัน / ความไม่เท่าเทียมกัน ( ==, !=, >, <, >=, <=)

  • เลขคณิต ( +, -, x)

  • ผู้ประกอบการเชิงตรรกะ ( !ไม่ใช่, &&และ, || หรือ)

  • Bitwise ผู้ประกอบการ ( ~ไม่&และ|หรือ^แฮคเกอร์, <<, >>, >>>คณิตศาสตร์และตรรกะซ้ายกะขวา)

  • ค่าคงที่ (จะดีกว่าถ้าคุณเก็บสิ่งเล็ก ๆ เหล่านี้ไว้)

  • การมอบหมายตัวแปร

เอาต์พุต0ถ้าเป็นเท็จ1ถ้าเป็นจริง

มีการใช้กฎรหัสอะตอมมิกแบบมาตรฐาน หากคุณมีคำถามใด ๆ โปรดทิ้งไว้ในความคิดเห็น วิธีการตัวอย่างที่นี่ โทเค็นใด ๆ ข้างต้นไม่รวมค่าคงที่และตัวแปร


@ GregHewgill พิมพ์ผิดของฉันมันควรจะเป็นจำนวน 8 บิต
qwr

2
เราได้รับอนุญาตให้ใช้โอเปอเรเตอร์ด้านบนเท่านั้นหรือไม่ มิฉะนั้นโมดูโล่จะทำให้วิธีนี้ง่ายเกินไป
Jwosty

นอกจากนี้วิธีการเกี่ยวกับการค้นหาตาราง?
Greg Hewgill

3
คุณสามารถอธิบายสิ่งที่คุณหมายถึงโดยไม่มีเงื่อนไข? มัน จำกัด อยู่ที่คำสั่ง IF หรือใช้กับสิ่งต่างๆเช่นลูปด้วยหรือไม่
Ruslan

1
@Ruslan คุณได้รับอนุญาตเท่านั้นที่จะใช้ข้างต้น
qwr

คำตอบ:


31

C - 2 โทเค็น

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

ดูเหมือนว่าจะทำงานได้ถึง 2 31 -1

ให้เครดิตzalgo("nhahtdh")สำหรับแนวคิดการผกผันทวีคูณ


1
+1 งงงันเล็กน้อยกับวิธีการ<=ทำงานและจำได้ว่า 0xAAAAAAAB ถูกนำไปเป็นunsigned intประเภทดังนั้นผลลัพธ์ของการคูณจะไม่ได้ลงนาม
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

ตัวดำเนินการ @DigitalTrauma ไม่เท่าเทียมกันไม่ได้รับอนุญาต
aditsu

@aditsu อ๊ะ! บางครั้งฉันต้องอ่านให้ละเอียดมากขึ้น! +1 คำตอบที่ยอดเยี่ยม!
บาดเจ็บทางดิจิตอล

@aditsu, ขอโทษด้วยฉันไม่มีอะไร, มันทำงานได้อย่างไร?
Kartik_Koro

2
@Kartik_Koro 0xAAAAAAAB * 3 == 1 เนื่องจากล้นดังนั้นสำหรับ int x ใด ๆ , x * 0xAAAAAAAB * 3 == x y * 3 ก็มีค่าต่างกันสำหรับ y ที่ต่างกันดังนั้น y = x * 0xAAAAAAAB จะต้องเป็น y เพียงตัวเดียวที่ y * 3 == x ถ้า x เป็นผลคูณของ 3 ดังนั้น y ต้องเป็น x / 3 มิฉะนั้นจะต้องผ่านการโอเวอร์โฟลว์ วิธีง่าย ๆ ในการตรวจสอบคือการเปรียบเทียบ y กับ x ดูen.wikipedia.org/wiki/Modular_multiplicative_inverse ด้วย
aditsu

17

Python 3 2 โทเค็น

วิธีการแก้ปัญหากำลังดุร้าย แต่ทำงานได้

0x9249249249249249249249249249249249249249249249249249249249249249>>x&1

ขอบคุณ Howard ที่ลดโทเค็น 1 ครั้ง


ว้าว! โซลูชันของคุณน่าจะสั้นที่สุด (3 โทเค็น) แต่ฉันต้องการสนับสนุนคำตอบอื่น ๆ ด้วย
qwr

11
แม้จะมีวิธีการแก้ปัญหาโทเค็น 0x9......>>x&12:
Howard

6

โทเค็นC - 5 4 (?)

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

การทำงานสำหรับจำนวน 32 บิตใด ๆ ที่ไม่ได้ลงชื่อ

รหัสนี้ใช้ประโยชน์จากตัวคูณผกผันโมดูโล 2 32ของตัวหารเพื่อแปลงการดำเนินการหารเป็นการดำเนินการคูณ

แก้ไข

โซลูชันของฉัน (โพสต์หลังจาก 2 นาที) มีจิตวิญญาณเช่นเดียวกับโซลูชันของ aditsu ให้เครดิตกับเขาสำหรับการใช้==ที่ปรับปรุงโซลูชันของฉันโดย 1 โทเค็น

การอ้างอิง


1
นี่เป็นเรื่องเหลือเชื่อ ฉันรู้เกี่ยวกับตัวเลขเวทย์มนตร์จากเคล็ดลับ squareroot inverse ที่มีชื่อเสียง แต่ฉันไม่รู้ว่ามันสามารถใช้กับตัวหารโดยพลการ นี่คือBull: P
qwr

ใช่ 0xAAAAAAAB = (2 ^ 33 + 1) / 3 และ 171 = (2 ^ 9 + 1) / 3 ฉันเลือกค่าคงที่ที่เล็กที่สุดที่ใช้กลอุบาย อืมจริงๆแล้วมันดูเหมือนว่าจะใช้งานกับ 86 = (2 ^ 8 + 2) / 3
aditsu

หนูยังทำงานได้ 43 = (2 ^ 7 + 1) / 3 ไม่แน่ใจว่าฉันพลาดมันไปได้อย่างไร แก้ไขแล้ว
aditsu

4

โทเค็น 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;
}

ตั้งแต่ 4 ≡ 1 (mod 3) เรามี 4 n ≡ 1 (mod 3) กฎการรวมตัวเลขไม่ได้ จำกัด อยู่แค่การรวมตัวเลข แต่ยังช่วยให้เราสามารถแบ่งจำนวนออกเป็นลำดับของตัวเลขโดยพลการและรวมทั้งหมดทั้งหมดโดยยังคงความสอดคล้อง

ตัวอย่างในฐาน 10 ตัวหาร = 9:

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

ข้อความทั้งหมดในโปรแกรมใช้ประโยชน์จากคุณสมบัตินี้ มันสามารถเป็นจริงได้ง่ายห่วงที่รันคำสั่งที่n = (n & 0x3) + (n >> 2);จนกว่าn < 4เนื่องจากคำสั่งเพียงแค่แบ่งจำนวนในฐาน-4 ที่หลักที่สำคัญน้อยที่สุดและเพิ่มขึ้น 2 ส่วน


+1: น่าสนใจใช้ได้กับ n มากถึง 512 (จริง ๆ n = 590) แต่ฉันไม่แน่ใจว่าทำไม
Paul R

@PaulR: มันจะไม่ทำงานสำหรับตัวเลขที่ใหญ่กว่าเนื่องจากการพกพา (โปรดทราบว่าฉันใช้การคำนวณเพิ่มเติม) ให้สังเกตเส้นที่ซ้ำ ๆ
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

ใช่ฉันแค่ไม่แน่ใจว่าทำไมถึงใช้งานได้กับค่า 9 บิตเนื่องจากดูเหมือนว่าจะทดสอบเพียง 8 บิตเท่านั้น
Paul R

สำหรับตัวเลข 9 บิตหลังจากการเติมครั้งแรกมันจะมากที่สุด 5 บิตหลังจากครั้งแรกn = (n & 0x3) + (n >> 2);ผลลัพธ์จะลดลงเหลือ 3 บิตและการทำซ้ำทำให้เหลืออยู่เพียง 2 บิตstackoverflow.com/a/3421654/995714
phuclv

1
โอ้ฉันทำผิดไป ตัวเลข 5 บิตและตัวเลข 4 บิตอาจส่งผลให้เป็นตัวเลข 6 บิต แต่ถ้า n <= 588 เพิ่ม 4 บิตสูงสุดและ 2 บิตด้านล่างของตัวเลข 6 บิตนั้นจะให้ผลรวม 4 บิตเท่านั้น การเพิ่มนั้นให้ผลลัพธ์เป็นตัวเลข 2 บิตอีกครั้ง ผลลัพธ์ 589 และ 590 ใน 3 บิตในผลรวมสุดท้าย แต่บังเอิญพวกเขาไม่ได้หารด้วย 3 เพื่อผลที่ถูกต้อง
phuclv

2

Python (2 โทเค็นหรือไม่)

1&66166908135609254527754848576393090201868562666080322308261476575950359794249L>>x

หรือ

1&0x9249249249249249249249249249249249249249249249249249249249249249L>>x

หรือ

1&0b1001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001>>x

2
ความคิดเห็นซ้ำซ้อนของฮาวเวิร์ด
aditsu

@aditsu ... จิตใจที่ดีคิดเหมือนกันเหรอ? ฉันสาบานว่าฉันไม่เห็นสิ่งนั้นก่อนที่จะโพสต์สิ่งนี้
Junıʇǝɥʇuʎs

2

JavaScript - 3 โทเค็น

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

สิ่งนี้เป็นการละเมิดความจริงที่ว่าการใช้ตัวดำเนินการระดับบิตในจำนวนจะตัดให้เป็นจำนวนเต็มใน JavaScript


ควรจะเป็น 4 ราชสกุล: =, *, |,==
n̴̖̋h̷͉a̷̭̿h̸̡̅ẗ̵̨d̷̰ĥ̷̳

1
ฉันไม่คิดว่าการมอบหมายตัวแปรถือเป็นโทเค็น
Tyilo

1

โทเค็น C - 4

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

ทำงานได้ถึง 383

รุ่นก่อนหน้า (ค่าคงที่ที่ใหญ่กว่า):

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

ใช้งานได้ถึง 1535


1

ทุบตี - ???

ไม่แน่ใจว่าจะทำคะแนนได้อย่างไร

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

เช่น

$ 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 โทเค็น

คงที่ - ลบหมวด

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

รับค่าเข้าทำให้ลบ 3 จนกระทั่งเล็กกว่า 0 ชี้ตัวชี้ขึ้น ('|') แล้วเพิ่ม 3 หากค่าเป็น 0 ตัวชี้จะเลื่อนไปทางขวา (" 1. @" เอาต์พุต '1') มิฉะนั้นจะเลื่อนไปทางซ้าย ("@. " เอาท์พุต '0') '@' ยุติโปรแกรม


1

แบตช์ - 7 โทเค็น

ฉันคิด

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

ส่งคืน1ถ้าจำนวนที่กำหนด (เป็น stdin) หารด้วยสาม


อนุญาตการวนซ้ำหรือไม่
sergiol

1

ทับทิมโทเค็น 6 (?)

ฉันไม่แน่ใจว่าจะนับโทเค็นได้อย่างไร OP คุณให้คะแนนฉันได้ไหม

ฉันคิดว่ามันเป็น 6 ... 1, 0, 0, *, 255,x

โปรดทราบว่าการ*คูณไม่ใช่จำนวนเต็ม

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

โทเค็นในความหมายของ OP จะไม่เป็นหนึ่งในรายการข้างต้นที่ระบุไว้ในคำถาม
C5H8NNaO4

@ C5H8NNaO4 อะไรนะ? 0?
ไม่ใช่ชาร์ลส์ที่

@ C5H8NNaO4 อาจเป็น 4 สำหรับค่าคงที่หรือไม่
ไม่ใช่ชาร์ลส์ที่

1

Python 0

ฉันโพสต์ eariler แต่ฉันใช้เงื่อนไข นี่คือการใช้ไม่มีเงื่อนไขและไม่มีโทเค็นเพียงแค่คำหลัก

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))])()

ใช้เคล็ดลับที่หลาย ๆ 3 มีตัวเลขที่เพิ่มถึง 3

แก้ไข: ลบแลมบ์ดาที่ไม่จำเป็นออก

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])])()

แก้ไข: Golfed เพิ่มเติม (117 ตัวอักษร) ยังคงไม่มีสัญญาณ

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 ')

ฆ่าการเข้าถึงโดยตรงของ python getitemอีกต่อไปอีกต่อไปที่ 132 ถ่าน

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
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

มันคือ? หลังจากกฎเหล่านี้codegolf.stackexchange.com/tags/atomic-code-golf/info
Dylan Madisetti

คำถามไม่ได้ใช้กฎในแท็กวิกิ คำถามมีข้อ จำกัด ในการดำเนินการที่ได้รับอนุญาต หมายเหตุ: onlyคำว่า
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ มันเป็นสิ่งที่ดีที่ไพ ธ อนมีคุณลักษณะดั้งเดิมสำหรับสิ่งนั้นด้วย
Dylan Madisetti

0

Python 25 โทเค็น

ในการเริ่มต้นสิ่งต่าง ๆ ฉันมีวิธีแก้ปัญหาที่ยืดยาวซึ่งเป็นการใช้งานหนึ่งในคำตอบในลิงค์ในโพสต์แรกของฉัน nเป็นอินพุต

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||เทียบเท่ากับ


0

JavaScript - 3 โทเค็น

ทดสอบบนคอนโซลของเบราว์เซอร์ของคุณ:

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)

คุณสรุปได้อย่างไร? ฉันนับประมาณ 37 โทเค็น
nyuszika7h

"โทเค็นใด ๆ ข้างต้นไม่รวมค่าคงที่และตัวแปร" คุณนับ 37 ได้อย่างไร
William Barbosa

1
อ้อเข้าใจแล้ว. สหกรณ์ดูเหมือนว่าจะไม่เห็นด้วยกับหน้าข้อมูลของอะตอมรหัสกอล์ฟ
nyuszika7h

จริงๆแล้วตอนนี้ฉันไม่แน่ใจว่าฉันถูกหรือไม่ คะแนนของฉันจะอยู่ที่ 70+ ตามซอฟต์โค้ดกอล์ฟอะตอม
William Barbosa

1
ปัญหาไม่ได้เกี่ยวกับจำนวนโทเค็น แต่เกี่ยวกับการดำเนินการที่คุณใช้ ฉันไม่คิดว่าจะกัด, แยกวิเคราะห์, ลูป, อาร์เรย์, ฯลฯ ได้รับอนุญาต
aditsu

0

JavaScript
ไม่แน่ใจเกี่ยวกับโทเค็น #

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

หรือถ้าผลลัพธ์สำหรับ 0 ได้รับอนุญาตให้เป็น 1;

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


2
ฉันต้องบอกว่าฉันไม่แน่ใจว่ากฎใดที่ใช้กับความท้าทายนี้ ฟังก์ชั่นการโทรและการเข้าถึงคุณสมบัติอนุญาตหรือไม่
C5H8NNaO4

0

Tcl , 83 ไบต์

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

ลองออนไลน์!


ล้มเหลว outgolf: 96 ไบต์ proc T n {set n [expr [join [split [expr [join [split $n ""] +]] ""] +]];expr {$n in {0 3 6 9}}} ลองออนไลน์!
sergiol

ความล้มเหลวอื่น: ** 87 ไบต์ ** proc T n {expr {[expr [join [split [expr [join [split $n ""] +]] ""] +]] in {0 3 6 9}}} ลองออนไลน์!
sergiol
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.