查找方根


19

编写代码给定一个正数时,为输入,输出的最大的正除数小于或等于的平方根。xxx

换句话说,找到最大的n>0使得

mn:mn=x

(存在m大于或等于n,使得m乘以nx


例如,如果输入是12的约数是12346,和12123的所有乘以较大的数字得到12,而3是最大的,所以我们返回3


这是因此答案将以字节计分,而较少的字节被视为更好的计分。

测试用例

(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
我看不出由于较老的不活跃问题而造成的封闭式热门问题对网站有何帮助??如果您发现得早,可以肯定,继续进行锤击。如果答案的数量是旧答案的两倍,并且投票数更多。保留它,如果有的话,关闭另一个...
Stewie Griffin

@StewieGriffin“热门问题”的一个问题是他们在HNQ上。这可能不是一件好事。/我也看不出它对网站有何危害,您只需将答案移至旧版本即可。
user202729

5
HNQ可能会吸引新用户,这是一件好事(IMO)。
Stewie Griffin

1
@qwr但是核心思想是相同的。差别很小。每个挑战中的方法都可以用于其他挑战。
user202729

1
@ Hand-E-Food我不认为这是不同的。实际上,我确实相信两者具有相同的内容。我关闭您的问题的原因与线程顶部评论中的原因相同,该问题有更多答案。如果您想在这里询问,请在这里找到 meta 。您可能对此也有兴趣。
小麦巫师

Answers:


10

Python349个 47字节

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

说明

  • l=x**.5//1→分配l小于等于的平方根的最大整数x
  • while x%l:l-=1→虽然l没有平均分配x,但递减l

编辑

  • 提及Python3,而不是Python2
  • 使用...//1保存两个字节。(小数还可以!谢谢@Rod)

欢迎使用PPCG,不错的第一答案!您可以通过使用节省几个字节input/ print不是def/ return,你也可以替换int(...)使用...//1,以节省更多的字节你可以看到在这里
罗德

@Rod不是// 1,正如我所说的Python3。(除非输出没有小数,否则我认为不是。)但是对于Python2,谢谢!
hunteke

@hunteke十进制输出很好,我看不到任何不应该的原因。
小麦巫师

用“ For”代替“ While”会更短一些,以便您可以在条件中分配值,可能避免定义“ l”?
Malady

8

MATL,7个字节

Z\tn2/)

在线尝试!

为了便于说明,我们将使用“ 12”作为样本输入。说明:

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

之所以如此,是因为有很多幸运的巧合。

  1. MATL使用1索引
  2. 如果我们有一个非整数索引(这将对于任何完全平方输入发生),那么<n>)将索引ñ

1
......好吧,我一直被惊呆了!
朱塞佩

必须是您在MATL中回答了这个问题:-)
Luis Mendo

顺便说一句,我认为你可以缩短Z\J2/)J2/或等效.5j表示end/2作为索引使用)
路易斯Mendo

应用于除数奇数的数字时的行为可能是值得解释的,因为带有非整数值的“索引”并不明显。
卡米尔·德拉卡里

@KamilDrakari怎么样?
DJMcMayhem

7

C(gcc) -lm,35个字节

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

在线尝试!


2
顺便说一句,这仅是由于GCC将其识别sqrt为内置功能而起作用。使用时-fno-builtin-sqrt,gcc会假设int sqrt(int)并且不会通过double。在x86-64上,double传递给与整数不同的寄存器。在32位上,a double将在堆栈上占用2个插槽,因此您还将传递垃圾(如果高32位为零,则将传递垃圾(如果为尾数,则为整数)。除非您要进行调试构建,否则这也会中断,因为它依赖gcc的默认未优化代码生成来评估返回值寄存器中的表达式。
彼得·科德斯

@PeterCordes是的,这是代码高尔夫球,而不是医疗器械:-)
cleblanc

好吧,我不喜欢假冒回报黑客。甚至不再是C,它只是一个实现细节,其中一个编译器设置恰好是默认设置。(这实际上是在扩展“必须与至少一个实现一起使用”的规则。)sqrt()问题有所不同:我很好奇它是如何工作的,因为调用者必须以某种方式知道要转换intdouble。如果有人好奇,我将答案作了评论。有效GCC有sqrt(其中包括原型)作为一个内置的,否则这将失败的原因,我们在这样ASM Qs的有时会看到
彼得·柯德斯

i;f(n){for(i=0;++i<n/i||n%i;);}是31B,并且可以gcc -O在x86-64上使用(在命令行选项中花费2或3个字节)。使用返回值寄存器(godbolt.org/g/RJYeui||代替|gcc将n/i结果保留idiv在EAX中)。没有序列点的未定义行为恰好起作用。(产生的asm与我的x86机器代码答案基本相同。)使用,gcc似乎总是保留在EAX中,但也许我们可以使用它……++i-O0i
Peter Cordes

无论如何,如果您喜欢非C gcc实现细节的答案,也许您会喜欢这个x86-64 gcc答案,因为它由编译器针对明显未定义的行为生成的asm碰巧起作用了:在线尝试!(31 + 2个字节)
Peter Cordes


5

APL(Dyalog Unicode)16 14 12字节

我很高兴能够在APL中写一些答案,因为我才刚刚学到它。非常感谢Adám打高尔夫球。打高尔夫球的建议非常受欢迎。在线尝试!

要了解有关APL的更多信息,请查看The APL Orchard

编辑: -2字节来解决我的代码的问题。感谢H.PWiz指出了这个问题。-2字节再次缩短了所有内容。

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

开球

⌈/{⍳⌊⍵*÷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.

您为什么以相反的顺序删除线?...我经常看到--- 16 --- --- 14 --- 12,而不是12 --- 14 --- --- 16 ---。
user202729

@ user202729坦白地说,已经有一段时间了,我完全忘记了删除线的顺序。会尽快修复。
Sherlock18年

实际上这不是问题,排行榜代码片段都支持。
user202729

4

外壳,4个字节

→←½Ḋ

在线尝试!

说明

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


3

x86 32位(IA32)机器代码:18 16字节

changelog:n=1正确处理测试用例,保存2个字节,然后以EAX返回。

数到n/i <= i(即到达sqrt时),然后使用第一个精确除数。

可以使用x86-64 System V调用约定从C调用此版本的64位版本
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

在线尝试!与一个asm调用程序,该调用程序直接将argv [1]的第一个字节用作整数,并将结果用作进程退出状态。

$ 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
您确定n = 1不仅是1吗?它被列为测试用例,它是除数≤√1=
1。– qwr

您的答案应该适用于1。如果它不适用于您的算法,那么您将不得不对其进行硬编码。
小麦巫师

2
@qwr:更新为适用于所有输入的较短版本。
彼得·科德斯

2

Japt -h8 6字节

â f§U¬

尝试一下

由于使用了Oliver,节省了2个字节


说明

           :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

标记仍然不消耗字节吗?
mbomb007 '18

@ mbomb007否。标志的每个实例均被视为新的语言条目。
奥利弗

没关系。我想我还没有看到该元发布
mbomb007



2

雪人,38个字节

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

在线尝试!

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

直流 24

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

在线尝试!

说明:

?                         # 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字节

-5字节归功于Sherlock的GCD想法

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

在线尝试!

原始答案

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

在线尝试!

解析

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

说明

  • 1 + i.@<.@%:给出范围1 .. floor(sqrt)
  • 整个动词(A) B组成一个钩子,以上范围作为右arg传递]给A,原始数字作为左arg传递[。从而...
  • ] | [ 给出范围内每个项目的剩余部分,并分为原始arg。
  • 0 = ] | [给出除数没有余数
  • ] #~ ... 然后过滤范围,仅保留那些范围。
  • {:给出列表中的最后一项,即最大的一项。


1

Haskell,36个字节

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

在线尝试!

ÿ[1..]ž[1..y]ÿžÿž

ÿž=XXÿžÿž

žž


1

QBasic(4.5),52字节

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

1

第四(gforth),53字节

最短的方法似乎是使用浮点堆栈fsqrt,而使用/mod并检查商是否大于除数,我可以获得的最短长度是62个字节。

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

在线尝试!

说明

  1. 计算平方根
  2. 从平方根开始,递减1,直到找到原始数的因数

代码说明

: 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字节

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

在线尝试!

Seq.findBack:返回给定函数返回的最后一个元素True。在这种情况下,该函数检查数字是否是该值的因数。


1

Brain-Flak,144字节

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

在线尝试!

我不太确定这个答案是否很好。我觉得可能有解决这个问题的好方法,但是我还不够聪明。

说明

我试图对答案进行分解,但是有太多的活动部分,并不是很有启发性,所以这里是对代码功能的解释。

最重要的一点是

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

XÿXÿ

下一部分是乘法,对Wiki进行了修改。这种乘法之所以特别,是因为它保留了现有的值而不破坏它们。就像这样:

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

因此,我们将所有这些有序对相乘。对于每个结果,我们检查它是否等于输入。如果是这样,我们终止并返回一对中较小的物品。





0

锈,71 70字节

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

预丑版

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
}

编辑

  • > 0over 保存一个字节!= 0。(感谢@CatWizard)

可以!=代替>吗?
小麦巫师

好决定!是。
hunteke



0

Pyret,93个字节

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

您可以通过将其复制到在线Pyret编辑器中来在线尝试

上面的结果为一个匿名函数。当将其应用于整数时,它将根据规范返回结果。


0

其实,7个字节

根据我的APL答案。欢迎打高尔夫球!在线尝试!

;√LR♀gM

开球

;√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

Mathematica答案的端口。

果冻,11字节

½ðḞ³÷Ċ³÷µÐL

在线尝试!

这(11个字节)也可以使用,并且不依赖于³

½Ḟ÷@Ċ÷@ʋƬµṪ

不幸的是½Ḟ÷@Ċ÷@ʋÐL(10个字节)不起作用。显然ƬÐĿ是不完全一样的(当链路二元)


ñ

  • 一世=ñ一种
  • 在每一步:
    • 一世一世(因为结果必须是整数)
    • ñ一世一种一世ñ一种ñ一世ñ一种ñ一世一种ñ÷ñ一世
  • 一世ñ÷ñ一世

0

Java 8,65 54字节

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

@hunteke的Python 3答案端口。

在线尝试。


旧的65个字节的答案:

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

在线尝试。

说明:

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`
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.