Tell me more ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

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.

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.

I'll be looking for innovative solutions which do not use repeated subtraction. The solution which is the shortest and takes the least time.

share|improve this question
is 740,2 also permitted for the input? ie comma separated? – gnibbler Feb 4 '11 at 10:44
"Results are rounded down for fractional results" - ok, so apparently the input can also result in a non-integer number... But what about the divisor being larger than the divided (say, 5 and 10) - is that permitted or not? – Aurel300 Feb 4 '11 at 12:13
@gnibber That would be fine, but make it clear in the program description. – Thomas O Feb 4 '11 at 12:23
@Aurel300 It is not required to have fractional output. 1/7 may produce 0.142857... or 0. – Thomas O Feb 4 '11 at 12:24
2  
is using exponentials and other math functions really allowed? they use division behind the scenes, because many solutions are doing ab⁻¹ – SHiNKiROU Feb 5 '11 at 7:12
show 3 more comments

21 Answers

up vote 16 down vote accepted

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
share|improve this answer
4  
This, my friend, is CLEVER – Aamir Feb 4 '11 at 11:25
Output for "740,2" is 369. Is this correct? – Eelvex Feb 17 '11 at 23:23
@Eelvex, should have been <=, fixed it and made it shorter :) – gnibbler Feb 17 '11 at 23:43

Perl, 15 characters

print<>*<>**-1
share|improve this answer
4  
I like the beauty of this one although **-1 probably counts as division. – user475 Feb 17 '11 at 23:47

JavaScript - 36 characters

p=prompt;alert(p()*Math.pow(p(),-1))
share|improve this answer
4  
Replacing alert with p will net you some extra characters. :) – Casey Chu Aug 9 '11 at 3:00

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!

share|improve this answer
1  
My favorite implementation here so far. Congrats for the cool code! – Thomas Eding Aug 12 '11 at 23:14
I tried to make it a little shorter. A=Array,P=prompt,P((''+A(+P())).split(','+A(+P())).length) – pimvdb Aug 30 '11 at 19:54

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
share|improve this answer

Python - 41 chars

Takes comma separated input, eg 740,2

x,y=input();z=x
while y*z>x:z-=1 
print z
share|improve this answer
1  
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. – Aamir Feb 4 '11 at 11:20

Mathematica: 34 chars

Solves symbolically the equation (x a == b)

Solve[x#[[1]]==#[[2]],x]&@Input[]
share|improve this answer

Yabasic - 17 characters

input a,b:?a*b^-1
share|improve this answer

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.
share|improve this answer
You used a division operator in this one, you might get away with a bit shift though. ;) – Thomas O Feb 4 '11 at 18:12
@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. – Aurel300 Feb 4 '11 at 18:52
The question says you need to use stdin, which PHP does have support for. – Kevin Brown Feb 5 '11 at 2:08
@Bass5098 Aaahhh... Oh well, gained 4 chars... Fixed. – Aurel300 Feb 5 '11 at 17:07

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
share|improve this answer
NoMethodError: private method `split' called for 69938:Fixnum – rkj Aug 26 '11 at 8:27
@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. – LBg Aug 29 '11 at 0:30

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.

share|improve this answer

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()))))
share|improve this answer

PHP, 55 characters

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

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

share|improve this answer
44 chars: <?$a=fgetcsv(STDIN);echo$a[0]*pow($a[1],-1); Just use a comma instead of a space to separate numbers. – jdstankosky May 10 at 17:28

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.

share|improve this answer

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)
share|improve this answer

Common Lisp, 42 charaacters

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

Accepts space or line-separated input

share|improve this answer

Python, 37

Step 1. Convert to unary.

Step 2. Unary division algorithm.

print('1'*input()).count('1'*input())
share|improve this answer

Python, 25 characters

print input()*input()**-1
share|improve this answer
this does floating point arithmetic, not integer as the problem asked for. – boothby May 12 at 2:59

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
share|improve this answer

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

share|improve this answer
#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);
}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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