Divisão de números não tão pequenos


15

Escreva um programa ou função que leva em inteiros positivos a, be c, e impressões ou retorna a/bpara ccasas decimais, utilizando as operações + - * /% [somar, subtrair, multiplicar, dividir, modular] sobre os inteiros positivos: você pode usar tudo o que seu idioma permite, mas não em números de ponto flutuante. O intervalo de a, b, c seria o intervalo permitido para números inteiros não assinados no seu idioma. O resultado do número será truncado para o último dígito a ser impresso (portanto, não round).

Isso significa que, se o seu idioma não tiver um tipo inteiro (apenas flutuante), você poderá participar usando esses números flutuantes apenas como números inteiros positivos. A pista deste exercício seria escrever a função que encontra os dígitos em uma divisão de ponto flutuante, usando apenas a operação + - * /% em números inteiros [não assinados].

Exemplos

  • print(1,2,1) imprimiria 0.5
  • print(1,2,2) imprimiria 0.50
  • print(13,7,27) imprimiria 1.857142857142857142857142857
  • print(2,3,1) imprimiria 0.6
  • print(4,5,7) imprimiria 0.8000000
  • print(4,5,1) imprimiria 0.8
  • print(9999,23,1) imprimiria 434.7
  • print(12345613,2321,89) seria impresso se o seu idioma não tiver assinatura de 32 bits 5319.09220163722533390779836277466609220163722533390779836277466609220163722533390779836277466

O código mais curto em bytes vence. Sinto muito se isso não parece claro ... Também não conheço idiomas, não lembro bem as palavras ... É melhor ter um link para Ideone.com ou algum outro lugar para tentar facilmente a resposta, especialmente para teste alguma entrada diferente da proposta.


1
Qual é o intervalo dos números inteiros a, b, c?
Ton Hospel

@ Ton Hospel, o intervalo de a, b, c seria o intervalo permitido para um número inteiro não assinado em seu idioma: por exemplo, se for um sinal de 32 bits, seria 0..0xFFFFFFFF, mas se c> = 0xFFFFFFF fosse tão grande, a saída seria ser um pouco lento ...
RosLuP

2
É uma função de arredondamento - ou, mais precisamente, precisa ser uma função de arredondamento para ser especificada corretamente. No momento, não está claro qual seria a resposta correta para, por exemplo (1,2,0). Veja meta.codegolf.stackexchange.com/a/5608/194
Peter Taylor

1
Desculpe por reabrir esta pergunta; Acho que está quase pronto para ser reaberto, exceto pelo problema apontado por Peter Taylor. Qual é a saída para (1,2,0)?
ETHproductions

2
Na verdade, (1,2,0)deve ser irrelevante, pois 0não é um número inteiro positivo. E eu prefiro que se c restos assim desde que eu prefiro não ter que pensar em acrescentar uma .ou não
Ton Hospel

Respostas:


5

05AB1E , 17 13 11 19 14 bytes

Entrada no formulário b, a, c.
Economizou 5 bytes graças ao Grimy .

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

Experimente online!


Eu apenas tentei-lo online com a entrada 13,7,27 e resposta não é correta
Mathieu J.

@shigazaru: retorna o mesmo resultado que os casos de teste. Você notou que a ordem das entradas é b,a,c?
Emigna

Eu tento o botão "Try online" onde há essa divisão: 12345613/2321 com 89 dígitos, mas o resultado não é algo tão 5.319,922 ... em vez de 5319,0922 ...
RosLuP

1
15:‰`I°*¹÷I°+¦'.sJ
Grimmy

2
14:‰`¹+I°*¹÷¦'.sJ
Grimmy

4

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

Exemplo de uso: (13#7)27-> "1.857142857142857142857142857".

23 bytes para lidar com o c==0caso e usar um zero à esquerda em vez de coisas do tipo .5.

Como funciona: multiplique acom 10^c, divida por b, transforme-se em uma sequência, divida onde .deve ser inserido, junte as duas partes com um .intermediário e corrija as arestas.


4

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}

O que é bastante irritante é que poderia ser reduzido para apenas {($^a.FatRat/$^b).base(10,$^c)}se fosse permitido arredondar para o valor mais próximo.

Explicação:

# 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
}

Não estou familiarizado com perl6, mas não é (...).FatRat / 10**$xuma divisão de um Rational? Você só pode dividir números inteiros.
nimi

@nimi a Rational é uma classe com duas entradas .
Brad Gilbert b2gills

Os operadores matemáticos são permitidos apenas para tipos inteiros e não para outros tipos numéricos. Citação: "A pista deste exercício ... para escrever a função ... usando apenas a operação + - * /% em números inteiros [não assinados]".
nimi

@nimi Então, se eu escrevesse uma reimplementação do Rational, e não adicionasse um does Realou does Numericseria permitido? E se eu aumentar (patch de macaco) a classe existente para remover essas funções, isso seria permitido?
Brad Gilbert b2gills

Não sei. Eu li as especificações como dito antes: +-*/%somente com tipos inteiros simples. "inteiro simples" em termos de funcionalidade (antes de tudo: divisão inteira) e não de representação interna. Você acha que é permitido usar uma biblioteca de ponto flutuante de software, que (apesar do nome) também usa apenas números inteiros para representação interna?
nimi

3

Perl, 55 bytes

Inclui +3 para -p

Dê aeb em uma linha em STDIN, c na próxima

division.pl
1 26
38
^D

division.pl:

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

o $_/$&é um pouco discutível. Na verdade, eu quero uma divisão inteira lá, mas o perl não tem isso sem carregar módulos especiais. Portanto, é temporariamente um não inteiro que eu imediatamente trunco ​​(usando |0) para terminar com o inteiro que uma divisão inteira daria. Ele pode ser reescrito ($_-$_%$&)/$&para não ter um valor não inteiro temporariamente (ainda assim seria internamente um valor flutuante)


Você poderia usar $-para torná-lo apenas int? (Eu acho que existem limites rígidos sobre o mix / max dele, e eu tenho certeza que você já tenha considerado, mas que ele vale a pena conferir!)
Dom Hastings

@DomHastings Ainda seria um truncado depois de fazer uma divisão de ponto flutuante. Perl simplesmente não tem divisão inteira semuse integer
Ton Hospel

Ah, então é só disfarçar $-, é bom saber. Obrigado!
Dom Hastings

3

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)executa a divisão de flutuação, mas lança imediatamente para um número inteiro. Informe-me se isso não for permitido.


3

PHP, 187 bytes

trabalha com strings para o numerador, que podem ser valores int maiores que 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);

Não tenho outra chance, então 13/7 é reduzido para 1,8571428571429 e chego a isso, não o caso de teste com 27 casas decimais

Dessa forma, 36 bytes não são permitidos

<?=bcdiv(($z=$argv)[1],$z[2],$z[3]);

divisão de flutuador não é permitida conforme OP
Maltysen

Maltysen @ Desculpe-me por fazer uma reversão. Eu estava com tanto medo de encontrar uma solução mais curta que não a reconheça contra a especificação.
Jörg Hülsermann 12/10

2

Pitão - 21 19 18 16 14 bytes

Estará olhando sobre o formato de entrada, que pode economizar bastante.

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

Conjunto de Teste . (PS 27 não termina online, então eu fiz 10 em seu lugar).


@Emigna Também não tem que uma vez 0não é um inteiro positivo (embora a op mantém exemplos acrescentando com c=0)
Ton Hospel

@TonHospel: Ah, de fato. Eu estava olhando os exemplos. I pode encurtar a minha resposta então :)
Emigna

Não funciona com números que tenham um 0 à esquerda após o ponto decimal, por exemplo, de 21/2 a 10 decimais.
Emigna

2/21 com 10 dígitos imprime apenas 9 dígitos após o ponto
RosLuP 1/16/16

2/21 with 10 digits as Emigna says instead of 0.09... print 0.9...
RosLuP

2

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


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

@ETHproductions - De fato. Obrigado!
Arnauld

2

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 & código de teste:

Experimente aqui.

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));
  }
}

Resultado:

0.5
0.50
1.857142857142857142857142857
0.6
0.8000000
0
434
5319.09220163722533390779836277466609220163722533390779836277466609220163722533390779836277466

Eu não acho que isso seja válido, porque é essencialmente uma divisão de ponto flutuante, mesmo que seja chamada dividee não /.
corvus_192

@ corvus_192 Outra resposta Java excluída que postou mais tarde do que eu tinha o raciocínio, que copio e colo aqui (o crédito para esta explicação vai para @SocraticPhoenix ): " Como funciona: os Java BigDecimals são implementados como BigIntegers, com uma escala. Esse é tecnicamente o ponto flutuante, no entanto, os objetos BigInteger e BigDecimal usam apenas o inttipo para armazenar valor numérico (isso não é legal? BigInteger é um int[]dígito. Por exemplo, {1,2,5} na base 10 é 125. I não tenho certeza em que base estão os dígitos do BigInteger, mas acho que são mais de
dez

2

Ruby, 67 bytes

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

se eu fizer uma função para executar os casos de teste acima

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 

Bem-vindo ao código de golfe! Para a maioria dos idiomas, quando você define uma função, precisa defini-la completamente e não pode confiar em assumir que existem variáveis ​​predefinidas como essa. No Ruby, a maneira mais curta de definir um lambda é ->a,b,c{...}onde você substitui as elipses pelo seu código. (A atribuição real da variável é desnecessário por consenso.)
Valor Ink

obrigado, tive a impressão errada de que outros haviam deixado de fora essa parte ... mas você está certo. Acabei de adicionar.
Mathieu J.

2

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

Uso:

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

Resultado:

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

Outro método (resposta não válida aqui):

(real->decimal-string(/ a b)c)

Receio que isso seja inválido, porque real->decimal-stringespera um realvalor como seu primeiro argumento, assim /como a divisão de ponto flutuante, o que não é permitido nesta tarefa. Também: real->decimal-stringarredonda ( (f 1 6 7)-> 0.1666667) em vez de truncar.
nimi

Obrigado pelas observações. Corrigirei o código em breve.
rnso

1

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

Para executar: defina a, b, c primeiro.


1

Ferrugem, 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()}}

código de teste:

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
}

1

PHP, 89 bytes

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

intdiv () é introduzido no php 7, portanto é necessário. O php 7.1 me permitiria mudar a lista () para [] e, assim, economizaria 4 bytes.

use como:

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

substituir $o.=intdiv($a=10*($a%$b),$b);por $o.=($a=10*($a%$b))/$b^0;economizará 4 bytes.
Jörg Hülsermann 13/10/16

Inicialmente, eu aceitaria esse conselho (editei a resposta e tudo mais), mas, pensando bem, é uma divisão de ponto flutuante e, em seguida, faça uma conversão para int, para um aumento de <10% no comprimento, prefiro ficar completamente dentro das especificações de a questão.
user59178

1

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),".");};

Programa completo com casos de teste:

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
        }
    }
}

Divisão inteira é implementada. Podem ser usados ​​números de qualquer tamanho, devido ao BigIntegertipo de dados (a importação System.Numericsé necessária). O parâmetro de contagem de dígitos cé restrito a 2 ^ 31-1, no entanto, deve fornecer dígitos mais que suficientes.


1

Groovy ( 78 77 42 bytes)

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

Explicação

Eval.me(a+'.0g');- Converta da entrada inteira para a entrada BigDecimal. Na notação BigDecimal groovy, há uma notação dupla com um G ou g anexado. Eu também poderia ter usado o construtor, new BigDecimal(it)mas isso salvou um byte.
.divide(b, n, 1)- Divida por b com precisão n, modo de arredondamento pela metade.

Experimente aqui: https://groovyconsole.appspot.com/script/5177545091710976


Mas o BigDecimal suporta operações de ponto flutuante que, a menos que eu esteja enganado, acredito que foram indicadas como proibidas para este exercício.
Mathieu J.

1

Lote, 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%

1

Mathematica, 50 bytes

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

Função Sem nome dos três argumentos (que são encomendadas c, a, bpara salvar a algum lugar byte), que retorna um string. Ele multiplica a/bpor 10^c, leva a maior função inteiro, em seguida, convertidos para uma string e insere um ponto decimal para o local apropriado. Pena que os nomes das funções não sejam mais curtos.


1

Python 3, 62 bytes

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

Experimente aqui

* Nota : repl.it usa uma versão mais antiga do Python 3 , que requer que todos os índices de campo sejam especificados, o que significa que o "{:.{1}f}"fará "{0:.{1}f}", com 63 bytes em repl.it

Como usar

Digite todos os três valores com espaços intermediários. isto é, uma entrada de1 2 1 daria um resultado de0.5

Explicação

input().split(): Obtém a entrada do usuário e a divide em uma lista com um separador de (espaço)

a,b,c = map(int,XX): Mapeia as variáveis ​​para os valores especificados pelo usuário com um tipo int

"{:.{1}f}".format(a/b,c): Formata uma sequência para exibir o resultado da divisão e substitui {1}porc para definir a casa decimal da sequência exibida

print(XX): imprime a sequência fornecida


1

Python 3 , 58 bytes

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

Experimente online!

Isso é preciso para o número especificado de casas decimais, desde que a * 10 ** c não seja muito grande.

Eu tentei o Python 2 para encurtar o str(...)para, `...`mas o Python 2 insere um Lno final, se for muito grande, portanto, verificar isso levaria muito mais bytes do que vale a pena.


1

Stax , 13 bytes

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

Execute e depure

Os argumentos são aceitos em c a bordem.


O problema seria o caso "print (9999,23,1)"; o resultado impresso no post é "434,7", enquanto o resultado parece "4,7", o mesmo que o último: 5319.092201etc em vez de 9.092201etc
RosLuP

Eu não concordo ... Eu segui esta manhã o seu link e o resultado para o caso "print (9999,23,1)" em seu pedido função foi de 4,7 e não 434,7
RosLuP

@RosLuP: mudei a abordagem. O resultado agora está corretamente `434.7`. Também reduzi o tamanho em um byte no processo.
recursivo

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.