Numero massimo in un intervallo quando viene sottratta la somma dei quadrati dei suoi fattori primi


17

La formula

Prendi ad esempio il numero 300

  • I fattori primi di 300 sono [2, 3, 5](numeri univoci che sono fattori di 300 e primi)
  • Quadrare ciascuno di quei numeri ti darà [4, 9, 25]
  • Sommare quella lista ti darà 4 + 9 + 25 = 38
  • Infine sottrai quella somma (38) dal tuo numero originale 300-38 = 262(questo è il risultato)

Ingresso

Il tuo input sarà un numero intero positivo maggiore di 2. Devi controllare tutti i numeri da 2 al valore di input (incluso) e trovare il numero che produce il miglior risultato con la formula sopra.


Produzione

L'output sarà composto da due numeri separati da uno spazio, una virgola, una nuova riga o qualsiasi altra cosa consentita dalla lingua (la separazione è necessaria per distinguere i due numeri). Questi possono essere emessi in un file, stdout o qualunque cosa usi la tua lingua. Il tuo obiettivo è trovare il numero nell'intervallo che produce l'output massimo quando si esegue la formula sopra. Il primo numero visualizzato dovrebbe essere il numero iniziale (come 300) e il secondo numero dovrebbe essere l'output prodotto dalla formula (come 262)


Casi test

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


Ho lavorato attraverso l'esempio

Considera l'input di 10, dobbiamo eseguire la formula per tutti i numeri da 2-10 (incluso)

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

Come puoi vedere, il risultato più grande è 4stato il risultato dell'inserimento del valore 8nella formula. Ciò significa che l'output per un input di 10dovrebbe essere8, 4


Punteggio e regole

Le regole predefinite per gli ingressi e le uscite si applicano: di default per il codice Golf: metodi di input / output
Le scappatoie standard sono vietati: scappatoie che sono proibite dalla predefinite
Inseriti può essere funzioni o programmi completi

Vince il codice più breve in byte


Ho corretto alcuni errori di ortografia e grammaticali e ho reso il titolo più descrittivo. Ho cambiato anche il po 'di non consentire separatori spazi bianchi, dal momento che non è chiaramente quello che volevi dire (in quanto a capo e gli spazi sono spazi bianchi caratteri). Se questo non è ciò che si intendeva, sentitevi liberi di tornare alla modifica e rendere la vostra intenzione più chiara.
Mego,

2
Cosa dovrebbe accadere se più numeri sono legati per il massimo risultato?
Dennis,

1
@Dennis è accettabile per me consentire che sia un numero che genera il massimo risultato? Non voglio imporre una nuova regola che rompe tutte le soluzioni esistenti.
Keatinge,

2
Sì, questa è probabilmente l'opzione migliore. 950 potrebbe essere un esempio, dove sia [900, 862] e [945, 862] sarebbe risposte valide.
Dennis,

1
Uscita Posso i numeri in ordine inverso, ad esempio per l'ingresso 50: 35, 48?
nimi,

Risposte:



4

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

Ho pensato che potesse essere possibile in meno di 300 caratteri perché ... sai ... Java!

Ed è davvero possibile anche con meno di 200 caratteri!

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

Non so se questo uso delle importazioni è legittimo ma suppongo, che dovrebbe essere a posto. Ecco l'lambda ungolfed in una classe:

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

Il primefactor-constatazione è basata su questa risposta . Il codice utilizza la funzionalità degli insiemi poiché salvano ogni valore una sola volta, quindi non mi devo preoccupare dei duplicati aggiunti in seguito. Il resto del codice è piuttosto semplice, solo seguendo la questione.

aggiornamenti

Rimosso il ritorno a capo dall'output.

Grazie a @ogregoire per giocare a golf l'Integer.MIN_VALUE al 1 << 31!

Dopo aver guardato sul codice di nuovo ho trovato alcuni altri luoghi in cui le cose potrebbero stato giocato a golf.

Grazie a @Blue per il == 0 a <1 trucco!

Rimosso alcuni avanzi di spazi bianchi. Anche per la separazione è necessario un unico carattere quindi nessun bisogno di sprecare un char.

Grazie ancora a @ogregoire per aver sottolineato che posso restituire il valore invece di stamparlo e mettere insieme le dichiarazioni! Questo ha salvato un sacco!

Ha scoperto che posso utilizzare un ternario al posto del secondo, se per salvare un altro carattere.

Grazie a @AstronDan per l' impressionante utilizzo di una matrice che salva l'importazione. Che mi ha dato anche la possibilità di accorciare il primo caso in un ternario.


1
Integer.MIN_VALUEpuò essere abbreviato come 1<<31.
Olivier Grégoire

1
Salva 1 byte con se (u% f <1), invece
Blu

1
Dichiarare tutti i ints nello stesso luogo per evitare di ripetere intpiù volte, e assegnare loro il valore di lì, se possibile.
Olivier Grégoire

1
Inoltre, eliminalo System.out.println(...)e restituisci un valore invece di stamparlo: come menziona l'OP, è in uso il metodo I / O standard.
Olivier Grégoire,

1
È inoltre possibile utilizzare il trucco matrice che ho usato in C # per trasformare il HashSet in un array int. Questo probabilmente permetterà di far cadere l'importazione salvare molte byte.
AstroDan

3

In realtà, 21 byte

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

Provalo online!

Spiegazione:

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

Puoi collegarti a questa lingua?
Non che Charles,

1
@NotthatCharles È possibile fare clic sul nome della lingua nel interprete in linea.
Dennis,

Ok, ho cercato Actually Programming Languagesu Google e non ho trovato nulla anche dopo aver sfogliato la quinta pagina dei risultati di Google. Che lingua è?
Tejas Kale

2
@Tejas Si potrebbe fare clic sul nome della lingua che avrebbe mandato alla sua fonte: github.com/Mego/Seriously
Amndeep7

3

MATL , 18 byte

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

Provalo online!

L'ultimo caso impiega troppo tempo per il compilatore in linea, ma produce il risultato corretto (ci vogliono circa 11 secondi nel mio computer, in esecuzione su Matlab):

inserisci qui la descrizione dell'immagine

Spiegazione

applicazione diretta della procedura descritta.

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

Il mio primo codice Golf :). Ho usato la mia lingua preferita nonostante la sua verbosità. Ho iniziato questo come una funzione C # @ porto di Java di Frozn ma ha trovato diversi modi per compattare il codice ulteriormente con le ottimizzazioni.

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

Questo utilizza una matrice per memorizzare i fattori primi. Perché è indicizzato il fattore sostituirà fattori ripetute con copie del fattore. Questo permette la funzione di non avere le importazioni. Questo non richiede nemmeno di sistema.


Questo è davvero un bel trucco! Cercherà uso nella mia versione
Frozn

3

utility Bash + GNU, 74

seq 2 $1|factor|sed -r 's/:?( \w+)\1*/-\1*\1/g'|bc|nl -v2|sort -nrk2|sed q
  • seq genera tutti i numeri interi da 2 a n
  • factorfornisce il numero seguito da due punti, quindi da un elenco separato da spazi di tutti i fattori primi, inclusi i duplicati. ad es. il risultato per 12 è12: 2 2 3
  • sedrimuove i due punti e i fattori duplicati, quindi genera l'espressione aritmetica richiesta. ad es. per 12:12- 2* 2- 3* 3
  • bc valuta questo
  • nl prefissi n back in (a partire da 2)
  • sort dalla seconda colonna, numericamente, in ordine decrescente
  • seq stampa la prima riga ed esce.

Ideone.


2

Brachylog , 48 byte

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

Spiegazione

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

Gelatina , 13 byte

ÆfQ²S_@,µ€ḊṀṚ

Provalo online! o verifica tutti i casi di test .

Come funziona

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

Codice:

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

Spiegazione:

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]

Provalo online


2

Julia, 56 byte

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

Provalo online!

Come funziona

Dato un input n , per ogni intero k tale che 2 ≤ k ≤ n , generiamo la tupla (f (k), k) , dove f (k) è la differenza tra k e la somma dei quadrati dei suoi fattori primi .

f (k) stesso viene calcolato con k-sumabs2(k|>factor|>keys), quali fattori k in un Dict di chiavi primi e valori di esponente, estrae tutte le chiavi (fattori primi), prende la somma dei loro quadrati e sottrae l'intero risultante da k .

Infine, prendiamo il massimo lessicografico delle tuple generate e lo invertiamo accedendolo agli indici 2 e 1 .


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

Segue solo le regole. Calcola i fattori primi di ogni numero, mettili al quadrato e sommali. Successivamente, genera un elenco di vettori di 2 elementi: numero iniziale e relativo risultato e trova l'elemento con il valore massimo del secondo elemento.

Puoi vederlo online qui: https://ideone.com/1J9i0y


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

Ho tradito e usato un pacchetto, gmp.




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"

La prima riga calcola i valori, la seconda viene appena emessa.

Si comincia con la creazione di una gamma da 2fino al nostro argomento della riga di comando $args[0]e ciclo che |%{...}. Ogni loop abbiamo impostato le variabili helper uguale al nostro valore corrente con $y=$z=$_. Abbiamo poi scorrere ogni numero dal 2fino al nostro numero attuale. Ogni ciclo interno, controlliamo se quel numero è un divisore !($z%$_)e se è il primo ('1'*$_-match'^(?!(..+)\1+$)..') , e se è sia noi sottrarre la piazza da $y(i controlli vengono effettuati mediante la moltiplicazione booleana).

Una volta che abbiamo passato tutti i divisori primi e sottratto le piazze, se il numero rimanente è il più grande che abbiamo visto fino ad ora $y-gt$o, abbiamo fissato i nostri variabili di output $o=$y;$p=$_. Dopo che abbiamo loop attraverso l'intera gamma, abbiamo semplicemente uscita con uno spazio tra.


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

Esempio di utilizzo: f 50-> [48,35].

Funzioni fattore principale sono disponibili solo via import Data.Numbers.Primesche costa troppi byte, quindi sto usando @ primo correttore di Lynn . Il resto è semplice: per input mloop nthrough [2..m]e in loop pthrough interno [2..n]. Mantieni tutto pciò che è primo e dividi n, quadrato e somma.


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)

Provalo su Ideone .


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

Non ho idea del perché non pensassi di farlo in modo ricorsivo prima.


1

J, 44 byte

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

Approccio diretto. Restituisce anche tutti i valori di nquel risultato in un valore massimo.

uso

   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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.