Знайдіть корінь кореня


19

Напишіть код, який при введенні додатного числа x як вихідний виводить найбільший позитивний дільник менший або рівний квадратному кореню .xx

Іншими словами, знайдіть найбільший такийn>0

mn:mn=x

(Існує більший або дорівнює таким, що разів дорівнює )mnmnx


Наприклад, якщо на вході було дільники , , , , і . , і всі множимо на більші числа, щоб отримати , але є найбільшим, тому повертаємо .1 2 3 4 6 12 1 2 3 12 31212346121231233


Це тому відповіді будуть набрані в байтах з меншою кількістю байтів, які вважатимуться кращим балом.

Випробування

(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
Я не бачу, як закриття популярних питань, як обдури старших неактивних, допомагають сайту ...? Якщо ви помітили це рано, обов’язково, ідіть вперед і забийте його. Якщо вона має вдвічі більше відповідей і більше оновлень, ніж стара. Тримай його, і якщо що, закрий інший ...
Стюі Гріффін

@StewieGriffin Проблема з "популярними питаннями" полягає в тому, що вони знаходяться в HNQ. Що, мабуть, не дуже гарна річ. / Я також не бачу, як це шкодить сайту, ви можете просто перемістити відповіді на старий.
користувач202729

5
HNQ може залучати нових користувачів, і це добре (IMO).
Стюі Гріффін

1
@qwr Але основна ідея однакова. Різниця дуже мала. Метод у кожному виклику може бути використаний для іншого.
користувач202729

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//1→ Призначте lнайбільше ціле число, менше рівного квадратному коренюx
  • while x%l:l-=1→ Хоча lне розділяє рівномірно x, декремент l.

Правки

  • Згадайте Python3, а не Python2
  • Використовуйте ...//1для збереження двох байтів. (Десяткові знаки в порядку! Спасибі @Rod)

Ласкаво просимо до PPCG, приємна перша відповідь! Ви можете зберегти кілька байтів, використовуючи input/ printзамість def/ return, можна також замінити int(...)з , ...//1щоб зберегти більше байт , як ви можете побачити тут
Rod

@Rod не // 1, як я мав на увазі, сказав Python3. (Якщо тільки десяткові знаки не в порядку для виводу, що я не вважав таким чином.) Але для Python2, дякую!
hunteke

@hunteke Десятковий вихід нормально, я не бачу причин, щоб це не було.
Пшеничний майстер

Чи буде коротше значення "For" замість "while", щоб ви могли призначити значення умовно, можливо, уникаючи визначення "l"?
Маладі

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 :-)
Луїс Мендо

До речі , я думаю , що ви можете скоротити до 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), а не передає a double. На x86-64 doubleпередається в інший регістр, ніж ціле число. У 32-розрядному випадку, doubleби займає 2 слота на стеці, тож ви також будете передавати сміття (або субнормальне з цілим числом, як нижня частина мантіси, якби у верхніх 32 біт було нуль). Це також порушується, якщо ви не створюєте помилку налагодження, оскільки вона покладається на неоптимізований кодовий каталог за замовчуванням gcc оцінювання виразів у регістрі повернених значень.
Пітер Кордес

@PeterCordes Так, це код гольфу, а не медичний пристрій :-)
cleblanc

Ну, я не шанувальник фальшивки. Це вже навіть не C, це лише детальна інформація про реалізацію з одним параметром компілятора, який, за замовчуванням, є. (. Це дійсно розтягуючи «повинен працювати, принаймні однієї реалізації» правила) sqrt()питання інакше: мені було цікаво , як це вдалося на роботу, тому що абонент повинен знати яким - то чином перетворити intв double. Я відповів на це як коментар у випадку, якщо хтось інший був цікавий. Ефективно gcc має sqrt(в тому числі прототип) як вбудований, інакше це не вдасться з причин, які ми іноді бачимо в SO asm Qs
Пітер Кордес,

i;f(n){for(i=0;++i<n/i||n%i;);}є 31B, і працює з gcc -Ox86-64 (коштує 2 або 3 байти більше опції командного рядка.) Використовуючи ||замість |причин gcc залишати n/iрезультат з idivEAX, реєстру повернення значень ( godbolt.org/g/RJYeui ). Невизначена поведінка ++iбез точки послідовності буває справною. (Зроблена Asm - це в основному така ж, як і моя відповідь на машинний код x86 .) З -O0, gcc, здається, завжди залишається iв EAX, але, можливо, ми можемо це використати ...
Пітер Кордес,

У будь-якому випадку, якщо вам подобаються відповіді, що не стосуються GCC, що деталізують, можливо, вам сподобається ця відповідь x86-64 gcc, яка, як правило, працює через asm, створений компілятором для чітко невизначеного поведінки: Спробуйте це в Інтернеті! (31 + 2 байти)
Пітер Кордес


5

APL (Dyalog Unicode) , 16 14 12 байт

Я радий, що мені вдалося написати якусь відповідь в APL, оскільки я тільки що це дізнався. Багато, багато хто дякує Адаму за допомогу в гольфі. Пропозиції з гольфу дуже вітаються.Спробуйте в Інтернеті!

Щоб дізнатися більше про APL, подивіться на The APL Orchard .

EDIT: -2 байти для вирішення проблеми з моїм кодом. Дякуємо H.PWiz за вказівку на цю проблему. -2 байти від скорочення всього заново.

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

Чому ви прокреслюєтесь у зворотному порядку? ... Я часто бачу --- 16 --- --- 14 --- 12, а не 12 --- 14 --- --- 16 ---.
користувач202729

@ user202729 Чесно кажучи, минув певний час, і я зовсім забув порядок закреслення. Виправить це незабаром.
Шерлок9

Насправді це не проблема, фрагмент лідерів підтримує обидва.
користувач202729



3

32-розрядний (IA32) код машини: x86: 18 16 байт

журнал змін: обробляти n=1 правильно тестовий випадок, зберегти 2 байти та повернутись у EAX.

Відлічити до n/i <= i (тобто коли ми досягнемо sqrt), і використовуємо перший точний дільник після цього.

64-бітну версію цього телефонує з C із умовою виклику системи x86-64 System V, як
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 -h, 8 6 байт

â f§U¬

Спробуй це

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 Ні. Кожен екземпляр прапора вважається новою мовою.
Олівер

Не зважай. Напевно, я ще не бачив цього метапосту .
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 байт завдяки ідеї Шерлока GCD

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

Спробуйте в Інтернеті!

оригінальна відповідь

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

Спробуйте в Інтернеті!

розібраний

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

пояснення

  • 1 + i.@<.@%: дає діапазон 1 .. floor(sqrt) .
  • все дієслово (A) Bутворює гачок, при цьому вищезазначений діапазон передається як правий аргумент ]А, а початкове число - як його лівий аргумент [. Таким чином ...
  • ] | [ дає залишком кожного елемента в діапазоні, поділеному на початковий арг.
  • і 0 = ] | [ дає дільники без залишку.
  • ] #~ ... потім фільтрує діапазон, залишаючи лише ті.
  • і {:дає останній пункт у списку, тобто найбільший.


1

Haskell , 36 байт

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

Спробуйте в Інтернеті!

Ну це моя відповідь на цей виклик. Тут використовується певне розуміння списку, щоб знайти відповідь. У нашому списку ми вибираємо розумінняузі нескінченного списку, [1..]який є натуральними числами, і ми вибираємоzзі списку [1..y]. Це означає що(у,z) чи всі впорядковані пари такі уz.

Потім вибираємо лише ті пари, що такі уz=х, тобто означає, що ми складаємо список усіх пар чисел, що множиться на х. Тепер, оскільки наше розуміння базується спочатку нау і потім z це означає, що наші пари перебувають у порядку зростання у, або більш корисно у порядку зменшення z.

Тож отримати найбільше z ми беремо zналежність до першого елемента. Це наш результат.



1

Четвертий (gforth) , 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

F #, 55 49 байт

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

Спробуйте в Інтернеті!

Seq.findBack: Повертає останній елемент, для якого повертається дана функція True. Функція в цьому випадку перевіряє, чи є число коефіцієнтом значення.


1

Мозок-Флак , 144 байти

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

Спробуйте в Інтернеті!

Я не впевнений, що ця відповідь дуже хороша. Я відчуваю, що може бути хороший спосіб вирішити цю задачу, проте я просто недостатньо розумний.

Пояснення

Я спробував зробити розгорнуту думку щодо відповіді, але є так багато рухомих частин, що це було не дуже просвітливо, тому ось пояснення того, що робить код.

Перший важливий біт - це

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

Це займає два числа на вершині стека, і якщо вони нерівні прирости, друге, якщо вони рівні, збільшує перше і замінює друге на нуль. Якщо ми повторимо цей код, ми отримаємо всі пари(х,у) такий як ху.

Наступна частина - це множення, взяті з модифікацією з вікі . Це множення є особливим, оскільки воно зберігає існуючі значення, не руйнуючи їх. Виходить так:

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

Отже ми множимо всі ці впорядковані пари. Для кожного результату ми перевіряємо, чи він дорівнює вхідному. Якщо так, ми припиняємо і повертаємо менший предмет у парі.





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
}

Правки

  • Збережіть байт з > 0над != 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 байт) не працює. І, мабуть, Ƭі ÐĿне зовсім те саме (коли посилання є діадичним)


Метод: (нехай н бути входом)

  • Почніть з верхньої межі i=н відповіді а.
  • На кожному кроці:
    • Якщо i не є цілим числом, то верхня межа може бути зроблена i (тому що результат повинен бути цілим числом)
    • Якщо нi значить, не ціле число аiнанiнанiан÷нi.
  • Тому ми неодноразово замінюємо i з н÷нi поки не буде виправлено.

0

Java 8, 65 54 байти

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

Порт відповіді Pyhhon 3 @hunteke .

Спробуйте в Інтернеті.


Старі 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`
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.