Divisi pelaksana


15

Terapkan algoritma divisi dalam bahasa favorit Anda yang menangani divisi integer. Itu hanya perlu menangani angka positif - tetapi poin bonus jika menangani divisi negatif dan campuran juga. Hasil dibulatkan ke bawah untuk hasil fraksional.

Program ini mungkin tidak berisi /, \, divatau serupa operator. Itu harus berupa rutinitas yang tidak menggunakan kemampuan pembagian asli bahasa.

Anda hanya perlu menangani divisi hingga 32-bit. Tidak boleh menggunakan pengurangan berulang.

Memasukkan

Ambil dua input pada stdin yang dipisahkan oleh garis atau spasi baru (pilihan Anda)

740 
2

Keluaran

Dalam hal ini, hasilnya adalah 370.

Solusi yang merupakan kemenangan tersingkat.


adalah 740,2juga diizinkan untuk input? yaitu dipisahkan koma?
gnibbler

"Hasil dibulatkan untuk hasil fraksional" - ok, jadi ternyata input juga dapat menghasilkan angka non-integer ... Tapi bagaimana dengan pembagi yang lebih besar daripada yang dibagi (katakanlah, 5 dan 10) - apakah itu diizinkan atau tidak?
Aurel Bílý

@gnibber Itu akan baik-baik saja, tetapi jelaskan dalam deskripsi program.
Thomas O

2
apakah menggunakan eksponensial dan fungsi matematika lainnya benar-benar diizinkan? mereka menggunakan pembagian di belakang layar, karena banyak solusi yang dilakukan ab⁻¹
Ming-Tang

2
ini adalah waktu terpendek tetapi saya belum melihat ada yang mengatur kode waktu
phuclv

Jawaban:


27

Python - 73 karakter

Mengambil input yang dipisahkan koma, mis 740,2

from math import*
x,y=input()
z=int(exp(log(x)-log(y)))
print(z*y+y<=x)+z

5
Ini, temanku, adalah CLEVER
Aamir

Output untuk "740,2" adalah 369. Apakah ini benar?
Eelvex

@Eelvex, seharusnya <=, memperbaikinya dan membuatnya lebih pendek :)
gnibbler

14

JavaScript, 61

A=Array,P=prompt,P((','+A(+P())).split(','+A(+P())).length-1)

Ini membuat string panjang dividen ,,,,,,(6) dan terbagi pada pembagi ,,,(3), menghasilkan array dengan panjang 3 ['', '', '']:, yang panjangnya saya kurangi satu dari. Jelas bukan yang tercepat, tapi semoga menarik!


2
Implementasi favorit saya di sini sejauh ini. Selamat atas kode kerennya!
Thomas Eding

Saya mencoba membuatnya sedikit lebih pendek. A=Array,P=prompt,P((''+A(+P())).split(','+A(+P())).length)
pimvdb

10

JavaScript - 36 karakter

p=prompt;alert(p()*Math.pow(p(),-1))

5
Mengganti alertdengan pakan memberi Anda beberapa karakter tambahan. :)
Casey Chu

9

Mathematica: 34 karakter

Memecahkan persamaan secara simbolis (xa == b)

Solve[x#[[1]]==#[[2]],x]&@Input[]

2
23 chars,Solve[x#==#2]&@@Input[]
chyanog

8

Python - 72 karakter

Mengambil input yang dipisahkan koma, misalnya 740,2

x,y=input();z=0
for i in range(32)[::-1]:z+=(1<<i)*(y<<i<=x-z*y)
print z

8

Python, 37

Langkah 1. Konversikan ke unary.

Langkah 2. Algoritma pembagian unary.

print('1'*input()).count('1'*input())

7

Python - 41 karakter

Mengambil input yang dipisahkan koma, mis 740,2

x,y=input();z=x
while y*z>x:z-=1 
print z

1
Ini, dalam beberapa kasus, lebih buruk daripada terus menerus mengurangi. mis. input adalah 5,4. sementara loop akan berjalan 4 kali sementara dalam kasus pengurangan, kita hanya perlu mengurangi sekali.
Aamir

6

Python, 70

Sesuatu yang gila saya hanya berpikir (menggunakan input yang dipisahkan koma):

from cmath import*
x,y=input()
print round(tan(polar(y+x*1j)[1]).real)

Jika Anda menerima kesalahan presisi float kecil, roundfungsinya dapat dijatuhkan.



3

PHP - 82 karakter (buggy)

$i=fgets(STDIN);$j=fgets(STDIN);$k=1;while(($a=$j*$k)<$i)$k++;echo($a>$i?--$k:$k);

Namun, ini adalah solusi yang sangat sederhana - ini tidak menangani pecahan atau tanda yang berbeda (akan melompat ke loop tak terhingga). Saya tidak akan menjelaskan secara detail, ini cukup sederhana.

Input dalam stdin, dipisahkan oleh baris baru.

PHP - 141 karakter (penuh)

$i*=$r=($i=fgets(STDIN))<0?-1:1;$j*=$s=($j=fgets(STDIN))<0?-1:1;$k=0;$l=1;while(($a=$j*$k)!=$i){if($a>$i)$k-=($l>>=2)*2;$k+=$l;}echo$k*$r*$s;

Input dan output sama dengan yang sebelumnya.

Ya, ini hampir dua kali ukuran dari yang sebelumnya, tetapi ini:

  • menangani pecahan dengan benar
  • menangani tanda-tanda dengan benar
  • tidak akan pernah masuk ke loop tak terbatas, KECUALI parameter kedua adalah 0 - tapi itu pembagian dengan nol - input tidak valid

Format ulang dan penjelasan:

$i *= $r = ($i = fgets(STDIN)) < 0 ? -1 : 1;
$j *= $s = ($j = fgets(STDIN)) < 0 ? -1 : 1;
                                    // First, in the parentheses, $i is set to
                                    // GET variable i, then $r is set to -1 or
                                    // 1, depending whether $i is negative or
                                    // not - finally, $i multiplied by $r ef-
                                    // fectively resulting in $i being the ab-
                                    // solute value of itself, but keeping the
                                    // sign in $r.
                                    // The same is then done to $j, the sign
                                    // is kept in $s.

$k = 0;                             // $k will be the result in the end.

$l = 1;                             // $l is used in the loop - it is added to
                                    // $k as long as $j*$k (the divisor times
                                    // the result so far) is less than $i (the
                                    // divided number).

while(($a = $j * $k) != $i){        // Main loop - it is executed until $j*$k
                                    // equals $i - that is, until a result is
                                    // found. Because a/b=c, c*b=a.
                                    // At the same time, $a is set to $j*$k,
                                    // to conserve space and time.

    if($a > $i)                     // If $a is greater than $i, last step
        $k -= ($l >>= 2) * 2;       // (add $l) is undone by subtracting $l
                                    // from $k, and then dividing $l by two
                                    // (by a bitwise right shift by 1) for
                                    // handling fractional results.
                                    // It might seem that using ($l>>=2)*2 here
                                    // is unnecessary - but by compressing the
                                    // two commands ($k-=$l and $l>>=2) into 1
                                    // means that curly braces are not needed:
                                    //
                                    // if($a>$i)$k-=($l>>=2)*2;
                                    //
                                    // vs.
                                    //
                                    // if($a>$i){$k-=$l;$l>>=2;}

    $k += $l;                       // Finally, $k is incremented by $l and
                                    // the while loop loops again.
}

echo $k * $r * $s;                  // To get the correct result, $k has to be
                                    // multiplied by $r and $s, keeping signs
                                    // that were removed in the beginning.

Anda menggunakan operator divisi yang satu ini, Anda mungkin bisa lolos dengan sedikit perubahan. ;)
Thomas O

@ Thomas O ya ... Saya menyadarinya sekarang ... Saya benar-benar berpikir tentang sedikit perubahan (ketika saya mengubahnya menjadi / = 2 bukannya / = 10) - tapi itu satu lagi char ... Tebak ' saya harus tetap menggunakannya ... Btw yang bukan divisi sama sekali: D.
Aurel Bílý

Pertanyaannya mengatakan Anda perlu menggunakan stdin, yang memang didukung oleh PHP.
Kevin Brown

@ Bass5098 Aaahhh ... Oh well, dapatkan 4 karakter ... Tetap.
Aurel Bílý

3

Ruby 1.9, 28 karakter

(?a*a+?b).split(?a*b).size-1

Sisa pembagian, 21 karakter

?a*a=~/(#{?a*b})\1*$/  

Sampel:

a = 756
b = 20
print (?a*a+?b).split(?a*b).size-1  # => 37
print ?a*a=~/(#{?a*b})\1*$/         # => 16

Untuk Ruby 1.8:

a = 756
b = 20
print ('a'*a+'b').split('a'*b).size-1  # => 37
print 'a'*a=~/(#{'a'*b})\1*$/          # => 16

NoMethodError: metode pribadi `split 'dipanggil untuk 69938: Fixnum
rkj

@ rkj, Maaf, hanya untuk Ruby 1.9. Untuk menjalankan Ruby 1.8 yang harus Anda lakukan ('a'*a+'b').split('a'*b).size-1, 3 karakter lebih besar.
LBg

3

APL (6)

⌊*-/⍟⎕

/bukan pembagian di sini, tapi foldr. yaitu,F/a b c adalah a F (b F c). Jika saya tidak dapat menggunakan foldrkarena namanya /, itu dapat dilakukan dalam 9 karakter:

⌊*(⍟⎕)-⍟⎕

Penjelasan:

  • : input()
  • ⍟⎕: map(log, input())
  • -/⍟⎕: foldr1(sub, map(log, input()))
  • *-/⍟⎕: exp(foldr1(sub, map(log, input())))
  • ⌊*-/⍟⎕: floor(exp(foldr1(sub, map(log, input()))))



2

Haskell, 96 karakter

main=getLine>>=print.d.map read.words
d[x,y]=pred.snd.head.filter((>x).fst)$map(\n->(n*y,n))[0..]

Input ada pada satu baris.

Kode hanya mencari jawaban dengan mengambil pembagi ddan mengalikannya dengan semua bilangan bulat n >= 0. Membiarkan mmenjadi dividen. Pilihan terbesar nyang n * d <= mdipilih menjadi jawabannya. Kode sebenarnya mengambil sedikit nsehingga n * d > mdan mengurangi 1 dari itu karena saya dapat mengambil elemen pertama dari daftar tersebut. Dalam kasus lain, saya harus mengambil yang terakhir, tetapi sulit untuk mengambil elemen terakhir dari daftar yang tidak terbatas. Yah, daftar itu bisa dibuktikan terbatas, tetapi Haskell tidak tahu lebih baik saat melakukan filter, sehingga terus menyaring tanpa batas.


2

Common Lisp, 42 karakter

(1-(loop as x to(read)by(read)counting t))

Menerima input yang dipisahkan spasi atau garis


2

Pesta, 72 64 karakter

read x y;yes ''|head -n$x>f;ls -l --block-size=$y f|cut -d\  -f5

Keluarkan jumlah baris baru yang tak terbatas, ambil x pertama, masukkan semuanya ke dalam file bernama f, lalu dapatkan ukuran f di blok ukuran y. Mengambil saran manatwork untuk mengurangi delapan karakter.


Sebagai "Ambil dua input pada stdin yang dipisahkan oleh garis atau spasi baru (pilihan Anda)", lebih baik pilih nanti, nilai-nilai yang dipisahkan ruang. Dalam hal ini Anda dapat menulis read x y. Dengan beberapa ruang lagi yang dihapus dapat dikurangi menjadi 64 karakter: pastebin.com/Y3SfSXWk
manatwork

1

Python - 45 karakter

Mengambil input yang dipisahkan koma, misalnya 740,2

x,y=input()
print-1+len((x*'.').split('.'*y))

1

Python, 94 karakter

Pencarian biner rekursif:

a,b=input()
def r(m,n):return r(m,m+n>>1)if n*b>a else n if n*b+b>a else r(n,2*n)
print r(0,1)

1

Python, 148

Solusi lain mungkin pendek, tetapi apakah itu skala web ?

Inilah solusi elegan dan waktu konstan yang memanfaatkan kekuatan CLOUD.

from urllib import*
print eval(urlopen('http://tryhaskell.org/haskell.json?method=eval&expr=div%20'+raw_input()+'%20'+raw_input()).read())['result']

Apakah saya menyebutkan itu juga menggunakan Haskell?


0

Python, 46 byte

Tidak ada yang memposting solusi pengurangan yang membosankan, jadi saya tidak bisa menahan diri untuk tidak melakukannya.

a, b = input ()
i = 0
sementara a> = b: a- = b; i + = 1
cetak saya

0

Smalltalk , Squeak 4.x rasa

mendefinisikan pesan biner ini di Integer:

% d 
    | i |
    d <= self or: [^0].
    i := self highBit - d highBit.
    d << i <= self or: [i := i - 1].
    ^1 << i + (self - (d << i) % d)

Setelah golf, hasil bagi ini masih panjang (88 karakter):

%d|i n|d<=(n:=self)or:[^0].i:=n highBit-d highBit.d<<i<=n or:[i:=i-1].^1<<i+(n-(d<<i)%d)

Tapi itu sangat cepat:

[0 to: 1000 do: [:n |
    1 to: 1000 do: [:d |
        self assert: (n//d) = (n%d)]].
] timeToRun.

-> 127 ms pada mini mac sederhana saya (8 MOp / s)

Dibandingkan dengan divisi reguler:

[0 to: 1000 do: [:n |
    1 to: 1000 do: [:d |
        self assert: (n//d) = (n//d)]].
] timeToRun.

-> 31 ms, hanya 4 kali lebih lambat

Saya tidak menghitung karakter untuk membaca stdin atau menulis stdout, Squeak tidak dirancang untuk skrip.

FileStream stdout nextPutAll:
    FileStream stdin nextLine asNumber%FileStream stdin nextLine asNumber;
    cr

Tentu saja, pengurangan yang lebih bodoh diulang

%d self>d and:[^0].^self-d%d+1

atau enumerasi bodoh biasa

%d^(0to:self)findLast:[:q|q*d<=self]

bisa bekerja juga, tetapi tidak terlalu menarik


0
#include <stdio.h>
#include <string.h>
#include <math.h>


main()
{
   int i,j,ans;
   i=740;
   j=2;

   ans = pow(10,log10(i) - log10(j));
   printf("\nThe answer is %d",ans);
}

0

DC: 26 karakter

?so?se0[1+dle*lo>i]dsix1-p

Saya akui itu bukan solusi tercepat.


0

Python 54

Mengambil input yang dibatasi koma.

  1. Membuat string titik-titik panjang x
  2. Mengganti segmen titik-titik dengan panjang y dengan koma tunggal
  3. Menghitung koma.

Kata-kata karena penurunan harga mati dengan daftar diikuti oleh kode ?:

x,y=input()
print("."*x).replace("."*y,',').count(',')

0

Q, 46

{-1+(#){x-y}[;y]\[{s[x-y]<>(s:signum)x}[y];x]}

.

q){-1+(#){x-y}[;y]\[{s[x-y]<>(s:signum)x}[y];x]}[740;2]
370
q){-1+(#){x-y}[;y]\[{s[x-y]<>(s:signum)x}[y];x]}[740;3]
246


0

Python, 40 karakter

print(float(input())*float(input())**-1)

0

Python, 37

x,y=input()
print len(('0'*x)[y-1::y])

Buat string dengan panjang x( '0'*x) dan gunakan slicing yang diperluas untuk memilih setiap ykarakter, mulai dari indeksy-1 . Mencetak panjang string yang dihasilkan.

Seperti Gnibbler, ini membutuhkan input yang dipisahkan koma. Menghapusnya biayanya 9:

i=input
x,y=i(),i()
print len(('0'*x)[y-1::y])

0

Retina 0.7.3, 33 byte (tidak bersaing)

Bahasa lebih baru daripada tantangan. Mengambil input yang dipisahkan ruang terlebih dahulu dengan pembagi. Membagi dengan nol tidak ditentukan.

\d+
$*
^(.+) (\1)+.*$
$#+
.+ .*
0

Cobalah online


Bagaimana Anda menghitung ini sebagai 25 byte? Jika Anda mengharapkan I / O unary Anda harus mengatakannya (dan saya pikir itu 24 byte). Tidak yakin mengapa Anda memperlakukan 0 case secara terpisah: retina.tryitonline.net/...
Martin Ender

Itu salah disalin
mbomb007
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.