Implementare la divisione


15

Implementa un algoritmo di divisione nella tua lingua preferita che gestisce la divisione di numeri interi. Deve solo gestire numeri positivi, ma punti bonus se gestisce anche la divisione di segni negativi e misti. I risultati sono arrotondati per risultati frazionari.

Il programma non può contenere i /, \, divo similari operatori. Deve essere una routine che non utilizza le capacità di divisione native della lingua.

Hai solo bisogno di gestire una divisione fino a 32 bit. L'uso di sottrazioni ripetute non è consentito.

Ingresso

Prendi due input su stdin separati da nuove linee o spazi (a tua scelta)

740 
2

Produzione

In questo caso, l'output sarebbe 370.

La soluzione più corta vince.


è 740,2consentito anche per l'ingresso? cioè separati da virgola?
Gnibbler,

"I risultati sono arrotondati per risultati frazionari" - ok, quindi a quanto pare l'input può anche comportare un numero non intero ... Ma che dire del divisore più grande del diviso (diciamo, 5 e 10) - è che è permesso o non?
Aurel Bílý,

@gnibber Andrebbe bene, ma chiariscilo nella descrizione del programma.
Thomas O

2
è davvero consentito l'uso di esponenziali e altre funzioni matematiche? usano la divisione dietro le quinte, perché molte soluzioni stanno facendo ab⁻¹
Ming-Tang il

2
questo è il tempo più breve, ma non ho visto nessuno che
cronometri

Risposte:


27

Python - 73 caratteri

Accetta input separati da virgola, ad es 740,2

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

5
Questo, amico mio, è CLEVER
Aamir,

L'output per "740,2" è 369. È corretto?
Eelvex,

@Eelvex, avrebbe dovuto essere <=, risolto e reso più breve :)
gnibbler,

14

JavaScript, 61

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

Questo rende una stringa la lunghezza del dividendo ,,,,,,(6) e si divide sul divisore ,,,(3), risultando in una matrice di lunghezza 3 ['', '', '']:, la cui lunghezza quindi sottraggo una. Sicuramente non il più veloce, ma si spera comunque interessante!


2
La mia implementazione preferita qui finora. Complimenti per il fantastico codice!
Thomas Eding,

Ho provato a renderlo un po 'più breve. A=Array,P=prompt,P((''+A(+P())).split(','+A(+P())).length)
pimvdb,

10

JavaScript - 36 caratteri

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

5
La sostituzione alertcon pti farà guadagnare qualche personaggio in più. :)
Casey Chu,

9

Mathematica: 34 caratteri

Risolve simbolicamente l'equazione (xa == b)

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

2
23 caratteri,Solve[x#==#2]&@@Input[]
chyanog

8

Python - 72 caratteri

Accetta input separati da virgola, ad esempio 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

Passaggio 1. Converti in unario.

Passaggio 2. Algoritmo di divisione unaria.

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

7

Python - 41 caratteri

Accetta input separati da virgola, ad es 740,2

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

1
Questo, in alcuni casi, è peggio della sottrazione continua. ad esempio, l'ingresso è 5,4. mentre il ciclo verrà eseguito 4 volte mentre in caso di sottrazione, dovremo sottrarre una sola volta.
Aamir,

6

Python, 70

Qualcosa di folle che ho appena pensato (usando un input separato da virgole):

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

Se si accettano errori di precisione float piccoli, la roundfunzione può essere eliminata.



3

PHP - 82 caratteri (buggy)

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

Questa è una soluzione molto semplice, tuttavia: non gestisce frazioni o segni diversi (saltare in un ciclo infinito). Non entrerò nei dettagli in questo, è abbastanza semplice.

L'input è in stdin, separato da una nuova riga.

PHP - 141 caratteri (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;

Ingresso e uscita uguali a quelli precedenti.

Sì, questa è quasi il doppio di quella precedente, ma:

  • gestisce correttamente le frazioni
  • gestisce i segni correttamente
  • non andrà mai in un ciclo infinito, A MENO CHE il secondo parametro sia 0 - ma che sia divisione per zero - input non valido

Riformattazione e spiegazione:

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

In questo caso hai utilizzato un operatore di divisione, ma potresti scappare con un po 'di turni. ;)
Thomas O

@Thomas O sì ... L'ho notato ora ... In realtà stavo pensando a un po 'di cambiamento (quando l'ho cambiato in / = 2 invece di / = 10) - ma era un altro carattere ... Immagino di' Dovrò usarlo comunque ... Btw che non è affatto divisione: D.
Aurel Bílý,

La domanda dice che devi usare stdin, per cui PHP ha il supporto.
Kevin Brown,

@ Bass5098 Aaahhh ... Oh beh, ho guadagnato 4 caratteri ... Risolto.
Aurel Bílý,

3

Ruby 1.9, 28 caratteri

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

Resto della divisione, 21 caratteri

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

Campione:

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

Per 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: metodo privato `split 'chiamato per 69938: Fixnum
rkj

@rkj, Siamo spiacenti, solo Ruby 1.9. Per correre su Ruby 1.8 devi fare ('a'*a+'b').split('a'*b).size-13 personaggi più grandi.
LG

3

APL (6)

⌊*-/⍟⎕

/non è divisione qui, ma foldr. cioè, F/a b cè a F (b F c). Se non posso usare foldrperché si chiama /, può essere fatto in 9 caratteri:

⌊*(⍟⎕)-⍟⎕

Spiegazione:

  • : 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 caratteri

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

L'input è su una sola riga.

Il codice cerca solo la risposta prendendo il divisore de moltiplicandolo per tutti i numeri interi n >= 0. Lascia che msia il dividendo. Il più grande ntale chen * d <= m viene scelto per essere la risposta. Il codice raccoglie effettivamente le almeno ntali che n * d > me sottrae 1 da esso perché posso prendere il primo elemento da tale lista. Nell'altro caso, dovrei prendere l'ultimo, ma è un duro lavoro prendere l'ultimo elemento da un elenco infinito. Bene, l'elenco può essere dimostrato essere finito, ma Haskell non conosce meglio quando si esegue il filtro, quindi continua a filtrare indefinitamente.


2

Lisp comune, 42 caratteri

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

Accetta input separati da linea o spazio


2

bash, 72 64 caratteri

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

Stampa un numero infinito di newline, prendi la prima x, inseriscili tutti in un file chiamato f, quindi ottieni la dimensione di f in blocchi della dimensione di y. Prese il consiglio dell'uomo per radere otto personaggi.


Come "Prendi due input su stdin separati da nuove linee o spazi (a tua scelta)", scegli meglio i valori successivi separati dallo spazio. Nel qual caso puoi scrivere read x y. Con qualche spazio in più rimosso può essere ridotto a 64 caratteri: pastebin.com/Y3SfSXWk
manatwork

1

Python - 45 caratteri

Accetta input separati da virgola, ad esempio 740,2

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

1

Python, 94 caratteri

Una ricerca binaria ricorsiva:

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

Altre soluzioni possono essere brevi, ma sono in scala web ?

Ecco un'elegante soluzione a tempo costante che sfrutta la potenza di CLOUD.

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

Ho già detto che usa anche Haskell?


0

Python, 46 byte

Nessuno aveva pubblicato la noiosa soluzione di sottrazione, quindi non ho resistito.

a, b = input ()
i = 0
mentre a> = b: a- = b; i + = 1
stampa i

0

Smalltalk , Squeak 4.x flavour

definire questo messaggio binario in Intero:

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

Una volta golfato, questo quoziente è ancora lungo (88 caratteri):

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

Ma è ragionevolmente veloce:

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

-> 127 ms sul mio mod mini mac (8 MOp / s)

Rispetto alla divisione regolare:

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

-> 31 ms, è solo 4 volte più lento

Non conto i caratteri per leggere stdin o scrivere stdout, Squeak non è stato progettato per lo scripting.

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

Certo, sottrazione ripetuta più stupida

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

o semplice stupida enumerazione

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

potrebbe funzionare anche, ma non sono molto interessanti


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 caratteri

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

Ammetto che non è la soluzione più veloce in circolazione.


0

Python 54

Accetta input delimitati da virgole.

  1. Crea una stringa di punti di lunghezza x
  2. Sostituisce segmenti di punti di lunghezza y con una virgola singola
  3. Conta le virgole.

Parole perché il markdown muore con un elenco seguito da un codice ?:

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 caratteri

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

0

Python, 37

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

Costruisce una stringa di lunghezza x( '0'*x) e utilizza lo slicing esteso per selezionare tutti yi caratteri, a partire dall'indice y-1. Stampa la lunghezza della stringa risultante.

Come Gnibbler, questo richiede input separati da virgola. Rimuoverlo costa 9caratteri:

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

0

Retina 0.7.3, 33 byte (non in competizione)

La lingua è più recente della sfida. Accetta prima l'input separato da spazio con il divisore. La divisione per zero non è definita.

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

Provalo online


Come si conta come 25 byte? Se ti aspetti l'I / O unario, dovresti dirlo (e penso che sia di 24 byte). Non sono sicuro del motivo per cui trattate il caso 0 separatamente però: retina.tryitonline.net/…
Martin Ender

È stato copiato male
mbomb007 il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.