Angka Terbesar dalam Kisaran Ketika Jumlah Kuadrat dari Faktor Utamanya Diurangkan

17

Rumus

Ambil contoh angka 300

  • Faktor prima 300 adalah [2, 3, 5](angka unik yang merupakan faktor 300 dan prima)
  • Mengkuadratkan masing-masing angka itu akan memberi Anda [4, 9, 25]
  • Menyimpulkan daftar itu akan memberi Anda 4 + 9 + 25 = 38
  • Akhirnya kurangi jumlah itu (38) dari nomor asli Anda 300-38 = 262(ini hasilnya)

Memasukkan

Input Anda akan menjadi bilangan bulat positif lebih besar dari 2. Anda harus memeriksa semua angka dari 2 hingga nilai input (inklusif) dan menemukan angka yang menghasilkan hasil terbesar dengan rumus di atas.


Keluaran

Output Anda akan menjadi dua angka yang dipisahkan oleh spasi, koma, baris baru atau apa pun bahasa Anda memungkinkan (pemisahan diperlukan untuk membedakan dua angka). Ini bisa berupa output ke file, stdout, atau apa pun yang digunakan bahasa Anda. Tujuan Anda adalah menemukan angka dalam rentang yang menghasilkan output maksimum saat dijalankan melalui rumus di atas. Angka pertama yang ditampilkan harus berupa angka awal (seperti 300) dan angka kedua harus menjadi output yang dihasilkan formula (seperti 262)


Uji Kasus

Input: 3       Output: 2, -2
Input: 10      Output: 8, 4
Input: 50      Output: 48, 35
Input: 1000    Output: 1000, 971
Input: 9999    Output: 9984, 9802


Bekerja Melalui Contoh

Pertimbangkan input 10, kita harus menjalankan rumus untuk semua angka dari 2-10 (termasuk)

Num PrimeFacs PrimeFacs^2 SumPrimeFacs^2 Result
2   [2]       [4]         4              -2
3   [3]       [9]         9              -6
4   [2]       [4]         4               0
5   [5]       [25]        25             -20
6   [2, 3]    [4, 9]      13             -7
7   [7]       [49]        49             -42
8   [2]       [4]         4               4
9   [3]       [9]         9               0
10  [2, 5]    [4, 25]     29             -19

Seperti yang Anda lihat, hasil terbesar adalah 4, yang merupakan hasil dari memasukkan nilai 8ke dalam rumus. Itu berarti output untuk input 10seharusnya8, 4


Penilaian & Aturan

Aturan default untuk input dan output berlaku: Default untuk Code Golf: Metode input / Output Celah
lubang standar dilarang: Celah yang dilarang oleh
Pengajuan standar dapat berupa fungsi atau program penuh

Kode terpendek dalam byte menang

Keatinge
sumber
Saya telah memperbaiki beberapa kesalahan pengejaan dan tata bahasa, dan menjadikan judulnya lebih deskriptif. Saya juga mengubah sedikit tentang pelarangan pemisah spasi putih, karena itu jelas bukan yang Anda maksudkan (karena baris baru dan spasi adalah karakter spasi putih). Jika ini bukan yang Anda inginkan, silakan kembali mengedit dan memperjelas niat Anda.
Mego
2
Apa yang harus terjadi jika beberapa angka diikat untuk hasil maksimal?
Dennis
1
@ Dennis, dapatkah saya mengizinkannya menjadi nomor apa pun yang menghasilkan hasil maksimal? Saya tidak ingin memaksakan aturan baru yang merusak semua solusi yang ada.
Keatinge
2
Ya, itu mungkin pilihan terbaik. 950 bisa menjadi contoh, di mana [900, 862] dan [945, 862] akan menjadi jawaban yang valid.
Dennis
1
Can I output angka dalam urutan terbalik, misalnya untuk input 50: 35, 48?
nimi

Jawaban:

4

Java 8 lambda, 247 239 233 225 224 219 198 161 karakter

Saya pikir itu mungkin di bawah 300 karakter karena ... Anda tahu ... Jawa!

Dan memang mungkin bahkan di bawah 200 karakter!

m->{int n=1,u,f,F[],g,G=g=1<<31;for(;++n<=m;){u=n;F=new int[m+1];for(f=1;++f<=u;)u/=u%f<1?(F[f]=f--):1;f=0;for(int p:F)f+=p*p;g=n-f>g?(G=n)-f:g;}return G+","+g;}

Saya tidak tahu apakah penggunaan impor ini sah tetapi saya berasumsi, bahwa itu boleh saja. Berikut adalah lambda yang tidak diolah menjadi kelas:

public class Q80507 {
    static String greatestAfterReduction(int maxNumber) {
        int number = 1, upper, factor, primeFactors[], greatestResult, greatestNumber = greatestResult = 1 << 31; // <-- Integer.MIN_VALUE;
        for (;++number <= maxNumber;) {
            // get unique primefactors
            upper = number;
            primeFactors = new int[maxNumber + 1];
            for (factor = 1; ++factor <= upper;)
                upper /= upper % factor < 1 ? (primeFactors[factor] = factor--) : 1;

            factor = 0;
            for (int prime : primeFactors)
                factor += prime * prime;

            greatestResult = number - factor > greatestResult ? (greatestNumber = number) - factor : greatestResult;
        }
        return greatestNumber + "," + greatestResult;
    }
}

Temuan utama didasarkan pada jawaban ini . Kode menggunakan fungsionalitas set karena mereka hanya menyimpan setiap nilai sekali, jadi saya tidak perlu peduli dengan duplikat tambahan nanti. Sisa kode cukup mudah, hanya mengikuti pertanyaan.

Pembaruan

Menghapus baris baru dari output.

Terima kasih kepada @ogregoire karena bermain golf Integer.MIN_VALUE ke 1 << 31!

Setelah melihat kode lagi saya menemukan beberapa tempat di mana hal-hal bisa golf.

Terima kasih kepada @Blue untuk trik == 0 hingga <1!

Menghapus beberapa spasi putih yang tersisa. Juga untuk pemisahan hanya satu char yang diperlukan sehingga tidak perlu membuang satu char.

Terima kasih lagi kepada @ogregoire karena menunjukkan bahwa saya dapat mengembalikan nilai alih-alih mencetaknya dan menyusun deklarasi! Ini banyak menghemat!

Mengetahui saya bisa menggunakan ternary bukan yang kedua jika untuk menyimpan satu char lagi.

Terima kasih kepada @AstronDan untuk penggunaan array yang mengagumkan yang menyimpan impor. Itu juga memberi saya kemungkinan untuk mempersingkat yang pertama jika menjadi terner.

Frozn
sumber
1
Integer.MIN_VALUEdapat disingkat menjadi 1<<31.
Olivier Grégoire
1
Simpan 1 byte dengan if (u% f <1) sebagai gantinya
Biru
1
Nyatakan semua milik Anda intdi tempat yang sama untuk menghindari pengulangan intbeberapa kali, dan berikan nilainya di sana jika memungkinkan.
Olivier Grégoire
1
Juga, singkirkan itu System.out.println(...)dan kembalikan nilai alih-alih mencetaknya: begitu OP menyebutkan, metode I / O standar sedang digunakan.
Olivier Grégoire
1
Anda juga dapat menggunakan trik array yang saya gunakan di C # untuk mengubah hashset menjadi array int. Ini akan memungkinkan Anda menjatuhkan impor, menghemat banyak byte.
AstroDan
3

Sebenarnya, 21 byte

u2x;`;y;*@-`M;M;)@í@E

Cobalah online!

Penjelasan:

u2x;`;y;*@-`M;M;)@í@E
u2x;                   push two copies of range(2, n+1) ([2, n])
    `      `M          map:
     ;                   duplicate
      y;                 push two copies of prime divisors
        *                dot product of prime divisors lists (equivalent to sum of squares)
         @-              subtract from n
             ;M;)      duplicate, two copies of max, move one copy to bottom of stack
                 @í    get index of max element
                   @E  get corresponding element from range
Mego
sumber
Bisakah Anda menautkan ke bahasa ini?
Bukan berarti Charles
1
@NotthatCharles Anda dapat mengklik nama bahasa di penerjemah online.
Dennis
Ok saya googled Actually Programming Languagedan tidak menemukan apa-apa bahkan setelah browsing halaman 5 hasil google. Bahasa apakah ini?
Tejas Kale
2
@Tejas Anda bisa mengklik nama bahasa yang akan mengirim Anda ke sumbernya: github.com/Mego/Serius
Amndeep7
3

MATL , 18 byte

:"@tYfu2^s-]v2#X>w

Cobalah online!

Kasing terakhir terlalu lama untuk kompiler online, tetapi menghasilkan hasil yang benar (dibutuhkan sekitar 11 detik di komputer saya, berjalan di Matlab):

masukkan deskripsi gambar di sini

Penjelasan

Penerapan langsung dari prosedur yang dijelaskan.

:         % Implicit input n. Range [1 2 ... n]
"         % For each
  @       %   Push that number
  tYfu    %   Duplicate. Prime factors. Unique values
  2^s-    %   Square. Sum of array values. Subtract
]         % End for each
v         % Concatenate stack contents into vertical vector
2#X>      % Max and arg max
w         % Swap. Implicit display         
Luis Mendo
sumber
3

C #, 194 byte

Golf Code pertama saya :). Saya menggunakan bahasa favorit saya meskipun sangat jelas. Saya memulai ini sebagai port fungsi C # dari Java @ Frozn tetapi menemukan beberapa cara untuk mengecilkan kode lebih lanjut dengan optimisasi.

string R(int a){int u,f,g,N=g=1<<31;for(int n=1;++n<=a;){u=n;int[]P=new int[a+1];for(f=1;++f<=u;){if(u%f<1){u/=f;P[f]=f--;}}f=0;foreach(var p in P){f+=p*p;}if(n-f>g){g=(N=n)-f;}}return N+","+g;}

Ini menggunakan array untuk menyimpan faktor prima. Karena diindeks oleh faktor itu akan menggantikan faktor yang diulang dengan salinan faktor. Ini memungkinkan fungsi tidak memiliki impor. Ini bahkan tidak memerlukan Sistem.

AstroDan
sumber
Ini benar-benar trik yang bagus! Akan mencoba menggunakannya dalam versi saya
Frozn
3

Utilitas Bash + GNU, 74

seq 2 $1|factor|sed -r 's/:?( \w+)\1*/-\1*\1/g'|bc|nl -v2|sort -nrk2|sed q
  • seq menghasilkan semua bilangan bulat 2 ke n
  • factormemberikan nomor diikuti oleh titik dua, lalu daftar yang dipisahkan ruang dari semua faktor utama, termasuk duplikat. misalnya hasil untuk 12 adalah12: 2 2 3
  • sedmenghilangkan titik dua dan faktor duplikat, kemudian menghasilkan ekspresi aritmatika yang diperlukan. misalnya untuk 12:12- 2* 2- 3* 3
  • bc mengevaluasi ini
  • nl awalan dan kembali (mulai dari 2)
  • sort oleh kolom kedua, secara numerik, dalam urutan menurun
  • seq mencetak baris pertama dan berhenti.

Ideone.

Trauma Digital
sumber
2

Brachylog , 48 byte

:2:{eI$pd:{:2^.}a+:I--:I.}fF$\hor:0m:Ir.r~m[F:J]

Penjelasan

Main predicate:

:2:{}fF                     Unify F with the list of all binding for which predicate 1 is
                            true, given [Input, 2] as input.
       $\hor:0m             Retrieve the max of F by diagonalizing it, taking the
                            first row, sorting that row and reversing the sorted row.
               :Ir.         Unify the Output with [I, Max],
                   r~m[F:J] [I, Max] is in F at index J (the index is unimportant)


Predicate 1:

eI                          I is an integer in the range given in Input
  $pd                       Get the list of prime factors of I, with no duplicates
     :{:2^.}a               Apply squaring to each element of that list
             +              Sum the list
              :I-           Subtract I from the sum
                 -          Multiply by -1 (let's call it Result)
                  :I.       Unify the Output with [Result, I]
Fatalisasi
sumber
2

Jelly , 13 byte

ÆfQ²S_@,µ€ḊṀṚ

Cobalah online! atau verifikasi semua kasus uji .

Bagaimana itu bekerja

ÆfQ²S_@,µ€ḊṀṚ  Main link. Argument: n

        µ      Combine the chain to the left into a link.
         €     Apply it to each k in [1, ..., n].
Æf               Yield k's prime factors as a list.
  Q              Unique; deduplicate the prime factors.
   ²             Square each unique prime factor.
    S            Compute their sum.
     _@          Subtract the result from k.
       ,         Pair with k, yielding [result(k), k].
          Ḋ    Dequeue; discard the first pair which corresponds to k = 1.
           Ṁ   Get the maximum (lexicographical order).
            Ṛ  Reverse the pair.
Dennis
sumber
2

05AB1E, 19 17 16 byte

Kode:

L©f€n€O®-®)ø¦{¤R

Penjelasan:

L                    # make a list of 1..input [1,2,3,4,5,6]
 ©                   # save the list for reuse
  f                  # get primefactors of numbers in list [[],[2],[3],[2],[5],[2,3]]
   €n                # square each factor [[],[4],[9],[4],[25],[4,9]]
     €O              # sum the factors [0,4,9,4,25,13]
       ®-            # subtract from saved list [1,-2,-6,0,-20,-7]
         ®)ø         # zip with saved list [[1,1],[-2,2],[-6,3],[0,4],[-20,5],[-7,6]]
            ¦        # drop the first item (n=1) [[-2,2],[-6,3],[0,4],[-20,5],[-7,6]]
             {       # sort [[-20,5],[-7,6],[-6,3],[-2,2],[0,4]]
              ¤      # get last item [0,4]
               R     # reverse [4,0]

Cobalah online

Emigna
sumber
2

Julia, 56 byte

!n=maximum(k->(k-sumabs2(k|>factor|>keys),k),2:n)[[2,1]]

Cobalah online!

Bagaimana itu bekerja

Diberi masukan n , untuk setiap bilangan bulat k sehingga 2 ≤ k ≤ n , kita menghasilkan tupel (f (k), k) , di mana f (k) adalah perbedaan antara k dan jumlah kuadrat dari faktor perdana .

f (k) sendiri dihitung dengan k-sumabs2(k|>factor|>keys), faktor mana k menjadi Dict dari kunci utama dan nilai eksponen, mengekstrak semua kunci (faktor utama), mengambil jumlah kuadratnya dan mengurangi bilangan bulat yang dihasilkan dari k .

Akhirnya, kami mengambil maksimum leksikografis tupel yang dihasilkan dan membalikkannya dengan mengaksesnya pada indeks 2 dan 1 .

Dennis
sumber
1

Clojure, 215 byte

(fn j[x](apply max-key second(map(fn[w][w(- w(let[y(reduce +(map #(* % %)(set(flatten((fn f[q](let[c(filter(fn[r](=(mod q r)0))(range 2 q))](if(empty? c)q(map f c))))w)))))](if(= y 0)(* w w)y)))])(range 2(inc x)))))

Ikuti saja aturannya. Hitung faktor prima dari setiap angka, masukkan ke kotak dan jumlahkan. Setelah itu buat daftar vektor dari 2 elemen: angka awal dan hasilnya dan temukan elemen dengan nilai maksimum elemen kedua.

Anda dapat melihatnya online di sini: https://ideone.com/1J9i0y

cliffroot
sumber
1

R 109 byte

y=sapply(x<-2:scan(),FUN=function(x)x-sum(unique(as.numeric(gmp::factorize(x))^2)));c(x[which.max(y)],max(y))

Saya curang dan menggunakan paket gmp,.

bouncyball
sumber
1

Pyke, 17 byte

FODP}mXs-)DSei@Oi

Coba di sini!

Biru
sumber
1

PowerShell v2 +, 124 120 117 byte

2..$args[0]|%{$y=$z=$_;2..$_|%{$y-=$_*$_*!($z%$_)*('1'*$_-match'^(?!(..+)\1+$)..')};if($y-gt$o){$o=$y;$p=$_}}
"$p $o"

Baris pertama menghitung nilainya, yang kedua hanya keluaran.

Kami mulai dengan membuat rentang dari 2hingga argumen baris perintah kami $args[0]dan mengulanginya |%{...}. Setiap loop yang kami tetapkan variabel pembantu sama dengan nilai kami saat ini dengan $y=$z=$_. Kami kemudian mengulangi setiap nomor dari 2hingga nomor kami saat ini. Setiap loop batin kita periksa apakah angka itu adalah pembagi !($z%$_)dan apakah itu prima ('1'*$_-match'^(?!(..+)\1+$)..') , dan jika keduanya kita kurangi kuadrat dari$y (cek dilakukan dengan menggunakan perkalian Boolean).

Setelah kami melewati semua pembagi utama dan mengurangi kuadrat, jika jumlah yang tersisa adalah yang terbesar yang kami lihat sejauh ini $y-gt$o, kami menetapkan variabel output kami $o=$y;$p=$_. Setelah kami mengulang seluruh rentang, kami cukup menampilkan dengan spasi di antaranya.

AdmBorkBork
sumber
1

Haskell, 91 byte

f m=reverse$maximum[[n-sum[p^2|p<-[2..n],mod n p<1,mod(product[1..p-1]^2)p>0],n]|n<-[2..m]]

Contoh penggunaan: f 50->[48,35] .

Fungsi faktor utama hanya tersedia melalui import Data.Numbers.Primesyang biaya byte terlalu banyak, jadi saya menggunakan pemeriksa utama @ Lynn . Sisanya adalah lurus ke depan: untuk input mlingkaran nmelalui [2..m]dan dalam loop batin pmelalui [2..n]. Simpan semua pyang prima dan bagi n, kuadrat dan jumlah.

nimi
sumber
1

Python 2, 108 105 100 byte

f=lambda n,m=2,p=1:m>n or-~f(n,m+1,p*m*m)-(n%m<p%m)*m*m
r=max(range(2,input()+1),key=f)
print r,f(r)

Uji di Ideone .

Dennis
sumber
1

JavaScript (ES6), 111 105 byte

f=n=>{r=n<2?[]:f(n-1);for(s=[],j=n,i=2;j>1;k%i?i++:j/s[i]=i);s.map(i=>j-=i*i,j=n);return j<r[1]?r:[n,j]}

Tidak tahu mengapa saya tidak berpikir untuk melakukan ini secara rekursif sebelumnya.

Neil
sumber
1

J, 44 byte

[:((],.~2+I.@e.)>./)@:}.1(-[:+/*:@~.@q:)@+i.

Pendekatan lurus ke depan. Juga mengembalikan semua nilain yang menghasilkan nilai maksimum.

Pemakaian

   f =: [:((],.~2+I.@e.)>./)@:}.1(-[:+/*:@~.@q:)@+i.
   f 3
2 _2
   f 10
8 4
   f 50
48 35
   f 1000
1000 971
   f 9999
9984 9802
   f 950
900 862
945 862
mil
sumber