Trouver la racine carrée

19

Écrivez du code qui, lorsqu'il reçoit un nombre positif en entrée, génère le plus grand diviseur positif de x inférieur ou égal à la racine carrée de x .xxx

En d'autres termes, trouvez le plus grand tel quen>0

mn:mn=x

(Existe supérieur ou égal à n tel que m fois n soit x )mnmnx


Par exemple, si l'entrée était les diviseurs sont 1 , 2 , 3 , 4 , 6 et 12 . 1 , 2 et 3 multiplient tous par de plus grands nombres pour obtenir 12 , mais12123461212312 étant le plus grand, nous retournons donc 3 .33


Il s'agit de donc les réponses seront notées en octets, moins d'octets étant considérés comme un meilleur score.

Cas de 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

Assistant de blé
la source
11
Je ne vois pas comment la fermeture de questions populaires car les dupes d'anciennes inactives aident le site ...? Si vous le remarquez tôt, bien sûr, allez-y et martelez-le. S'il a deux fois plus de réponses et plus de votes positifs que l'ancien. Gardez-le, et si quelque chose, fermez l'autre ...
Stewie Griffin
@StewieGriffin Un problème avec les "questions populaires" est qu'elles sont sur HNQ. Ce qui n'est probablement pas une très bonne chose. / Je ne vois pas non plus comment cela nuit au site, vous pouvez simplement déplacer les réponses vers l'ancienne.
user202729
5
Le HNQ pourrait attirer de nouveaux utilisateurs, et c'est une bonne chose (IMO).
Stewie Griffin
1
@qwr Mais l'idée centrale est la même. La différence est très faible. La méthode de chaque défi peut être utilisée pour un autre.
user202729
1
@ Hand-E-Food Je ne prétends pas que celui-ci est différent. En fait, je crois que les deux ont le même contenu. Mes raisons pour la fermeture de votre question sont les mêmes que celles du commentaire en haut du fil, cette question a plus de réponses. La méta est si vous souhaitez y demander. Vous pouvez également vous intéresser à cela .
Wheat Wizard

Réponses:

10

Python3 , 49 47 octets

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

Explication

  • l=x**.5//1 → Attribuer l le plus grand entier inférieur à égal à la racine carrée dex
  • while x%l:l-=1→ Tandis que lne se divise pas uniformément x, décrémenter l.

Modifications

  • Mentionnez Python3, pas Python2
  • Utilisez ...//1pour enregistrer deux octets. (Les décimales vont bien! Merci @Rod)
hunteke
la source
Bienvenue chez PPCG, belle première réponse! Vous pouvez enregistrer quelques octets en utilisant input/ à la printplace def/ return, vous pouvez également remplacer int(...)par ...//1pour enregistrer plus d'octets comme vous pouvez le voir ici
Rod
@Rod pas // 1, comme je l'ai dit, ont dit Python3. (À moins que les décimales soient correctes pour la sortie, ce que je ne pensais pas.) Mais pour Python2, merci!
hunteke
@hunteke La sortie décimale est correcte, je ne vois aucune raison pour laquelle elle ne devrait pas l'être.
Wheat Wizard
Serait-il plus court avec "For" au lieu de "While", afin que vous puissiez affecter des valeurs au conditionnel, évitant éventuellement de définir "l"?
Malady
8

MATL , 7 octets

Z\tn2/)

Essayez-le en ligne!

Pour cette explication, nous utiliserons «12» comme exemple d'entrée. Explication:

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

Cela fonctionne en raison de nombreuses coïncidences heureuses.

  1. MATL utilise 1 indexation
  2. Si nous index avec un non entier (ce sera le cas pour toute entrée carré parfait), puis <n>)indexera n
DJMcMayhem
la source
1
...... eh bien j'ai été profondément trompé!
Giuseppe
Ce devait être vous qui avez répondu à cela en MATL :-)
Luis Mendo
BTW Je pense que vous pouvez raccourcir Z\J2/)( J2/ou équivaut .5jà end/2lorsqu'il est utilisé comme index)
Luis Mendo
Il pourrait être utile d'expliquer le comportement lorsqu'il est appliqué à un nombre avec un nombre impair de diviseurs, car "Index" avec une valeur non entière n'est pas évident.
Kamil Drakari
@KamilDrakari Comment est-ce?
DJMcMayhem
7

C (gcc) -lm , 35 octets

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

Essayez-le en ligne!

cleblanc
la source
2
BTW, cela ne fonctionne que grâce à la reconnaissance par GCC d' sqrtune fonction intégrée. Avec -fno-builtin-sqrt, gcc suppose int sqrt(int)et ne passe pas a double. Sur x86-64, doubleest passé dans un registre différent d'un entier. Sur 32 bits, a doubleprendrait 2 emplacements sur la pile, vous passeriez donc également des ordures (ou une sous-normale avec l'entier comme bas de la mantisse, si les 32 bits supérieurs étaient zéro). Cela casse également, sauf si vous effectuez une génération de débogage, car il repose sur le code-gen non optimisé par défaut de gcc pour évaluer les expressions dans le registre de valeur de retour.
Peter Cordes
@PeterCordes Yes, it's code golf, not a medical device :-)
cleblanc
Well I'm not a fan of the fake-return hack. That's not even C anymore, it's just an implementation detail with one compiler setting which happens to be the default. (It's really stretching the "has to work with at least one implementation" rule.) The sqrt() issue is different: I was curious how that managed to work, because the caller has to somehow know to convert int to double. I posted the answer to that as a comment in case anyone else was curious. Effectively gcc has sqrt (including prototype) as a built-in, otherwise this would fail for reasons we sometimes see in SO asm Qs
Peter Cordes
i;f(n){for(i=0;++i<n/i||n%i;);} is 31B, and works with gcc -O on x86-64 (costing 2 or 3 more bytes for the command line option.) Using || instead of | causes gcc to leave the n/i result from idiv in EAX, the return-value register (godbolt.org/g/RJYeui). The undefined-behaviour from ++i without a sequence point happens to work. (The asm produced is basically the same as my x86 machine code answer.) With -O0, gcc always seems to leave i in EAX, but maybe we can use that...
Peter Cordes
Anyway, if you like non-C gcc implementation-details answers, maybe you'll like this x86-64 gcc answer that happens to work because of the asm produced by the compiler for clearly undefined behaviour: Try it online! (31+2 bytes)
Peter Cordes
5

05AB1E, 5 bytes

Ñ2äнθ

Try it online! or as a Test suite

Explanation

Ñ        # push the list of divisors
 2ä      # split it into 2 parts
   н     # take the first haft
    θ    # take the last element of that
Emigna
la source
5

APL (Dyalog Unicode), 16 14 12 bytes

I'm glad I was able to write some answer in APL since I only just learned it. Many, many thanks to Adám for help with golfing. Golfing suggestions very much welcome. Try it online!

To learn more about APL, take a look at The APL Orchard.

EDIT: -2 bytes to fixing a problem with my code. Thanks to H.PWiz for pointing out that problem. -2 bytes from shortening everything again.

⌈/{⍳⌊⍵*÷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.
Sherlock9
la source
Why do you strikethrough in reverse order? ... I often see ---16--- ---14--- 12, not 12 ---14--- ---16---.
user202729
@user202729 Frankly, it's been a while, and I quite forgot the order of strikethrough. Will fix it shortly.
Sherlock9
Actually it's not a problem, the leaderboard snippet supports both.
user202729
4

Husk, 4 bytes

→←½Ḋ

Try it online!

Explanation

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

la source
3

Code machine x86 32 bits (IA32): 18 16 octets

changelog: gérer n=1correctement le cas de test, enregistrer 2 octets et retourner dans EAX.

Comptez jusqu'à n/i <= i(c'est-à-dire lorsque nous atteignons le sqrt), et utilisez le premier diviseur exact après cela.

Une version 64 bits de ceci est appelable depuis C avec la convention d'appel System V x86-64, comme
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

Essayez-le en ligne! avec un appelant asm qui utilise directement le premier octet d'argv [1] comme entier et utilise le résultat comme état de sortie du processus.

$ 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
   ...
Peter Cordes
la source
1
Êtes-vous sûr que n = 1 n'est pas seulement 1? Il est répertorié comme un cas de test et c'est un diviseur ≤ √1 = 1.
qwr
Votre réponse devrait fonctionner pour 1. Si cela ne fonctionne pas avec votre algorithme, vous devrez le coder en dur.
Wheat Wizard
2
@qwr: mis à jour avec une version plus courte qui fonctionne pour toutes les entrées.
Peter Cordes
2

Japt -h, 8 6 octets

â f§U¬

Essayez-le

2 octets économisés grâce à Oliver


Explication

           :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
Shaggy
la source
Don't flags still cost bytes?
mbomb007
@mbomb007 No. Each instance of a flag is considered a new language entry.
Oliver
Never mind. I guess I hadn't seen that meta post yet.
mbomb007
2

Snowman, 38 bytes

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

Try it 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
))
Doorknob
la source
2

dc, 24

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

Try it online!

Explanation:

?                         # 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
Digital Trauma
la source
2

J, 24 19 bytes

-5 bytes thanks to Sherlock's GCD idea

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

Try it online!

original answer

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

Try it online!

parsed

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

explanation

  • 1 + i.@<.@%: gives the range 1 .. floor(sqrt).
  • the entire verb (A) B forms a hook, with the above range passed as the right arg ] to A and the original number passed as its left arg [. Thus...
  • ] | [ gives the remainer of each item in the range divided into the original arg.
  • and 0 = ] | [ gives the divisors with no remainder.
  • ] #~ ... then filters the range, leaving only those.
  • and {: gives the last item in the list, ie, the largest one.
Jonah
la source
1

Haskell, 36 bytes

f x=[z|y<-[1..],z<-[1..y],y*z==x]!!0

Try it online!

Well this is my answer to this challenge. This uses a particular list comprehension to find the answer. In our list comprehension we pick y from the infinite list [1..] that is the positive integers, and we pick z from the list [1..y]. This means that (y,z) is all the ordered pairs such that yz.

We then select only those pairs such that yz=x, meaning that we make the list of all pairs of numbers that multiply to x. Now since our comprehension is based first on y and then z this means that our pairs are in ascending order of y, or more usefully in descending order of z.

So to get the largest z we take the z belonging to the first element. This is our result.

Wheat Wizard
la source
1

QBasic (4.5), 52 bytes

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

Forth (gforth), 53 bytes

The shortest way seems to be using the floating point stack and fsqrt, the shortest I could get without it was 62 bytes using /mod and checking if the quotient was greater than the divisor.

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

Try it online!

Explanation

  1. Calculate the square root
  2. Starting at the square root, decrement by 1 until we find a factor of the original number

Code Explanation

: 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
reffu
la source
1

F#, 55 49 bytes

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

Try it online!

Seq.findBack: Returns the last element for which the given function returns True. The function in this case checks to see if a number is a factor of the value.

Ciaran_McCarthy
la source
1

Brain-Flak, 144 bytes

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

Try it online!

I'm not really sure this answer is very good. I feel like there may be a nice way to solve this task however I'm just not clever enough.

Explanation

I tried to do an exploded view of the answer but there are so many moving parts it was not very enlightening, so here is an explanation of what the code does.

The first important bit is this

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

This takes the two numbers on top of the stack and if they are unequal increments the second one, if they are equal it increments the first one and replaces the second one with zero. If we repeat this code a bunch we will get all the pairs (x,y) such that xy.

The next part is multiplication, taken with modification from the wiki. This multiplication is special because it preserves the existing values without destroying them. It goes like:

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

So we are multiplying all these ordered pairs. For each result we check if it is equal to the input. If so we terminate and return the smaller item in the pair.

Wheat Wizard
la source
0

Rust, 71 70 bytes

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

Pre-uglified version

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
}

Edits

  • Save a byte with > 0 over != 0. (Thanks to @CatWizard)
hunteke
la source
Can != be replaced with >?
Wheat Wizard
Good call! Yes.
hunteke
0

Pyret, 93 bytes

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

You can try this online by copying it into the online Pyret editor!

The above evaluates to an anonymous function. When it is applied to an integer, it returns a result according to the specification.

Tango
la source
0

Actually, 7 bytes

Based on my APL answer here. Golfing suggestions welcome! Try it 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.
Sherlock9
la source
0

A port of this Mathematica answer.

Jelly, 11 bytes

½ðḞ³÷Ċ³÷µÐL

Try it online!

This (11 bytes) also works, and don't depend on ³:

½Ḟ÷@Ċ÷@ʋƬµṪ

Unfortunately ½Ḟ÷@Ċ÷@ʋÐL (10 bytes) doesn't work. And apparently Ƭ and ÐĿ is not exactly the same (when the link is dyadic)


Method: (let n be the input)

  • Start with an upper bound i=n of the answer a.
  • At each step:
    • If i is not an integer, then the upper bound can be made i (because the result must be an integer)
    • If ni is not an integer, then ainaninanian÷ni.
  • So we repeatedly replace i with n÷ni until it's fixed.
user202729
la source
0

Java 8, 65 54 bytes

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

Port of @hunteke's Python 3 answer.

Try it online.


Old 65 bytes answer:

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

Try it online.

Explanation:

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`
Kevin Cruijssen
la source