Найти квадратный корень

19

Напишите код, который при получении положительного числа качестве ввода выводит наибольший положительный делитель x, меньший или равный квадратному корню из x .ИксИксИкс

Другими словами, найдите наибольшее такое, чтоN>0

мN:мNзнак равноИкс

(Существует большее или равное n, такое что m умноженное на n равно x )мNмNИкс


Например, если на входе было делителей, это 1 , 2 , 3 , 4 , 6 и 12 . 1 , 2 и 3 все умножаются на большие числа, чтобы получить 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
Я не понимаю, как закрытие популярных вопросов, так как пароли старых неактивных вопросов помогают сайту ...? Если вы заметили это рано, конечно, идти вперед и забить это. Если у него вдвое больше ответов и больше голосов, чем у старого. Держите его, и если что, закройте другой ...
Стьюи Гриффин
@StewieGriffin Проблема с «популярными вопросами» заключается в том, что они находятся в HNQ. Что, вероятно, не очень хорошая вещь. / Я тоже не вижу, как это вредит сайту, вы можете просто перенести ответы на старый.
user202729
5
HNQ может привлечь новых пользователей, и это хорошо (ИМО).
Стьюи Гриффин
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//1→ Назначить lнаибольшее целое число меньше, чем квадратный корень изx
  • while x%l:l-=1→ Пока lне делится поровну x, уменьшать l.

Правки

  • Упомяните Python3, а не Python2
  • Используйте, ...//1чтобы сохранить два байта. (Десятичные числа в порядке! Спасибо @Rod)
hunteke
источник
Добро пожаловать в PPCG, хороший первый ответ! Вы можете сохранить несколько байтов, используя input/ printвместо def/ return, вы также можете заменить int(...)на, ...//1чтобы сохранить больше байтов, как вы можете видеть здесь
Rod
@Rod не // 1, как я и сказал, сказал Python3. (Если только десятичные дроби не подходят для вывода, что я так не думаю.) Но для Python2, спасибо!
хунтеке
@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
DJMcMayhem
источник
1
...... хорошо, я был обоснованно обеспокоен!
Джузеппе
Это должен был быть ты, кто ответил на это в MATL :-)
Луис Мендо
Кстати, я думаю, что вы можете сократить Z\J2/)( J2/или эквивалентно .5jозначает, end/2когда используется в качестве индекса)
Луис Мендо
Возможно, стоит объяснить поведение применительно к числу с нечетным числом делителей, поскольку «Индекс» с нецелым значением не очевиден.
Камил Дракари
@KamilDrakari Как это?
DJMcMayhem
7

C (gcc) -lm , 35 байт

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

Попробуйте онлайн!

cleblanc
источник
2
Кстати, это работает только из-за признания GCC sqrtкак встроенной функции. С -fno-builtin-sqrt, gcc предполагает int sqrt(int), и не передает double. На x86-64 doubleпередается в другом регистре, чем целое число. На 32-битном, a 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результат idivв EAX, регистр возвращаемого значения ( godbolt.org/g/RJYeui ). ++iСлучается неопределенное поведение без точки последовательности. (Произведенный asm в основном такой же, как мой ответ с машинным кодом x86 .) С помощью -O0gcc всегда кажется, что он уходит iв EAX, но, возможно, мы можем использовать это ...
Peter Cordes
В любом случае, если вам нравятся ответы, не относящиеся к реализации gcc, не относящиеся к C, возможно, вам понравится этот gcc-ответ x86-64, который сработает из-за asm, созданного компилятором для явно неопределенного поведения: попробуйте его онлайн! (31 + 2 байта)
Питер Кордес
5

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

Я рад, что смог написать какой-то ответ в APL, так как я только что узнал об этом. Большое, большое спасибо Адаму за помощь в игре в гольф. Предложения по гольфу очень приветствуются. Попробуйте онлайн!

Чтобы узнать больше об APL, взгляните на APL Orchard .

РЕДАКТИРОВАТЬ: -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.
Sherlock9
источник
Почему вы зачеркиваете в обратном порядке? ... Я часто вижу --- 16 --- --- 14 --- 12, а не 12 --- 14 --- --- 16 ---.
user202729
@ user202729 Честно говоря, это было давно, и я совсем забыл порядок зачеркивания. Скоро исправлю.
Sherlock9
На самом деле это не проблема, фрагмент списка лидеров поддерживает оба.
user202729
3

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

changelog: n=1правильно обработать контрольный пример, сохранить 2 байта и вернуться в EAX.

Считайте до n/i <= i(т. Е. Когда мы достигнем sqrt), и используйте первый точный делитель после этого.

64-битная версия этого вызывается из C с соглашением о вызовах System V x86-64, as
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

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 байт

-5 байт благодаря идее Шерлока GCD

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

Попробуйте онлайн!

оригинальный ответ

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

Попробуйте онлайн!

разобранный

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

объяснение

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

QBasic (4.5), 52 байта

INPUT x
FOR i=1TO sqr(x)
if x/i=x\i then m=i
next
?m
steenbergh
источник
1

Forth (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
reffu
источник
1

F #, 55 49 байтов

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

Попробуйте онлайн!

Seq.findBackВозвращает последний элемент, для которого возвращается данная функция True. Функция в этом случае проверяет, является ли число фактором фактора.

Ciaran_McCarthy
источник
1

Brain-Flak , 144 байта

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

Попробуйте онлайн!

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

объяснение

Я попытался сделать ответ в разобранном виде, но движущихся частей было так много, что это было не очень поучительно, поэтому вот объяснение того, что делает код.

Первый важный момент это

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

(Икс,Y)ИксY

Следующая часть - умножение, взятое с модификацией из вики . Это умножение является особенным, поскольку оно сохраняет существующие значения, не разрушая их. Это идет как:

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

Итак, мы умножаем все эти упорядоченные пары. Для каждого результата мы проверяем, равен ли он входу. Если это так, мы прекращаем и возвращаем меньший элемент в паре.

Мастер пшеницы
источник
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

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

Порт этого Mathematica ответа .

Желе , 11 байт

½ðḞ³÷Ċ³÷µÐL

Попробуйте онлайн!

Это (11 байт) также работает и не зависит от ³:

½Ḟ÷@Ċ÷@ʋƬµṪ

К сожалению ½Ḟ÷@Ċ÷@ʋÐL(10 байт) не работает. И видимо ƬиÐĿ не совсем то же самое (когда ссылка диадическая)


N

  • язнак равноNa .
  • На каждом этапе:
    • яя (потому что результат должен быть целым числом)
    • NяaяNaNяNaNяaN÷Nя
  • яN÷Nя
user202729
источник
0

Java 8, 65 54 байта

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

Порт @hunteke 's 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`
Кевин Круйссен
источник