제곱근 찾기


19

양수 주어진 때 쓰기 코드 x 입력으로, 가장 큰 양의 약수로 출력 x 이하의 제곱근과 동일 x .

즉 가장 큰 찾을에서 그러한를n>0

mn:mn=x

(존재 초과하거나 동일한 되도록 시간 N 이고 X )mnmnx


예를 들어 입력이 경우 제수는 1 , 2 , 3 , 4 , 612 입니다. 1 , 23은 모두 12 를 얻기 위해 더 큰 숫자를 곱 하지만 3 이 가장 크므 로 3 을 반환 합니다.1212346121231233


이것은 이므로 답은 더 적은 바이트로 더 나은 점수로 간주됩니다.

테스트 사례

(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 나는 이것이 다르다고 주장하지 않습니다. 사실 나는 두 사람이 같은 내용을 가지고 있다고 생각합니다. 귀하의 질문을 폐쇄 한 이유는 스레드 상단의 주석에있는 것과 동일합니다.이 질문에는 더 많은 답변이 있습니다. 당신이 거기에 묻고 싶다면 메타가 여기 있습니다. 이것에 관심 있을 수도 있습니다 .
밀 마법사

답변:


10

Python3 , 49 47 바이트

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

설명

  • l=x**.5//1l가장 큰 정수를 제곱근보다 작게 지정하십시오 .x
  • while x%l:l-=1l균등하게 나누지는 않지만 줄어 x듭니다 l.

편집

  • Python2가 아니라 Python3을 언급
  • ...//12 바이트를 저장하는 데 사용 합니다. (소수자는 괜찮습니다! 감사합니다 @Rod)

PPCG에 오신 것을 환영합니다. 좋은 첫 답변입니다! 당신은을 사용하여 몇 바이트를 저장할 수 input/ print대신에 def/ return, 당신은 또한 대체 할 수 int(...)와 함께 ...//1당신이 볼 수있는 더 바이트를 저장하는 여기
로드

@Rod not // 1, Python3이 말했듯이. (소수점은 출력에 괜찮지 않으면 그렇게 생각하지 않았습니다.) 그러나 Python2의 경우 감사합니다!
hunteke

@hunteke Decimal 출력은 괜찮습니다. 그렇지 않아야 할 이유가 없습니다.
밀 마법사

"While"대신 "For"를 사용하면 더 짧아 지므로 조건부에서 값을 할당하여 "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>)색인 n

1
...... 잘 소리가 났어요!
주세페

MATL :-)에서 응답 한 사람은 다음과 같습니다.
Luis Mendo

BTW 나는 당신이 단축 할 수 있다고 생각합니다 Z\J2/)( J2/또는 색인으로 사용될 때 동등하게 .5j의미합니다 end/2)
Luis Mendo

정수가 아닌 값을 가진 "인덱스"는 분명하지 않기 때문에 홀수의 제수를 가진 숫자에 적용될 때 동작을 설명하는 것이 좋습니다.
Kamil Drakari

@KamilDrakari 어때요?
DJMcMayhem

7

C (gcc) -lm , 35 바이트

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

온라인으로 사용해보십시오!


2
BTW, 이것은 GCC가 sqrt내장 함수로 인식했기 때문에 작동 합니다. 로 -fno-builtin-sqrt, GCC는 가정 int sqrt(int)및 전달하지 않습니다 double. x86-64에서는 double정수가 아닌 다른 레지스터로 전달됩니다. 32 비트에서 a double는 스택에서 2 개의 슬롯을 차지하므로 가비지 (또는 상위 32 비트가 0 인 경우 가수의 맨 아래로 정수를 가진 하위 표준)도 전달합니다. 또한 리턴 값 레지스터에서 표현식을 평가하는 gcc의 기본 최적화되지 않은 코드 생성에 의존하기 때문에 디버그 빌드를 작성하지 않는 한 중단됩니다.
Peter Cordes

@PeterCordes 네, 의료 기기가 아닌 코드 골프입니다. :-)
cleblanc

글쎄, 난 가짜 반환 해킹의 팬이 아니야. 그것은 더 이상 C가 아니며 기본값 인 하나의 컴파일러 설정으로 구현 세부 사항 일뿐입니다. (실제로 "적어도 하나의 구현으로 작업해야 함"규칙을 확장하고 있습니다.) sqrt()문제는 다릅니다. 호출자가로 변환 int해야한다는 것을 알고 있기 때문에 어떻게 작동했는지 궁금 했습니다 double. 다른 사람이 궁금한 경우에 대한 답변으로 의견을 게시했습니다. 효과적으로 gcc는 sqrt내장형으로 프로토 타입을 포함합니다. 그렇지 않으면 SO asm Qs에서 볼 수있는 이유로 실패 할 것입니다.
Peter Cordes

i;f(n){for(i=0;++i<n/i||n%i;);}(31B), 그리고 작동 gcc -O사용 - 64은 (명령 행 옵션 2 또는 3 바이트 이상을 요.)에 ||대신 |나가기 위해 GCC 원인 n/i에서 결과를 idiv(EAX, 반환 값 레지스터에 godbolt.org/g/RJYeui ). ++i시퀀스 포인트가없는 정의되지 않은 동작 이 작동합니다. (생산 된 asm은 기본적으로 내 x86 기계 코드 답변 과 동일합니다 .) -O0gcc는 항상 iEAX 에 그대로 있는 것처럼 보이지만 아마도 우리는 그것을 사용할 수 있습니다 ...
Peter Cordes

어쨌든, 비 C gcc 구현 세부 정보 답변을 좋아한다면 명확하게 정의되지 않은 동작을 위해 컴파일러가 생성 한 asm 때문에 작동하는이 x86-64 gcc 답변을 원할 것입니다. 온라인으로 사용해보십시오! (31 + 2 바이트)
Peter Cordes 2016 년


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.

왜 역순으로 취소합니까? ...------------------------------------------------------------ 12 --- 14 ------- 16 ---.
user202729

@ user202729 솔직히, 그것은 오랜 시간이었고, 나는 취소 선의 명령을 잊어 버렸습니다. 곧 고칠 것입니다.
Sherlock9

실제로 문제는 아닙니다. 리더 보드 스 니펫은 두 가지를 모두 지원합니다.
user202729



3

x86 32 비트 (IA32) 기계 코드 : 18 16 바이트

changelog : n=1테스트 케이스를 올바르게 처리하고 2 바이트를 저장 한 후 EAX로 리턴하십시오.

때까지 n/i <= i(즉, sqrt에 도달 할 때 까지) 카운트 한 후 첫 번째 정확한 제수를 사용하십시오.

이것의 64 비트 버전은 x86-64 System V 호출 규칙을 사용하여 C에서 호출 할 수
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

온라인으로 사용해보십시오! argv [1]의 첫 번째 바이트를 정수로 직접 사용하고 결과를 프로세스 종료 상태로 사용하는 asm 호출자가 있습니다.

$ 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에 효과가 있습니다. 알고리즘에서 작동하지 않으면 하드 코딩해야합니다.
위트 마법사

2
@qwr : 모든 입력에서 작동하는 더 짧은 버전으로 업데이트되었습니다.
Peter Cordes 2016 년

2

Japt -h, 8 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

@ mbomb007 아니요. 플래그의 각 인스턴스는 새로운 언어 항목으로 간주됩니다.
Oliver

신경 쓰지 마. 나는 그 메타 포스트를 아직 보지 못했다고 생각한다 .
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

dc , 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 바이트

Sherlock의 GCD 아이디어 덕분에 -5 바이트

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

온라인으로 사용해보십시오!

원래 답변

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

온라인으로 사용해보십시오!

파싱

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

설명

  • 1 + i.@<.@%:범위를 제공합니다 1 .. floor(sqrt).
  • 전체 동사 (A) B는 후크를 형성하며, 위의 범위는 오른쪽 arg ]로 전달되고 원래 숫자는 왼쪽 arg로 전달됩니다 [. 그러므로...
  • ] | [ 범위에서 각 항목의 나머지를 원래 인수로 나눈 값을 제공합니다.
  • 그리고 0 = ] | [나눗셈에 나머지를 제공하지 않습니다.
  • ] #~ ... 그런 다음 범위 만 필터링하여 해당 범위 만 남겨 둡니다.
  • {:목록, 즉, 가장 큰 하나의 마지막 항목을 제공합니다.




1

4 번째 (2 번째) , 53 바이트

가장 짧은 방법은 부동 소수점 스택을 사용하는 것 같고 몫이 제수보다 큰지 확인하고 fsqrt사용하지 않고 62 바이트를 사용하지 않고 얻을 수있는 가장 짧은 방법 /mod입니다.

: 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

Brain-Flak , 144 바이트

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

온라인으로 사용해보십시오!

나는이 대답이 매우 좋다는 것을 확신하지 못한다. 이 작업을 해결할 수있는 좋은 방법이 있다고 생각하지만 충분히 영리하지는 않습니다.

설명

답을 분해하여 보려고 시도했지만 너무 밝지 않은 움직이는 부분이 너무 많아서 코드의 기능에 대한 설명이 있습니다.

가장 중요한 것은 이것입니다

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

이것은 스택 위에 두 숫자를 취하고 두 숫자가 같지 않으면 두 번째 숫자를 증가시키고, 같으면 첫 번째 숫자를 증가시키고 두 번째 숫자를 0으로 대체합니다. 이 코드를 반복하면 모든 쌍을 얻습니다.(엑스,와이) 그런 엑스와이.

다음 부분은 위키 에서 수정 한 곱셈 입니다 . 이 곱셈은 기존 값을 손상시키지 않고 보존하기 때문에 특별합니다. 다음과 같습니다.

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

그래서 우리는이 모든 순서 쌍을 곱하고 있습니다. 각 결과에 대해 입력과 같은지 확인합니다. 그렇다면 더 작은 품목을 종료하고 쌍으로 반품하십시오.





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

피 레트 , 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

이 Mathematica 답변 의 포트 .

젤리 , 11 바이트

½ðḞ³÷Ċ³÷µÐL

온라인으로 사용해보십시오!

이 (11 바이트)도 작동하며 다음에 의존하지 않습니다 ³.

½Ḟ÷@Ċ÷@ʋƬµṪ

불행히도 ½Ḟ÷@Ċ÷@ʋÐL(10 바이트)는 작동하지 않습니다. 그리고 분명히 Ƭ하고 ÐĿ정확하게 동일하지 않습니다 (링크가 이항 인 경우)


방법 : (let 입력)

  • 상한으로 시작 나는=.
  • 각 단계에서 :
    • 만약 나는 정수가 아닌 경우 상한을 만들 수 있습니다. 나는 (결과는 정수 여야하므로)
    • 만약 나는 정수가 아닌 경우 나는나는나는÷나는.
  • 그래서 우리는 반복적으로 교체합니다 나는÷나는 고정 될 때까지

0

자바 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`
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.