Squarish Root'u Bulun


19

Pozitif bir sayı verildiğinde bu yaz kod girdi olarak, en büyük pozitif böleni verir az veya kare köküne eşit .xxx

Başka bir deyişle, en büyük n>0 bu şekilde

mn:mn=x

(Var m daha büyük ya da eşit n , öyle ki m kez n olduğu x )


Örneğin giriş 12 ise bölücüler 1 , 2 , 3 , 4 , 6 ve 12 . 1 , 2 ve 3 hepsi daha büyük sayılarla çarparak 12 , ancak 3 en büyüğüdür, bu yüzden 3'ü döndürürüz 3.


Bu bu nedenle cevaplar bayt cinsinden puanlandırılacak ve daha az bayt daha iyi bir puan olarak kabul edilecektir.

Test Durumları

(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
Eski aktif olmayanların kopyaları siteye nasıl yardımcı oluyor gibi popüler soruları kapatmanın ...? Erken fark ederseniz, devam edin ve çekiçleyin. Cevapların sayısı eskisine göre iki kat fazla ve daha fazla oy veriyorsa. Saklayın ve bir şey varsa, diğerini kapatın ...
Stewie Griffin

@StewieGriffin "Popüler sorular" ile ilgili bir sorun HNQ'da olmalarıdır. Bu muhtemelen çok iyi bir şey değil. / Siteye nasıl zarar verdiğini de görmüyorum, cevapları eskisine taşıyabilirsiniz.
user202729

5
HNQ yeni kullanıcıları çekebilir ve bu iyi bir şeydir (IMO).
Stewie Griffin

1
@qwr Ama temel fikir aynı. Fark çok küçük. Her meydan okumadaki yöntem bir başkası için kullanılabilir.
user202729

1
@ Hand-E-Food Bunun farklı olduğunu iddia etmiyorum. Aslında ikisinin de aynı içeriğe sahip olduğuna inanıyorum. Sorunuzun kapatılmasına ilişkin nedenlerim, konunun üst kısmındaki yorumdakilerle aynı, bu sorunun daha fazla yanıtı var. Orada sormak isterseniz meta burada . Ayrıca ilgi olabilir bu .
Buğday Büyücüsü

Yanıtlar:


10

Python3 , 49 47 bayt

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

açıklama

  • l=x**.5//1→ ' lnın kareköküne eşit olan en büyük tamsayıyı atayın .x
  • while x%l:l-=1lEşit olarak bölünmese xde azaltın l.

Düzenlemeler

  • Python2'den değil, Python2'den bahsedin
  • ...//1İki bayt kaydetmek için kullanın . (Ondalıklar tamam! Teşekkürler @Rod)

PPCG'ye hoş geldiniz, güzel ilk cevap! Sen kullanarak birkaç byte kaydedebilirsiniz input/ printyerine def/ return, ayrıca yerini alabilir int(...)ile ...//1gördüğünüz gibi daha bayt kaydetmek için buraya
Rod

@Rod değil // 1, Dediğim gibi Python3. (Ondalık sayılar, öyle düşünmediğim çıktı için uygun olmadığı sürece.) Ama Python2 için, teşekkürler!
hunteke

@hunteke Ondalık çıktı gayet iyi, olmaması için hiçbir neden göremiyorum.
Buğday Büyücüsü

"While" yerine "For" ile daha kısa olur, bu nedenle koşullu değerler atayabilir ve muhtemelen "l" tanımından kaçınabilirsiniz?
Malady

8

MATL , 7 bayt

Z\tn2/)

Çevrimiçi deneyin!

Bu açıklama için örnek girdi olarak '12' kullanacağız. Açıklama:

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

Bu çok şanslı tesadüfler nedeniyle işe yarıyor.

  1. MATL 1 indeksleme kullanır
  2. Biz olmayan bir tamsayı ile indeksi (bu herhangi mükemmel kare girişi için olur), sonra <n>)dizine ekleyecektir n

1
...... iyi selâmetle sarsıldım!
Giuseppe

Bunu MATL'de cevaplayan siz olmalısınız :-)
Luis Mendo

BTW ben size kısaltmak düşünüyorum Z\J2/)( J2/veya eşdeğer .5jaçılımı end/2bir endeks olarak kullanıldığında)
Luis Mendo

Tam sayı olmayan bir değere sahip "Dizin" açık olmadığı için, tek bölen sayısına sahip bir sayıya uygulandığında davranışı açıklamaya değer olabilir.
Kamil Drakari

@KamilDrakari Bu nasıl?
DJMcMayhem

7

C (gcc) -lm , 35 bayt

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

Çevrimiçi deneyin!


2
BTW, bu sadece GCC'nin sqrtyerleşik bir işlev olarak tanınması nedeniyle çalışır . İle -fno-builtin-sqrt, gcc varsayar int sqrt(int)ve geçmez double. X86-64 üzerinde, doublebir tamsayıdan farklı bir yazmaçta geçirilir. 32-bit, a doubleyığını üzerinde 2 yuva alır, bu yüzden de çöp geçirirsiniz (veya üst 32 bit sıfırsa mantisin tabanı olarak tamsayı ile bir alt normal). Bu, aynı zamanda bir hata ayıklama derlemesi yapmadığınız sürece kırılır, çünkü gcc'nin döndürülmemiş değer kaydındaki ifadeleri değerlendirmenin varsayılan optimize edilmemiş kod genine dayanır.
Peter Cordes

@PeterCordes Evet, bu kod golf, tıbbi bir cihaz değil :-)
cleblanc

Ben sahte geri dönüşün hayranı değilim. Artık C bile değil, sadece varsayılan olan bir derleyici ayarıyla bir uygulama detayı. (. Gerçekten kuralı "işe en az bir uygulamasıyla vardır" germe bulunuyor) sqrt()sorunu farklıdır: Arayan bir şekilde dönüştürmek için bilmek zorunda çünkü, işin nasıl başardığını merak ediyordum intiçin double. Başkalarının merak etmesi durumunda cevabı bir yorum olarak gönderdim. Etkili bir şekilde gcc sqrtyerleşik olarak (prototip dahil) vardır, aksi takdirde bu bazen SO asm Qs'de gördüğümüz nedenlerden dolayı başarısız olur
Peter Cordes

i;f(n){for(i=0;++i<n/i||n%i;);}31B ve çalışır gcc -Okullanarak X86-64 (komut satırı seçeneği için 2 veya 3 daha bayt malolan.) üzerine ||yerine |bırakmak gcc nedenleri n/isonucunu idiv(EAX, dönüş değeri kayıt godbolt.org/g/RJYeui ). ++iBir sıra noktası olmadan tanımsız davranış çalışır. (Üretilen asm temelde benim x86 makine kodu cevabımla aynı .) İle -O0, gcc her zaman iEAX içinde ayrılıyor gibi görünüyor , ama belki de bunu kullanabiliriz ...
Peter Cordes

Her neyse, eğer C gcc olmayan uygulama ayrıntıları cevaplarını seviyorsanız, belki de açıkça tanımlanmamış davranış için derleyici tarafından üretilen asm nedeniyle işe yarayan bu x86-64 gcc cevabını beğeneceksiniz: Çevrimiçi deneyin! (31 + 2 bayt)
Peter Cordes


5

APL (Dyalog Unicode) , 16 14 12 bayt

Sadece öğrendiğimden beri APL'de bir cevap yazabildiğim için memnunum. Adám'a golf konusunda yardım ettiği için çok, çok teşekkürler. Golf önerileri çok hoş geldiniz. Çevrimiçi deneyin!

APL hakkında daha fazla bilgi edinmek için, APL Orchard'a bir göz atın .

EDIT: kodum ile ilgili bir sorunu gidermek için -2 bayt. Bu sorunu işaret ettiği için H.PWiz'e teşekkürler. Her şeyi tekrar kısaltmak için -2 bayt.

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

Neden ters sırayla çarpıyorsunuz? ... sık sık --- 16 --- --- 14 --- 12, 12 --- 14 --- --- 16 --- değil.
user202729

Açıkçası, bir süre geçti ve üstü çizili sırayı oldukça unuttum. Kısa sürede düzeltir.
Sherlock9

Aslında sorun değil, skor tablosu snippet'i her ikisini de destekliyor.
user202729

4

Kabuk , 4 bayt

→←½Ḋ

Çevrimiçi deneyin!

açıklama

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


3

x86 32 bit (IA32) makine kodu: 18 16 bayt

changelog: n=1test senaryosunu doğru kullanın, 2 bayt kaydedin ve EAX'a dönün.

Kadar sayın n/i <= i(yani, sqrt ulaşmak zaman) ve bundan sonra ilk kesin böleni kullanın.

Bunun 64-bit sürümü, x86-64 System V çağrı kuralı ile C'den çağrılabilir
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

Çevrimiçi deneyin! argv [1] 'in ilk baytını doğrudan bir tamsayı olarak kullanan ve sonucu işlem çıkış durumu olarak kullanan bir asm arayanıyla.

$ 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'in sadece 1 olmadığından emin misiniz? Bir test senaryosu olarak listelenir ve bir bölen ≤ √1 = 1.
qwr

Cevabınız 1 için çalışmalıdır. Eğer algoritmanızla çalışmazsa, onu kodlamanız gerekecektir.
Buğday Büyücüsü

2
@ qwr: tüm girdiler için çalışan daha kısa bir sürümle güncellendi.
Peter Cordes

2

Japt -h, 8 6 bayt

â f§U¬

Dene

Oliver sayesinde 2 bayt kurtardı


açıklama

           :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

Bayrakların maliyeti hala bayt değil mi?
mbomb007

@ mbomb007 Hayır. Her bayrağın örneği yeni bir dil girişi olarak kabul edilir.
Oliver

Boşver. Sanırım bu meta yayını henüz görmemiştim .
mbomb007



2

Kardan adam , 38 bayt

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

Çevrimiçi deneyin!

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

Çevrimiçi deneyin!

Açıklama:

?                         # 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 bayt

Sherlock'un GCD fikri sayesinde -5 bayt

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

Çevrimiçi deneyin!

orijinal cevap

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

Çevrimiçi deneyin!

çözümlü

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

açıklama

  • 1 + i.@<.@%:aralığı verir 1 .. floor(sqrt).
  • tüm fiil (A) Bbir kanca oluşturur, yukarıdaki aralık ]A'ya doğru arg olarak ve orijinal sayı sol argüman olarak geçti [. Böylece...
  • ] | [ aralıktaki her öğenin kalanını orijinal bağımsız değişkene böler.
  • ve 0 = ] | [bölenlere hiçbir kalıntı bırakmadan verir.
  • ] #~ ... sonra aralığı filtreler, yalnızca bunları bırakır.
  • ve {:listedeki son öğeyi, yani en büyüğünü verir.


1

Haskell , 36 bayt

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

Çevrimiçi deneyin!

İşte bu meydan okumaya cevabım. Bu, cevabı bulmak için belirli bir liste kavrayışı kullanır. Liste kavrayışımızday[1..]pozitif listeden sonsuz listeden ,zlisteden [1..y]. Bunun anlamı şudur ki(y,z) tüm sıralı çiftler öyle ki yz.

Sonra sadece o çiftleri seçeriz ki yz=x, yani çarpılan tüm sayı çiftlerinin listesini yaparız x. Şimdi anlayışımız ilk olaraky ve sonra z Bu, çiftlerimizin artan sırada olduğu anlamına gelir yveya daha yararlı bir şekilde z.

Yani en büyüğü almak için z alıyoruz zbirinci elemana ait. Bu bizim sonucumuz.


1

QBasic (4.5), 52 bayt

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

1

İleri (gforth) , 53 bayt

En kısa yol kayan nokta yığınını kullanıyor gibi görünüyor ve fsqrtonsuz alabileceğim en kısa yol /mod, bölümün bölenden büyük olup olmadığını kontrol etmek ve kullanmak için 62 bayttı.

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

Çevrimiçi deneyin!

açıklama

  1. Karekök hesaplama
  2. Karekökten başlayarak, orijinal sayının bir faktörünü bulana kadar 1 azaltın.

Kod Açıklaması

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

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

Çevrimiçi deneyin!

Seq.findBack: Verilen işlevin döndürdüğü son öğeyi döndürür True. Bu durumda işlev, bir sayının değerin bir faktörü olup olmadığını kontrol eder.


1

Brain-Flak , 144 bayt

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

Çevrimiçi deneyin!

Bu cevabın çok iyi olduğundan emin değilim. Bu görevi çözmenin güzel bir yolu olabilir gibi hissediyorum ama yeterince zeki değilim.

açıklama

Cevabın patlatılmış bir görünümünü yapmaya çalıştım ama çok aydınlatıcı olmayan birçok hareketli parça var, bu yüzden kodun ne yaptığının bir açıklaması.

İlk önemli nokta bu

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

Bu, yığının üstündeki iki sayıyı alır ve ikincisinde eşit olmayan artışlar varsa, eşitse ilk sayıyı artırır ve ikinciyi sıfırla değiştirir. Bu kodu bir demet tekrarlarsak, tüm çiftleri alırız(x,y) öyle ki xy.

Bir sonraki bölüm, wiki'den değiştirilerek alınan çarpmadır . Bu çarpma özeldir, çünkü mevcut değerleri yok etmeden korur. Şöyle gider:

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

Bu yüzden tüm bu sıralı çiftleri çoğalıyoruz. Her sonuç için girişe eşit olup olmadığını kontrol ederiz. Eğer öyleyse sonlandırırız ve çiftteki küçük eşyayı iade ederiz.





0

Pas, 71 70 bayt

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

Önceden çoğaltılmış versiyon

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
}

Düzenlemeler

  • > 0Üzerinde bir bayt kaydedin != 0. (@CatWizard sayesinde)

İle !=değiştirilebilir >?
Buğday Büyücüsü

İyi karar! Evet.
hunteke




0

Aslında 7 bayt

Buradaki APL cevabım temel alınarak . Golf önerileri hoş geldiniz! Çevrimiçi deneyin!

;√LR♀gM

Ungolfing

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

Bu Mathematica cevabının bir limanı .

Jöle , 11 bayt

½ðḞ³÷Ċ³÷µÐL

Çevrimiçi deneyin!

Bu (11 bayt) da çalışır ve aşağıdakilere bağlı değildir ³:

½Ḟ÷@Ċ÷@ʋƬµṪ

Ne yazık ki ½Ḟ÷@Ċ÷@ʋÐL(10 bayt) çalışmıyor. Ve görünüşe göre Ƭve ÐĿtam olarak aynı değil (bağlantı ikili olduğunda)


Yöntem: (let n girdi olun)

  • Üst sınır ile başlayın ben=n cevabın bir.
  • Her adımda:
    • Eğer ben bir tam sayı değil, daha sonra üst sınır yapılabilir ben (çünkü sonuç bir tam sayı olmalıdır)
    • Eğer nben bir tam sayı değil, birbennbirnbennbirnbenbirn÷nben.
  • Bu yüzden tekrar tekrar değiştiriyoruz ben ile n÷nben düzeltilinceye kadar.

0

Java 8, 65 54 bayt

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

Limanı @hunteke 'nin Python 3 cevabı .

Çevrimiçi deneyin.


Eski 65 bayt cevap:

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

Çevrimiçi deneyin.

Açıklama:

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`
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.