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.

Thomas O
la source
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
grignoteur
la source
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!

Casey Chu
la source
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))
Veuillez vous lever
la source
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[]
Dr. belisarius
la source
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
grignoteur
la source
8

Python, 37

Étape 1. Convertissez en unaire.

Étape 2. Algorithme de division unaire.

print('1'*input()).count('1'*input())
boothby
la source
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
grignoteur
la source
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.

JBernardo
la source
4

Yabasic - 17 caractères

input a,b:?a*b^-1
Veuillez vous lever
la source
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.
Aurel Bílý
la source
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
LBg
la source
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()))))
marinus
la source
2

PHP, 55 caractères

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

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

Kevin Brown
la source
44 caractères: il <?$a=fgetcsv(STDIN);echo$a[0]*pow($a[1],-1);suffit d'utiliser une virgule au lieu d'un espace pour séparer les nombres.
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)
Utilisateur inconnu
la source
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.

Thomas Eding
la source
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

Strigoides
la source
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.

Hovercouch
la source
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))
grignoteur
la source
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)
note
la source
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?

Fée lambda
la source
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
cemper93
la source
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

aka.nice
la source
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
la source
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.

Fors
la source
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(',')

la source
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
la source
0

Python, 40 caractères

print(float(input())*float(input())**-1)
fdvfcges
la source
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])
Justin
la source
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

mbomb007
la source
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