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.


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

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!


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

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[]

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

8

Python, 37

Schritt 1. In Unary konvertieren.

Schritt 2. Algorithmus der unären Division.

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

7

Python - 41 Zeichen

Kommagetrennte Eingabe, z 740,2

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

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.



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.

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

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



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.


2

Common Lisp, 42 Zeichen

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

Akzeptiert durch Leerzeichen oder Zeilen getrennte Eingaben


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.


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

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)

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?


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

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


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 Zeichen

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

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


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

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 Zeichen

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

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

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


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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.