17
\$\begingroup\$

Implement a division algorithm in your favourite language which handles integer division. It need only handle positive numbers - but bonus points if it handles negative and mixed-sign division, too. Results are rounded down for fractional results.

The program may not contain the /, \, div or similar operators. It must be a routine which does not use native division capabilities of the language.

You only need to handle up to 32-bit division. Using repeated subtraction is not allowed.

Input

Take two inputs on stdin separated by new lines or spaces (your choice)

740 
2

Output

In this case, the output would be 370.

The solution which is the shortest wins.

\$\endgroup\$
12
  • \$\begingroup\$ is 740,2 also permitted for the input? ie comma separated? \$\endgroup\$
    – gnibbler
    Commented Feb 4, 2011 at 10:44
  • 1
    \$\begingroup\$ @Aurel300 It is not required to have fractional output. 1/7 may produce 0.142857... or 0. \$\endgroup\$
    – Thomas O
    Commented Feb 4, 2011 at 12:24
  • 3
    \$\begingroup\$ is using exponentials and other math functions really allowed? they use division behind the scenes, because many solutions are doing ab⁻¹ \$\endgroup\$
    – Ming-Tang
    Commented Feb 5, 2011 at 7:12
  • 2
    \$\begingroup\$ this is shortest-time but I haven't seen anyone time the code \$\endgroup\$
    – phuclv
    Commented Jun 9, 2014 at 13:45
  • 1
    \$\begingroup\$ @sergiol Most programming languages provide the division operator dividend / divisor. Some programming languages also provide the division operation with reversed operands, so dividend / divisor = divisor \ dividend. This is what Thomas wanted to exclude. \$\endgroup\$ Commented Nov 30 at 10:22

38 Answers 38

29
\$\begingroup\$

Python - 73 chars

Takes comma separated input, eg 740,2

from math import*
x,y=input()
z=int(exp(log(x)-log(y)))
print(z*y+y<=x)+z
\$\endgroup\$
3
  • 5
    \$\begingroup\$ This, my friend, is CLEVER \$\endgroup\$
    – Aamir
    Commented Feb 4, 2011 at 11:25
  • \$\begingroup\$ Output for "740,2" is 369. Is this correct? \$\endgroup\$
    – Eelvex
    Commented Feb 17, 2011 at 23:23
  • \$\begingroup\$ @Eelvex, should have been <=, fixed it and made it shorter :) \$\endgroup\$
    – gnibbler
    Commented Feb 17, 2011 at 23:43
14
\$\begingroup\$

JavaScript, 61

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

This makes a string the length of the dividend ,,,,,, (6) and splits on the divisor ,,, (3), resulting in an array of length 3: ['', '', ''], whose length I then subtract one from. Definitely not the fastest, but hopefully interesting nonetheless!

\$\endgroup\$
2
  • 2
    \$\begingroup\$ My favorite implementation here so far. Congrats for the cool code! \$\endgroup\$ Commented Aug 12, 2011 at 23:14
  • \$\begingroup\$ I tried to make it a little shorter. A=Array,P=prompt,P((''+A(+P())).split(','+A(+P())).length) \$\endgroup\$
    – pimvdb
    Commented Aug 30, 2011 at 19:54
10
\$\begingroup\$

JavaScript - 36 characters

p=prompt;alert(p()*Math.pow(p(),-1))
\$\endgroup\$
1
  • 6
    \$\begingroup\$ Replacing alert with p will net you some extra characters. :) \$\endgroup\$
    – Casey Chu
    Commented Aug 9, 2011 at 3:00
10
\$\begingroup\$

Python, 37

Step 1. Convert to unary.

Step 2. Unary division algorithm.

print('1'*input()).count('1'*input())
\$\endgroup\$
0
9
\$\begingroup\$

Python - 72 chars

Takes comma separated input, eg 740,2

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

Mathematica: 34 chars

Solves symbolically the equation (x a == b)

Solve[x#[[1]]==#[[2]],x]&@Input[]
\$\endgroup\$
1
  • 2
    \$\begingroup\$ 23 chars, Solve[x#==#2]&@@Input[] \$\endgroup\$
    – chyanog
    Commented Jul 21, 2013 at 10:42
8
\$\begingroup\$

Python - 41 chars

Takes comma separated input, eg 740,2

x,y=input();z=x
while y*z>x:z-=1 
print z
\$\endgroup\$
1
  • 1
    \$\begingroup\$ This, in some cases, is worse than continuously subtracting. e.g., input is 5,4. while loop will run 4 times while in case of subtraction, we will only have to subtract once. \$\endgroup\$
    – Aamir
    Commented Feb 4, 2011 at 11:20
6
\$\begingroup\$

Python, 70

Something crazy I just thought (using comma separated input):

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

If you accept small float precision errors, the round function can be dropped.

\$\endgroup\$
1
  • \$\begingroup\$ it's meant to be integer division, so you need to add a thing like what this answer does \$\endgroup\$
    – guest4308
    Commented Dec 1 at 6:32
5
\$\begingroup\$

APL (6)

⌊*-/⍟⎕

/ is not division here, but foldr. i.e, F/a b c is a F (b F c). If I can't use foldr because it's called /, it can be done in 9 characters:

⌊*(⍟⎕)-⍟⎕

Explanation:

  • : input()
  • ⍟⎕: map(log, input())
  • -/⍟⎕: foldr1(sub, map(log, input()))
  • *-/⍟⎕: exp(foldr1(sub, map(log, input())))
  • ⌊*-/⍟⎕: floor(exp(foldr1(sub, map(log, input()))))
\$\endgroup\$
4
\$\begingroup\$

Yabasic - 17 characters

input a,b:?a*b^-1
\$\endgroup\$
3
\$\begingroup\$

PHP - 82 characters (buggy)

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

This is a very simple solution, however - it doesn't handle fractions or different signs (would jump into an infinite loop). I won't go into detail in this one, it is fairly simple.

Input is in stdin, separated by a new line.

PHP - 141 characters (full)

$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 and output same as the previous one.

Yes, this is almost twice the size of the previous one, but it:

  • handles fractions correctly
  • handles signs correctly
  • won't ever go into an infinite loop, UNLESS the second parameter is 0 - but that is division by zero - invalid input

Re-format and explanation:

$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.
\$\endgroup\$
4
  • \$\begingroup\$ You used a division operator in this one, you might get away with a bit shift though. ;) \$\endgroup\$
    – Thomas O
    Commented Feb 4, 2011 at 18:12
  • \$\begingroup\$ @Thomas O yeah... I noticed it now... I was actually thinking about a bit shift (when I changed it to /=2 instead of /=10) - but it was one more char... Guess I'll have to use it anyway... Btw that is not division at all :D. \$\endgroup\$ Commented Feb 4, 2011 at 18:52
  • \$\begingroup\$ The question says you need to use stdin, which PHP does have support for. \$\endgroup\$ Commented Feb 5, 2011 at 2:08
  • \$\begingroup\$ @Bass5098 Aaahhh... Oh well, gained 4 chars... Fixed. \$\endgroup\$ Commented Feb 5, 2011 at 17:07
3
\$\begingroup\$

Ruby 1.9, 28 characters

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

Rest of division, 21 characters

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

Sample:

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

For Ruby 1.8:

a = 756
b = 20
print ('a'*a+'b').split('a'*b).size-1  # => 37
print 'a'*a=~/(#{'a'*b})\1*$/          # => 16
\$\endgroup\$
2
  • \$\begingroup\$ NoMethodError: private method `split' called for 69938:Fixnum \$\endgroup\$
    – rkj
    Commented Aug 26, 2011 at 8:27
  • \$\begingroup\$ @rkj, Sorry, Ruby 1.9 only. To run on Ruby 1.8 you must do ('a'*a+'b').split('a'*b).size-1, 3 characters bigger. \$\endgroup\$
    – LBg
    Commented Aug 29, 2011 at 0:30
3
\$\begingroup\$

Python, 37

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

Constructs a string of length x ('0'*x) and uses extended slicing to pick every yth character, starting from the index y-1. Prints the length of the resulting string.

Like Gnibbler, this takes comma separated input. Removing it costs 9 chars:

i=input
x,y=i(),i()
print len(('0'*x)[y-1::y])
\$\endgroup\$
2
\$\begingroup\$

PHP, 55 characters

<?$a=explode(" ",fgets(STDIN));echo$a[0]*pow($a[1],-1);

Output (740/2): http://codepad.viper-7.com/ucTlcq

\$\endgroup\$
1
  • \$\begingroup\$ 44 chars: <?$a=fgetcsv(STDIN);echo$a[0]*pow($a[1],-1); Just use a comma instead of a space to separate numbers. \$\endgroup\$ Commented May 10, 2013 at 17:28
2
\$\begingroup\$

Scala 77

def d(a:Int,b:Int,c:Int=0):Int=if(b<=a)d(a-b,b,c+1)else c
d(readInt,readInt)
\$\endgroup\$
2
\$\begingroup\$

Haskell, 96 characters

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

Input is on a single line.

The code just searches for the answer by taking the divisor d and multiplying it against all integers n >= 0. Let m be the dividend. The largest n such that n * d <= m is picked to be the answer. The code actually picks the least n such that n * d > m and subtracts 1 from it because I can take the first element from such a list. In the other case, I would have to take the last, but it's hard work to take the last element from an infinite list. Well, the list can be proven to be finite, but Haskell does not know better when performing the filter, so it continues to filter indefinitately.

\$\endgroup\$
2
\$\begingroup\$

Common Lisp, 42 charaacters

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

Accepts space or line-separated input

\$\endgroup\$
2
\$\begingroup\$

Python - 45 chars

Takes comma separated input, eg 740,2

x,y=input()
print-1+len((x*'.').split('.'*y))
\$\endgroup\$
2
\$\begingroup\$

Bash, 72 64 characters

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

Output an infinite number of newlines, take the first x, put them all into a file called f, then get the size of f in blocks the size of y. Took manatwork's advice to shave off eight characters.

\$\endgroup\$
1
  • \$\begingroup\$ As “Take two inputs on stdin separated by new lines or spaces (your choice)”, better choose the later, the space separated values. In which case you can write read x y. With a few more spaces removed can be reduced to 64 characters: pastebin.com/Y3SfSXWk \$\endgroup\$
    – manatwork
    Commented Sep 20, 2013 at 8:20
2
\$\begingroup\$

Retina 0.7.3, 33 bytes

Takes space-separated input with the divisor first. Dividing by zero is undefined.

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

Try it online

\$\endgroup\$
2
  • \$\begingroup\$ How do you count this as 25 bytes? If you expect unary I/O you should say so (and I think then it's 24 bytes). Not sure why you treat the 0 case separately though: retina.tryitonline.net/… \$\endgroup\$ Commented Dec 7, 2016 at 22:24
  • \$\begingroup\$ It was mis-copied \$\endgroup\$
    – mbomb007
    Commented Dec 7, 2016 at 23:05
2
\$\begingroup\$

Pascal, 54 B

In the era Pascal was conceived, slide rules were a standard tool among engineers. This was probably motivation to include ln (natural logarithm) and exp (exponenantion) to be part of the language. For a non‑zero dividend and non‑zero divisor we can use the relationship $$ \frac{\text{dividend}}{\text{divisor}} = e^{\ln\left(\text{dividend}\right)\,-\,\ln\left(\text{divisor}\right)} $$

function q(e,d:real):real;begin q:=exp(ln(e)−ln(d))end

−8 B if you want to deal with negative dividends and divisors, too, you need a processor supporting the built‐in real exponentiation operator ** of Extended Pascal:

function q(e,d:real):real;begin q:=e*d**−1 end

+7 B if you consider x−1 a division operation:

function q(e,d:complex):real;begin q:=re(exp(ln(e)−ln(d)))end

Note that the built‐in data type real only provides a “reasonable approximation.” What is “reasonable” depends on the implementation. You may get the result that $$ 740\:/\:2 = 369.\overline{9} $$ This, however, is outside of the domain of the programming language. Apply the built‐in function round if it can be concluded that the quotient is integral.

\$\endgroup\$
1
  • \$\begingroup\$ Using the same approach, I am also getting also non integers in Tcl: tio.run/##K0nO@f@/oCg/… \$\endgroup\$
    – sergiol
    Commented Dec 2 at 11:57
2
\$\begingroup\$

Tcl, 45 bytes

proc D p\ f {while {[incr i]*$f<$p} {}
set i}

Try it online!

\$\endgroup\$
0
1
\$\begingroup\$

Python, 46 bytes

Nobody had posted the boring subtraction solution, so I could not resist doing it.

a,b=input()
i=0
while a>=b:a-=b;i+=1
print i
\$\endgroup\$
1
\$\begingroup\$

Python 54

Takes comma delimited input.

  1. Makes a string of dots of length x
  2. Replaces segments of dots of length y with a single comma
  3. Counts commas.

Words because markdown dies with a list followed by code?:

x,y=input()
print("."*x).replace("."*y,',').count(',')
\$\endgroup\$
1
\$\begingroup\$

Python, 94 characters

A recursive binary search:

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)
\$\endgroup\$
1
\$\begingroup\$

Python, 40 characters

print(float(input())*float(input())**-1)
\$\endgroup\$
1
\$\begingroup\$

C, 43 bytes

Implements a/b in a linear search. Handles only positive arguments.

i;f(a,b){i=0;while(1)if(++i*b>a)return--i;}

Ungolfed:

i;
f(a, b){
  i = 0;              
  while (1)           
    if (++i * b > a)  
      return --i;     
}
\$\endgroup\$
1
\$\begingroup\$

Javascript (ES6): 14 Bytes

(a,b)=>a*b**-1

Try It Online!

Explanation:

(a,b)=>  // non recursive function with 2 params
a*       // a * 1/b == a/b
   b**-1 // b^-1 = 1/(b^1) = 1/b

I do believe this is the best and fastest method of division, especially if you are running things on the GPU.

\$\endgroup\$
0
\$\begingroup\$

Smalltalk, Squeak 4.x flavour

define this binary message in 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)

Once golfed, this quotient is still long (88 chars):

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

But it's reasonnably fast:

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

-> 127 ms on my modest mac mini (8 MOp/s)

Compared to regular division:

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

-> 31 ms, it's just 4 times slower

I don't count the chars to read stdin or write stdout, Squeak was not designed for scripting.

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

Of course, more stupid repeated subtraction

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

or plain stupid enumeration

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

could work too, but are not really interesting

\$\endgroup\$
0
\$\begingroup\$

DC: 26 characters

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

I do admit that it is not the fastest solution around.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.