Temukan Root Squarish


19

Tulis kode yang ketika diberi angka positif x sebagai input, menghasilkan pembagi positif terbesar x kurang dari atau sama dengan akar kuadrat x .

Dengan kata lain cari yang terbesar n>0 sedemikian rupa

mn:mn=x

(Ada m lebih besar dari atau sama dengan n sehingga m kali n adalah x )


Misalnya, jika inputnya adalah pembagi adalah , , , , , dan . , dan semua kalikan dengan angka yang lebih besar untuk mendapatkan , tetapi adalah yang terbesar jadi kami kembalikan .1 2 3 4 6 12 1 2 3 12 3 31212346121231233


Ini adalah sehingga jawaban akan dicetak dalam byte dengan lebih sedikit byte yang dianggap sebagai skor yang lebih baik.

Uji Kasus

(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
Saya tidak melihat bagaimana menutup pertanyaan populer karena penipu yang tidak aktif lebih tua membantu situs ...? Jika Anda menyadarinya lebih awal, tentu saja, lanjutkan dan pukullah. Jika memiliki dua kali jumlah jawaban dan lebih banyak suara daripada yang lama. Simpan, dan jika ada, tutup yang lain ...
Stewie Griffin

@StewieGriffin Masalah dengan "pertanyaan populer" adalah mereka ada di HNQ. Yang mungkin bukan hal yang sangat baik. / Aku juga tidak melihat bagaimana itu merusak situs, kamu bisa memindahkan jawaban ke yang lama.
user202729

5
HNQ mungkin menarik pengguna baru, dan itu hal yang baik (IMO).
Stewie Griffin

1
@ qwr Tapi ide intinya sama. Perbedaannya sangat kecil. Metode dalam setiap tantangan dapat digunakan untuk tantangan lainnya.
user202729

1
@ Hand-E-Food Saya tidak mengklaim yang ini berbeda. Sebenarnya saya percaya bahwa keduanya memiliki konten yang sama. Alasan saya untuk penutupan pertanyaan Anda sama dengan yang ada di komentar di bagian atas utas, pertanyaan ini memiliki lebih banyak jawaban. Meta ada di sini jika Anda ingin bertanya di sana. Anda mungkin juga tertarik dengan ini .
Wheat Wizard

Jawaban:


10

Python3 , 49 47 byte

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

Penjelasan

  • l=x**.5//1→ Tetapkan linteger terbesar kurang dari sama dengan akar kuadrat darix
  • while x%l:l-=1→ Meskipun ltidak terbagi rata x, penurunan l.

Suntingan

  • Sebutkan Python3, bukan Python2
  • Gunakan ...//1untuk menyimpan dua byte. (Desimal baik-baik saja! Terima kasih @Rod)

Selamat datang di PPCG, jawaban pertama yang bagus! Anda dapat menyimpan beberapa byte dengan menggunakan input/ printsebagai gantinya def/ return, Anda juga dapat menggantinya int(...)dengan ...//1untuk menyimpan lebih banyak byte seperti yang Anda lihat di sini
Rod

@Rod tidak // 1, seperti yang saya maksud mengatakan Python3. (Kecuali desimal tidak apa-apa untuk output, yang saya pikir tidak begitu.) Tapi untuk Python2, terima kasih!
hunteke

@ Hunteke Output desimal baik-baik saja, saya tidak melihat alasan apa pun.
Wheat Wizard

Apakah akan lebih pendek dengan "Untuk" daripada "Sementara", sehingga Anda dapat menetapkan nilai dalam kondisi, mungkin menghindari mendefinisikan "l"?
Malady

8

MATL , 7 byte

Z\tn2/)

Cobalah online!

Untuk penjelasan ini, kita akan menggunakan '12' sebagai input sampel. Penjelasan:

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

Ini berhasil karena banyak kebetulan yang beruntung.

  1. MATL menggunakan 1 pengindeksan
  2. Jika kita mengindeks dengan non-integer (ini akan terjadi untuk input kuadrat sempurna), maka <n>)akan mengindeks n

1
...... yah aku sudah sangat tertipu!
Giuseppe

Pasti kamu yang menjawab ini di MATL :-)
Luis Mendo

BTW Saya pikir Anda dapat mempersingkat Z\J2/)( J2/atau setara .5jartinya end/2bila digunakan sebagai indeks)
Luis Mendo

Mungkin layak menjelaskan perilaku ketika diterapkan ke nomor dengan jumlah pembagi ganjil, karena "Indeks" dengan nilai non-integer tidak jelas.
Kamil Drakari

@ KamilDrakari Bagaimana itu?
DJMcMayhem

7

C (gcc) -lm , 35 byte

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

Cobalah online!


2
BTW, ini hanya berfungsi karena pengakuan GCC sqrtsebagai fungsi bawaan. Dengan -fno-builtin-sqrt, gcc mengasumsikan int sqrt(int), dan tidak lulus a double. Pada x86-64, doublediteruskan dalam register berbeda dari integer. Pada 32-bit, a doubleakan mengambil 2 slot di tumpukan, jadi Anda juga akan melewati sampah (atau subnormal dengan bilangan bulat sebagai bagian bawah mantissa, jika 32 bit atas adalah nol). Ini juga rusak kecuali jika Anda membuat debug build karena bergantung pada kode-gen default un-dioptimalkan gcc untuk mengevaluasi ekspresi dalam register nilai-kembali.
Peter Cordes

@PeterCordes Ya, ini kode golf, bukan perangkat medis :-)
cleblanc

Yah aku bukan penggemar retas balik palsu. Itu bahkan bukan C lagi, itu hanya detail implementasi dengan satu pengaturan kompiler yang merupakan default. (Ini benar-benar memperluas aturan "harus bekerja dengan setidaknya satu implementasi".) sqrt()Masalahnya berbeda: Saya ingin tahu bagaimana itu berhasil, karena penelepon entah bagaimana harus mengonversi intke double. Saya memposting jawaban itu sebagai komentar kalau-kalau ada orang lain yang penasaran. Secara efektif gcc memiliki sqrt(termasuk prototipe) sebagai bawaan, jika tidak, ini akan gagal karena alasan yang kadang-kadang kita lihat dalam SO asm Qs
Peter Cordes

i;f(n){for(i=0;++i<n/i||n%i;);}adalah 31B, dan bekerja dengan gcc -Opada x86-64 (dengan biaya 2 atau 3 byte lebih untuk opsi baris perintah). Menggunakan ||bukannya |menyebabkan gcc untuk meninggalkan n/ihasil dari idivdalam EAX, register nilai pengembalian ( godbolt.org/g/RJYeui ). Perilaku tidak terdefinisi dari ++itanpa titik urutan terjadi untuk bekerja. (ASM yang dihasilkan pada dasarnya sama dengan jawaban kode mesin x86 saya .) Dengan -O0, gcc sepertinya selalu pergi idi EAX, tapi mungkin kita bisa menggunakannya ...
Peter Cordes

Lagi pula, jika Anda menyukai jawaban detail implementasi non-C gcc, mungkin Anda akan menyukai jawaban x86-64 gcc ini yang berfungsi karena asm yang dihasilkan oleh kompiler untuk perilaku yang tidak terdefinisi dengan jelas: Coba online! (31 + 2 byte)
Peter Cordes


5

APL (Dyalog Unicode) , 16 14 12 byte

Saya senang saya bisa menulis jawaban di APL karena saya baru mempelajarinya. Banyak, banyak terima kasih kepada Adám untuk bantuan bermain golf. Saran bermain golf sangat disambut. Cobalah online!

Untuk mempelajari lebih lanjut tentang APL, lihat di The APL Orchard .

EDIT: -2 byte untuk memperbaiki masalah dengan kode saya. Terima kasih kepada H.PWiz untuk menunjukkan masalah itu. -2 byte dari memperpendek segalanya lagi.

⌈/{⍳⌊⍵*÷2}∨⊢

Tidak melakukanolf

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

Mengapa Anda dicoret dalam urutan terbalik? ... Saya sering melihat --- 16 --- --- 14 --- 12, bukan 12 --- 14 --- --- 16 ---.
user202729

@ user202729 Terus terang, sudah lama, dan saya cukup lupa urutan dicoret. Akan segera memperbaikinya.
Sherlock9

Sebenarnya ini bukan masalah, snipet leaderboard mendukung keduanya.
user202729

4

Sekam , 4 byte

→←½Ḋ

Cobalah online!

Penjelasan

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


3

x86 32-bit (IA32) kode mesin: 18 16 byte

changelog: menangani n=1test case dengan benar, menyimpan 2 byte, dan kembali dalam EAX.

Hitung sampai n/i <= i(yaitu ketika kita mencapai sqrt), dan gunakan pembagi pertama yang tepat setelah itu.

Versi 64-bit dari ini dapat dipanggil dari C dengan konvensi pemanggilan Sistem 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

Cobalah online! dengan pemanggil asm yang menggunakan byte pertama dari argv [1] sebagai integer secara langsung, dan menggunakan hasilnya sebagai status proses keluar.

$ 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
Apakah Anda yakin n = 1 bukan hanya 1? Terdaftar sebagai test case dan merupakan pembagi ≤ √1 = 1.
qwr

Jawaban Anda harus berfungsi untuk 1. Jika tidak bekerja dengan algoritme Anda, maka Anda harus membuat kode keras.
Wheat Wizard

2
@ qwr: diperbarui dengan versi yang lebih pendek yang berfungsi untuk semua input.
Peter Cordes

2

Japt -h, 8 6 byte

â f§U¬

Cobalah

2 byte disimpan berkat Oliver


Penjelasan

           :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

Jangan menandai masih byte biaya?
mbomb007

@ mbomb007 Tidak. Setiap turunan bendera dianggap sebagai entri bahasa baru.
Oliver

Lupakan. Saya kira saya belum melihat meta post itu.
mbomb007



2

Snowman , 38 byte

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

Cobalah online!

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

Cobalah online!

Penjelasan:

?                         # 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 berkat ide GCD Sherlock

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

Cobalah online!

jawaban asli

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

Cobalah online!

diurai

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

penjelasan

  • 1 + i.@<.@%:memberi jarak 1 .. floor(sqrt).
  • seluruh kata kerja (A) Bmembentuk kait, dengan kisaran di atas dilewati sebagai arg kanan ]ke A dan angka asli dilewatkan sebagai arg kirinya[ . Jadi...
  • ] | [ memberikan sisa-sisa setiap item dalam kisaran dibagi ke dalam arg asli.
  • dan 0 = ] | [memberi pembagi tanpa sisa.
  • ] #~ ... lalu menyaring rentang, hanya menyisakan itu.
  • dan {:memberikan item terakhir dalam daftar, yaitu yang terbesar.



1

QBasic (4.5), 52 byte

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

1

Keempat (gforth) , 53 byte

Cara terpendek tampaknya menggunakan stack floating point dan fsqrt, terpendek yang bisa saya dapatkan tanpa menggunakan 62 byte /moddan memeriksa apakah hasil bagi lebih besar dari pembagi.

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

Cobalah online!

Penjelasan

  1. Hitung akar kuadrat
  2. Mulai dari akar kuadrat, turun 1 hingga kita menemukan faktor dari angka aslinya

Penjelasan Kode

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

Cobalah online!

Seq.findBack: Mengembalikan elemen terakhir yang mengembalikan fungsi yang diberikan True. Fungsi dalam kasus ini memeriksa untuk melihat apakah angka merupakan faktor nilai.


1

Brain-Flak , 144 byte

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

Cobalah online!

Saya tidak begitu yakin jawaban ini sangat bagus. Saya merasa mungkin ada cara yang bagus untuk menyelesaikan tugas ini namun saya tidak cukup pintar.

Penjelasan

Saya mencoba melakukan tampilan jawaban yang meledak tetapi ada begitu banyak bagian yang bergerak sehingga tidak terlalu mencerahkan, jadi di sini ada penjelasan tentang apa yang dilakukan kode.

Bit penting pertama adalah ini

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

(x,y)xy

Bagian selanjutnya adalah perkalian, diambil dengan modifikasi dari wiki . Penggandaan ini istimewa karena menjaga nilai yang ada tanpa merusaknya. Bunyinya seperti:

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

Jadi kami mengalikan semua pasangan yang dipesan ini. Untuk setiap hasil, kami memeriksa apakah sama dengan input. Jika demikian, kami mengakhiri dan mengembalikan item yang lebih kecil dalam pasangan.





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}

Versi pra-uglified

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
}

Suntingan

  • Simpan satu byte dengan > 0lebih != 0. (Terima kasih kepada @CatWizard)

Bisakah !=diganti >?
Wheat Wizard

Panggilan bagus! Iya.
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)))}

Anda dapat mencoba ini secara online dengan menyalinnya ke dalam editor Pyret online !

Di atas mengevaluasi ke fungsi anonim. Ketika diterapkan ke bilangan bulat, itu mengembalikan hasil sesuai dengan spesifikasi.


0

Sebenarnya , 7 byte

Berdasarkan jawaban APL saya di sini . Selamat datang saran bermain golf! Cobalah online!

;√LR♀gM

Tidak melakukanolf

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

Port jawaban Mathematica ini .

Jelly , 11 byte

½ðḞ³÷Ċ³÷µÐL

Cobalah online!

Ini (11 byte) juga berfungsi, dan tidak bergantung pada ³:

½Ḟ÷@Ċ÷@ʋƬµṪ

Sayangnya ½Ḟ÷@Ċ÷@ʋÐL(10 byte) tidak berfungsi. Dan ternyata Ƭdan ÐĿtidak persis sama (ketika tautannya diad)


n

  • saya=nSebuah
  • Di setiap langkah:
    • sayasaya
    • nsayaSebuahsayanSebuahnsayanSebuahnsayaSebuahn÷nsaya
  • sayan÷nsaya sampai diperbaiki.

0

Java 8, 65 54 byte

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

Port of @hunteke 's Python 3 menjawab .

Cobalah online.


Jawaban 65 byte lama:

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

Cobalah online.

Penjelasan:

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`
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.