Membagi angka dengan 3 tanpa menggunakan operator *, /, +, -,%


48

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__atau add()). Ini juga berlaku untuk operator yang menambah dan mengurangi, seperti i++atau i--. 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

1
Bagaimana seharusnya hasilnya dibulatkan ketika positif? Bagaimana bila negatif?
dfeuer

Jawaban:


15

J, 45 44 10 karakter

".,&'r3'":

Bekerja dengan negatif:

".,&'r3'": 15
5
   ".,&'r3'": _9
_3
   ".,&'r3'": 3e99
1e99

": - format sebagai teks

,&'r3'- tambahkan r3sampai akhir

". - jalankan string, mis 15r3


1
Ini berfungsi jika Anda melakukannya 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.
Gareth

1
Mungkin ##~3=_3#\i.untuk 11 karakter?
Gareth

1
Sebenarnya, Anda dapat mengecilkan karakter Anda hingga 10 karakter dengan ##~0 0 1$~.
Gareth

1
Anda dapat mengecilkannya menggunakan kait 3#.}:(#:~$&3)tetapi masih lebih lama dan itu tidak memperbaiki masalah angka negatif.
Gareth

1
Ya, Anda dapat menggunakan fungsi Daya ^: atau Agenda @. untuk ifatau if...elsemengganti. 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.
Gareth

56

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:

#!/usr/bin/env python3
import sys

# 71
sys.stdout.write('''#include <stdint.h>
#include <stdio.h>
int32_t div_by_3(int32_t input){''')

# 39 * 2**32
for i in range(-2**31, 2**31):
    # 18 + 11 + 10 = 39
    sys.stdout.write('if(input==%11d)return%10d;' % (i, i / 3))

# 95
sys.stdout.write(r'''return 7;}int main(int c,char**v){int32_t n=atoi(a[1]);printf("%d / 3 = %d\n",n, div_by_3(n));}''')

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:

  • Waktu eksekusi skrip - Berjalan ./test.py | pv --buffer-size=1M --average-rate > /dev/nullsekitar 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.
  • Waktu kompilasi - Kompiler TCC mengklaim untuk mengkompilasi kode C pada 29,6 MB / s , yang membuat waktu kompilasi 167503724710 B / (29,6 * 1048576 B / s) ≈ 5397 s. (Tentu saja ini dapat berjalan dalam pipa dengan skrip.)
  • Ukuran kode yang dikompilasi - Saya mencoba memperkirakan menggunakan ./test.py | tcc -c - -o /dev/stdout | pv --buffer-size=1M --average-rate > /dev/null, tetapi tampaknya tcctidak menghasilkan apa-apa sampai membaca seluruh file sumber masuk
  • Penggunaan memori untuk dijalankan - Karena algoritma ini linier (dan tcc tidak mengoptimalkan lintas baris), overhead memori harus hanya beberapa kilobyte (terlepas dari kode itu sendiri, tentu saja).

22
Ini adalah contoh hardcoding. ++++++++++
Joe Z.

4
Yang sedang berkata, saya yakin jika Anda memberi mereka file sumber 160 GB dan meminta mereka untuk mengkompilasi dan mengujinya, mereka akan melihat Anda seperti Anda gila.
Joe Z.

16
Jika bos saya meminta saya untuk menghitung pembagian dengan tiga tanpa - + / *% saya akan berpikir dia gila.
Mikaël Mayer

Namun, a[b]adalah gula sintaksis untuk *(a + b), yang melakukan penambahan.
Konrad Borowski

12
@NicolasBarbulesco Ada batasan ukuran pada jawaban Stack Exchange.
Timtech

38

Ruby 28

b=->n{n.to_s(3).chop.to_i 3}

Untuk membaginya dengan 3 kita hanya perlu menghapus trailing nol di nomor basis 3: 120 -> 11110 -> 1111 -> 40

Bekerja dengan negatif:

ice distantstar:~/virt/golf [349:1]% ruby ./div3.rb
666
222
ice distantstar:~/virt/golf [349]% ruby ./div3.rb
-15        
-5

Ruby, 60 45

Atau, tanpa menggunakan konversi basis:

d = -> n {x = n.abs; r = (0..1.0 / 0) .step (3) .take (x) .index x; n> 0? r: -r}

d=->n{(r=1.step(n.abs,3).to_a.size);n>0?r:-r}

1
Alternatif tanpa konversi basis menjadikan /operator terlarang Float::INFINITYmenjadi tempat 1.0/0. Dengan Ruby 2.1, satu Mei golf (0..1.0/0).step(3)ke dalam 0.step(p,3), menghapus /. Masalah yang lebih besar adalah yang -rdigunakan -untuk meniadakan. Biayanya 5 karakter untuk mengubah -rke ~r.pred, menyalahgunakan Integer # pred untuk mengurangi 1 tanpa operator pengurangan.
kernigh

26

Mathematica, 13 karakter

Mean@{#,0,0}&

Ini jahat: Saya kira Anda bisa menyimpan &dan menggunakan variabel polos (orang lain di sini juga melakukannya).
Yves Klett

3
@YvesKlett: Mean pada dasarnya jahat.
GuitarPicker

18

JavaScript, 56

alert(Array(-~prompt()).join().replace(/,,,/g,1).length)

Membuat string panjang nmengulang ,s dan menggantikan ,,,dengan 1. Kemudian, ia mengukur panjang string yang dihasilkan. (Semoga unary -diizinkan!)


+1 tetapi tidak bekerja dengan nilai negatif
Francesco Casula

Uh, pertanyaan ... bagaimana ini dihitung? Ini menggunakan -operator negasi.
Patrick Roberts

@ Patrick Saya mengambil spesifikasinya tanpa pengurangan - jika Anda mau, Anda bisa menggantinya -~denganparseInt()
Casey Chu

@CaseyChu nilai yang dikembalikan oleh -~prompt()adalah lebih besar dari parseInt(prompt()). Tidak yakin bagaimana Anda akan menghadapinya.
Patrick Roberts

alert(Array(parseInt(prompt())).slice(1).join().replace(/,,,/g,1).length)
Casey Chu

16

Python, 41 38

print"-"[x:]+`len(xrange(2,abs(x),3))`

xrange tampaknya dapat menangani jumlah besar (saya pikir batasnya sama dengan lama di C) hampir secara instan.

>>> x = -72
-24

>>> x = 9223372036854775806
3074457345618258602

2
10/3sama dengan 3, bukan 4.
Joel Cornett

Melakukan print" -"[x<0]+len (rentang (2, abs (x), 3)) `` akan mencukurnya menjadi 39 karakter
Joel Cornett

Format komentar golfexchange mengacaukannya. di atas saya menggunakan backticks untuk melampirkan len()sebagai singkatan untukrepr()
Joel Cornett

Saya sudah memperbaruinya. Saya tidak dapat menggunakan range, karena itu benar-benar akan membuat daftar. xrangehanya berpura-pura, sehingga mampu menangani jumlah besar tanpa membuang waktu / memori.
grc

2
Berpura-puralah itu Python 3;) Saya suka char slicing btw.
Joel Cornett

11

Haskell, 90 106

d n=snd.head.dropWhile((/=n).fst)$zip([0..]>>=ν)([0..]>>=replicate 3>>=ν);ν q=[negate q,q]

Membuat 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 cocok n( /=adalah ketidaksetaraan dalam Haskell) dan mengembalikan yang pertama yang tidak.

Ini menjadi jauh lebih mudah jika tidak ada angka negatif:

25 27

(([0..]>>=replicate 3)!!)

cukup mengembalikan nelemen th daftar [0,0,0,1,1,1,2, ...].


3
oO saya tidak pernah memikirkan solusi kedua itu. Saya mungkin bisa mengimplementasikan sesuatu seperti itu di python
acolyte

8

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.

class l:System.Collections.Generic.List<int>{}class p{static void Main(string[] g){int n=int.Parse(g[0]);l b,a=new l();b=new l();while(a.Count<n)a.Add(1);while(a.Count>2){a.RemoveRange(0,3);b.Add(1);}System.Console.Write(b.Count);}}

Tidak disatukan

class l : System.Collections.Generic.List<int>
{ }
class p
{
    static void Main(string[] g)
    {
        int n = int.Parse(g[0]);
        l b, a = new l();
        b = new l();
        while (a.Count < n) a.Add(1);
        while (a.Count > 2)
        {
            a.RemoveRange(0, 3);
            b.Add(1);
        }
        System.Console.Write(b.Count);
    }
}

2
Sekitar 5 tahun kemudian .. Anda dapat menyimpan 1 byte dengan menghapus ruang dari string[] g, mengubahnya menjadistring[]g
Metoniem

Mengutip "Jangan gunakan operator non-teks *, /, +, -, atau% (atau yang setara, seperti div atau tambahkan ()" - apakah Anda tidak menggunakan yang setara - .Add?
Jonathan Frech

@JonathanFrech Metode menambahkan itu tidak bekerja pada dua angka, itu hanya menambah nilai koleksi
Perwujudan Ketidaktahuan

7

Perl (26 22)

$_=3x pop;say s|333||g

Versi ini (ab) menggunakan mesin regex Perl. Itu membaca angka sebagai argumen baris perintah terakhir ( pop) dan membangun string 3s dengan panjang ini ( "3" x $number). Operator substitusi regex ( s///, di sini ditulis dengan pembatas yang berbeda karena aturan teka-teki dan dengan gbendera lobal) menggantikan tiga karakter dengan string kosong dan mengembalikan jumlah substitusi, yang merupakan bilangan integer input dibagi dengan tiga. Bahkan bisa ditulis tanpa 3, tetapi versi di atas terlihat lebih lucu.

$ perl -E '$_=3x pop;say s|333||g' 42
14

2
Hey @memowe, kerja bagus! Anda dapat menyimpan beberapa karakter lagi (4) dengan melakukan $_=3x pop;say s|333||g.
Dom Hastings

2
Ketika inputnya 0, 1, atau 2, maka ia mencetak string kosong. Jika perlu mencetak 0, maka perlu 3 lebih karakter (25 Total): '$_=3x pop;say s|333||g||0. Lambat dengan angka besar seperti 99999999, dan tidak berfungsi dengan angka negatif.
kernigh

1
Gunakan -ppada commandline, dan Anda dapat melakukan: $_=3x$_;$_=0|s|...||guntuk total 22, termasuk cakupan input 0, 1, atau 2.
Xcali

6

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.

main(int n,char**a){
char*s=a[1],*x=0;
if(*s==45)s=&s[1];
for(;*s;s=&s[1])n=&x[*s&15],x="036"[(int)x],*s=&x["000111222333"[n]&3],x="012012012012"[n]&3;
puts(a[1]);
}

catatan:

  • penyalahgunaan akses array untuk mengimplementasikan penambahan.
  • kompilasi dengan clang 4.0, kompiler lain mungkin muntah.

Pengujian:

./a.out -6            -2
./a.out -5            -1
./a.out -4            -1
./a.out -3            -1
./a.out -2            -0
./a.out -1            -0
./a.out 0             0
./a.out 1             0
./a.out 2             0
./a.out 3             1
./a.out 4             1
./a.out 5             1
./a.out 6             2
./a.out 42            14
./a.out 2011          0670

6

Python 42

int(' -'[x<0]+str(len(range(2,abs(x),3))))

Karena setiap solusi yang diposting di sini saya telah memeriksa desimal truncate di sini adalah solusi saya yang melakukan itu.

Python 50 51

int(' -'[x<0]+str(len(range([2,0][x<0],abs(x),3))))

Karena 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.


+1 Untuk menawarkan kedua alternatif pada situasi nilai negatif. Karena sudah ada begitu banyak jawaban, saya tidak akan menyesuaikan spesifikasi untuk mengecualikan satu atau opsi lain, meskipun saya pribadi akan setuju bahwa itu -3adalah jawaban yang benar -10/3.
Gaffi

Bagi mereka yang peduli tentang pembagian lantai dengan python: python-history.blogspot.com/2010/08/...
Matt

ada apa dengan multiplikasi dan pengurangan dalam solusi kedua Anda?
booth

@ boothby Solusi kedua mengimplementasikan pembagian lantai. Saya ingin melakukan range (0, abs (x), 3) untuk angka negatif dan range (2, abs (x), 3) untuk angka positif. Untuk melakukan itu, saya memiliki rentang (2 ... lalu saya kurangi 2 ketika x negatif. X <0 Benar ketika x negatif, (Benar) * 2 == 2
Matt

Saya tidak mengerti perbedaan antara pembagian lantai dan desimal truncating. Apakah ini harus dengan pembagian negatif?
Joel Cornett

6

JavaScript, 55

alert(parseInt((~~prompt()).toString(3).slice(0,-1),3))

Jika seseorang tidak dapat menggunakan -1, maka ini adalah versi untuk menggantinya ~0(terima kasih Peter Taylor!).

alert(parseInt((~~prompt()).toString(3).slice(0,~0),3))

1
@ArtemIce One ~adalah operator Bitwise yang membalikkan bit operan (pertama mengubahnya menjadi angka). Ini adalah cara terpendek untuk mengubah string menjadi angka (sejauh yang saya tahu).
Inkbug

1
Saya merasa seperti menggunakan string parsing / konversi curang, karena itu a) proses yang sangat rumit dan mahal dibandingkan dengan operasi bitwise, b) menggunakan operator terlarang secara internal, dan c) akan mengambil waaaaay lebih banyak karakter daripada solusi homerolled. Seperti bagaimana orang menjadi pemarah ketika Anda menggunakan built-in macam ketika diminta untuk mengimplementasikan quicksort.
Wug

1
@ Sam Juga, ~~konversikan ke integer, sebagai lawan +.
Inkbug

1
@Wug Ini adalah codegolf, jadi ini bukan tentang efisiensi kecuali ditentukan dalam tugas.
defhlt

3
+1 untuk memanfaatkan basis yang berbeda. Itu salah satu teknik golf JavaScript favorit saya.
DocMax

6

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)

I(unsigned a){a=a&1?I(a>>1)<<1:a|1;}main(a,b,c){scanf("%i",&b);a=b;a=a<0?a:I(~a);for(c=0;a<~1;a=I(I(I(a))))c=I(c);b=b<0?I(~c):c;}

Jika dinegasikan unary IS diizinkan: (123)

I(unsigned a){a=a&1?I(a>>1)<<1:a|1;}main(a,b,c){scanf("%i",&b);a=b;a=a<0?a:-a;for(c=0;a<~1;a=I(I(I(a))))c=I(c);b=b<0?-c:c;}

EDIT: ugoren menunjukkan kepada saya bahwa - ~ adalah kenaikan ...

83 Karakter jika negate unary diizinkan: D

main(a,b,c){scanf("%i",&b);a=b;a=a<0?a:-a;for(c=0;a<~1;a=-~-~-~a)c=-~c;b=b<0?-c:c;}

Jika negate unary diizinkan, x+3adalah -~-~-~x.
ugoren

Terima kasih untuk itu. Saya tidak tahu mengapa itu tidak pernah terpikir oleh saya. Kurasa aku tidak sadar kamu bisa menumpuk unaries dengan sangat hehe.
Kaslai

5

C, 139 karakter

t;A(a,b){return a?A((a&b)<<1,a^b):b;}main(int n,char**a){n=atoi(a[1]);for(n=A(n,n<0?2:1);n&~3;t=A(n>>2,t),n=A(n>>2,n&3));printf("%d\n",t);}

Jalankan dengan angka sebagai argumen baris perintah

  • Menangani angka negatif dan positif

Pengujian:

 ./a.out -6            -2
 ./a.out -5            -1
 ./a.out -4            -1
 ./a.out -3            -1
 ./a.out -2            0
 ./a.out -1            0
 ./a.out 0             0
 ./a.out 1             0
 ./a.out 2             0
 ./a.out 3             1
 ./a.out 4             1
 ./a.out 5             1
 ./a.out 6             2
 ./a.out 42            14
 ./a.out 2011          670

Suntingan:

  • disimpan 10 karakter dengan mengocok penambahan (A) untuk menghapus variabel lokal.

1
Bagus sekali. Saya mencoba yang terbaik di bit twiddling dan sampai ke 239. Saya hanya tidak bisa mendapatkan kepalaku A, fungsi saya hanya memeriksa bit i di nomor n. Apakah standar C memperbolehkan menghilangkan deklarasi tipe atau itu sesuatu yang kompiler?
shiona

1
C akan menganggap int jika tidak ditentukan.
Wug

5

ZSH - 31 20/21

echo {2..x..3}|wc -w

Untuk angka negatif:

echo {-2..x..3}|wc -w

Dengan angka negatif (ZSH + bc) -62 61

Saya mungkin tidak seharusnya memberikan dua program sebagai jawaban saya, jadi inilah salah satu yang berfungsi untuk tanda nomor:

echo 'obase=10;ibase=3;'`echo 'obase=3;x'|bc|sed 's/.$//'`|bc

Ini menggunakan trik konversi basis yang sama dengan jawaban Artem Ice .


5

C, 81 73 karakter

Hanya mendukung angka non-negatif.

char*x,*i;
main(){
    for(scanf("%d",&x);x>2;x=&x[~2])i=&i[1];
    printf("%d",i);
}

Idenya adalah menggunakan pointer arithemtic. Angka tersebut dibaca ke dalam pointer x, yang tidak mengarah ke mana pun. &x[~2]= &x[-3]= x-3digunakan untuk mengurangi 3. Ini diulang selama jumlahnya di atas 2. imenghitung berapa kali ini dilakukan ( &i[1]= i+1).


Mencoba memahami kodenya, seseorang memberi penerangan? Terima kasih
Cong Hui

@ Chui, menambahkan penjelasan.
ugoren

@ugoren sejauh yang saya mengerti, tidak boleh printf ("% d") mencetak pointer alamat memori yang saya pegang di Hex? mengapa mencetak bilangan bulat? atau karakter * saya diinisialisasi untuk menunjuk ke alamat memori 0 secara default? Terima kasih
Cong Hui

5

Jawa 86 79

Anggap 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.

System.out.print(~2<y&y<3?0:Long.valueOf(Long.toString(y,3).split(".$")[0],3));

Pertama kali memposting di kode golf. =) Jadi belum bisa berkomentar.

Terima kasih Kevin Cruijssen untuk tipsnya.


Saya tahu ini sudah lebih dari dua tahun yang lalu, tetapi Anda bisa bermain golf beberapa bagian: &&untuk &, dan 2x Integerke Long. (Juga, mengapa Anda menggunakan ~2bukan hanya -3? Mereka adalah byte-count yang sama.)
Kevin Cruijssen

1
@KevinCruijssen Sangat nostalgia untuk mengedit posting pertama saya setelah sekian lama. Tidak terlalu yakin mengapa aku berpikir ~ 2 lebih baik saat itu.
Vektor

2
@KevinCruijssen dengan baik, tantangannya mengatakan Anda tidak diizinkan untuk menggunakan -, tapi saya tidak tahu apakah itu dianggap sebagai negasi yang tidak disadari.
FlipTack

@FlipTack Ah Anda benar sekali. Kalau begitu lupakan aku yang pernah mengatakannya. :)
Kevin Cruijssen

4

Python2.6 ( 29 ) ( 71 ) ( 57 ) ( 52 ) (43)

z=len(range(2,abs(x),3))
print (z,-z)[x<0]

print len(range(2,input(),3))

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


Silakanabs()
defhlt

lebih singkat untuk dilakukanprint z if x==abs(x) else -z
Joel Cornett

lebih baik lagi,print (z,-z)[x<0]
Joel Cornett

@ ArtemIce terima kasih, baru sadar saya bisa menggunakannya setelah membaca jawaban lain di atas.
elssar

@ JoelCornett humm, tidak tahu tentang itu, terima kasih
elssar

4

Javascript, 47 29

Menggunakan evalsecara dinamis menghasilkan a /. Menggunakan +hanya untuk penggabungan string, bukan penambahan.

alert(eval(prompt()+"\57"+3))

EDIT: Digunakan "\57"sebagai gantiString.fromCharCode(47)


-1 untuk alert(eval(prompt()+"\573"))?
Shieru Asakoto

4

Ruby ( 43 22 17)

Tidak hanya golf, tapi juga keanggunan :)

p Rational gets,3

Output akan seperti (41/1). Jika harus integer maka kita harus menambahkan .to_ihasil, dan jika kita mengubah to_ike to_fmaka kita akan bisa mendapatkan output untuk mengapung juga.


1
Bekerja tanpa memerlukan rationalgaris pada Ruby 1.9.3. Menghilangkan tanda kurung menghemat satu char lagi .
steenslag

4

TI-Basic, 8 byte

Pemenang? :)

int(mean({Ans,0,0

Putaran PS menuju tak terhingga untuk angka negatif (lihat di sini untuk alasannya). Untuk membulatkan ke nol, ganti int(dengan iPart(tanpa perubahan byte.

Uji kasus

-4:prgmDIVIDE
              -2
11:prgmDIVIDE
               3
109:prgmDIVIDE
              36

3

Python 2.x, 54 53 51

print' -'[x<0],len(range(*(2,-2,x,x,3,-3)[x<0::2]))

Di mana _dividen dan dimasukkan seperti itu.

>>> x=-19
>>> print' -'[x<0],len(range(*(2,-2,x,x,3,-3)[x<0::2]))
- 6

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.


Bekerja di python 3 juga?
Siput mekanik

Tidak harus dapat disubkripsikan; memiliki __len__sudah cukup.
Siput mekanik

len(range(100,1000))berikan 900di 3.2.3 di linux.
Siput mekanik

Ini tidak berfungsi untuk angka negatif. Dan len(xrange(0,_,3))lebih pendek dan lebih cepat lagi.
grc

@ Mekanis thumbnail: Titik diambil. Saya mengakui. Ini bekerja pada 3.
Joel Cornett

3

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.

#include<iostream>
#define R return
typedef unsigned int U;U a(U x,U y){R y?a(x^y,(x|y^x^y)<<1):x;}U d(U i){if(i==3)R 1;U t=i&3,r=i>>=2;t=a(t,i&3);while(i>>=2)t=a(t,i&3),r=a(r,i);R r&&t?a(r,d(t)):0;}U main(){U i;std::cin>>i,std::cout<<d(i);R 0;}

menggunakan shift untuk membagi angka dengan 4 berulang kali, dan menghitung jumlah (yang konvergen ke 1/3)

Kodesemu:

// typedefs and #defines for brevity

function a(x, y):
    magically add x and y using recursion and bitwise things
    return x+y.

function d(x):
    if x = 3:
        return 1.
    variable total, remainder
    until x is zero:
        remainder = x mod 4
        x = x / 4
        total = total + x
    if total and remainder both zero:
        return 0.
    else:
        return a(total, d(remainder)).

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:

#define R return
typedef unsigned int U;U a(U x,U y){R y?a(x^y,(x|y^x^y)<<1):x;}U main(U i,char**q){if(i==3)R 1;U t=i&3,r=i>>=2;t=a(t,i&3);while(i>>=2)t=a(t,i&3),r=a(r,i);R r&&t?a(r,d(t)):0;}

3

Golfscript - 13 karakter

~3base);3base

tampaknya tidak menangani input negatif
res

1
@res s/seem to //:(. Saya harus memikirkannya
gnibbler

3

PowerShell 57 atau 46

Dalam 57 karakter menggunakan %sebagai operator PowerShell foreach, bukan modulo. Solusi ini dapat menerima bilangan bulat positif atau negatif.

(-join(1..(Read-Host)|%{1})-replace111,0-replace1).Length

Dalam 46 karakter jika *diizinkan sebagai operator pengulangan string, jangan gandakan. Opsi ini membutuhkan bilangan bulat positif sebagai nilai input.

("1"*(Read-Host)-replace111,0-replace1).Length

Jika Anda pernah kembali, saya memposting perbaikan bug. Jika Anda ingin saya menghapus milik saya dan memasukkan perubahan ke dalam milik Anda, beri tahu saya.
Veskah

3

R

Ini hanya bekerja dengan bilangan bulat positif:

max(sapply(split(1:x,1:3), length))
# Gives a warning that should be ignored

Atau:

min(table(rep(1:3, x)[1:x]))

Atau:

length((1:x)[seq(3,x,3)])

Atau:

sum(rep(1,x)[seq(3,x,3)])

[[EDIT]] Dan yang jelek:

trunc(sum(rep(0.3333333333, x)))

[[EDIT2]] Plus mungkin yang terbaik - terinspirasi oleh kode matlab di atas oleh Elliot G:

length(seq(1,x,3))

Saya ingin menerapkan ide yang sama seperti pada EDIT2 Anda tetapi tidak bekerja untuk angka negatif:wrong sign in 'by' argument
Andreï Kostyrka

3

SmileBASIC, 58 51 36 byte (tidak ada fungsi matematika!)

INPUT N
BGANIM.,4,-3,N
WAIT?BGROT(0)

Penjelasan:

INPUT N           'get input
BGANIM 0,"R",-3,N 'smoothly rotate background layer 0 by N degrees over 3 frames
WAIT              'wait 1 frame
PRINT BGROT(0)    'display angle of layer 0

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:

INPUT N
BGANIM.,7,-3,N
WAIT?BGVAR(0,7)

Penjelasan:

INPUT N           'input
BGANIM 0,"V",-3,N 'smoothly change layer 0's internal variable to N over 3 frames
WAIT              'wait 1 frame
PRINT BGVAR(0,7)  'display layer 0's internal variable

3

Haskell 41 39 karakter

Bekerja dengan set lengkap bilangan bulat positif dan negatif

f n=sum[sum$1:[-2|n<0]|i<-[3,6..abs n]]

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.


Tidak bekerja pada angka negatif (-3/3 adalah -1 bukan 1).
Cormac

Bagus Anda membuatnya bekerja pada angka negatif tetapi Anda tidak dapat menggunakan /, baca spesifikasinya.
Cormac

Ya ampun, Anda mendapatkan saya dua kali. Semua sudah diperbaiki;)
Charl Kruger

Bagus! Btw Anda bisa mendapatkan 39 karakter dengan fn = jumlah [jumlah $ 1: [- 2 | n <0] | i <- [3,6..ab n]]
Cormac

2

Clojure, 87; bekerja dengan yang negatif; berdasarkan lazyseqs

(defn d[n](def r(nth(apply interleave(repeat 3(range)))(Math/abs n)))(if(> n 0)r(- r)))

Tidak Disatukan:

(defn d [n]
  (let [r (nth (->> (range) (repeat 3) (apply interleave))
               (Math/abs n))]
        (if (pos? n)
          r
          (- r))))

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.