Prime Faktörlerinin Karelerinin Toplamı Çıkarıldığında Bir Aralıktaki En Büyük Sayı


17

Formül

Örneğin, 300 sayısını ele alalım

  • 300'ün asal faktörleri (300 ve asal faktör olan [2, 3, 5]benzersiz sayılar)
  • Bu sayıların her birinin karesini almak size [4, 9, 25]
  • Bu listeyi toplamak size 4 + 9 + 25 = 38
  • Son olarak, bu toplamı (38) orijinal numaranızdan çıkarın 300-38 = 262(sonuç budur)

Giriş

Girişiniz 2'den büyük bir pozitif tamsayı olacaktır. 2'den giriş değerine (dahil) tüm sayıları kontrol etmeli ve yukarıdaki formülle en iyi sonucu veren sayıyı bulmalısınız.


Çıktı

Çıktınız bir boşlukla ayrılmış iki sayı, virgül, yeni satır veya dilinizin izin verdiği her şey olacaktır (iki sayıyı ayırt etmek için ayırma gereklidir). Bunlar bir dosyaya, stdout'a veya dilinizin kullandığı her şeye çıkarılabilir. Amacınız, yukarıdaki formülle çalışırken maksimum çıktıyı üreten aralıktaki sayıyı bulmaktır. Görüntülenen ilk sayı başlangıç ​​numarası (300 gibi) ve ikinci sayı, formülün ürettiği çıktı (262 gibi) olmalıdır


Test Durumları

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


Örnek Çalışma

10'un girişini düşünün, 2-10 (dahil) tüm sayılar için formülü çalıştırmalıyız

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

Gördüğünüz gibi en büyük sonuç, 4değerin 8formüle girilmesinin bir sonucudur . Bu, bir giriş için çıkış anlamına gelir 10olmalıdır8, 4


Puanlama ve Kurallar

Girişler ve çıkışlar için varsayılan kurallar geçerlidir: Code Golf için varsayılan: Giriş / Çıkış yöntemleri
Standart boşluklar yasaktır: Varsayılan
Gönderimler tarafından yasaklanan delikler işlevler veya tam programlar olabilir

Bayt cinsinden en kısa kod kazanır


Birkaç yazım ve dilbilgisi hatasını düzelttim ve başlığı daha açıklayıcı hale getirdim. Ayrıca, boşluk ayırıcılarına izin vermeme konusundaki biraz da değiştim, çünkü kastettiğiniz şey bu değil (çünkü satırlar ve boşluklar boşluk karakterleri). İstediğiniz bu değilse, düzenlemeyi geri almaktan ve niyetinizi daha net yapmaktan çekinmeyin.
Mego

2
Maksimum sonuç için birkaç sayı bağlanırsa ne olur?
Dennis

1
@Dennis, maksimum sonuç üreten herhangi bir sayı olmasına izin vermem kabul edilebilir mi? Mevcut çözümlerin tümünü ihlal eden yeni bir kural koymak istemiyorum.
Keatinge

2
Evet, bu muhtemelen en iyi seçenektir. 950 hem [900, 862] hem de [945, 862] ' nin geçerli cevaplar olacağı bir örnek olabilir .
Dennis

1
Can I çıkış girişi için ters sırada sayılar, örneğin 50: 35, 48?
nimi

Yanıtlar:



4

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

Bunun 300 karakter altında olması gerektiğini düşündüm çünkü ... bilirsin ... Java!

Ve hatta 200 karakter altında bile mümkündür!

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

İthalatın bu kullanımının yasal olup olmadığını bilmiyorum ama her şeyin yolunda olduğunu düşünüyorum.İşte bir sınıfa sokulan lambda:

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

Temel faktör bulma, bu cevaba . Onlar sadece bir kez her değeri kaydetmek gibi kod kümelerin işlevselliğini kullanır, bu nedenle daha sonra ek kopyaları umurumda değil. Kodun geri kalanı oldukça basittir, sadece soruyu takip eder.

Güncellemeler

Yeni satır çıktıdan kaldırıldı.

@Ogregoire'a Integer.MIN_VALUE değerini 1 << 31'e verdiği için teşekkürler!

Tekrar kod baktıktan sonra şeyler golf olabilir bazı yerler bulundu.

== 0 - <1 numara @Blue'ya teşekkürler!

Artık kalan boşluk kaldırıldı. Ayrıca ayırma için sadece bir karakter gereklidir, bu nedenle bir karakter harcanmasına gerek yoktur.

@Ogregoire'e, değeri yazdırmak ve beyanları bir araya getirmek yerine değeri iade edebileceğimi işaret ettiği için tekrar teşekkürler! Bu çok tasarruf etti!

Bir tane daha kaydetmek için ikinci yerine bir üçlü kullanabilirsiniz.

İçe aktarmayı kaydeden bir dizinin harika kullanımı için @AstronDan'a teşekkürler . Bu da bana bir üçlü içine ilk girilirse kısaltma imkânı verdi.


1
Integer.MIN_VALUEolarak kısaltılabilir 1<<31.
Olivier Grégoire

1
Mavi

1
Birkaç kez inttekrarlamaktan kaçınmak için hepsini aynı yerde ilan intedin ve mümkünse değerlerini atayın.
Olivier Grégoire

1
Ayrıca, bundan kurtulun System.out.println(...)ve yazdırmak yerine bir değer döndürün: OP'den bahsedildiği gibi, standart G / Ç yöntemi kullanılmaktadır.
Olivier Grégoire

1
C # 'da kullandığım dizi hilesini hashset'i int dizisine dönüştürmek için de kullanabilirsiniz. Bu, büyük olasılıkla içe aktarmayı birçok bayt tasarruf etmenize izin verir.
AstroDan

3

Aslında 21 bayt

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

Çevrimiçi deneyin!

Açıklama:

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

Bu dile bağlantı verebilir misiniz?
Charles

1
@NotthatCharles Çevrimiçi yorumlayıcıda dilin adını tıklatabilirsiniz.
Dennis

Tamam Actually Programming Language, google'a gittim ve google sonuçlarının 5. sayfasına göz attıktan sonra bile hiçbir şey bulamadım. Bu dil nedir?
Tejas Kale

2
@Tejas Sizi kaynağına gönderecek dilin adını tıklayabilirsiniz: github.com/Mego/Seriously
Amndeep7

3

MATL , 18 bayt

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

Çevrimiçi deneyin!

Son durum çevrimiçi derleyici için çok uzun sürüyor, ancak doğru sonucu veriyor (Matlab'da çalışan bilgisayarımda yaklaşık 11 saniye sürüyor):

enter image description here

açıklama

Açıklanan prosedürün doğrudan uygulanması.

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

3

C #, 194 bayt

İlk Kod Golfüm :). Ayrıntılarına rağmen en sevdiğim dili kullandım. Ben @ Frozn Java'nın C # fonksiyon portu olarak başladı ama optimizasyonlar ile kodu daha daraltmak için çeşitli yollar buldum.

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

Bu, asal faktörleri saklamak için bir dizi kullanır. Faktör tarafından endekslendiği için, tekrarlanan faktörleri faktörün kopyaları ile değiştirecektir. Bu, işlevin içe aktarılmasına izin vermez. Bu bile Sistem gerektirmez.


Bu gerçekten güzel bir numara! Benim sürümde kullanmaya çalışacağız
Frozn

3

Bash + GNU yardımcı programları, 74

seq 2 $1|factor|sed -r 's/:?( \w+)\1*/-\1*\1/g'|bc|nl -v2|sort -nrk2|sed q
  • seq 2 ile n arasındaki tüm tamsayıları üretir
  • factorardından iki nokta üst üste işaretini, ardından kopyalar dahil tüm asal faktörlerin boşlukla ayrılmış bir listesini verir. 12 için sonuç12: 2 2 3
  • sediki nokta üst üste ve yinelenen faktörleri kaldırır, ardından gerekli aritmetik ifadeyi üretir. örneğin 12 için:12- 2* 2- 3* 3
  • bc bunu değerlendirir
  • nl ön ekler n geri (2'den başlayarak)
  • sort ikinci sütuna göre, sayısal olarak, azalan sırada
  • seq ilk satırı yazdırır ve çıkar.

Ideone.


2

Brachylog , 48 bayt

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

açıklama

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]

2

Jöle , 13 bayt

ÆfQ²S_@,µ€ḊṀṚ

Çevrimiçi deneyin! veya tüm test senaryolarını doğrulayın .

Nasıl çalışır

Æ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.

2

05AB1E, 19 17 16 bayt

Kod:

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

Açıklama:

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]

Çevrimiçi deneyin


2

Julia, 56 bayt

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

Çevrimiçi deneyin!

Nasıl çalışır

Bir giriş göz önüne alındığında , n , her tam sayı için, k bu şekilde 2 ≤ k ≤ n , biz başlığın oluşturmak (f (k), k) , r (k) arasındaki farktır , k ve ana faktör karelerinin toplamının .

f (k) 'nin kendisi ile hesaplanır k-sumabs2(k|>factor|>keys), bu da k'yi asal anahtarların ve üs değerlerinin bir Diksiyonuna dönüştüren, tüm anahtarları (asal çarpanlar) ayıklayan, karelerinin toplamını alan ve elde edilen tamsayıyı k'dan çıkartan .

Son olarak, oluşturulan tuple'lerin sözlükbilimsel maksimumunu alırız ve 2. ve 1. indekslere erişerek tersine çeviririz .


1

Clojure, 215 bayt

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

Sadece kurallara uyun. Her sayının asal çarpanlarını hesaplar, kareye koyar ve toplar. Bundan sonra 2 elemandan oluşan vektörlerin bir listesini oluşturun: ilk sayı ve sonucu ve maksimum ikinci eleman değerine sahip elemanı bulun.

Çevrimiçi olarak burada görebilirsiniz: https://ideone.com/1J9i0y


1

R 109 bayt

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

Aldattım ve bir paket kullandım gmp.




1

PowerShell V2 +, 124 , 120 117 bayt

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

İlk satır değerleri hesaplar, ikincisi sadece çıktıdır.

2Komut satırı argümanımıza kadar bir aralık oluşturmaya başlıyoruz $args[0]ve bunu döngüye alıyoruz |%{...}. Her döngüde yardımcı değişkenler mevcut değerimize eşit olarak ayarlanır $y=$z=$_. Daha sonra 2şu anki sayımıza kadar her sayıyı gözden geçiririz. Her iç döngü, bu sayının bir bölen !($z%$_)olup olmadığını ve asal olup olmadığını kontrol eder ('1'*$_-match'^(?!(..+)\1+$)..')ve her ikisi de ise kareyi çıkarırız $y(kontroller Boole çarpımı kullanılarak yapılır).

Tüm ana bölücülerden geçip kareleri çıkardığımızda, kalan sayı şimdiye kadar gördüğümüz en büyük sayı ise, $y-gt$oçıktı değişkenlerimizi belirleriz $o=$y;$p=$_. Tüm ürün yelpazesinde dolaştıktan sonra, aralarında boşluk bırakıyoruz.


1

Haskell, 91 bayt

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]]

Kullanım örneği: f 50-> [48,35].

Başbakan faktör fonksiyonları sadece import Data.Numbers.Primesçok fazla bayt maliyeti ile kullanılabilir , bu yüzden @ Lynn'in prime checker kullanıyorum . Gerisi düz ileri: giriş mdöngüsü niçinden [2..m]ve iç döngü piçinden [2..n]. pAsal ve böl n, kare ve toplamı koruyun .


1

Piton 2, 108 105 , 100 bayt

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)

Ideone üzerinde test edin .


1

JavaScript (ES6), 111 105 bayt

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

Bunu daha önce yinelemeli olarak yapmayı düşünmedim.


1

J, 44 bayt

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

Basit yaklaşım. Ayrıca nbu sonucun tüm değerlerini maksimum değerle döndürür .

kullanım

   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
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.