Divisão de implementos

15

Implemente um algoritmo de divisão no seu idioma favorito que lida com a divisão inteira. Ele precisa apenas lidar com números positivos - mas pontos de bônus se ele também lidar com a divisão de sinais negativos e mistos. Os resultados são arredondados para resultados fracionários.

O programa não pode conter os /, \, divou semelhantes operadores. Deve ser uma rotina que não use os recursos de divisão nativos do idioma.

Você só precisa lidar com a divisão de até 32 bits. O uso de subtração repetida não é permitido.

Entrada

Tome duas entradas no stdin separadas por novas linhas ou espaços (sua escolha)

740 
2

Resultado

Nesse caso, a saída seria 370.

A solução que é o menor ganha.

Thomas O
fonte
740,2também é permitido para a entrada? ou seja, vírgula separada?
Gnibbler
"Os resultados são arredondados para resultados fracionários" - ok, portanto, aparentemente, a entrada também pode resultar em um número não inteiro ... Mas e quanto ao divisor ser maior que o dividido (por exemplo, 5 e 10) - isso é permitido ou não?
Aurel Bílý
@gnibber Isso seria bom, mas deixe claro na descrição do programa.
Thomas O
2
o uso de exponenciais e outras funções matemáticas é realmente permitido? eles usam divisão nos bastidores, porque muitas soluções estão fazendo ab⁻¹
Ming-Tang
2
este é mais curto de tempo, mas eu não vi vez que alguém o código
phuclv

Respostas:

27

Python - 73 caracteres

Toma entrada separada por vírgula, por exemplo 740,2

from math import*
x,y=input()
z=int(exp(log(x)-log(y)))
print(z*y+y<=x)+z
mordedor
fonte
5
Este, meu amigo, é CLEVER
Aamir
A saída para "740,2" é 369. Isso está correto?
Eelvex 17/02/11
@Eelvex, deveria ter sido <=, fixa-lo e tornou mais curto :)
gnibbler
14

JavaScript, 61

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

Isso torna uma string o comprimento do dividendo ,,,,,,(6) e se divide no divisor ,,,(3), resultando em uma matriz de comprimento 3 ['', '', '']:, cujo comprimento então eu subtraí um. Definitivamente não é o mais rápido, mas espero que seja interessante!

Casey Chu
fonte
2
Minha implementação favorita aqui até agora. Parabéns pelo código legal!
Thomas Eding
Eu tentei torná-lo um pouco mais curto. A=Array,P=prompt,P((''+A(+P())).split(','+A(+P())).length)
Pimvdb
10

JavaScript - 36 caracteres

p=prompt;alert(p()*Math.pow(p(),-1))
PleaseStand
fonte
5
Substituir alertpor pfornecerá alguns caracteres extras. :)
Casey Chu
9

Mathematica: 34 caracteres

Resolve simbolicamente a equação (xa == b)

Solve[x#[[1]]==#[[2]],x]&@Input[]
Dr. belisarius
fonte
2
23 chars,Solve[x#==#2]&@@Input[]
chyanog
8

Python - 72 caracteres

Toma entrada separada por vírgula, por exemplo, 740,2

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

Python, 37

Etapa 1. Converta para unário.

Etapa 2. Algoritmo de divisão unário.

print('1'*input()).count('1'*input())
boothby
fonte
7

Python - 41 chars

Takes comma separated input, eg 740,2

x,y=input();z=x
while y*z>x:z-=1 
print z
gnibbler
fonte
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
6

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.

JBernardo
fonte
4

Yabasic - 17 caracteres

input a,b:?a*b^-1
PleaseStand
fonte
3

PHP - 82 caracteres (buggy)

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

Esta é uma solução muito simples, no entanto - ela não lida com frações ou sinais diferentes (poderia entrar em um loop infinito). Não vou entrar em detalhes neste, é bastante simples.

A entrada está em stdin, separada por uma nova linha.

PHP - 141 caracteres (completo)

$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;

Entrada e saída iguais à anterior.

Sim, isso é quase o dobro do tamanho do anterior, mas:

  • lida com frações corretamente
  • lida com sinais corretamente
  • nunca entrará em um loop infinito, a menos que o segundo parâmetro seja 0 - mas isso é divisão por zero - entrada inválida

Re-formatar e explicação:

$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.
Aurel Bílý
fonte
Você usou um operador de divisão neste, mas pode se dar bem com uma pequena mudança. ;)
Thomas O
@ Thomas O sim ... eu notei isso agora ... Na verdade, eu estava pensando em mudar um pouco (quando mudei para / = 2 em vez de / = 10) - mas era mais um caractere ... Acho que eu ' terei que usá-lo de qualquer maneira ... Mas isso não é divisão: D.
Aurel Bílý
A pergunta diz que você precisa usar stdin, que o PHP tem suporte.
27611 Kevin Kevin Brown
@ Bass5098 Aaahhh ... Oh, bem, ganhou 4 caracteres ... Fixo.
Aurel Bílý
3

Ruby 1.9, 28 caracteres

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

Resto da divisão, 21 caracteres

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

Amostra:

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

Para Ruby 1.8:

a = 756
b = 20
print ('a'*a+'b').split('a'*b).size-1  # => 37
print 'a'*a=~/(#{'a'*b})\1*$/          # => 16
LBg
fonte
NoMethodError: private method `split' called for 69938:Fixnum
rkj
@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
3

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()))))
marinus
fonte
2

PHP, 55 characters

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

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

Kevin Brown
fonte
44 chars: <?$a=fgetcsv(STDIN);echo$a[0]*pow($a[1],-1); Just use a comma instead of a space to separate numbers.
jdstankosky
2

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)
user unknown
fonte
2

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.

Thomas Eding
fonte
2

Common Lisp, 42 charaacters

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

Accepts space or line-separated input

Strigoides
fonte
2

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.

Hovercouch
fonte
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
manatwork
1

Python - 45 chars

Takes comma separated input, eg 740,2

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

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)
memo
fonte
1

Python, 148

Other solutions may be short, but are they web scale?

Here's an elegant, constant-time solution that leverages the power of the CLOUD.

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

Did I mention it also uses Haskell?

Lambda Fairy
fonte
0

Python, 46 bytes

Ninguém postou a solução de subtração entediante, então não pude resistir a fazê-lo.

a, b = entrada ()
i = 0
enquanto a> = b: a- = b; i + = 1
imprimir i
cemper93
fonte
0

Smalltalk , sabor Squeak 4.x

defina esta mensagem binária em Inteiro:

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

Depois de jogar golfe, esse quociente ainda é longo (88 caracteres):

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

Mas é razoavelmente rápido:

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

-> 127 ms no meu modesto mac mini (8 MOp / s)

Comparado à divisão regular:

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

-> 31 ms, é apenas 4 vezes mais lento

Não conto os caracteres para ler stdin ou escrever stdout, o Squeak não foi projetado para scripts.

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

Claro, subtração repetida mais estúpida

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

ou enumeração estúpida

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

poderia funcionar também, mas não é realmente interessante

aka.nice
fonte
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);
}
jithin
fonte
0

DC: 26 caracteres

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

Admito que não é a solução mais rápida.

Para s
fonte
0

Python 54

Recebe entrada delimitada por vírgula.

  1. Cria uma sequência de pontos de comprimento x
  2. Substitui segmentos de pontos de comprimento y por uma única vírgula
  3. Conta vírgulas.

Palavras porque a remarcação morre com uma lista seguida por código ?:

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

fonte
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
tmartin
fonte
0

Python, 40 caracteres

print(float(input())*float(input())**-1)
fdvfcges
fonte
0

Python, 37

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

Constrói uma sequência de length x( '0'*x) e usa fatias estendidas para escolher todos osy caracteres, começando no índicey-1 . Imprime o comprimento da sequência resultante.

Como o Gnibbler, isso exige entrada separada por vírgula. Removê-lo custa 9caracteres:

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

Retina 0.7.3, 33 bytes (não competindo)

A linguagem é mais nova que o desafio. Recebe a entrada separada por espaço com o divisor primeiro. A divisão por zero é indefinida.

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

Experimente online

mbomb007
fonte
Como você conta isso como 25 bytes? Se você espera E / S unárias, deve dizer isso (e acho que são 24 bytes). Mas não sei por que você trata o caso 0 separadamente: retina.tryitonline.net/…
Martin Ender
Foi copiado
incorretamente #