Mettre en œuvre la division


15

Implémentez un algorithme de division dans votre langue préférée qui gère la division entière. Il ne doit gérer que des nombres positifs - mais des points bonus s'il gère également la division négative et mixte. Les résultats sont arrondis pour des résultats fractionnaires.

Le programme ne peut pas contenir les /, \, divou opérateurs similaires. Ce doit être une routine qui n'utilise pas les capacités de division native de la langue.

Vous avez seulement besoin de gérer jusqu'à 32 bits de division. L'utilisation d'une soustraction répétée n'est pas autorisée.

Contribution

Prenez deux entrées sur stdin séparées par de nouvelles lignes ou espaces (votre choix)

740 
2

Production

Dans ce cas, la sortie serait 370.

La solution la plus courte l'emporte.


est 740,2également autorisé pour l'entrée? c'est-à-dire séparés par des virgules?
gnibbler

"Les résultats sont arrondis vers le bas pour les résultats fractionnaires" - ok, donc apparemment, l'entrée peut également entraîner un nombre non entier ... Mais qu'en est-il du diviseur étant plus grand que le divisé (disons, 5 et 10) - est-ce autorisé ou ne pas?
Aurel Bílý

@gnibber Ce serait bien, mais précisez-le dans la description du programme.
Thomas O

2
l'utilisation d'exponentielles et d'autres fonctions mathématiques est-elle vraiment autorisée? ils utilisent la division dans les coulisses, car de nombreuses solutions font ab⁻¹
Ming-Tang

2
c'est le temps le plus court mais je n'ai vu personne chronométrer le code
phuclv

Réponses:


27

Python - 73 caractères

Prend une entrée séparée par des virgules, par exemple 740,2

from math import*
x,y=input()
z=int(exp(log(x)-log(y)))
print(z*y+y<=x)+z

5
Ceci, mon ami, est PLUS CLAIR
Aamir

La sortie pour "740,2" est 369. Est-ce correct?
Eelvex

@Eelvex, aurait dû être <=, corrigé et raccourci :)
gnibbler

14

JavaScript, 61

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

Cela fait une chaîne de la longueur du dividende ,,,,,,(6) et se divise sur le diviseur ,,,(3), résultant en un tableau de longueur 3:, ['', '', '']dont je soustrais alors une longueur. Certainement pas le plus rapide, mais j'espère néanmoins intéressant!


2
Mon implémentation préférée ici jusqu'à présent. Félicitations pour le code cool!
Thomas Eding

J'ai essayé de le raccourcir un peu. A=Array,P=prompt,P((''+A(+P())).split(','+A(+P())).length)
pimvdb

10

JavaScript - 36 caractères

p=prompt;alert(p()*Math.pow(p(),-1))

5
Le remplacement alertpar pvous donnera des caractères supplémentaires. :)
Casey Chu

9

Mathematica: 34 caractères

Résout symboliquement l'équation (xa == b)

Solve[x#[[1]]==#[[2]],x]&@Input[]

2
23 caractères,Solve[x#==#2]&@@Input[]
chyanog

8

Python - 72 caractères

Prend une entrée séparée par des virgules, par exemple 740,2

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

8

Python, 37

Étape 1. Convertissez en unaire.

Étape 2. Algorithme de division unaire.

print('1'*input()).count('1'*input())

7

Python - 41 caractères

Prend une entrée séparée par des virgules, par exemple 740,2

x,y=input();z=x
while y*z>x:z-=1 
print z

1
Dans certains cas, cela est pire que la soustraction continue. par exemple, l'entrée est 5,4. tandis que la boucle s'exécutera 4 fois tandis qu'en cas de soustraction, nous n'aurons à soustraire qu'une seule fois.
Aamir

6

Python, 70

Quelque chose de fou que je viens de penser (en utilisant une entrée séparée par des virgules):

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

Si vous acceptez de petites erreurs de précision flottante, la roundfonction peut être supprimée.



3

PHP - 82 caractères (buggy)

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

C'est une solution très simple, cependant - elle ne gère pas les fractions ou les signes différents (sauterait dans une boucle infinie). Je n'entrerai pas dans les détails dans celui-ci, c'est assez simple.

L'entrée est en stdin, séparée par une nouvelle ligne.

PHP - 141 caractères (complet)

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

Entrée et sortie identiques à la précédente.

Oui, c'est presque le double de la taille de la précédente, mais cela:

  • gère correctement les fractions
  • gère correctement les panneaux
  • n'entrera jamais dans une boucle infinie, SAUF si le deuxième paramètre est 0 - mais c'est la division par zéro - entrée invalide

Reformater et expliquer:

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

Vous avez utilisé un opérateur de division dans celui-ci, vous pourriez cependant vous en sortir avec un peu de décalage. ;)
Thomas O

@Thomas O ouais ... Je l'ai remarqué maintenant ... Je pensais en fait à un petit changement (quand je l'ai changé en / = 2 au lieu de / = 10) - mais c'était un autre caractère ... Je suppose que je ' ll faudra quand même l'utiliser ... Btw ce n'est pas du tout la division: D.
Aurel Bílý

La question dit que vous devez utiliser stdin, que PHP prend en charge.
Kevin Brown

@ Bass5098 Aaahhh ... Eh bien, gagné 4 caractères ... Fixe.
Aurel Bílý

3

Ruby 1.9, 28 caractères

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

Reste de la division, 21 caractères

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

Échantillon:

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

Pour Ruby 1.8:

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

NoMethodError: méthode privée `split 'appelée pour 69938: Fixnum
rkj

@rkj, Désolé, Ruby 1.9 uniquement. Pour fonctionner sur Ruby 1.8, vous devez faire ('a'*a+'b').split('a'*b).size-1, 3 caractères plus gros.
LBg

3

APL (6)

⌊*-/⍟⎕

/n'est pas ici la division, mais foldr. c'est-à-dire, F/a b cest a F (b F c). Si je ne peux pas l'utiliser foldrparce qu'on l'appelle /, cela peut se faire en 9 caractères:

⌊*(⍟⎕)-⍟⎕

Explication:

  • : input()
  • ⍟⎕: map(log, input())
  • -/⍟⎕: foldr1(sub, map(log, input()))
  • *-/⍟⎕: exp(foldr1(sub, map(log, input())))
  • ⌊*-/⍟⎕: floor(exp(foldr1(sub, map(log, input()))))



2

Haskell, 96 caractères

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

L'entrée se fait sur une seule ligne.

Le code recherche simplement la réponse en prenant le diviseur det en le multipliant par tous les entiers n >= 0. Soit mle dividende. Le plus grand ntel qui n * d <= mest choisi pour être la réponse. Le code choisit en fait le moins ntel n * d > met en soustrait 1 parce que je peux prendre le premier élément d'une telle liste. Dans l'autre cas, je devrais prendre le dernier, mais il est difficile de prendre le dernier élément d'une liste infinie. Eh bien, la liste peut être prouvée finie, mais Haskell ne sait pas mieux quand il effectue le filtre, il continue donc de filtrer indéfiniment.


2

Lisp commun, 42 personnages

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

Accepte une entrée séparée par un espace ou une ligne


2

Frapper, 72 64 caractères

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

Générez un nombre infini de sauts de ligne, prenez le premier x, mettez-les tous dans un fichier appelé f, puis obtenez la taille de f en blocs de la taille de y. A suivi les conseils de manatwork pour raser huit personnages.


En tant que «Prenez deux entrées sur stdin séparées par de nouvelles lignes ou espaces (votre choix)», choisissez mieux la dernière, les valeurs séparées par des espaces. Dans ce cas, vous pouvez écrire read x y. Avec quelques espaces supplémentaires supprimés, vous pouvez réduire à 64 caractères: pastebin.com/Y3SfSXWk
manatwork

1

Python - 45 caractères

Prend une entrée séparée par des virgules, par exemple 740,2

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

1

Python, 94 caractères

Une recherche binaire récursive:

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)

1

Python, 148

D'autres solutions peuvent être courtes, mais sont-elles à l'échelle du Web ?

Voici une solution élégante à temps constant qui exploite la puissance du CLOUD.

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

Ai-je mentionné qu'il utilise également Haskell?


0

Python, 46 octets

Personne n'avait publié la solution de soustraction ennuyeuse, donc je n'ai pas pu résister à le faire.

a, b = entrée ()
i = 0
tandis que a> = b: a- = b; i + = 1
imprimer i

0

Smalltalk , Squeak 4.x saveur

définir ce message binaire en entier:

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

Une fois golfé, ce quotient est encore long (88 caractères):

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

Mais c'est relativement rapide:

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

-> 127 ms sur mon modeste mac mini (8 MOp / s)

Par rapport à la division régulière:

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

-> 31 ms, c'est 4 fois plus lent

Je ne compte pas les caractères pour lire stdin ou écrire stdout, Squeak n'a pas été conçu pour les scripts.

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

Bien sûr, une soustraction répétée plus stupide

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

ou simple énumération stupide

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

pourrait aussi fonctionner, mais n'est pas vraiment intéressant


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

0

DC: 26 caractères

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

J'admets que ce n'est pas la solution la plus rapide.


0

Python 54

Prend une entrée séparée par des virgules.

  1. Fait une chaîne de points de longueur x
  2. Remplace les segments de points de longueur y par une seule virgule
  3. Compte les virgules.

Des mots parce que le démarquage meurt avec une liste suivie d'un code?:

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

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


0

Python, 40 caractères

print(float(input())*float(input())**-1)

0

Python, 37

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

Construit une chaîne de longueur x( '0'*x) et utilise un découpage étendu pour sélectionner chaque ye caractère, à partir de l'index y-1. Imprime la longueur de la chaîne résultante.

Comme Gnibbler, cela prend une entrée séparée par des virgules. Le supprimer coûte des 9caractères:

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

0

Retina 0.7.3, 33 octets (pas en compétition)

La langue est plus récente que le défi. Prend une entrée séparée par un espace avec le diviseur en premier. La division par zéro n'est pas définie.

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

Essayez-le en ligne


Comment comptez-vous cela comme 25 octets? Si vous vous attendez à des E / S unaires, vous devez le dire (et je pense que c'est 24 octets). Je ne sais pas pourquoi vous traitez le cas 0 séparément cependant: retina.tryitonline.net/…
Martin Ender

Il a été mal copié
mbomb007
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.