Tìm rễ cây Squarish


19

Viết mã khi cho số dương làm đầu vào, xuất ra ước số dương lớn nhất của nhỏ hơn hoặc bằng căn bậc hai của .x xxxx

Nói cách khác, tìm lớn nhất sao chon>0

mn:mn=x

(Tồn tại lớn hơn hoặc bằng sao cho lần là )mnmnx


Ví dụ: nếu đầu vào là thì các ước là , , , , và . , và tất cả nhân với số lớn hơn để có được , nhưng là lớn nhất nên chúng ta trả về .1212346121231233


Đây là vì vậy câu trả lời sẽ được tính bằng byte với ít byte hơn được coi là điểm tốt hơn.

Các trường hợp thử nghiệm

(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
Tôi không thấy cách đóng các câu hỏi phổ biến như bản sao của những câu hỏi không hoạt động cũ giúp trang web ...? Nếu bạn nhận thấy nó sớm, chắc chắn, hãy tiếp tục và đập nó. Nếu nó có số câu trả lời gấp đôi và nhiều câu trả lời hơn câu trả lời cũ. Giữ nó, và nếu có bất cứ điều gì, hãy đóng cái khác ...
Stewie Griffin

@StewieGriffin Một vấn đề với "những câu hỏi phổ biến" là họ đang ở trên HNQ. Mà có lẽ không phải là một điều rất tốt. / Tôi cũng không thấy nó gây hại cho trang web như thế nào, bạn chỉ có thể chuyển câu trả lời sang câu hỏi cũ.
dùng202729

5
HNQ có thể thu hút người dùng mới và đó là một điều tốt (IMO).
Stewie Griffin

1
@qwr Nhưng ý tưởng cốt lõi là như nhau. Sự khác biệt là rất nhỏ. Phương pháp trong mỗi thử thách có thể được sử dụng cho một thử thách khác.
dùng202729

1
@ Hand-E-Food Tôi không khẳng định cái này là khác. Trong thực tế, tôi tin rằng hai người có cùng một nội dung. Lý do của tôi cho việc đóng câu hỏi của bạn cũng giống như những lý do trong bình luận ở đầu chủ đề, câu hỏi này có nhiều câu trả lời hơn. Meta ở đây nếu bạn muốn hỏi ở đó. Bạn cũng có thể quan tâm đến điều này .
Thuật sĩ lúa mì

Câu trả lời:


10

Python3 , 49 47 byte

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

Giải trình

  • l=x**.5//1→ Gán lsố nguyên lớn nhất nhỏ hơn bằng căn bậc hai củax
  • while x%l:l-=1→ Trong khi lkhông chia đều x, giảm dần l.

Chỉnh sửa

  • Đề cập Python3, không phải Python2
  • Sử dụng ...//1để lưu hai byte. (Số thập phân không sao! Cảm ơn @Rod)

Chào mừng bạn đến với PPCG, câu trả lời đầu tiên tốt đẹp! Bạn có thể lưu vài byte bằng cách sử dụng input/ printthay thế def/ return, bạn cũng có thể thay thế int(...)bằng ...//1để lưu nhiều byte hơn như bạn có thể thấy ở đây
Rod

@Rod không // 1, như tôi muốn nói là Python3. (Trừ khi số thập phân ổn với đầu ra, điều mà tôi không nghĩ vậy.) Nhưng đối với Python2, cảm ơn!
hunteke

@hunteke Sản lượng thập phân là tốt, tôi không thấy bất kỳ lý do nào nó không nên.
Phù thủy lúa mì

Nó sẽ ngắn hơn với "For" thay vì "While", vì vậy bạn có thể gán giá trị trong điều kiện, có thể tránh việc xác định "l"?
Malady

8

MATL , 7 byte

Z\tn2/)

Hãy thử trực tuyến!

Đối với lời giải thích này, chúng tôi sẽ sử dụng '12' làm đầu vào mẫu. Giải trình:

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

Điều này hoạt động vì rất nhiều sự trùng hợp may mắn.

  1. MATL sử dụng 1 chỉ mục
  2. Nếu chúng ta chỉ có một tổ chức phi nguyên (điều này sẽ xảy ra đối với bất kỳ đầu vào vuông hoàn hảo), sau đó <n>)sẽ index n

1
...... tốt, tôi đã bị đánh bại một cách rõ ràng!
Giuseppe

Chính bạn là người đã trả lời điều này trong MATL :-)
Luis Mendo

BTW Tôi nghĩ bạn có thể rút ngắn Z\J2/)( J2/hoặc tương đương .5jviết tắt end/2khi được sử dụng làm chỉ mục)
Luis Mendo

Có thể đáng để giải thích hành vi khi áp dụng cho một số có số ước lẻ, vì "Chỉ mục" có giá trị không nguyên không rõ ràng.
Kamil Drakari

@KamilDrakari Thế nào?
DJMcMayhem

7

C (gcc) -lm , 35 byte

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

Hãy thử trực tuyến!


2
BTW, điều này chỉ hoạt động vì sự công nhận của GCC là sqrtchức năng tích hợp. Với -fno-builtin-sqrt, gcc giả định int sqrt(int), và không vượt qua a double. Trên x86-64, doubleđược truyền vào một thanh ghi khác với số nguyên. Trên 32 bit, a doublesẽ lấy 2 vị trí trên ngăn xếp, do đó, bạn cũng sẽ chuyển rác (hoặc không bình thường với số nguyên là dưới cùng của lớp phủ, nếu 32 bit trên bằng 0). Điều này cũng bị phá vỡ trừ khi bạn thực hiện một bản dựng gỡ lỗi vì nó phụ thuộc vào kiểu gen đánh giá các biểu thức không được tối ưu hóa mặc định của gcc trong thanh ghi giá trị trả về.
Peter Cordes

@PeterCordes Có, đó là mã golf, không phải thiết bị y tế :-)
cleblanc

Vâng, tôi không phải là một fan hâm mộ của hack-return giả. Điều đó thậm chí không còn là C nữa, nó chỉ là một chi tiết triển khai với một cài đặt trình biên dịch là mặc định. (Nó thực sự kéo dài quy tắc "phải làm việc với ít nhất một lần thực hiện".) sqrt()Vấn đề là khác: Tôi tò mò làm thế nào mà nó hoạt động được, bởi vì người gọi phải bằng cách nào đó biết để chuyển đổi intsang double. Tôi đã đăng câu trả lời cho điều đó như một bình luận trong trường hợp bất kỳ ai khác tò mò. Hiệu quả gcc có sqrt(bao gồm cả nguyên mẫu) như là một tích hợp, nếu không điều này sẽ thất bại vì lý do đôi khi chúng ta thấy trong SO asm Qs
Peter Cordes

i;f(n){for(i=0;++i<n/i||n%i;);}là 31B và hoạt động với gcc -Otrên x86-64 (tốn thêm 2 hoặc 3 byte cho tùy chọn dòng lệnh.) Sử dụng ||thay vì |gcc để lại n/ikết quả từ idivtrong EAX, thanh ghi giá trị trả về ( godbolt.org/g/RJYeui ). Hành vi không xác định từ ++ikhông có điểm trình tự xảy ra để làm việc. (Mã asm được sản xuất về cơ bản giống như câu trả lời mã máy x86 của tôi .) Với -O0, gcc dường như luôn để lại itrong EAX, nhưng có lẽ chúng ta có thể sử dụng nó ...
Peter Cordes

Dù sao, nếu bạn thích câu trả lời chi tiết triển khai gcc không C, có thể bạn sẽ thích câu trả lời x86-64 gcc này xảy ra do trình biên dịch được tạo bởi trình biên dịch cho hành vi không xác định rõ ràng: Hãy thử trực tuyến! (31 + 2 byte)
Peter Cordes


5

APL (Dyalog Unicode) , 16 14 12 byte

Tôi rất vui vì tôi đã có thể viết một số câu trả lời trong APL vì tôi chỉ mới học nó. Rất, rất cám ơn Adám đã giúp đỡ chơi golf. Gợi ý chơi golf rất được chào đón. Hãy thử trực tuyến!

Để tìm hiểu thêm về APL, hãy xem The APL Orchard .

EDIT: -2 byte để khắc phục sự cố với mã của tôi. Cảm ơn H.PWiz đã chỉ ra vấn đề đó. -2 byte từ rút ngắn mọi thứ một lần nữa.

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

Tại sao bạn tấn công theo thứ tự ngược lại? ... Tôi thường thấy --- 16 --- --- 14 --- 12, không phải 12 --- 14 --- --- 16 ---.
dùng202729

@ user202729 Thành thật mà nói, đã được một thời gian và tôi hoàn toàn quên mất thứ tự tấn công. Sẽ sửa nó trong thời gian ngắn.
Sherlock9

Trên thực tế, đó không phải là vấn đề, đoạn trích bảng xếp hạng hỗ trợ cả hai.
dùng202729

4

Husk , 4 byte

→←½Ḋ

Hãy thử trực tuyến!

Giải trình

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


3

Mã máy x86 32 bit (IA32): 18 16 byte

changelog: xử lý n=1trường hợp kiểm tra chính xác, lưu 2 byte và trả về EAX.

Đếm cho đến khi n/i <= i(tức là khi chúng ta đạt đến sqrt) và sử dụng ước số chính xác đầu tiên sau đó.

Phiên bản 64 bit này có thể gọi được từ C với quy ước gọi System V x86-64, như
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

Hãy thử trực tuyến! với một người gọi asm sử dụng byte đầu tiên của argv [1] làm số nguyên trực tiếp và sử dụng kết quả làm trạng thái thoát quy trình.

$ 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
Bạn có chắc n = 1 không chỉ là 1? Nó được liệt kê như một trường hợp thử nghiệm và nó là một ước số 1 = 1.
qwr

Câu trả lời của bạn sẽ hoạt động cho 1. Nếu nó không hoạt động với thuật toán của bạn thì bạn sẽ phải mã hóa nó.
Thuật sĩ lúa mì

2
@qwr: được cập nhật với phiên bản ngắn hơn hoạt động cho tất cả các đầu vào.
Peter Cordes

2

Japt -h, 8 6 byte

â f§U¬

Thử nó

Lưu 2 byte nhờ Oliver


Giải trình

           :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

Cờ không có chi phí byte?
mbomb007

@ mbomb007 Không. Mỗi phiên bản của một cờ được coi là một mục ngôn ngữ mới.
Oliver

Đừng bận tâm. Tôi đoán tôi chưa thấy bài meta đó.
mbomb007



2

Người tuyết , 38 byte

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

Hãy thử trực tuyến!

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

đc , 24

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

Hãy thử trực tuyến!

Giải trình:

?                         # 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 nhờ ý tưởng GCD của Sherlock

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

Hãy thử trực tuyến!

câu trả lời gốc

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

Hãy thử trực tuyến!

phân tích cú pháp

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

giải trình

  • 1 + i.@<.@%: đưa ra phạm vi 1 .. floor(sqrt) .
  • toàn bộ động từ (A) Btạo thành một hook, với phạm vi trên được truyền dưới dạng arg bên phải ]cho A và số ban đầu được truyền dưới dạng arg bên trái của nó [. Do đó ...
  • ] | [ cung cấp phần còn lại của mỗi mục trong phạm vi được chia thành đối số ban đầu.
  • 0 = ] | [đưa ra các ước số không có phần còn lại.
  • ] #~ ... sau đó lọc phạm vi, chỉ để lại những cái đó.
  • {:đưa ra mục cuối cùng trong danh sách, tức là mục lớn nhất.



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

Cách ngắn nhất dường như là sử dụng ngăn xếp dấu phẩy động và fsqrt, ngắn nhất tôi có thể nhận được mà không có nó là 62 byte bằng cách sử dụng /modvà kiểm tra xem thương số có lớn hơn ước số hay không.

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

Hãy thử trực tuyến!

Giải trình

  1. Tính căn bậc hai
  2. Bắt đầu từ căn bậc hai, giảm 1 cho đến khi chúng ta tìm thấy một yếu tố của số ban đầu

Giải thích mã

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

Hãy thử trực tuyến!

Seq.findBack: Trả về phần tử cuối cùng mà hàm đã cho trả về True. Hàm trong trường hợp này kiểm tra xem một số có phải là một yếu tố của giá trị không.


1

Brain-Flak , 144 byte

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

Hãy thử trực tuyến!

Tôi không thực sự chắc chắn câu trả lời này là rất tốt. Tôi cảm thấy có thể có một cách hay để giải quyết nhiệm vụ này tuy nhiên tôi không đủ thông minh.

Giải trình

Tôi đã cố gắng thực hiện một cái nhìn bùng nổ về câu trả lời nhưng có rất nhiều phần chuyển động mà nó không được khai sáng cho lắm, vì vậy đây là một lời giải thích về những gì mã làm.

Điều quan trọng đầu tiên là điều này

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

(x,y)xy .

Phần tiếp theo là nhân, được thực hiện với sửa đổi từ wiki . Phép nhân này là đặc biệt vì nó bảo tồn các giá trị hiện có mà không phá hủy chúng. Nó như sau:

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

Vì vậy, chúng tôi đang nhân tất cả các cặp theo thứ tự. Đối với mỗi kết quả, chúng tôi kiểm tra nếu nó bằng với đầu vào. Nếu vậy, chúng tôi chấm dứt và trả lại các mục nhỏ hơn trong cặp.





0

Rust, 71 70 byte

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

Phiên bản tiền xấu

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
}

Chỉnh sửa

  • Lưu một byte với > 0hơn != 0. (Cảm ơn @CatWizard)

!=thể thay thế bằng >?
Phù thủy lúa mì

Cuộc gọi tốt Vâng.
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)))}

Bạn có thể thử trực tuyến bằng cách sao chép nó vào trình soạn thảo Pyret trực tuyến !

Trên đây đánh giá một chức năng ẩn danh. Khi nó được áp dụng cho một số nguyên, nó sẽ trả về một kết quả theo đặc tả.



0

Một cổng của câu trả lời Mathicala này .

Thạch , 11 byte

½ðḞ³÷Ċ³÷µÐL

Hãy thử trực tuyến!

Điều này (11 byte) cũng hoạt động và không phụ thuộc vào ³:

½Ḟ÷@Ċ÷@ʋƬµṪ

Thật không may ½Ḟ÷@Ċ÷@ʋÐL(10 byte) không hoạt động. Và rõ ràng ƬÐĿkhông hoàn toàn giống nhau (khi liên kết là dyadic)


n

  • i=na .
  • Ở mỗi bước:
    • ii
    • niainaninanian÷ni
  • in÷ni

0

Java 8, 65 54 byte

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

Cổng 3 câu trả lời Python của @hunteke .

Hãy thử trực tuyến.


Câu trả lời cũ 65 byte:

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

Hãy thử trực tuyến.

Giải trình:

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`
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.