Tentukan apakah bilangan bulat dapat dibagi 3

20

Tujuan Anda adalah untuk menentukan apakah angka dapat dibagi oleh 3 tanpa menggunakan persyaratan. Masukan akan berupa angka 8 bit yang tidak ditandatangani dari 0 hingga 255. Kreativitas didorong!

Anda HANYA diizinkan untuk menggunakan

  • Kesetaraan / Ketimpangan ( ==, !=, >, <, >=, <=)

  • Aritmatika ( +, -, x)

  • Operator Logis ( !bukan, &&dan, || atau)

  • Bitwise Operator ( ~tidak, &dan, |atau, ^xor, <<, >>, >>>aritmatika dan logis kiri dan pergeseran kanan)

  • Konstanta (akan lebih baik jika Anda menyimpan ini kecil)

  • Tugas variabel

Keluaran 0jika salah, 1jika benar.

Aturan golf-atom standar berlaku. Jika Anda memiliki pertanyaan, silakan tinggalkan di komentar. Contoh metode di sini . Token adalah salah satu dari konstanta dan variabel tidak termasuk di atas.

qwr
sumber
@GregHewgill Kesalahan ketik saya, itu harus nomor 8 bit.
qwr
2
Apakah kita hanya diperbolehkan menggunakan operator di atas? Kalau tidak, modulo akan membuat cara ini terlalu mudah.
Jwosty
Juga, bagaimana dengan pencarian tabel?
Greg Hewgill
3
Bisakah Anda mengklarifikasi apa yang Anda maksudkan tanpa syarat? Apakah ini terbatas pada pernyataan IF, atau apakah itu berlaku untuk hal-hal seperti loop juga?
Ruslan
1
@Ruslan Anda hanya diizinkan menggunakan yang di atas.
qwr

Jawaban:

31

C - 2 token

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

Tampaknya bekerja hingga 2 31 -1.

Kredit untuk zalgo("nhahtdh")untuk ide terbalik multiplikatif.

aditsu
sumber
1
+1. Bingung sedikit tentang cara <=kerjanya, dan ingat bahwa 0xAAAAAAAB diambil menjadi unsigned inttipe, sehingga hasil perkalian tidak ditandatangani.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
@DigitalTrauma operator ketidaksetaraan diperbolehkan, tidak dilarang
aditsu
@aditsu Ups! Saya perlu membaca lebih cermat kadang-kadang! +1 jawaban yang bagus!
Digital Trauma
@ Aditsu, maaf saya noob, bagaimana tepatnya ini bekerja?
Kartik_Koro
2
@Kartik_Koro 0xAAAAAAAB * 3 == 1 karena overflow, jadi untuk int x, x * 0xAAAAAAAAB * 3 == x. Juga y * 3 memiliki nilai yang berbeda untuk y yang berbeda, oleh karena itu y = x * 0xAAAAAAAB harus menjadi satu-satunya y sehingga y * 3 == x. Jika x adalah kelipatan dari 3, maka y harus x / 3, jika tidak itu harus bekerja melalui overflow. Cara sederhana untuk memeriksa adalah membandingkan y dengan x. Juga lihat en.wikipedia.org/wiki/Modular_multiplicative_inverse
aditsu
17

Python, 3 2 token

Solusi brute force, tetapi berhasil.

0x9249249249249249249249249249249249249249249249249249249249249249>>x&1

Terima kasih kepada Howard untuk pengurangan 1 token.

Greg Hewgill
sumber
Wow! Solusi Anda mungkin yang terpendek (3 token), tetapi saya ingin mendorong jawaban lain juga.
qwr
11
Bahkan ada solusi tanda 2: 0x9......>>x&1.
Howard
6

C - 5 4 (?) Token

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

Berfungsi untuk nomor 32-bit yang tidak ditandatangani .

Kode ini menggunakan modulo 2 32 invers multiplicative dari pembagi untuk mengubah operasi divisi menjadi operasi multiplikasi.

Edit

Solusi saya (diposting 2 menit setelahnya) memiliki semangat yang sama dengan solusi aditsu. Kredit kepadanya untuk penggunaan ==yang meningkatkan solusi saya dengan 1 token.

Referensi

n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
sumber
1
Ini luar biasa. Saya tahu tentang angka ajaib dari trik squareroot terbalik terkenal, tapi saya tidak tahu itu bisa digunakan untuk pembagi yang sewenang-wenang. Ini adalah Bull: P
qwr
Yap, 0xAAAAAAAB = (2 ^ 33 + 1) / 3 dan 171 = (2 ^ 9 + 1) / 3. Saya memilih konstanta terkecil yang berhasil. Hmm, sebenarnya itu juga berfungsi dengan 86 = (2 ^ 8 + 2) / 3
aditsu
Tikus, bahkan 43 = (2 ^ 7 + 1) / 3 berfungsi, tidak yakin bagaimana saya melewatkannya. Diedit sekarang.
aditsu
4

C - 15 (?) Token

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;
}

Sejak 4 ≡ 1 (mod 3), kami memiliki 4 n ≡ 1 (mod 3). Aturan penjumlahan digit tidak terbatas pada penjumlahan angka, tetapi juga memungkinkan kita untuk secara acak memecah angka menjadi urutan angka dan menjumlahkan semuanya sambil mempertahankan kesesuaian.

Contoh dalam basis 10, pembagi = 9:

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

Semua pernyataan dalam program memanfaatkan properti ini. Ini sebenarnya dapat disederhanakan menjadi loop yang menjalankan pernyataan n = (n & 0x3) + (n >> 2);sampai n < 4, karena pernyataan hanya memecah angka di basis-4 pada digit paling tidak signifikan dan menambahkan 2 bagian ke atas.

n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
sumber
+1: yang menarik ini berfungsi untuk n hingga 512 (sebenarnya n = 590), tapi saya tidak yakin mengapa.
Paul R
@ PaulR: Ini tidak akan berfungsi untuk angka yang lebih besar karena membawa (perhatikan bahwa saya menggunakan tambahan dalam perhitungan). Perhatikan juga garis yang diulang.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
Ya, saya tidak yakin mengapa ia bekerja untuk nilai 9 bit, karena sepertinya hanya menguji 8 bit?
Paul R
untuk angka 9-bit setelah penambahan pertama menjadi paling banyak 5 bit, setelah yang pertama n = (n & 0x3) + (n >> 2);hasilnya dikurangi menjadi 3 bit dan pengulangan menyebabkannya tetap hanya 2 bit stackoverflow.com/a/3421654/995714
phuclv
1
oh saya telah membuat kesalahan. Angka 5-bit + angka 4-bit dapat menghasilkan angka 6-bit. Tetapi jika n <= 588 menambahkan 4 bit teratas dan 2 bit terbawah dari angka 6-bit tersebut menghasilkan jumlah hanya 4-bit. Sekali lagi menambahkan itu menghasilkan angka 2-bit. 589 dan 590 menghasilkan 3 bit dalam jumlah terakhir tetapi secara kebetulan mereka tidak dapat dibagi 3 sehingga hasilnya benar
phuclv
2

Python (2 token?)

1&66166908135609254527754848576393090201868562666080322308261476575950359794249L>>x

Atau

1&0x9249249249249249249249249249249249249249249249249249249249249249L>>x

Atau

1&0b1001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001>>x
ɐɔıʇǝɥʇu
sumber
2
Duplikat dari komentar Howard
aditsu
@ Aditsu ... Pikiran besar berpikir sama? Saya bersumpah saya tidak melihat itu sebelum saya memposting ini.
ɐɔıʇǝɥʇuʎ
2

JavaScript - 3 token

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

Ini menyalahgunakan fakta bahwa menggunakan operator bitwise pada angka memotongnya menjadi integer dalam JavaScript.

Tyilo
sumber
Harus 4 token: =, *, |,==
n̴̖̋h̷͉a̷̭̿h̸̡̅ẗ̵̨d̷̰ĥ̷̳
1
Saya tidak berpikir tugas variabel dianggap sebagai token.
Tyilo
1

C - 4 token

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

Bekerja hingga 383.

Versi sebelumnya (konstanta yang lebih besar):

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

Berfungsi hingga 1535

aditsu
sumber
1

bash - ???

Tidak yakin bagaimana cara mencetak ini.

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

misalnya

$ 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

sumber
1

Befunge 93 - 5 token

Divisi tetap dihapus.

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

Dapatkan input, terus kurangi 3 hingga lebih kecil dari 0, arahkan pointer ke atas ('|'), lalu tambahkan 3. Jika nilainya 0 maka pointer bergerak ke kanan (" 1. @" menghasilkan '1') yang lain bergerak ke kiri ("@. " menampilkan '0'). '@' mengakhiri program.

AndoDaan
sumber
1

Gelombang - 7 Token

kupikir

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

Mengembalikan 1jika nomor yang diberikan (seperti stdin) dapat dibagi tiga.

hapus clemeat
sumber
Apakah loop diizinkan?
sergiol
1

Ruby, 6 (?) Token

Saya benar-benar tidak yakin bagaimana cara menghitung token. OP, dapatkah Anda mencetak saya?

Saya pikir itu 6 ... 1, 0, 0, *, 255,x

Perhatikan bahwa *ini bukan perkalian bilangan bulat.

def div3(x)
  ([1,0,0]*255)[x]
end
Bukan itu Charles
sumber
Bukankah token dalam arti OP hanya salah satu dari yang tercantum di atas dalam pertanyaan?
C5H8NNaO4
@ C5H8NNaO4 Jadi apa? 0?
Bukan berarti Charles
@ C5H8NNaO4 mungkin 4 untuk konstanta?
Bukan berarti Charles
1

Python 0

Saya memposting eariler tetapi saya menggunakan conditional. Ini untuk menggunakan tanpa syarat dan tidak ada token, hanya kata kunci

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

menggunakan trik yang kelipatan 3s memiliki angka yang menambah 3

Sunting: Menghapus lambda yang tidak perlu

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

Sunting: Lebih lanjut golf (117 karakter) masih belum ada token

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

Membunuh akses langsung untuk getitem bagus python Lebih lama di 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

Dylan Madisetti
sumber
Akses array []tidak diizinkan.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
Ini? Setelah aturan ini, codegolf.stackexchange.com/tags/atomic-code-golf/info
Dylan Madisetti
Nah, pertanyaannya tidak menggunakan aturan di tag wiki. Pertanyaannya memiliki batasan pada operasi yang diizinkan. Perhatikan kata itu only.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ Yah itu hal yang baik python memiliki atribut asli untuk itu juga
Dylan Madisetti
0

Python - 25 token

Untuk memulai, saya punya solusi panjang yang merupakan implementasi dari salah satu jawaban di tautan di posting pertama saya. nadalah 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)

orsetara dengan ||.

qwr
sumber
0

JavaScript - 3 Token

Uji di konsol browser Anda:

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)
William Barbosa
sumber
Bagaimana Anda sampai pada kesimpulan itu? Saya menghitung sekitar 37 token.
nyuszika7h
"Token adalah salah satu dari konstanta dan variabel tidak termasuk di atas". Bagaimana Anda menghitung 37?
William Barbosa
1
Oh begitu. OP tampaknya tidak setuju dengan halaman info atom-code-golf .
nyuszika7h
Sebenarnya, sekarang saya tidak yakin apakah saya benar atau tidak. Skor saya akan menjadi 70+ menurut biola golf kode atom.
William Barbosa
1
Masalahnya bukan tentang jumlah token, tetapi tentang operasi apa yang Anda gunakan. Saya tidak berpikir toString, parseInt, loop, array, dll diperbolehkan.
aditsu
0

JavaScript
tidak yakin tentang token #

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

atau jika output untuk 0 diizinkan menjadi 1;

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

C5H8NNaO4
sumber
2
Saya harus mengatakan, saya tidak yakin aturan apa yang berlaku untuk tantangan ini. Apakah panggilan fungsi dan akses properti diizinkan?
C5H8NNaO4
0

Tcl , 83 byte

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

Cobalah online!

sergiol
sumber
Gagal outgolf: 96 byte proc T n {set n [expr [join [split [expr [join [split $n ""] +]] ""] +]];expr {$n in {0 3 6 9}}} Cobalah online!
sergiol
Gagal lain: ** 87 byte ** proc T n {expr {[expr [join [split [expr [join [split $n ""] +]] ""] +]] in {0 3 6 9}}} Cobalah online!
sergiol