17
\$\begingroup\$

Write a program or function that takes in positive integers a, b and c, and prints or returns a/b to c decimal places, using the operations +-*/% [add, subtract, multiply, divide, modulate] on the positive integers: you can use all that your language allows, but not on floating point numbers. The range of a,b,c would be the range allowed for unsigned integers in your language. The number result will be truncated to the last digit to print (so no round).

This means that if your language does not have an integer type (only float), you can participate by using these float numbers as positive integers only. The clue of this exercise it would be to write the function that find the digits in a float point division, using only the operation +-*/% on [unsigned] integers.

Examples

  • print(1,2,1) would print 0.5
  • print(1,2,2) would print 0.50
  • print(13,7,27) would print 1.857142857142857142857142857
  • print(2,3,1) would print 0.6
  • print(4,5,7) would print 0.8000000
  • print(4,5,1) would print 0.8
  • print(9999,23,1) would print 434.7
  • print(12345613,2321,89) would print if your Language has 32 bit unsigned 5319.09220163722533390779836277466609220163722533390779836277466609220163722533390779836277466

The shortest code in bytes wins. I'm sorry if this appear not clear... I don't know languages too, not remember words well... It is better to have one link to Ideone.com or some other place for easily try the answer especially for to test some input different from proposed.

\$\endgroup\$
18
  • 1
    \$\begingroup\$ What is the range of the integers a,b,c ? \$\endgroup\$
    – Ton Hospel
    Oct 12, 2016 at 20:42
  • \$\begingroup\$ @Ton Hospel the range of a,b,c would be the range allow for unsigned integer in your Language: for example if it is a 32 bit unsigned it would be 0..0xFFFFFFFF but if c>=0xFFFFFFF so big the output would be a little slow... \$\endgroup\$
    – user58988
    Oct 12, 2016 at 20:45
  • 2
    \$\begingroup\$ It is a rounding function - or, more precisely, it needs to be a rounding function to be properly specified. At present, it's unclear what the correct answer would be for e.g. (1,2,0). See meta.codegolf.stackexchange.com/a/5608/194 \$\endgroup\$ Oct 12, 2016 at 20:52
  • 1
    \$\begingroup\$ Sorry for reopening this question; I think it's almost ready to be reopened, except for the problem Peter Taylor pointed out. What is the output fo (1,2,0)? \$\endgroup\$ Oct 12, 2016 at 20:59
  • 2
    \$\begingroup\$ Actually (1,2,0) should be irrelevant since 0 is not a positive integer. And I'd prefer it if c remains like that since I'd prefer not having to think about appending a . or not \$\endgroup\$
    – Ton Hospel
    Oct 12, 2016 at 21:30

22 Answers 22

5
\$\begingroup\$

05AB1E, 17 13 11 19 14 bytes

Input in the form b, a, c.
Saved 5 bytes thanks to Grimy.

‰`¹+I°*¹÷¦'.sJ

Try it online!

\$\endgroup\$
9
  • \$\begingroup\$ I just tried it online with input 13,7,27 and answer is not correct \$\endgroup\$
    – Mathieu J.
    Oct 13, 2016 at 12:39
  • \$\begingroup\$ @shigazaru: It returns the same result as the test-cases. Did you notice the order of inputs is b,a,c? \$\endgroup\$
    – Emigna
    Oct 13, 2016 at 12:59
  • \$\begingroup\$ I try the button "Try online" where there is this division:12345613/2321 with 89 digits, but the result there is something as 5319.922... instead of 5319.0922... \$\endgroup\$
    – user58988
    Nov 1, 2016 at 20:18
  • 1
    \$\begingroup\$ 15: ‰`I°*¹÷I°+¦'.sJ \$\endgroup\$
    – Grimmy
    May 15, 2019 at 14:55
  • 2
    \$\begingroup\$ 14: ‰`¹+I°*¹÷¦'.sJ \$\endgroup\$
    – Grimmy
    May 15, 2019 at 15:26
5
\$\begingroup\$

Haskell, 87 bytes

(a#b)c|s<-show$div(a*10^c)b,l<-length s-c,(h,t)<-splitAt l s=['0'|l<1]++h++['.'|c>0]++t

Usage example: (13#7)27 -> "1.857142857142857142857142857".

23 bytes to handle the c==0 case and using a leading zero instead of things like .5.

How it works: multiply a with 10^c, divide by b, turn into a string, split where the . must be inserted, join both parts with a . in-between and fix the edge cases.

\$\endgroup\$
4
\$\begingroup\$

Perl 6,  58 57 55  48 bytes

{(($^a.FatRat/$^b*10**$^c).Int.FatRat/10**$c).base(10,$c)}
{(Int($^a.FatRat/$^b*10**$^c).FatRat/10**$c).base(10,$c)}
{base Int($^a.FatRat/$^b*10**$^c).FatRat/10**$c: 10,$c}
{base ($^a*10**$^c div$^b).FatRat/10**$c: 10,$c}

What is fairly annoying is that it could be shortened to just {($^a.FatRat/$^b).base(10,$^c)} if it was allowed to round to the nearest value.

Explanation:

# bare block lambda with 3 placeholder parameters 「$^a」, 「$^b」 and 「$^c」
{
  (
    (

      # create an Int containing all of the digits we care about
      $^a * 10 ** $^c div $^b

    ).FatRat / 10**$c  # turn it into a Rational

  ).base( 10, $c )     # force it to display 「$c」 digits after the decimal point
}
\$\endgroup\$
8
  • \$\begingroup\$ I'm not familiar with perl6, but isn't (...).FatRat / 10**$x a division of a Rational? You're only allowed to divide integers. \$\endgroup\$
    – nimi
    Oct 13, 2016 at 5:34
  • \$\begingroup\$ @nimi a Rational is a class with two Ints. \$\endgroup\$ Oct 13, 2016 at 15:02
  • \$\begingroup\$ The math operators are only allowed for integer types and not for other numerical types. Quote: "The clue of this exercise ... to write the function ... using only the operation +-*/% on [unsigned] integers." \$\endgroup\$
    – nimi
    Oct 13, 2016 at 15:55
  • \$\begingroup\$ @nimi So if I wrote a reimplementation of Rational, and didn't add a does Real or does Numeric it would be allowed? What if I augment (monkey patch) the existing class to remove those roles, would that be allowed? \$\endgroup\$ Oct 13, 2016 at 16:14
  • \$\begingroup\$ Don't know. I read the spec as said before: +-*/% only with plain integer types. "plain integer" in terms of functionality (first of all: integer division) not of internal representation. Do you think it's allowed to use a software floating point library, which (despite the name) also uses only integers for internal representation? \$\endgroup\$
    – nimi
    Oct 13, 2016 at 16:34
3
\$\begingroup\$

Perl, 55 bytes

Includes +3 for -p

Give a and b on one line on STDIN, c on the next

division.pl
1 26
38
^D

division.pl:

#!/usr/bin/perl -p
eval'$\.=($_/$&|0)."."x!$\;$_=$_%$&.0;'x(/ .*/+<>)}{

the $_/$& is a bit arguable. I Actually want an integer division there but perl doesn't have that without loading special modules. So it's temporarily a non-integer which I then immediately truncate (using |0) so I end up with the integer an integer division would give. It could be rewritten as ($_-$_%$&)/$& in order to not even temporarily have a non-integer value (it would internally still be a float though)

\$\endgroup\$
3
  • \$\begingroup\$ Could you use $- to make it int only? (I think there are strict limits on the mix/max of it, and I'm sure you'd have already considered it, but though it worth checking!) \$\endgroup\$ Oct 13, 2016 at 8:16
  • \$\begingroup\$ @DomHastings It would still be a truncate after doing a floating point division. Perl simply doesn't have integer division without use integer \$\endgroup\$
    – Ton Hospel
    Oct 13, 2016 at 8:37
  • \$\begingroup\$ Ah, so it's just masked with $-, good to know. Thanks! \$\endgroup\$ Oct 13, 2016 at 9:04
3
\$\begingroup\$

JavaScript (ES6), 55 50 bytes

f=(a,b,c,d=".")=>~c?(a/b|0)+d+f(a%b*10,b,c-1,""):d

(a/b|0) performs float division but immediately casts to an integer. Please let me know if this is not allowed.

\$\endgroup\$
3
\$\begingroup\$

PHP, 187 Bytes

works with strings for the numerator which can be int values greater then PHP_INT_MAX

list(,$n,$d,$c)=$argv;$a=str_split($n);while($a){$n.=array_shift($a);if($n>=$d||$r)$n-=$d*$r[]=$n/$d^0;}if(!$r)$r[]=0;if($c)$r[]=".";while($c--){$n*=10;$n-=$d*$r[]=$n/$d^0;}echo join($r);

I have no other chance then 13/7 is shorten to 1.8571428571429 and I reach so not the test case with 27 decimal places

This way 36 Bytes is not allowed

<?=bcdiv(($z=$argv)[1],$z[2],$z[3]);
\$\endgroup\$
2
  • \$\begingroup\$ float division is not allowed as per OP \$\endgroup\$
    – Maltysen
    Oct 12, 2016 at 22:27
  • \$\begingroup\$ @Maltysen Sorry I make a rollback.I was so afraid to find a shorter solution that I not recognize that it against the specifation. \$\endgroup\$ Oct 12, 2016 at 22:36
2
\$\begingroup\$

Pyth - 21 19 18 16 14 bytes

Will be looking over the input format, that can prolly save a bunch.

j\.c`/*E^TQE]_

Test Suite. (P.S. the 27 one doesn't finish online, so I did 10 instead).

\$\endgroup\$
5
  • \$\begingroup\$ @Emigna Nor does it have to since 0 is not a positive integer (even though the op keeps adding examples with c=0) \$\endgroup\$
    – Ton Hospel
    Oct 13, 2016 at 9:40
  • \$\begingroup\$ @TonHospel: Ah, indeed. I was looking at the examples. I can shorten my answer then :) \$\endgroup\$
    – Emigna
    Oct 13, 2016 at 9:43
  • \$\begingroup\$ Doesn't work with numbers that has a leading 0 after the decimal point, for example 2/21 to 10 decimals. \$\endgroup\$
    – Emigna
    Nov 1, 2016 at 21:23
  • \$\begingroup\$ 2/21 with 10 digits print only 9 digit after the point \$\endgroup\$
    – user58988
    Nov 1, 2016 at 23:25
  • \$\begingroup\$ 2/21 with 10 digits as Emigna says instead of 0.09... print 0.9... \$\endgroup\$
    – user58988
    Nov 1, 2016 at 23:39
2
\$\begingroup\$

JavaScript (ES6),  64  62 59 bytes

Saved 2 bytes thanks to ETHproductions.

The included division always results in an integer.

f=(a,b,n,s)=>~n?f((q=(a-a%b)/b,a%b*10),b,n-1,s?s+q:q+'.'):s

console.log(f(13,7,27))

\$\endgroup\$
2
  • \$\begingroup\$ Would skipping m altogether still work? f=(a,b,n,s)=>n+1?f((q=(a-a%b)/b,a%b*10),b,n-1,s?s+q:q+'.'):s is 60 bytes. \$\endgroup\$ Oct 13, 2016 at 0:51
  • \$\begingroup\$ @ETHproductions - Indeed. Thanks! \$\endgroup\$
    – Arnauld
    Oct 13, 2016 at 7:22
2
\$\begingroup\$

Java 7, 105 bytes

import java.math.*;String c(int...a){return new BigDecimal(a[0]).divide(new BigDecimal(a[1]),a[2],3)+"";}

Ungolfed & test code:

Try it here.

import java.math.*;
class M{
  static String c(int... a){
    return new BigDecimal(a[0]).divide(new BigDecimal(a[1]), a[2], 3)+"";
  }

  public static void main(String[] a){
    System.out.println(c(1, 2, 1));
    System.out.println(c(1, 2, 2));
    System.out.println(c(13, 7, 27));
    System.out.println(c(2, 3, 1));
    System.out.println(c(4, 5, 7));
    System.out.println(c(4, 5, 0));
    System.out.println(c(9999, 23, 0));
    System.out.println(c(12345613, 2321, 89));
  }
}

Output:

0.5
0.50
1.857142857142857142857142857
0.6
0.8000000
0
434
5319.09220163722533390779836277466609220163722533390779836277466609220163722533390779836277466
\$\endgroup\$
2
  • \$\begingroup\$ I don't think this is valid, because it's essentially floating-point division, even though it's called divide and not /. \$\endgroup\$
    – corvus_192
    Oct 13, 2016 at 19:14
  • \$\begingroup\$ @corvus_192 Another deleted Java answer that posted later than me had the reasoning, which I'll copy-paste here (Credit for this explanation goes to @SocraticPhoenix): "How It Works: Java BigDecimals are implemented as BigIntegers, with a scale. This is technically floating point, however the BigInteger and BigDecimal objects use only the int type to store numerical value. (Isn't that cool? BigInteger is an int[] of digits. Like, {1,2,5} in base 10 is 125. I'm not sure what base the digits of BigInteger are actually in, but I would guess it's more than 10." \$\endgroup\$ Oct 14, 2016 at 8:56
2
\$\begingroup\$

Ruby, 67 bytes

->(a,b,c){('0'+(a*10**c/b).to_s).gsub(/^0*(.+)(.{#{c}})$/,'\1.\2')}

if I make it a function to execute the test cases above

def print(a,b,c); ('0'+(a*10**c/b).to_s).gsub(/^0*(.+)(.{#{c}})$/, '\1.\2'); end
 => :print 
print(1,2,1)   # would print 0.5
 => "0.5" 
print(1,2,2)   # would print 0.50
 => "0.50" 
print(13,7,27) # would print 1.857142857142857142857142857
 => "1.857142857142857142857142857" 
print(2,3,1)   # would print 0.6
 => "0.6" 
print(4,5,7)   # would print 0.8000000
 => "0.8000000" 
print(4,5,1)   # would print 0.8
 => "0.8" 
print(9999,23,1) # would print 434.7
 => "434.7" 
print(12345613,2321,89) # would print if your Language has 32 bit unsigned 5319.09220163722533390779836277466609220163722533390779836277466609220163722533390779836277466
 => "5319.09220163722533390779836277466609220163722533390779836277466609220163722533390779836277466" 
"('0'+(a*10**c/b).to_s).gsub(/^0*(.+)(.{#{c}})$/, '\1.\2')".length
 => 52 
\$\endgroup\$
2
  • \$\begingroup\$ Welcome to code golf! For most languages, when you define a function, you have to define it all the way, and you can't rely on assuming there are predefined variables like that. In Ruby, the shortest way to define a lambda is with ->a,b,c{...} where you replace the ellipses with your code. (The actual assigning of the variable is unneeded by consensus.) \$\endgroup\$
    – Value Ink
    Oct 13, 2016 at 19:21
  • \$\begingroup\$ thanks, I was under the wrong impression that others had left out that part... but you're right. I just added it. \$\endgroup\$
    – Mathieu J.
    Oct 21, 2016 at 3:22
2
\$\begingroup\$

Racket 203 bytes

(let*((s(~r(/ a b)#:precision c))(sl(string-split s "."))(s2(list-ref sl 1))(n(string-length s2)))
(if(< n c)(begin(for((i(- c n)))(set! s2(string-append s2 "0")))(string-append(list-ref sl 0)"."s2))s))

Ungolfed:

(define (f a b c)
  (let* ((s (~r(/ a b)#:precision c))
         (sl (string-split s "."))
         (s2 (list-ref sl 1))
         (n (string-length s2)))
    (if (< n c)
        (begin 
          (for ((i (- c n)))
            (set! s2 (string-append s2 "0")))
          (string-append (list-ref sl 0) "." s2))
        s )))

Usage:

(f 7 5 3)
(f 1 2 1) 
(f 1 2 2) 
(f 13 7 27)

Output:

"1.400"
"0.5"
"0.50"
"1.857142857142857142857142857"

Other method (not valid answer here):

(real->decimal-string(/ a b)c)
\$\endgroup\$
2
  • \$\begingroup\$ I'm afraid this is invalid, because real->decimal-string expects a real value as its first argument, so / is floating point division, which is not allowed in this task. Also: real->decimal-string rounds ((f 1 6 7) -> 0.1666667) instead of truncating. \$\endgroup\$
    – nimi
    Oct 13, 2016 at 6:33
  • \$\begingroup\$ Thanks for the observations. I will correct the code soon. \$\endgroup\$
    – rnso
    Oct 13, 2016 at 11:41
1
\$\begingroup\$

q, 196 bytes

w:{((x 0)div 10;1+x 1)}/[{0<x 0};(a;0)]1;{s:x 0;m:x 2;r:(10*x 1)+$[m<0;{x*10}/[-1*m;a];{x div 10}/[m;a]]mod 10;d:1#.Q.s r div b;($[m=-1;s,".",d;$[s~,:'["0"];d;s,d]];r mod b;m-1)}/[c+w;("";0;w-1)]0

To run: set a, b, c first.

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

Rust, 114 bytes

fn print(mut a:u32,b:u32,c:u32){let mut p=||{print!("{}",a/b);a=a%b*10};p();if c>0{print!(".")}for _ in 0..c{p()}}

test code:

fn main() {
    print(1, 2, 1);    println!(""); // should print 0.5
    print(1, 2, 2);    println!(""); // should print 0.50
    print(13, 7, 27);  println!(""); // should print 1.857142857142857142857142857
    print(2, 3, 1);    println!(""); // should print 0.6
    print(4, 5, 7);    println!(""); // should print 0.8000000
    print(4, 5, 0);    println!(""); // should print 0
    print(9999, 23, 0);println!(""); // should print 434
    print(12345613,2321,89); println!("\n");  // 5319.09220163722533390779836277466609220163722533390779836277466609220163722533390779836277466
}
\$\endgroup\$
1
\$\begingroup\$

PHP, 89 bytes

list(,$a,$b,$c)=$argv;for($o=intdiv($a,$b).'.';$c--;)$o.=intdiv($a=10*($a%$b),$b);echo$o;

intdiv() is introduced in php 7 so it requires that. php 7.1 would allow me to change the list() to [] and so would save 4 bytes.

use like:

php -r "list(,$a,$b,$c)=$argv;for($o=intdiv($a,$b).'.';$c--;)$o.=intdiv($a=10*($a%$b),$b);echo$o;" 1 2 1
\$\endgroup\$
2
  • \$\begingroup\$ replace $o.=intdiv($a=10*($a%$b),$b); with $o.=($a=10*($a%$b))/$b^0; will save 4 Bytes. \$\endgroup\$ Oct 13, 2016 at 14:56
  • \$\begingroup\$ Initially I was going to take that advice (I edited the answer and everything) but on second thought it IS floating point division and then a cast to int so for a <10% increase in length I'd rather stick completely within the specs of the question. \$\endgroup\$
    – user59178
    Oct 13, 2016 at 16:00
1
\$\begingroup\$

C#, 126 bytes

(a,b,c)=>{var v=a*BigInteger.Parse("1"+new string('0',c))/b+"";return v.PadLeft(c+1,'0').Insert(Math.Max(1,v.Length-c),".");};

Full program with test cases:

using System;
using System.Numerics;

namespace DivisionOfNotSoLittleNumbers
{
    class Program
    {
        static void Main(string[] args)
        {
            Func<BigInteger,BigInteger,int,string>f= (a,b,c)=>{var v=a*BigInteger.Parse("1"+new string('0',c))/b+"";return v.PadLeft(c+1,'0').Insert(Math.Max(1,v.Length-c),".");};
            
            //test cases:
            Console.WriteLine(f(1,2,1));    //0.5
            Console.WriteLine(f(1,2,2));    //0.50
            Console.WriteLine(f(13,7,27));  //1.857142857142857142857142857
            Console.WriteLine(f(2,3,1));    //0.6
            Console.WriteLine(f(4,5,7));    //0.8000000
            Console.WriteLine(f(4,5,1));    //0.8
            Console.WriteLine(f(9999,23,1));    //434.7
            Console.WriteLine(f(12345613,2321,89)); //5319.09220163722533390779836277466609220163722533390779836277466609220163722533390779836277466
            Console.WriteLine(f(2,3,1));    //0.6
            Console.WriteLine(f(4,5,2));    //0.80
        }
    }
}

Integer division is implemented. Numbers of any size can be used, due to the BigInteger data type (the import System.Numerics is required). The digit-count parameter c is restricted to 2^31-1, however it should provide more than enough digits.

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

Groovy (78 77 42 Bytes)

{a,b,n->Eval.me(a+'.0g').divide(b, n, 1)}​

Explanation

Eval.me(a+'.0g'); - Convert from integer input to BigDecimal input. In groovy BigDecimal notation is double notation with an appended G or g. I could've also used the constructor new BigDecimal(it) but this saved a byte.
.divide(b, n, 1) - Divide by b with n precision, rounding mode half-up.

Try it here: https://groovyconsole.appspot.com/script/5177545091710976

\$\endgroup\$
1
  • \$\begingroup\$ But BigDecimal supports floating point operation which, unless I am mistaken, I believe was indicated to be forbidden for this exercise. \$\endgroup\$
    – Mathieu J.
    Oct 21, 2016 at 3:08
1
\$\begingroup\$

Batch, 122 bytes

@set/as=%1/%2,r=%1%%%2
@set s=%s%.
@for /l %%a in (1,1,%3)do @set/ad=r*10/%2,r=r*10%%%2&call set s=%%s%%%%d%%
@echo %s%
\$\endgroup\$
1
\$\begingroup\$

Mathematica, 50 bytes

StringInsert[ToString@Floor[10^# #2/#3],".",-#-1]&

Unnamed function of three arguments (which are ordered c, a, b to save a byte somewhere), which returns a string. It multiplies a/b by 10^c, takes the greatest integer function, then converts to a string and inserts a decimal point at the appropriate spot. Too bad the function names aren't shorter.

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

Python 3, 62 Bytes

a,b,c=map(int,input().split());print("{:.{1}f}".format(a/b,c))

Try It Here

*Note: repl.it uses an older ver of Python 3, which requires all field indices to be specified, meaning "{:.{1}f}" will be "{0:.{1}f}" instead, making it 63 bytes in repl.it

How to use

Enter all three values with spaces in-between. i.e. An input of 1 2 1 would give a result of 0.5

Explanation

input().split(): Gets user input and splits it into a list with a separator of (space)

a,b,c = map(int,XX): Maps the variables into the values specified by the user with an int type

"{:.{1}f}".format(a/b,c): Formats a string to display the division result and substitutes {1} with c to set the decimal place of the displayed string

print(XX): prints the string supplied

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

Python 3, 58 bytes

lambda a,b,c:(lambda s:s[:-c]+"."+s[-c:])(str(a*10**c//b))

Try it online!

This is precise to the specified number of decimals as long as a * 10 ** c isn't too large.

I tried Python 2 to shorten the str(...) to `...` but Python 2 inserts an L at the end if it's too large so checking for that would take way more bytes than it's worth.

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

Stax, 13 bytes

ä·oαì█↕▬AS¥é▼

Run and debug it

Arguments are accepted in c a b order.

\$\endgroup\$
3
  • \$\begingroup\$ The problem would be the case "print(9999,23,1)" the result print in the post is "434.7" while your result seems "4.7" the same the case last: 5319.092201etc instead of 9.092201etc \$\endgroup\$
    – user58988
    May 16, 2019 at 8:51
  • \$\begingroup\$ I not agree... I followed this morning your link and the result for the case "print(9999,23,1)" in your function order was 4.7 and not 434.7 \$\endgroup\$
    – user58988
    May 16, 2019 at 15:48
  • \$\begingroup\$ @RosLuP: I changed the approach. The result is now correctly ` 434.7`. I also reduced the size by a byte in the process. \$\endgroup\$
    – recursive
    May 16, 2019 at 16:11
0
\$\begingroup\$

C, 67 bytes

h(a,b,i){int j=!i;for(;printf(j++?"%u":"%u.",a/b),i--;a=10*(a%b));}

Try it online!

Some previous version I think had a bug in read memory out of assigned to the program...Thanks to ceilingcat and for all...

\$\endgroup\$
3
  • \$\begingroup\$ @ceilingcat ok thank you \$\endgroup\$
    – user58988
    May 16, 2019 at 17:30
  • \$\begingroup\$ I like the last one 69 bytes \$\endgroup\$
    – user58988
    May 16, 2019 at 18:34
  • \$\begingroup\$ 62 bytes \$\endgroup\$
    – ceilingcat
    May 16, 2019 at 21:02

Your Answer

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