Division implementieren

15

Implementieren Sie einen Divisionsalgorithmus in Ihrer bevorzugten Sprache, der die Ganzzahldivision handhabt. Es muss nur mit positiven Zahlen umgehen - aber mit Bonuspunkten, wenn es auch mit negativer Division und Division mit gemischten Vorzeichen umgehen kann. Die Ergebnisse werden für Teilergebnisse abgerundet.

Das Programm kann nicht enthalten /, \, divoder ähnliche Operatoren. Es muss eine Routine sein, die die nativen Teilungsfähigkeiten der Sprache nicht nutzt.

Sie müssen nur bis zu 32-Bit-Division behandeln. Die wiederholte Subtraktion ist nicht zulässig.

Eingang

Nehmen Sie zwei Eingaben auf stdin, die durch neue Zeilen oder Leerzeichen voneinander getrennt sind (Ihre Wahl)

740 
2

Ausgabe

In diesem Fall wäre die Ausgabe 370.

Die Lösung, die die kürzeste ist, gewinnt.

Thomas O.
quelle
ist das 740,2auch für die eingabe erlaubt? dh durch Komma getrennt?
Gnibbler
"Ergebnisse werden für gebrochene Ergebnisse abgerundet" - ok, also kann die Eingabe anscheinend auch zu einer nicht ganzzahligen Zahl führen nicht?
Aurel Bílý
@gnibber Das wäre in Ordnung, mache es aber in der Programmbeschreibung deutlich.
Thomas O
2
ist die Verwendung von Exponentialen und anderen mathematischen Funktionen wirklich erlaubt? Sie verwenden die Unterteilung hinter den Kulissen, weil viele Lösungen ab ¹
Ming-Tang
2
Dies ist die kürzeste Zeit, aber ich habe noch niemanden gesehen, der den Code
liest

Antworten:

27

Python - 73 Zeichen

Kommagetrennte Eingabe, z 740,2

from math import*
x,y=input()
z=int(exp(log(x)-log(y)))
print(z*y+y<=x)+z
Knabberzeug
quelle
5
Dies ist, mein Freund, CLEVER
Aamir
Die Ausgabe für "740,2" ist 369. Stimmt das?
Eelvex,
@Eelvex, sollte <=, behoben und verkürzt worden sein :)
gnibbler
14

JavaScript, 61

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

Dies macht eine Zeichenkette zur Länge des Dividenden ,,,,,,(6) und teilt sich auf den Divisor ,,,(3), was zu einem Array der Länge 3: führt ['', '', ''], von dessen Länge ich dann eine subtrahiere. Auf jeden Fall nicht die schnellste, aber hoffentlich trotzdem interessant!

Casey Chu
quelle
2
Meine bisherige Lieblingsimplementierung hier. Herzlichen Glückwunsch zum coolen Code!
Thomas Eding
Ich habe versucht, es etwas kürzer zu machen. A=Array,P=prompt,P((''+A(+P())).split(','+A(+P())).length)
pimvdb
10

JavaScript - 36 Zeichen

p=prompt;alert(p()*Math.pow(p(),-1))
PleaseStand
quelle
5
Ersetzen alertmit pIhnen einige zusätzliche Zeichen Netz. :)
Casey Chu
9

Mathematica: 34 Zeichen

Löst symbolisch die Gleichung (xa == b)

Solve[x#[[1]]==#[[2]],x]&@Input[]
Dr. belisarius
quelle
2
23 Zeichen,Solve[x#==#2]&@@Input[]
Chyanog
8

Python - 72 Zeichen

Übernimmt kommagetrennte Eingaben, zB 740,2

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

Python, 37

Schritt 1. In Unary konvertieren.

Schritt 2. Algorithmus der unären Division.

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

Python - 41 Zeichen

Kommagetrennte Eingabe, z 740,2

x,y=input();z=x
while y*z>x:z-=1 
print z
Knabberzeug
quelle
1
Dies ist in einigen Fällen schlimmer als ein kontinuierliches Subtrahieren. Die Eingabe ist z. B. 5,4. Die while-Schleife wird viermal ausgeführt, während im Falle einer Subtraktion nur einmal subtrahiert werden muss.
Aamir
6

Python, 70

Etwas Verrücktes, was ich mir gerade gedacht habe (mit kommagetrennter Eingabe):

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

Wenn Sie kleine Schwimmergenauigkeitsfehler akzeptieren, kann die roundFunktion gelöscht werden.

JBernardo
quelle
4

Yabasic - 17 Zeichen

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

PHP - 82 Zeichen (fehlerhaft)

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

Dies ist jedoch eine sehr einfache Lösung - sie verarbeitet keine Brüche oder andere Vorzeichen (würde in eine Endlosschleife springen). Ich werde hier nicht ins Detail gehen, es ist ziemlich einfach.

Die Eingabe erfolgt in stdin, getrennt durch eine neue Zeile.

PHP - 141 Zeichen (voll)

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

Ein- und Ausgabe wie zuvor.

Ja, das ist fast doppelt so groß wie das vorherige, aber es:

  • behandelt Brüche richtig
  • handhabt Zeichen richtig
  • wird niemals in eine Endlosschleife gehen, es sei denn, der zweite Parameter ist 0 - aber das ist eine Division durch Null - ungültige Eingabe

Neuformatierung und Erläuterung:

$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ý
quelle
Sie haben in diesem Beispiel einen Divisionsoperator verwendet, es kann jedoch zu einer leichten Verschiebung kommen. ;)
Thomas O
@Thomas O yeah ... Ich habe es jetzt bemerkt ... Ich habe tatsächlich über eine kleine Verschiebung nachgedacht (als ich sie auf / = 2 anstatt auf / = 10 geändert habe) - aber es war noch ein Zeichen ... Ich werde es sowieso benutzen müssen ... Übrigens, das ist überhaupt keine Unterteilung: D.
Aurel Bílý
Die Frage besagt, dass Sie stdin verwenden müssen, für das PHP Unterstützung bietet.
Kevin Brown
@ Bass5098 Aaahhh ... Na ja, habe 4 Zeichen gewonnen ... Behoben.
Aurel Bílý
3

Ruby 1.9, 28 Zeichen

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

Restliche Teilung, 21 Zeichen

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

Stichprobe:

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

Für 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
quelle
NoMethodError: Private Methode `split 'für 69938 aufgerufen: Fixnum
rkj
@rkj, Sorry, nur Ruby 1.9. Um auf Ruby 1.8 laufen zu können, müssen Sie ('a'*a+'b').split('a'*b).size-1drei Zeichen größer sein.
LBg
3

APL (6)

⌊*-/⍟⎕

/ist hier keine Teilung, aber foldr. dh F/a b cist a F (b F c). Wenn ich nicht verwenden kann, foldrweil es aufgerufen wird /, kann es in 9 Zeichen erfolgen:

⌊*(⍟⎕)-⍟⎕

Erläuterung:

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

PHP, 55 Zeichen

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

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

Kevin Brown
quelle
44 Zeichen: <?$a=fgetcsv(STDIN);echo$a[0]*pow($a[1],-1);Verwenden Sie einfach ein Komma anstelle eines Leerzeichens, um Zahlen zu trennen.
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)
Benutzer unbekannt
quelle
2

Haskell, 96 Zeichen

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

Die Eingabe erfolgt in einer einzelnen Zeile.

Der Code sucht einfach nach der Antwort, indem er den Divisor nimmt dund mit allen ganzen Zahlen multipliziert n >= 0. Sei mdie Dividende. Die größte ndavon n * d <= mwird ausgewählt, um die Antwort zu sein. Der Code wählt tatsächlich am wenigsten ndas aus n * d > mund subtrahiert 1 davon, weil ich das erste Element von einer solchen Liste nehmen kann. Im anderen Fall müsste ich das letzte nehmen, aber es ist harte Arbeit, das letzte Element von einer unendlichen Liste zu nehmen. Nun, die Liste kann als endlich erwiesen werden, aber Haskell weiß es nicht besser, wenn er den Filter ausführt, und filtert daher unbegrenzt weiter.

Thomas Eding
quelle
2

Common Lisp, 42 Zeichen

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

Akzeptiert durch Leerzeichen oder Zeilen getrennte Eingaben

Strigoides
quelle
2

Bash, 72 64 Zeichen

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

Eine unendliche Anzahl von Zeilenumbrüchen ausgeben, das erste x nehmen, alle in eine Datei mit dem Namen f einfügen und dann die Größe von f in Blöcken mit der Größe von y abrufen. Manatworks Rat befolgt, um acht Charaktere zu rasieren.

Hovercouch
quelle
Wählen Sie als "Nehmen Sie zwei durch neue Zeilen oder Leerzeichen getrennte Eingaben für stdin (Ihre Wahl)" die späteren, durch Leerzeichen getrennten Werte aus. In diesem Fall können Sie schreiben read x y. Mit ein paar mehr Leerzeichen entfernt kann auf 64 Zeichen reduziert werden: pastebin.com/Y3SfSXWk
Manatwork
1

Python - 45 Zeichen

Übernimmt kommagetrennte Eingaben, zB 740,2

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

Python, 94 Zeichen

Eine rekursive binäre Suche:

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
quelle
1

Python, 148

Andere Lösungen mögen kurz sein, aber sind sie webbasiert ?

Hier ist eine elegante, zeitlich konstante Lösung, die die Kraft der CLOUD nutzt.

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

Habe ich erwähnt, dass es auch Haskell verwendet?

Lambda-Fee
quelle
0

Python, 46 Bytes

Niemand hatte die langweilige Subtraktionslösung veröffentlicht, also konnte ich nicht widerstehen, es zu tun.

a, b = input ()
i = 0
während a> = b: a- = b; i + = 1
drucke i
cemper93
quelle
0

Smalltalk , Squeak 4.x Geschmack

Definiere diese binäre Nachricht in Integer:

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

Nach dem Golfen ist dieser Quotient immer noch lang (88 Zeichen):

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

Aber es ist vernünftigerweise schnell:

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

-> 127 ms auf meinem bescheidenen mac mini (8 MOp / s)

Im Vergleich zur regulären Aufteilung:

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

-> 31 ms, es ist nur 4 mal langsamer

Ich zähle die Zeichen nicht, um stdin zu lesen oder stdout zu schreiben, Squeak wurde nicht für Skripte entwickelt.

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

Natürlich mehr dumme wiederholte Subtraktion

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

oder einfach blöde Aufzählung

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

könnte auch funktionieren, ist aber nicht wirklich interessant

aka.nice
quelle
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
quelle
0

DC: 26 Zeichen

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

Ich gebe zu, dass es nicht die schnellste Lösung ist.

Fors
quelle
0

Python 54

Übernimmt kommagetrennte Eingaben.

  1. Erzeugt eine Folge von Punkten der Länge x
  2. Ersetzt Segmente von Punkten der Länge y durch ein einzelnes Komma
  3. Zählt Kommas.

Wörter, weil Markdown mit einer Liste gefolgt von Code stirbt ?:

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

quelle
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
quelle
0

Python, 40 Zeichen

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

Python, 37

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

Erstellt eine Zeichenfolge der Länge x( '0'*x) und verwendet erweitertes Slicing, um jedes yZeichen beginnend mit dem Index auszuwählen y-1. Gibt die Länge der resultierenden Zeichenfolge aus.

Wie bei Gnibbler werden auch hier durch Kommas getrennte Eingaben verwendet. Das Entfernen kostet 9Zeichen:

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

Retina 0.7.3, 33 Bytes (nicht konkurrierend)

Die Sprache ist neuer als die Herausforderung. Nimmt die durch Leerzeichen getrennte Eingabe zuerst mit dem Divisor auf. Das Teilen durch Null ist undefiniert.

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

Probieren Sie es online aus

mbomb007
quelle
Wie zählt man das als 25 Bytes? Wenn Sie unäre E / A erwarten, sollten Sie dies sagen (und ich denke, dann sind es 24 Bytes). Nicht sicher, warum Sie den Fall 0 separat behandeln: retina.tryitonline.net/…
Martin Ender
Es wurde falsch kopiert
mbomb007