Massimo comun divisore


40

Il tuo compito è calcolare il massimo divisore comune (GCD) di due interi dati nel minor numero di byte di codice possibile.

È possibile scrivere un programma o una funzione, prendendo input e restituendo output tramite uno qualsiasi dei nostri metodi standard accettati (inclusi STDIN / STDOUT, parametri di funzione / valori di ritorno, argomenti della riga di comando, ecc.).

L'input sarà due numeri interi non negativi. Dovresti essere in grado di gestire l'intero intervallo supportato dal tipo intero predefinito della tua lingua o l'intervallo [0,255], a seconda di quale sia maggiore. Si garantisce che almeno uno degli ingressi sarà diverso da zero.

Non è consentito utilizzare gli incorporamenti che calcolano il GCD o l'LCM (il minimo comune multiplo).

Si applicano le regole standard del .

Casi test

0 2     => 2
6 0     => 6
30 42   => 6
15 14   => 1
7 7     => 7
69 25   => 1
21 12   => 3
169 123 => 1
20 142  => 2
101 202 => 101

1
Se stiamo permettendo ad asm di avere input in qualunque registri sia conveniente, e il risultato in qualunque reg sia conveniente, dovremmo sicuramente consentire funzioni o persino frammenti di codice (cioè solo un corpo di funzione). Rendere la mia risposta una funzione completa aggiungerebbe circa 4B con una convenzione di chiamata del registro come vectorcall a 32 bit di MS (un xchg eax, un mov e un ret), o più con una convenzione di chiamata dello stack.
Peter Cordes,

@PeterCordes Spiacente, avrei dovuto essere più specifico. Puoi semplicemente scrivere il codice necessario per l'orso, ma se tu fossi così gentile da includere un modo per eseguire quel codice sarebbe bello.
Mike Shlanta,

Quindi contare solo il codice gcd, ma fornire il codice circostante in modo che le persone possano verificare / sperimentare / migliorare? A proposito, i tuoi casi di test con zero come uno dei due ingressi infrangono le nostre risposte al codice macchina x86. div per zero genera un'eccezione hardware. Su Linux, il tuo processo ottiene a SIGFPE.
Peter Cordes,

3
@CodesInChaos Di solito i limiti di memoria e di tempo vengono ignorati fintanto che l'algoritmo stesso può in linea di principio gestire tutti gli input. La regola ha lo scopo di evitare alle persone di codificare limiti arbitrari per loop che limitano artificialmente l'algoritmo a una gamma più piccola di input. Non capisco bene come l'immutabilità si manifesti in questo?
Martin Ender,

1
gcd (0, n) è errore non n
RosLuP

Risposte:


37

Retina , 16

^(.+)\1* \1+$
$1

Questo non usa affatto l'algoritmo di Euclide, ma trova il GCD usando i gruppi di corrispondenza regex.

Provalo online. - Questo esempio calcola GCD (8,12).

Immettere come 2 numeri interi separati da spazio. Si noti che l'I / O è in unario. Se ciò non è accettabile, possiamo farlo:

Retina, 30

\d+
$*
^(.+)\1* \1+$
$1
1+
$.&

Provalo online.

Come sottolinea @ MartinBüttner, questo si distingue per grandi numeri (come generalmente accade per qualsiasi cosa unaria). Come minimo, un input di INT_MAX richiederà l'assegnazione di una stringa da 2 GB.


2
Vorrei votare ancora per questo
MickyT

Ora dovrebbe andare bene con l'intervallo di numeri. Ho modificato le specifiche (con l'autorizzazione dei PO) per richiedere solo l'intervallo di numeri naturali della lingua (o [0,255] se questo è di più). Dovrai supportare gli zero, anche se penso che cambiare le tue +s in *s dovrebbe fare. E puoi ridurre significativamente l'ultima fase del codice lungo riducendolo a 1.
Martin Ender,

2
Per riferimento futuro, ho appena trovato una soluzione alternativa a 16 byte che funziona per un numero arbitrario di input (incluso uno), quindi potrebbe essere più utile in altri contesti: retina.tryitonline.net/…
Martin Ender,

1
Ho appena notato che né le tue soluzioni né quella nel mio commento sopra hanno bisogno di ^, perché è impossibile che la partita fallisca dalla posizione iniziale.
Martin Ender,

28

codice macchina i386 (x86-32), 8 byte (9B per non firmato)

+ 1B se dobbiamo gestire b = 0l'input.

codice macchina amd64 (x86-64), 9 byte (10B per unsigned o 14B 13B per interi 64b con segno o senza segno)

10 9B per unsigned su amd64 che si interrompe con uno dei due input = 0


Gli ingressi sono a 32 bit non-zero firmato interi eaxe ecx. Uscita in eax.

## 32bit code, signed integers:  eax, ecx
08048420 <gcd0>:
 8048420:       99                      cdq               ; shorter than xor edx,edx
 8048421:       f7 f9                   idiv   ecx
 8048423:       92                      xchg   edx,eax    ; there's a one-byte encoding for xchg eax,r32.  So this is shorter but slower than a mov
 8048424:       91                      xchg   ecx,eax    ; eax = divisor(from ecx), ecx = remainder(from edx), edx = quotient(from eax) which we discard
    ; loop entry point if we need to handle ecx = 0
 8048425:       41                      inc    ecx        ; saves 1B vs. test/jnz in 32bit mode
 8048426:       e2 f8                   loop   8048420 <gcd0>
08048428 <gcd0_end>:
 ; 8B total
 ; result in eax: gcd(a,0) = a

Questa struttura ad anello non ha esito positivo nel caso di test ecx = 0. ( divprovoca #DEun'esecuzione hardware sulla divisione per zero. (Su Linux, il kernel fornisce SIGFPEun'eccezione in virgola mobile). Se il punto di ingresso del ciclo fosse proprio prima del inc, eviteremmo il problema. La versione x86-64 può gestirlo gratuitamente, vedi sotto.

La risposta di Mike Shlanta è stata il punto di partenza per questo . Il mio ciclo fa la stessa cosa della sua, ma per numeri interi con segno perché cdqè un byte più breve di xor edx,edx. E sì, funziona correttamente con uno o entrambi gli ingressi negativi. La versione di Mike funzionerà più velocemente e occuperà meno spazio nella cache uop ( xchgè 3 uops su CPU Intel ed loopè molto lenta sulla maggior parte delle CPU ), ma questa versione vince con le dimensioni del codice macchina.

All'inizio non ho notato che la domanda richiedeva 32 bit senza segno . Tornare indietro xor edx,edxinvece di cdqcosterebbe un byte. divha le stesse dimensioni di idiv, e tutto il resto può rimanere lo stesso ( xchgper lo spostamento dei dati e inc/loopancora funzionare).

È interessante notare che per le versioni operando a 64 bit ( raxe rcx), le versioni firmate e non firmate hanno le stesse dimensioni. La versione firmata necessita di un prefisso REX per cqo(2B), ma la versione non firmata può ancora utilizzare 2B xor edx,edx.

Nel codice a 64 bit, inc ecxè 2B: il singolo byte inc r32e gli dec r32opcode sono stati riproposti come prefissi REX. inc/loopnon salva alcuna dimensione del codice in modalità 64 bit, quindi potresti anche test/jnz. Operando su numeri interi a 64 bit aggiunge un altro byte per istruzione nei prefissi REX, ad eccezione di loopo jnz. È possibile che il resto abbia tutti gli zeri nei 32b bassi (ad es. gcd((2^32), (2^32 + 1))), Quindi abbiamo bisogno di testare l'intero rcx e non possiamo salvare un byte con test ecx,ecx. Tuttavia, l' jrcxzinsn più lento è solo 2B e possiamo inserirlo nella parte superiore del ciclo per gestirlo ecx=0all'entrata :

## 64bit code, unsigned 64 integers:  rax, rcx
0000000000400630 <gcd_u64>:
  400630:       e3 0b                   jrcxz  40063d <gcd_u64_end>   ; handles rcx=0 on input, and smaller than test rcx,rcx/jnz
  400632:       31 d2                   xor    edx,edx                ; same length as cqo
  400634:       48 f7 f1                div    rcx                      ; REX prefixes needed on three insns
  400637:       48 92                   xchg   rdx,rax
  400639:       48 91                   xchg   rcx,rax
  40063b:       eb f3                   jmp    400630 <gcd_u64>
000000000040063d <gcd_u64_end>:
## 0xD = 13 bytes of code
## result in rax: gcd(a,0) = a

Programma di test eseguibile completa con una mainche corre printf("...", gcd(atoi(argv[1]), atoi(argv[2])) ); fonte e l'uscita asm sul Godbolt compilatore Explorer , per i 32 e 64b versioni. Testato e funzionante per 32 bit ( -m32), 64 bit ( -m64) e x32 ABI ( -mx32) .

Incluso anche: una versione che utilizza solo sottrazioni ripetute , che è 9B per unsigned, anche per la modalità x86-64, e può prendere uno dei suoi input in un registro arbitrario. Tuttavia, non è in grado di gestire entrambi gli input che sono 0 alla voce (rileva quando subproduce uno zero, che x - 0 non lo fa mai).

GNU C inline asm source per la versione a 32 bit (compilare con gcc -m32 -masm=intel)

int gcd(int a, int b) {
    asm (// ".intel_syntax noprefix\n"
        // "jmp  .Lentry%=\n" // Uncomment to handle div-by-zero, by entering the loop in the middle.  Better: `jecxz / jmp` loop structure like the 64b version
        ".p2align 4\n"                  // align to make size-counting easier
         "gcd0:   cdq\n\t"              // sign extend eax into edx:eax.  One byte shorter than xor edx,edx
         "        idiv    ecx\n"
         "        xchg    eax, edx\n"   // there's a one-byte encoding for xchg eax,r32.  So this is shorter but slower than a mov
         "        xchg    eax, ecx\n"   // eax = divisor(ecx), ecx = remainder(edx), edx = garbage that we will clear later
         ".Lentry%=:\n"
         "        inc     ecx\n"        // saves 1B vs. test/jnz in 32bit mode, none in 64b mode
         "        loop    gcd0\n"
        "gcd0_end:\n"
         : /* outputs */  "+a" (a), "+c"(b)
         : /* inputs */   // given as read-write outputs
         : /* clobbers */ "edx"
        );
    return a;
}

Normalmente scriverei un'intera funzione in asm, ma GNU C inline asm sembra essere il modo migliore per includere uno snippet che può avere in / output in qualsiasi reg scegliamo. Come puoi vedere, la sintassi di GNU C inline asm rende brutta e rumorosa. È anche un modo davvero difficile per imparare l' asm .

.att_syntax noprefixCompilerebbe e funzionerebbe in modalità, perché tutti gli insn utilizzati sono operandi singoli / no o xchg. Non è davvero un'osservazione utile.


2
@MikeShlanta: grazie. Se ti piace ottimizzare asm, dai un'occhiata ad alcune delle mie risposte su StackOverflow. :)
Peter Cordes

2
@MikeShlanta: ho trovato un uso jrcxzdopo tutto nella versione uint64_t :). Inoltre, non ho notato che avevi specificato unsigned, quindi ho incluso anche i conteggi dei byte.
Peter Cordes,

Perché non è possibile utilizzare jecxznella versione a 32 bit con lo stesso effetto?
Cody Grey,

1
@CodyGray: inc/loop3 byte nella versione a 32 bit, ma 4B nella versione a 64 bit. Ciò significa che solo nella versione a 64 bit, non costa byte aggiuntivi da utilizzare jrcxze jmpinvece di inc / loop.
Peter Cordes,

Non puoi indicare la metà come voce?
l4m2

14

Esagonia , 17 byte

?'?>}!@<\=%)>{\.(

non piegato:

  ? ' ?
 > } ! @
< \ = % )
 > { \ .
  ( . .

Provalo online!

Inserirlo nella lunghezza 3 è stato un gioco da ragazzi. Rasare quei due byte alla fine non era ... Non sono nemmeno convinto che sia ottimale, ma sono sicuro di pensare che sia vicino.

Spiegazione

Un'altra implementazione dell'algoritmo euclideo.

Il programma utilizza tre fronti di memoria, che chiamerò A , B e C , con il puntatore di memoria (MP) che inizia come mostrato:

inserisci qui la descrizione dell'immagine

Ecco il diagramma di flusso di controllo:

inserisci qui la descrizione dell'immagine

Il flusso di controllo inizia sul percorso grigio con un breve bit lineare per l'input:

?    Read first integer into memory edge A.
'    Move MP backwards onto edge B.
?    Read second integer into B.

Si noti che il codice ora si avvolge attorno ai bordi <nell'angolo sinistro. Questo <funge da ramo. Se il fronte corrente è zero (ovvero l'algoritmo euclideo termina), l'IP viene deviato a sinistra e prende il percorso rosso. Altrimenti, un'iterazione dell'algoritmo euclideo viene calcolata sul percorso verde.

Considereremo prima il percorso verde. Si noti che >e \tutti agiscono come specchi che deviano semplicemente il puntatore dell'istruzione. Si noti inoltre che il flusso di controllo avvolge tre volte i bordi, una volta dal fondo verso l'alto, una volta dall'angolo destro alla riga inferiore e infine dall'angolo inferiore destro all'angolo sinistro per ricontrollare la condizione. Si noti anche che. non ci sono operazioni.

Ciò lascia il seguente codice lineare per una singola iterazione:

{    Move MP forward onto edge C.
'}   Move to A and back to C. Taken together this is a no-op.
=    Reverse the direction of the MP so that it now points at A and B. 
%    Compute A % B and store it in C.
)(   Increment, decrement. Taken together this is a no-op, but it's
     necessary to ensure that IP wraps to the bottom row instead of
     the top row.

Ora siamo tornati da dove siamo partiti, tranne per il fatto che i tre bordi hanno cambiato ciclicamente i loro ruoli (la C originale ora assume il ruolo di B e la B originale il ruolo di A ...). In effetti, abbiamo riposizionato gli input Ae Bcon Be A % B, rispettivamente.

Una volta A % B(sul bordo C ) è zero, il GCD può essere trovato sul bordo B . Ancora una volta il >giusto devia l'IP, quindi sul percorso rosso eseguiamo:

}    Move MP to edge B.
!    Print its value as an integer.
@    Terminate the program.

9

Codice macchina x86 little-endian a 32 bit, 14 byte

Generato utilizzando nasm -f bin

d231 f3f7 d889 d389 db85 f475

    gcd0:   xor     edx,edx
            div     ebx
            mov     eax,ebx
            mov     ebx,edx
            test    ebx,ebx
            jnz     gcd0

4
Ho ottenuto questo fino a 8 byte usando cdqe firmato idiv, e un byte xchg eax, r32invece di mov. Per il codice a 32 bit: inc/loopanziché test/jnz(Non riuscivo a vedere un modo di usare jecxze non c'è jecxnz). Ho pubblicato la mia versione finale come una nuova risposta poiché penso che i cambiamenti siano abbastanza grandi da giustificarlo.
Peter Cordes,

9

T-SQL, 153 169 byte

Qualcuno ha menzionato la peggior lingua per giocare a golf?

CREATE FUNCTION G(@ INT,@B INT)RETURNS TABLE RETURN WITH R AS(SELECT 1D,0R UNION ALL SELECT D+1,@%(D+1)+@B%(D+1)FROM R WHERE D<@ and D<@b)SELECT MAX(D)D FROM R WHERE 0=R

Crea una funzione con valori di tabella che utilizza una query ricorsiva per elaborare i divisori comuni. Quindi restituisce il massimo . Ora usa l'algoritmo euclideo per determinare il GCD derivato dalla mia risposta qui .

Esempio di utilizzo

SELECT * 
FROM (VALUES
        (15,45),
        (45,15),
        (99,7),
        (4,38)
    ) TestSet(A, B)
    CROSS APPLY (SELECT * FROM G(A,B))GCD

A           B           D
----------- ----------- -----------
15          45          15
45          15          15
99          7           1
4           38          2

(4 row(s) affected)

1
Gesù che è prolisso.
Cyoce,

9

Gelatina, 7 byte

ṛß%ðḷṛ?

Implementazione ricorsiva dell'algoritmo euclideo. Provalo online!

Se gli built-in non fossero vietati, g(1 byte, GCD integrato) otterrebbe un punteggio migliore.

Come funziona

ṛß%ðḷṛ?  Main link. Arguments: a, b

   ð     Convert the chain to the left into a link; start a new, dyadic chain.
 ß       Recursively call the main link...
ṛ %        with b and a % b as arguments.
     ṛ?  If the right argument (b) is non-zero, execute the link.
    ḷ    Else, yield the left argument (a).

Sembra quasi imbrogliare haha, potrei dover specificare che le risposte non possono usare butlins ...
Mike Shlanta,

13
Se decidi di farlo, dovresti farlo rapidamente. Al momento invaliderebbe tre delle risposte.
Dennis,

Si noti che la lunghezza specificata è in byte - questi caratteri sono per lo più> 1 byte in UTF8.
cortecce

8
@cortices Sì, tutti i concorsi di golf di codice sono assegnati in byte per impostazione predefinita. Tuttavia, Jelly non utilizza UTF-8, ma una codepage personalizzata che codifica ciascuno dei 256 caratteri che comprende come un singolo byte.
Dennis,

@Dennis ah, intelligente.
cortecce

7

Haskell, 19 byte

a#0=a
a#b=b#rem a b

Esempio di utilizzo: 45 # 35-> 5.

Euclide, di nuovo.

PS: ovviamente c'è anche un built-in gcd.


dovresti spiegare il trucco che inverte l'ordine di input per evitare il controllo condizionale
orgoglioso haskeller il

@proudhaskeller: che trucco? Tutti usano questo algoritmo, cioè fermandosi 0o andando avanti con il modulo.
nimi,

Nevrmind, tutti usano il trucco
orgoglioso haskeller il

Questo, meno golfato, è quasi esattamente quello che c'è dentroPrelude
Michael Klein

6

Python 3, 31

Salvato 3 byte grazie a Sp3000.

g=lambda a,b:b and g(b,a%b)or a

3
In Python 3.5+:from math import*;gcd
Sp3000,

@ Sp3000 Bello, non sapevo che lo avessero spostato in matematica.
Morgan Thrapp,

1
Mentre ci sei:g=lambda a,b:b and g(b,a%b)or a
Sp3000

@ Grazie Sp3000! Ho appena finito una soluzione ricorsiva, ma è persino meglio di quello che avevo.
Morgan Thrapp,

Gli built-in per GCD e LCM non sono consentiti, quindi la seconda soluzione non sarebbe valida.
mbomb007,

6

MATL , 11 9 byte

Nessuno sembra aver usato la forza bruta fino ad ora, quindi eccolo qui.

ts:\a~f0)

L'input è un array di colonne con i due numeri (usando ;come separatore).

Provalo online! o verifica tutti i casi di test .

Spiegazione

t     % Take input [a;b] implicitly. Duplicate
s     % Sum. Gives a+b
:     % Array [1,2,...,a+b]
\     % Modulo operation with broadcast. Gives a 2×(a+b) array
a~    % 1×(a+b) array that contains true if the two modulo operations gave 0
f0)   % Index of last true value. Implicitly display

5

C, 38 byte

g(x,y){while(x^=y^=x^=y%=x);return y;}

1
Devi includere la definizione della funzione nel tuo Bytecount.
Rɪᴋᴇʀ

1
@Riker mi dispiace per questo, aggiungo la definizione e aggiorno il conteggio
Come Chen

È possibile salvare due byte nominando la funzione semplicemente ganziché gcd.
Steadybox,

@Steadybox ok, sì, la prima volta entra a far parte di questa community :)
Come Chen il

1
Benvenuti in PPCG!
Rɪᴋᴇʀ

4

C, 28 byte

Una funzione piuttosto semplice che implementa l'algoritmo di Euclide. Forse si può accorciare usando un algoritmo alternativo.

g(a,b){return b?g(b,a%b):a;}

Se uno scrive un piccolo wrapper principale

int main(int argc, char **argv)
{
  printf("gcd(%d, %d) = %d\n", atoi(argv[1]), atoi(argv[2]), g(atoi(argv[1]), atoi(argv[2])));
}

quindi si possono verificare alcuni valori:

$ ./gcd 6 21
mcd (6, 21) = 3
$ ./gcd 21 6
mcd (21, 6) = 3
$ ./gcd 6 8
mcd (6, 8) = 2
$ ./gcd 1 1
mcd (1, 1) = 1
$ ./gcd 6 16
mcd (6, 16) = 2
$ ./gcd 27 244
mcd (27, 244) = 1

4

Labirinto , 18 byte

?}
:
)"%{!
( =
}:{

Termina con un errore, ma il messaggio di errore passa a STDERR.

Provalo online!

Questo non sembra ancora del tutto ottimale, ma non vedo un modo per comprimere il loop sotto 3x3 a questo punto.

Spiegazione

Questo utilizza l'algoritmo euclideo.

Innanzitutto, c'è un bit lineare per leggere l'input e accedere al loop principale. Il puntatore dell'istruzione (IP) inizia nell'angolo in alto a sinistra, verso est.

?    Read first integer from STDIN and push onto main stack.
}    Move the integer over to the auxiliary stack.
     The IP now hits a dead end so it turns around.
?    Read the second integer.
     The IP hits a corner and follows the bend, so it goes south.
:    Duplicate the second integer.
)    Increment.
     The IP is now at a junction. The top of the stack is guaranteed to be
     positive, so the IP turns left, to go east.
"    No-op.
%    Modulo. Since `n % (n+1) == n`, we end up with the second input on the stack.

Entriamo ora in una sorta di ciclo while-do che calcola l'algoritmo euclideo. Le cime delle pile contengono ae b(sopra una quantità infinita implicita di zeri, ma non ne avremo bisogno). Rappresenteremo le pile da una parte all'altra, crescendo l'una verso l'altra:

    Main     Auxiliary
[ ... 0 a  |  b 0 ... ]

Il ciclo termina una volta aè zero. Un'iterazione ciclica funziona come segue:

=    Swap a and b.           [ ... 0 b  |  a 0 ... ]
{    Pull a from aux.        [ ... 0 b a  |  0 ... ]
:    Duplicate.              [ ... 0 b a a  |  0 ... ]
}    Move a to aux.          [ ... 0 b a  |  a 0 ... ]
()   Increment, decrement, together a no-op.
%    Modulo.                 [ ... 0 (b%a)  |  a 0 ... ]

Puoi vedere, abbiamo sostituito ae bcon b%aea rispettivamente.

Infine, una volta che b%aè zero, l'IP continua a spostarsi verso est ed esegue:

{    Pull the non-zero value, i.e. the GCD, over from aux.
!    Print it.
     The IP hits a dead end and turns around.
{    Pull a zero from aux.
%    Attempt modulo. This fails due to division by 0 and the program terminates.

4

Julia, 21 15 byte

a\b=a>0?b%a\a:b

Implementazione ricorsiva dell'algoritmo euclideo. Provalo online!

Se gli built-in non fossero vietati, gcd(3 byte, GCD incorporato) otterrebbero un punteggio migliore.

Come funziona

a\b=             Redefine the binary operator \ as follows:
    a>0?     :       If a > 0:
        b%a\a        Resursively apply \ to b%a and a. Return the result.
              b      Else, return b.

4

Cubix , 10 12 byte

?v%uII/;O@

Provalo qui

Questo si avvolge sul cubo come segue:

    ? v
    % u
I I / ; O @ . .
. . . . . . . .
    . .
    . .

Usa il metodo euclideo.

IIDue numeri vengono presi da STDIN e messi in pila.
/Flusso riflesso
%Mod la parte superiore dello stack. Resto a sinistra sopra lo stack
?Se TOS 0 continua, altrimenti gira a destra In
vcaso contrario 0 reindirizza verso il basso e ugira a destra due volte indietro sul mod
/Se 0 gira intorno al cubo al riflettore
;rilascia TOS, Oemetti TOS e @termina


Ho appena scritto una risposta Cubix a 12 byte, quindi ho iniziato a scorrere le risposte per vedere se avevo bisogno di gestirle entrambe 0,xe x,0... poi mi sono imbattuto in questo. Ben fatto!
ETHproductions


3

Batch di Windows, 76 byte

Funzione ricorsiva. Chiamalo come GCD a bcon il nome del file gcd.

:g
if %2 equ 0 (set f=%1
goto d)
set/a r=%1 %% %2
call :g %2 %r%
:d
echo %f%

3

MATL, 7 byte

pG1$Zm/

Provalo online!

Spiegazione

Dato che non possiamo usare esplicitamente la funzione GCD integrata ( Zdin MATL), ho sfruttato il fatto che il minimo comune multiplo di ae bvolte il massimo comune denominatore di aed bè uguale al prodotto di ae b.

p       % Grab the input implicitly and multiply the two elements
G       % Grab the input again, explicitly this time
1$Zm    % Compute the least-common multiple
/       % Divide the two to get the greatest common denominator

È possibile salvare un byte con due ingressi separati:*1MZm/
Luis Mendo

3

Racchetta (schema), 44 byte

Implementazione di Euclid in Racket (Schema)

(define(g a b)(if(= 0 b)a(g b(modulo a b))))

Modifica: non ho visto la soluzione di @Numeri lol. In qualche modo abbiamo ottenuto lo stesso codice in modo indipendente


Funziona in entrambi?
NoOneIsHere

@NoOneIsHere sì, funziona in entrambi
kronicmage,

3

> <> , 32 byte

::{::}@(?\=?v{:}-
.!09}}${{/;n/>

Accetta due valori dallo stack e applica l'algoritmo euclideo per produrre il loro GCD.

Puoi provarlo qui !

Per una risposta molto migliore in> <>, controlla Sok's !


1
Oggi ho trovato una nuova lingua :)
nsane,


2

GML, 57 byte

a=argument0
b=argument1
while b{t=b;b=a mod b;a=t}return a

2

Delfi 7, 148

Bene, penso di aver trovato la nuova peggior lingua per giocare a golf.

unit a;interface function g(a,b:integer):integer;implementation function g(a,b:integer):integer;begin if b=0then g:=a else g:=g(b,a mod b);end;end.

Oh, non lo so, la parentesi è piuttosto scarsa per il golf
MickyT

2

Hoon, 20 byte

|=
{@ @}
d:(egcd +<)

-

Hoon # 2, 39 byte

|=
{a/@ b/@}
?~
b
a
$(a b, b (mod a b))

Stranamente, l'unica implementazione nello stdlib di Hoon per GCD è quella in uso per la sua crittografia RSA, che restituisce anche altri valori. Devo avvolgerlo in una funzione che richiede solod dall'output.

L'altra implementazione è solo la definizione GCD ricorsiva predefinita.


2

Python 3.5, 70 82 73 byte:

lambda*a:max([i for i in range(1,max(*a)+1)if not sum(g%i for g in[*a])])

In notquesto caso, la somma di tutti i numeri nel *argsmodulo isarà zero.

Inoltre, ora questa funzione lambda può contenere tutti i valori desiderati, purché la quantità di valori sia >=2, a differenza della gcdfunzione del modulo matematico. Ad esempio, può contenere i valori 2,4,6,8,10e restituire il GCD corretto di 2.


1
Sei in arresto per nomi di variabili multichar. (O argomenti di funzione, ma qualunque cosa)
CalculatorFeline

2

Rubino, 23 byte

g=->a,b{b>0?a:g[b,a%b]}

ricorda che i blocchi ruby ​​sono chiamati con g [...] o g.call (...), invece di g (...)

crediti parziali a voidpigeon


2
Invece di g.call(a,b)te puoi usare g[a,b]. Invece di proc{|a,b|, puoi usare ->a,b{.
afuoso

1
È inoltre possibile salvare un byte utilizzando b>0anziché b<=0e cambiando l'ordine degli altri operandi.
afuoso

2

Codice macchina ARM, 12 byte:

montaggio:

gcd: cmp r0, r1
     sublt r0, r0, r1
     bne gcd

Attualmente non è possibile compilarlo, ma ogni istruzione in ARM richiede 4 byte. Probabilmente potrebbe essere abbattuto usando la modalità THUMB-2.


Bel lavoro amico, chiunque faccia questo nel codice macchina ottiene da me oggetti di scena seri.
Mike Shlanta,

Questo sembra essere un tentativo dell'algo di Euclide usando solo la sottrazione , ma non credo che funzioni. Se r0 > r1allora subltnon farà nulla (il ltpredicato è falso) e bnesarà un ciclo infinito. Penso che tu abbia bisogno di uno scambio in caso contrario lt, quindi lo stesso loop può fare b-=ao a-=bse necessario. O una negazione se il sottoprodotto trasporta (noto anche come prestito).
Peter Cordes,

Questa guida al set di istruzioni ARM utilizza effettivamente un algoritmo GCD di sottrazione come esempio per la previsione. (pag. 25). Usano cmp r0, r1/ subgt r0, r0, r1/ sublt r1, r1, r0/ bne gcd. Sono 16 B nelle istruzioni ARM, forse 12 nelle istruzioni thumb2?
Peter Cordes,

1
Su x86, ho gestito 9 byte con: sub ecx, eax/ jae .no_swap/ add ecx,eax/ xchg ecx,eax/ jne. Quindi, invece di un cmp, eseguo semplicemente il sub, quindi annullo e cambio se il sub avrebbe dovuto andare nell'altra direzione. Ho provato questo e funziona. ( addnon uscirà jneal momento sbagliato, perché non può produrre uno zero a meno che uno degli input fosse zero per cominciare, e non lo supportiamo. Aggiornamento: dobbiamo supportare entrambi gli input essendo zero: /)
Peter Cordes,

Per Thumb2, c'è iteun'istruzione: if-then-else. Dovrebbe essere perfetto per cmp / sub in un modo / sub nell'altro modo.
Peter Cordes,

2

TI-Basic, 10 byte

Prompt A,B:gcd(A,B

Non competitiva a causa di una nuova regola che vieta gli incorporati di gcd


Soluzione a 17 byte senza gcd(built-in

Prompt A,B:abs(AB)/lcm(A,B

Non competitiva a causa della nuova regola che vieta gli incorporati di mcm


Soluzione a 27 byte senza gcd(o lcm(integrata:

Prompt A,B:While B:B→T:BfPart(A/B→B:T→A:End:A

Soluzione ricorsiva a 35 byte senza gcd(o lcm(incorporata (richiede un sistema operativo da 2,53 MP o superiore, deve essere denominata prgmG ):

If Ans(2:Then:{Ans(2),remainder(Ans(1),Ans(2:prgmG:Else:Disp Ans(1:End

Passeresti argomenti alla variante ricorsiva come {A,B}ad esempio {1071, 462}:prgmGcederebbe 21.


Colorami colpito.
Mike Shlanta,

Dovresti probabilmente menzionare che l'ultimo deve essere salvato come prgmG.
uno spaghetto il

2

05AB1E , 10 byte

Codice:

EàF¹N%O>iN

Provalo online!


Con incorporati:

¿

Spiegazione:

¿   # Implicit input, computes the greatest common divisor.
    # Input can be in the form a \n b, which computes gcd(a, b)
    # Input can also be a list in the form [a, b, c, ...], which computes the gcd of
      multiple numbers.

Provalo online! oppure Prova con più numeri .


2

Oracle SQL 11.2, 104 118 byte

SELECT MAX(:1+:2-LEVEL+1)FROM DUAL WHERE(MOD(:1,:1+:2-LEVEL+1)+MOD(:2,:1+:2-LEVEL+1))*:1*:2=0 CONNECT BY LEVEL<=:1+:2;

Risolto per l'immissione di 0


Non funziona correttamente se uno degli ingressi è zero.
Egor Skriptunoff,

Questo dovrebbe farvi risparmiare alcuniSELECT MAX(LEVEL)FROM DUAL WHERE MOD(:1,LEVEL)+MOD(:2,LEVEL)=0 CONNECT BY LEVEL<=:1+:2;
MickyT

2

> <> , 12 + 3 = 15 byte

:?!\:}%
;n~/

Si aspetta che i numeri di input siano presenti nello stack, quindi +3 byte per il -vflag.Provalo online!

Un'altra implementazione dell'algoritmo euclideo.

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.