Trova la radice quadrata


19

Scrivi il codice che quando viene dato un numero positivo come input, genera il divisore positivo più grande di minore o uguale alla radice quadrata di .x xXXX

In altre parole, trova il più grande tale chen>0

mn:mn=X

(Esiste m maggiore o uguale a n tale che m volte n è x )


Ad esempio, se l'ingresso era 12 i divisori sono 1 , 2 , 3 , 4 , 6 e 12 . 1 , 2 e 3 moltiplicano per numeri più grandi per ottenere 12 , ma 3 è il più grande, quindi restituiamo 3 .


Si tratta di quindi le risposte verranno classificate in byte con un numero inferiore di byte considerato un punteggio migliore.

Casi test

(1,1)
(2,1)
(3,1)
(4,2)
(5,1)
(6,2)
(7,1)
(8,2)
(9,3)
(10,2)
(11,1)
(12,3)
(13,1)
(14,2)
(15,3)
(16,4)
(17,1)
(18,3)
(19,1)
(20,4)
(21,3)
(22,2)
(23,1)
(24,4)
(25,5)
(26,2)
(27,3)
(28,4)
(29,1)
(30,5)
(31,1)
(32,4)
(33,3)
(34,2)
(35,5)
(36,6)
(37,1)
(38,2)
(39,3)
(40,5)
(41,1)
(42,6)
(43,1)
(44,4)
(45,5)
(46,2)
(47,1)
(48,6)
(49,7)
(50,5)

OEIS A033676


11
Non vedo in che modo la chiusura di domande popolari come i duplicati di quelli inattivi più vecchi aiutano il sito ...? Se lo noti presto, vai avanti e martellalo. Se ha il doppio del numero di risposte e più voti rispetto a quello precedente. Tienilo, e semmai chiudi l'altro ...
Stewie Griffin,

@StewieGriffin Un problema con le "domande popolari" è che si trovano su HNQ. Che probabilmente non è una cosa molto buona. / Non vedo nemmeno come danneggi il sito, puoi semplicemente spostare le risposte a quello vecchio.
user202729,

5
L'HNQ potrebbe attrarre nuovi utenti, e questa è una buona cosa (IMO).
Stewie Griffin,

1
@qwr Ma l'idea di base è la stessa. La differenza è molto piccola Il metodo in ogni sfida può essere usato per un altro.
user202729

1
@ Hand-E-Food Non pretendo che questo sia diverso. In effetti credo che i due abbiano lo stesso contenuto. Le mie ragioni per la chiusura della tua domanda sono le stesse di quelle nel commento nella parte superiore della discussione, questa domanda ha più risposte. Il meta è qui se vuoi chiedere lì. Potresti anche essere interessato a questo .
Wheat Wizard

Risposte:


10

Python3 , 49 47 byte

def f(x):
 l=x**.5//1
 while x%l:l-=1
 return l

Spiegazione

  • l=x**.5//1→ Assegna lil numero intero più grande minore di uguale alla radice quadrata dix
  • while x%l:l-=1→ Mentre lnon si divide uniformemente x, diminuisce l.

Le modifiche

  • Menziona Python3, non Python2
  • Utilizzare ...//1per salvare due byte. (I decimali vanno bene! Grazie @Rod)

Benvenuto in PPCG, bella prima risposta! Puoi salvare pochi byte usando input/ printinvece def/ return, puoi anche sostituirlo int(...)con ...//1per salvare più byte come puoi vedere qui
Rod

@Rod non // 1, come intendevo dire Python3. (A meno che i decimali non vadano bene per l'output, cosa che non pensavo fosse così.) Ma per Python2, grazie!
hunteke,

@hunteke L'output decimale va bene, non vedo alcun motivo per cui non dovrebbe esserlo.
Mago del grano,

Sarebbe più breve con "For" invece di "While", in modo da poter assegnare valori nel condizionale, evitando possibilmente di definire "l"?
Malady,

8

MATL , 7 byte

Z\tn2/)

Provalo online!

Per questa spiegazione, useremo '12' come input di esempio. Spiegazione:

Z\      % Divisors.
        % Stack:
        %   [1 2 3 4 6 12]
  t     % Duplicate.
        % Stack:
        %   [1 2 3 4 6 12]
        %   [1 2 3 4 6 12]
   n    % Number of elements.
        % Stack:
        %   6
        %   [1 2 3 4 6 12]
    2/  % Divide by 2
        % Stack:
        %   3
        %   [1 2 3 4 6 12]
      ) % Index (grab the 3rd element)
        % 3

Questo funziona a causa di molte coincidenze fortunate.

  1. MATL utilizza 1 indicizzazione
  2. Se indicizziamo con un numero intero (ciò accadrà per qualsiasi input quadrato perfetto), allora <n>)indicizzeremon

1
...... beh, sono stato ben troncato!
Giuseppe,

Sei stato tu a rispondere a questo in MATL :-)
Luis Mendo,

A proposito, penso che tu possa accorciare Z\J2/)( J2/o equivale .5ja end/2quando usato come indice)
Luis Mendo,

Potrebbe valere la pena spiegare il comportamento quando applicato a un numero con un numero dispari di divisori, dal momento che "Index" con un valore non intero non è ovvio.
Kamil Drakari,

@KamilDrakari Com'è?
DJMcMayhem

7

C (gcc) -lm , 35 byte

i;f(n){for(i=sqrt(n);n%i;i--);n=i;}

Provalo online!


2
A proposito, questo funziona solo a causa del riconoscimento di GCC sqrtcome funzione integrata. Con -fno-builtin-sqrt, gcc assume int sqrt(int)e non passa a double. Su x86-64, doubleviene passato in un registro diverso da un numero intero. Su 32 bit, a doubleoccuperebbe 2 slot nello stack, quindi passeresti anche spazzatura (o un subnormale con il numero intero come fondo della mantissa, se i 32 bit superiori fossero zero). Ciò si interrompe anche a meno che non si stia realizzando una build di debug perché si basa sul codice-gen predefinito non ottimizzato di gcc per la valutazione delle espressioni nel registro del valore restituito.
Peter Cordes,

@PeterCordes Sì, è un codice golf, non un dispositivo medico :-)
cleblanc

Beh, non sono un fan dell'hack di ritorno falso. Non è nemmeno più C, è solo un dettaglio dell'implementazione con un'impostazione del compilatore che risulta essere l'impostazione predefinita. (. E 'davvero si estende il "deve lavorare con almeno un'implementazione" regola) Il sqrt()problema è diverso: ero curioso come quello gestito a lavoro, perché il chiamante deve sapere in qualche modo per la conversione inta double. Ho pubblicato la risposta come commento nel caso in cui qualcun altro fosse curioso. In effetti, gcc ha sqrt(incluso il prototipo) come integrato, altrimenti ciò fallirebbe per ragioni che a volte vediamo in SO asm Qs
Peter Cordes,

i;f(n){for(i=0;++i<n/i||n%i;);}è 31B e funziona con gcc -Ox86-64 (costa 2 o 3 byte in più per l'opzione della riga di comando). Usando ||invece di far |sì che gcc lasci il n/irisultato idivin EAX, il registro del valore restituito ( godbolt.org/g/RJYeui ). Il comportamento indefinito da ++isenza punto sequenza sembra funzionare. (L'asm prodotto è sostanzialmente lo stesso della mia risposta al codice macchina x86 .) Con -O0, gcc sembra sempre partire iin EAX, ma forse possiamo usarlo ...
Peter Cordes,

Ad ogni modo, se ti piacciono le risposte ai dettagli di implementazione non-gcc, forse ti piacerà questa risposta gcc x86-64 che sembra funzionare a causa dell'asm prodotto dal compilatore per un comportamento chiaramente indefinito: provalo online! (31 + 2 byte)
Peter Cordes,


5

APL (Dyalog Unicode) , 16 14 12 byte

Sono contento di essere stato in grado di scrivere una risposta in APL poiché l'ho appena appreso. Mille grazie ad Adám per l'aiuto nel golf. Suggerimenti di golf molto graditi. Provalo online!

Per ulteriori informazioni su APL, dai un'occhiata a The APL Orchard .

EDIT: -2 byte per risolvere un problema con il mio codice. Grazie a H.PWiz per aver segnalato questo problema. -2 byte dall'accorciamento di nuovo di tutto.

⌈/{⍳⌊⍵*÷2}∨⊢

Ungolfing

⌈/{⍳⌊⍵*÷2}∨⊢
             GCD of the following...
               The right argument, our input.
  {⍳⌊⍵*÷2}
                 Our input.
      2         To the power of 1/2, i.e. square root.
                 Floor.
                 Indices up to floor(sqrt(input)).
                In total, range from 1 to floor(sqrt(input)).
⌈/            The maximum of the GCDs of our input with the above range.

Perché si barrano in ordine inverso? ... Vedo spesso --- 16 --- --- 14 --- 12, non 12 --- 14 --- --- 16 ---.
user202729

@ user202729 Francamente, è passato un po 'di tempo e ho completamente dimenticato l'ordine di barrato. Risolverà a breve.
Sherlock9,

In realtà non è un problema, lo snippet della classifica supporta entrambi.
user202729

4

Buccia , 4 byte

→←½Ḋ

Provalo online!

Spiegazione

→←½Ḋ
   Ḋ      Divisors of (implicit) input.
  ½       Bisect.
→←        Take the last element of the first half.


3

Codice macchina x86 a 32 bit (IA32): 18 16 byte

log delle modifiche: gestire n=1correttamente il test case, salvare 2 byte e tornare in EAX.

Conta fino a n/i <= i(cioè quando raggiungiamo il sqrt) e usa il primo divisore esatto dopo quello.

Una versione a 64 bit di questo è richiamabile da C con la convenzione di chiamata System86 x86-64, come
int squarish_root_countup(int edi).

nasm -felf32 -l/dev/stdout squarish-root.asm:

58                         DEF(squarish_root_countup)
59                             ; input: n in EDI
60                             ; output: EAX
61                             ; clobbers: eax,ecx,edx
62                         .start:
63 00000025 31C9               xor    ecx, ecx
64                         .loop:                    ; do{
65                         
66 00000027 41                 inc    ecx                ; ++i
67 00000028 89F8               mov    eax, edi
68 0000002A 99                 cdq
69 0000002B F7F9               idiv   ecx                ; edx=n%i    eax=n/i
70                         
71 0000002D 39C1               cmp    ecx, eax
72 0000002F 7CF6               jl     .loop          ; }while(i < n/i
73                                                   ;          || n%i != 0);  // checked below
74                             ; falls through for i >= sqrt(n)
75                             ; so quotient <= sqrt(n) if we get here
76                         
77                                                   ; test edx,edx / jnz  .loop
78 00000031 4A                 dec    edx            ; edx-1 is negative only if edx was zero to start with
79 00000032 7DF3               jge   .loop           ; }while(n%i >= 1);
80                             ; falls through for exact divisors
81                         
82                             ; return value = quotient in EAX
83                         
84 00000034 C3                 ret

           0x10 bytes = 16 bytes.

85 00000035 10             .size: db $ - .start

Provalo online! con un chiamante asm che utilizza direttamente il primo byte di argv [1] come numero intero e utilizza il risultato come stato di uscita del processo.

$ asm-link -m32 -Gd squarish-root.asm && 
for i in {0..2}{{0..9},{a..f}};do 
    printf "%d   " "0x$i"; ./squarish-root "$(printf '%b' '\x'$i)"; echo $?;
done

0   0  # bash: warning: command substitution: ignored null byte in input
1   1
2   1
3   1
4   2
5   1
6   2
7   1
8   2
9   3
10   0       # this is a testing glitch: bash ate the newline so we got an empty string.  Actual result is 2 for n=10
11   1
12   3
13   1
14   2
15   3
16   4
   ...

1
Sei sicuro che n = 1 non sia solo 1? È elencato come test case ed è un divisore ≤ √1 = 1.
qwr

La tua risposta dovrebbe funzionare per 1. Se non funziona con il tuo algoritmo, dovrai codificarlo.
Wheat Wizard

2
@qwr: aggiornato con una versione più breve che funziona per tutti gli input.
Peter Cordes,

2

Japt -h, 8 6 byte

â f§U¬

Provalo

2 byte salvati grazie a Oliver


Spiegazione

           :Implicit input of integer U
â          :Divisors of U
  f        :Filter
   §       :  Less than or equal to
    U¬     :  Square root of U
           :Implicitly get the last element in the array and output it

Le bandiere non costano ancora byte?
mbomb007,

@ mbomb007 No. Ogni istanza di un flag è considerata una nuova lingua.
Oliver,

Non importa. Immagino di non aver ancora visto quel meta post .
mbomb007,



2

Pupazzo di neve , 38 byte

((}1vn2nD`#nPnF|:|NdE|;:,#NMo*|,;bW*))

Provalo online!

((
  }        activate variables b, e, and g
  1vn2nD`  e=1/2
  #        retrieve the input into b
  nP       set b=b^e, which is sqrt(input)
  nF       floor the square root
  |        move b into g so there's space for a while loop
  :        body of the loop
    |NdE|  decrement the value in g
  ;:       loop condition
    ,#     assign b=input, e=current value
    NMo    store the modulo in g
    *|     discard the input value and place the modulo in the condition slot
    ,      put the current value back into g
  ;bW      continue looping while the modulo is nonzero
  *        return the result
))

2

dc , 24

?dsnv1+[1-dlnr%0<m]dsmxp

Provalo online!

Spiegazione:

?                         # read input
 d                        # duplicate
  sn                      # store copy 1 in register n
    v                     # take the square root of copy 2
     1+                   # add 1
       [          ]       # define macro to:
        1-                #   subtract 1
          d               #   duplicate
           ln             #   load from register n
             r            #   reverse top 2 stack members
              %           #   calculate modulo
               0<m        #   if not 0, recursively call macro m again
                   d      # duplicate macro
                    sm    # store copy 1 in register m
                      x   # execute copy 2
                       p  # print final value

2

J, 24 19 byte

-5 byte grazie all'idea GCD di Sherlock

([:>./+.)1+i.@<.@%:

Provalo online!

risposta originale

([:{:]#~0=]|[)1+i.@<.@%:

Provalo online!

parsed

┌───────────────────────────────┬──────────────────────┐
│┌──┬──┬───────────────────────┐│┌─┬─┬────────────────┐│
││[:│{:│┌─┬─────┬─────────────┐│││1│+│┌─────────┬─┬──┐││
││  │  ││]│┌─┬─┐│┌─┬─┬───────┐││││ │ ││┌──┬─┬──┐│@│%:│││
││  │  ││ ││#│~│││0│=│┌─┬─┬─┐│││││ │ │││i.│@│<.││ │  │││
││  │  ││ │└─┴─┘││ │ ││]│|│[││││││ │ ││└──┴─┴──┘│ │  │││
││  │  ││ │     ││ │ │└─┴─┴─┘│││││ │ │└─────────┴─┴──┘││
││  │  ││ │     │└─┴─┴───────┘│││└─┴─┴────────────────┘│
││  │  │└─┴─────┴─────────────┘││                      │
│└──┴──┴───────────────────────┘│                      │
└───────────────────────────────┴──────────────────────┘

spiegazione

  • 1 + i.@<.@%:dà la gamma 1 .. floor(sqrt).
  • l'intero verbo (A) Bforma un hook, con l'intervallo sopra passato come arg destro ]a A e il numero originale passato come arg sinistro [. Così ...
  • ] | [ fornisce il resto di ogni articolo nell'intervallo diviso nell'arg originale.
  • e 0 = ] | [dà ai divisori senza resto.
  • ] #~ ... quindi filtra l'intervallo, lasciando solo quelli.
  • e {:fornisce l'ultimo elemento dell'elenco, ovvero il più grande.



1

QBasic (4.5), 52 byte

INPUT x
FOR i=1TO sqr(x)
if x/i=x\i then m=i
next
?m

1

Forth (gforth) , 53 byte

Il modo più breve sembra usare lo stack in virgola mobile e fsqrt, il più breve che potrei ottenere senza di esso era di 62 byte usando /mode controllando se il quoziente era maggiore del divisore.

: f dup s>f fsqrt f>s 1+ begin 1- 2dup mod 0= until ;

Provalo online!

Spiegazione

  1. Calcola la radice quadrata
  2. A partire dalla radice quadrata, decrementa di 1 fino a trovare un fattore del numero originale

Spiegazione del codice

: f                \ Start a word definition
dup                \ duplicate the input
s>f fsqrt          \ move the number to the float stack and get the square root
f>s                \ truncate result and move to integer stack
1+                 \ add 1 to the square root
begin              \ start indefinite loop
  1- 2dup          \ decrement divisor and duplicate input and divisor
  mod              \ calculate n % divisor
0= until           \ if result equals 0 (no remainder) end the loop
;                  \ end the word definition

1

F #, 55 49 byte

let f x=Seq.findBack(fun i->x%i=0.0){1.0..x**0.5}

Provalo online!

Seq.findBack: Restituisce l'ultimo elemento per il quale restituisce la funzione specificata True. La funzione in questo caso controlla se un numero è un fattore del valore.


1

Brain-Flak , 144 byte

{({}{}<<>({}<>)<>([({})()]<>({}(<>)())){(<{}({}[()]{}<({}())>)>)}{}((({}<>)<>(({})))[({}[{}])])>[({<({}[()])><>({})<>}{}<><{}>)])}{}{}<>{}({}<>)

Provalo online!

Non sono davvero sicuro che questa risposta sia molto buona. Sento che potrebbe esserci un buon modo per risolvere questo compito, ma non sono abbastanza intelligente.

Spiegazione

Ho provato a fare una vista esplosa della risposta, ma ci sono così tante parti mobili che non era molto illuminante, quindi ecco una spiegazione di ciò che fa il codice.

Il primo bit importante è questo

({}<>)<>([({})()]<>({}(<>)())){(<{}({}[()]{}<({}())>)>)}{}

(X,y)Xy

La parte successiva è la moltiplicazione, presa con modifiche dal wiki . Questa moltiplicazione è speciale perché conserva i valori esistenti senza distruggerli. Va come:

((({}<>)<>(({})))[({}[{}])])({<({}[()])><>({})<>}{}<><{}>)

Quindi stiamo moltiplicando tutte queste coppie ordinate. Per ogni risultato controlliamo se è uguale all'input. In tal caso, terminiamo e restituiamo l'articolo più piccolo nella coppia.





0

Ruggine, 71 70 byte

fn f(x:u64)->u64{let mut l=(x as f64).sqrt()as u64;while x%l>0{l-=1}l}

Versione preconfezionata

fn f(x: u64) -> u64 {                    // function takes u64, gives u64
  let mut l = (x as f64).sqrt() as u64;  // l takes integer'ed root value
  while x % l > 0 {                      // loop while l leaves remainder
    l -= 1                               // decrement
  }
  l                                      // return the found value
}

Le modifiche

  • Salva un byte con > 0over != 0. (Grazie a @CatWizard)

Può !=essere sostituito con >?
Wheat Wizard

Ottima scelta! Sì.
hunteke,



0

Pyret , 93 byte

{(z):rec f={(i,x):if num-modulo(i, x) == 0:x else:f(i,x - 1)end}
f(z,num-floor(num-sqrt(z)))}

Puoi provarlo online copiandolo nell'editor online di Pyret !

Quanto sopra restituisce una funzione anonima. Quando viene applicato a un numero intero, restituisce un risultato in base alle specifiche.


0

In realtà , 7 byte

Basato sulla mia risposta APL qui . Suggerimenti di golf benvenuti! Provalo online!

;√LR♀gM

Ungolfing

;√LR♀gM  Implicit input n
;        Duplicate n
 √       sqrt(n)
  L      floor(sqrt(n))
   R     1..floor(sqrt(n))
    ♀g   gcd(n, foreach(1..floor(sqrt(n)))
      M  The maximum of the GCDs.
         Return this maximum.

0

Una porta di questa risposta di Mathematica .

Gelatina , 11 byte

½ðḞ³÷Ċ³÷µÐL

Provalo online!

Anche questo (11 byte) funziona e non dipende da ³:

½Ḟ÷@Ċ÷@ʋƬµṪ

Sfortunatamente ½Ḟ÷@Ċ÷@ʋÐL(10 byte) non funziona. E apparentemente Ƭe ÐĿnon è esattamente lo stesso (quando il collegamento è diadico)


n

  • io=nun'
  • Ad ogni passo:
    • ioio
    • nioun'ionun'nionun'nioun'n÷nio
  • ion÷nio

0

Java 8, 65 54 byte

n->{int r=(int)Math.sqrt(n);for(;n%r>0;r--);return r;}

Python 3 di Port of @hunteke .

Provalo online.


Risposta a 65 byte precedenti:

n->{int r=1,i=n;for(;i-->1;)r=n%i<1&n/i<=i&n/i>r?n/i:r;return r;}

Provalo online.

Spiegazione:

n->{                // Method with integer as both parameter and return-type
  int r=1,          //  Result-integer, starting at 1
  i=n;for(;i-->1;)  //  Loop `i` in the range (n, 1]
    r=n%i<1         //   If `n` is divisible by `i`,
      &n/i<=i       //   and if `n` divided by `i` is smaller than or equal to `i` itself,
      &n/i>r?       //   and if `n` divided by `i` is larger than the current `r`
       n/i          //    Set `n` divided by `i` as the new result `r`
      :             //   Else:
       r;           //    Leave result `r` unchanged
  return r;}        //  Return the result `r`
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.