Mengutip pertanyaan ini pada SO (Spoiler alert!):
Pertanyaan ini telah diajukan dalam wawancara Oracle.
Bagaimana Anda membagi angka dengan 3 tanpa menggunakan operator *, /, +, -,%,?
Nomor tersebut dapat ditandatangani atau tidak ditandatangani.
Tugas ini dapat dipecahkan, tetapi lihat apakah Anda dapat menulis kode terpendek.
Aturan:
- Lakukan pembagian integer yang diperlukan (
/3
) - Jangan menggunakan operator berbasis non-teks
*
,/
,+
,-
, atau%
(atau setara mereka, seperti__div__
atauadd()
). Ini juga berlaku untuk operator yang menambah dan mengurangi, sepertii++
ataui--
. Penggunaan operator untuk penggabungan string dan pemformatan tidak masalah. Menggunakan karakter ini untuk operator yang berbeda, seperti-
operator unary untuk angka negatif, atau*
untuk mewakili pointer di C juga OK. - Nilai input dapat besar secara arbitrer (apa pun yang dapat ditangani sistem Anda), baik positif maupun negatif
- Input bisa di STDIN atau ARGV atau dimasukkan dengan cara lain
- Buat kode terpendek yang dapat Anda lakukan di atas
Jawaban:
J,
45 4410 karakter".,&'r3'":
Bekerja dengan negatif:
":
- format sebagai teks,&'r3'
- tambahkanr3
sampai akhir".
- jalankan string, mis15r3
sumber
3 3 3 #: 9
. Sepertinya Anda perlu tahu berapa lama nomor terner Anda._3]\i.
juga merupakan titik awal yang mungkin untuk sesuatu, tetapi saya tidak tahu apakah itu akan lebih pendek dari solusi Anda di sini. Masalah dengan#_3]\i.
apa yang berdiri adalah bahwa ia selalu membulatkan ke atas, bukan ke bawah.##~3=_3#\i.
untuk 11 karakter?##~0 0 1$~
.3#.}:(#:~$&3)
tetapi masih lebih lama dan itu tidak memperbaiki masalah angka negatif.^:
atau Agenda@.
untukif
atauif...else
mengganti. Dalam hal ini Anda mungkin dapat menggunakan@.
dengan dua kata kerja yang terhubung dengan karakter '' '(gerund dalam bahasa-J) untuk memilih satu atau yang lain berdasarkan suatu kondisi.C, 167503724710
Inilah solusi saya untuk masalah ini. Saya akui tidak mungkin untuk memenangkan kompetisi kode ketat golf, tetapi tidak menggunakan trik apa pun untuk secara tidak langsung memanggil fungsi divisi built-in, ditulis dalam portable C (seperti yang diminta oleh pertanyaan Stack Overflow), ia bekerja dengan sempurna untuk angka negatif, dan kode ini sangat jelas dan eksplisit.
Program saya adalah output dari skrip berikut:
Hitungan karakter: 71 + 39 * 2 ** 32 + 95 = 167503724710
Tolak ukur
Ditanyakan berapa lama ini dan berapa banyak memori yang akan digunakan, jadi inilah beberapa tolok ukur:
./test.py | pv --buffer-size=1M --average-rate > /dev/null
sekitar 30 detik menghasilkan kecepatan sekitar 14,8 MB / s. Tingkat output secara wajar dapat dianggap kira-kira konstan, sehingga waktu penyelesaian hingga sekitar 167503724710 B / (14,8 * 1048576 B / s) ≈ 10794 s../test.py | tcc -c - -o /dev/stdout | pv --buffer-size=1M --average-rate > /dev/null
, tetapi tampaknyatcc
tidak menghasilkan apa-apa sampai membaca seluruh file sumber masuksumber
a[b]
adalah gula sintaksis untuk*(a + b)
, yang melakukan penambahan.Ruby 28
Untuk membaginya dengan 3 kita hanya perlu menghapus trailing nol di nomor basis 3:
120 -> 11110 -> 1111 -> 40
Bekerja dengan negatif:
Ruby,
6045Atau, tanpa menggunakan konversi basis:
d = -> n {x = n.abs; r = (0..1.0 / 0) .step (3) .take (x) .index x; n> 0? r: -r}sumber
/
operator terlarangFloat::INFINITY
menjadi tempat1.0/0
. Dengan Ruby 2.1, satu Mei golf(0..1.0/0).step(3)
ke dalam0.step(p,3)
, menghapus/
. Masalah yang lebih besar adalah yang-r
digunakan-
untuk meniadakan. Biayanya 5 karakter untuk mengubah-r
ke~r.pred
, menyalahgunakan Integer # pred untuk mengurangi 1 tanpa operator pengurangan.Mathematica, 13 karakter
sumber
&
dan menggunakan variabel polos (orang lain di sini juga melakukannya).JavaScript, 56
Membuat string panjang
n
mengulang,
s dan menggantikan,,,
dengan1
. Kemudian, ia mengukur panjang string yang dihasilkan. (Semoga unary-
diizinkan!)sumber
-
operator negasi.-~
denganparseInt()
-~prompt()
adalah lebih besar dariparseInt(prompt())
. Tidak yakin bagaimana Anda akan menghadapinya.alert(Array(parseInt(prompt())).slice(1).join().replace(/,,,/g,1).length)
Python,
4138xrange
tampaknya dapat menangani jumlah besar (saya pikir batasnya sama dengan lama di C) hampir secara instan.sumber
10/3
sama dengan 3, bukan 4.print" -"[x<0]+
len (rentang (2, abs (x), 3)) `` akan mencukurnya menjadi 39 karakterlen()
sebagai singkatan untukrepr()
range
, karena itu benar-benar akan membuat daftar.xrange
hanya berpura-pura, sehingga mampu menangani jumlah besar tanpa membuang waktu / memori.Haskell, 90
106Membuat daftar pencarian tak terbatas (malas)
[(0,0),(0,0),(-1,0),(1,0),(-2,0),(2,0),(-3,-1),(3,1), ...]
, memotong semua elemen yang tidak cocokn
(/=
adalah ketidaksetaraan dalam Haskell) dan mengembalikan yang pertama yang tidak.Ini menjadi jauh lebih mudah jika tidak ada angka negatif:
25
27cukup mengembalikan
n
elemen th daftar[0,0,0,1,1,1,2, ...]
.sumber
C #, 232 byte
Golf kode pertama saya ... Dan karena tidak ada C # dan saya ingin mencoba metode yang berbeda tidak mencoba di sini, saya pikir saya akan mencobanya. Seperti beberapa orang lain di sini, hanya angka non-negatif.
Tidak disatukan
sumber
string[] g
, mengubahnya menjadistring[]g
.Add
?Perl (
2622)Versi ini (ab) menggunakan mesin regex Perl. Itu membaca angka sebagai argumen baris perintah terakhir (
pop
) dan membangun string3
s dengan panjang ini ("3" x $number
). Operator substitusi regex (s///
, di sini ditulis dengan pembatas yang berbeda karena aturan teka-teki dan dengang
bendera lobal) menggantikan tiga karakter dengan string kosong dan mengembalikan jumlah substitusi, yang merupakan bilangan integer input dibagi dengan tiga. Bahkan bisa ditulis tanpa3
, tetapi versi di atas terlihat lebih lucu.sumber
$_=3x pop;say s|333||g
.'$_=3x pop;say s|333||g||0
. Lambat dengan angka besar seperti 99999999, dan tidak berfungsi dengan angka negatif.-p
pada commandline, dan Anda dapat melakukan:$_=3x$_;$_=0|s|...||g
untuk total 22, termasuk cakupan input 0, 1, atau 2.C, 160 karakter
Solusi pembagian karakter dengan karakter panjang menggunakan tabel pencarian, yaitu tanpa string atoi () atau printf () untuk mengkonversi antara basis 10 string dan integer.
Output kadang-kadang akan mencakup nol terkemuka - bagian dari pesona itu.
catatan:
Pengujian:
sumber
Python 42
Karena setiap solusi yang diposting di sini saya telah memeriksa desimal truncate di sini adalah solusi saya yang melakukan itu.
Python
5051Karena python melakukan pembagian lantai, inilah solusi saya yang mengimplementasikannya.
Bilangan bulat input dalam variabel x.
Diuji dalam Python 2.7 tapi saya menduga itu bekerja di 3 juga.
sumber
-3
adalah jawaban yang benar-10/3
.JavaScript, 55
Jika seseorang tidak dapat menggunakan
-1
, maka ini adalah versi untuk menggantinya~0
(terima kasih Peter Taylor!).sumber
~
adalah operator Bitwise yang membalikkan bit operan (pertama mengubahnya menjadi angka). Ini adalah cara terpendek untuk mengubah string menjadi angka (sejauh yang saya tahu).~~
konversikan ke integer, sebagai lawan+
.C 83 karakter
Nomor untuk dibagi dilewatkan melalui stdin, dan mengembalikannya sebagai kode keluar dari
main()
(% ERRORLEVEL% di CMD). Kode ini menyalahgunakan beberapa versi MinGW di mana ketika optimasi tidak aktif, itu memperlakukan nilai tugas terakhir sebagai pernyataan pengembalian. Mungkin bisa dikurangi sedikit. Mendukung semua nomor yang dapat ditampungint
Jika negate unate (-) tidak diizinkan: (129)
Jika dinegasikan unary IS diizinkan: (123)
EDIT: ugoren menunjukkan kepada saya bahwa - ~ adalah kenaikan ...
83 Karakter jika negate unary diizinkan: D
sumber
x+3
adalah-~-~-~x
.C, 139 karakter
Jalankan dengan angka sebagai argumen baris perintah
Pengujian:
Suntingan:
sumber
A
, fungsi saya hanya memeriksa bit i di nomor n. Apakah standar C memperbolehkan menghilangkan deklarasi tipe atau itu sesuatu yang kompiler?ZSH -
3120/21Untuk angka negatif:
Dengan angka negatif (ZSH +
bc
) -6261Saya mungkin tidak seharusnya memberikan dua program sebagai jawaban saya, jadi inilah salah satu yang berfungsi untuk tanda nomor:
Ini menggunakan trik konversi basis yang sama dengan jawaban Artem Ice .
sumber
C,
8173 karakterHanya mendukung angka non-negatif.
Idenya adalah menggunakan pointer arithemtic. Angka tersebut dibaca ke dalam pointer
x
, yang tidak mengarah ke mana pun.&x[~2]
=&x[-3]
=x-3
digunakan untuk mengurangi 3. Ini diulang selama jumlahnya di atas 2.i
menghitung berapa kali ini dilakukan (&i[1]
=i+1
).sumber
Jawa
8679Anggap bilangan bulat ada di dalam y:
Konversi ke string dalam basis 3, menghapus karakter terakhir (pergeseran kanan ">>" di basis 3), lalu mengonversi kembali ke integer.
Berfungsi untuk angka negatif.
Jika angkanya, y, adalah <3 atau> -3, maka itu memberi 0.
Pertama kali memposting di kode golf. =) Jadi belum bisa berkomentar.
Terima kasih Kevin Cruijssen untuk tipsnya.
sumber
&&
untuk&
, dan 2xInteger
keLong
. (Juga, mengapa Anda menggunakan~2
bukan hanya-3
? Mereka adalah byte-count yang sama.)-
, tapi saya tidak tahu apakah itu dianggap sebagai negasi yang tidak disadari.Python2.6 (
29) (71) (57) (52) (43)Sunting - Baru menyadari bahwa kita juga harus menangani bilangan bulat negatif. Akan memperbaikinya nanti
Edit2 - Tetap
Sunting3 - Disimpan 5 karakter dengan mengikuti saran Joel Cornett
Sunting4 - Karena input tidak harus dari STDIN atau ARGV, disimpan 9 karakter dengan tidak mengambil input dari stdin
sumber
abs()
print z if x==abs(x) else -z
print (z,-z)[x<0]
Javascript,
4729Menggunakan
eval
secara dinamis menghasilkan a/
. Menggunakan+
hanya untuk penggabungan string, bukan penambahan.EDIT: Digunakan
"\57"
sebagai gantiString.fromCharCode(47)
sumber
alert(eval(prompt()+"\573"))
?Ruby (
432217)Tidak hanya golf, tapi juga keanggunan :)
Output akan seperti
(41/1)
. Jika harus integer maka kita harus menambahkan.to_i
hasil, dan jika kita mengubahto_i
keto_f
maka kita akan bisa mendapatkan output untuk mengapung juga.sumber
rational
garis pada Ruby 1.9.3. Menghilangkan tanda kurung menghemat satu char lagi .TI-Basic, 8 byte
Pemenang? :)
Putaran PS menuju tak terhingga untuk angka negatif (lihat di sini untuk alasannya). Untuk membulatkan ke nol, ganti
int(
denganiPart(
tanpa perubahan byte.Uji kasus
sumber
Python 2.x,
545351print' -'[x<0],len(range(*(2,-2,x,x,3,-3)[x<0::2]))
Di mana
_
dividen dan dimasukkan seperti itu.Catatan: Tidak yakin apakah menggunakan interpreter interaktif diperbolehkan, tetapi menurut OP: "Input bisa di STDIN atau ARGV atau dimasukkan dengan cara lain"
Sunting: Sekarang untuk python 3 (berfungsi dalam 2.x, tetapi mencetak tuple). Bekerja dengan negatif.
sumber
__len__
sudah cukup.len(range(100,1000))
berikan900
di 3.2.3 di linux.len(xrange(0,_,3))
lebih pendek dan lebih cepat lagi.C ++, 191
Dengan main dan include, 246, tanpa main dan include, hanya 178. Baris dihitung sebagai 1 karakter. Memperlakukan semua nomor sebagai tidak ditandatangani. Saya tidak mendapatkan peringatan karena memiliki pengembalian utama yang tidak ditandatangani jadi permainan yang adil.
Pengajuan codegolf pertama saya.
menggunakan shift untuk membagi angka dengan 4 berulang kali, dan menghitung jumlah (yang konvergen ke 1/3)
Kodesemu:
Sebagai tambahan, saya bisa menghilangkan metode utama dengan memberi nama d main dan membuatnya mengambil char ** dan menggunakan nilai pengembalian program sebagai output. Ini akan mengembalikan jumlah argumen baris perintah dibagi dengan tiga, dibulatkan ke bawah. Ini membawa panjangnya ke yang diiklankan 191:
sumber
Golfscript - 13 karakter
sumber
s/seem to //
:(. Saya harus memikirkannyaPowerShell 57 atau 46
Dalam 57 karakter menggunakan
%
sebagai operator PowerShell foreach, bukan modulo. Solusi ini dapat menerima bilangan bulat positif atau negatif.Dalam 46 karakter jika
*
diizinkan sebagai operator pengulangan string, jangan gandakan. Opsi ini membutuhkan bilangan bulat positif sebagai nilai input.sumber
R
Ini hanya bekerja dengan bilangan bulat positif:
Atau:
Atau:
Atau:
[[EDIT]] Dan yang jelek:
[[EDIT2]] Plus mungkin yang terbaik - terinspirasi oleh kode matlab di atas oleh Elliot G:
sumber
wrong sign in 'by' argument
SmileBASIC,
585136 byte (tidak ada fungsi matematika!)Penjelasan:
Program memindahkan lapisan latar belakang dengan lebih dari 3 frame, dan kemudian mendapatkan sudut setelah 1 frame, ketika ia telah menempuh 1/3 dari total jaraknya.
Versi divisi float, 38 byte:
Penjelasan:
sumber
Haskell
4139 karakterBekerja dengan set lengkap bilangan bulat positif dan negatif
Pertama membuat daftar 1 atau (-1) (tergantung pada tanda input) untuk setiap bilangan bulat ketiga dari 0 hingga input
n
.abs(n)
untuk angka negatif termasuk.misalnya
n=8 -> [0,3,6]
Kemudian mengembalikan jumlah daftar ini.
sumber
Clojure, 87; bekerja dengan yang negatif; berdasarkan lazyseqs
Tidak Disatukan:
sumber
Sage Notebook (21)
sumber