Trova il numero di quelli per ottenere un numero usando + e *


28

introduzione

Il tuo obiettivo è trovare il numero minimo di quelli che devi aggiungere o moltiplicare insieme per ottenere il valore di input, questo è A005245 .

Ingresso

Un intero positivo N .

Produzione

Il minor numero di quelli che devono essere aggiunti / moltiplicato per ottenere N .

Input di esempio

7

Uscita campione

6

Spiegazione

( 1+ 1+ 1) * ( 1+ 1) + 1= 7

Perché questo richiede 6quelli, l'output è6

Casi test

 1  1
 2  2
 3  3
 5  5
10  7
20  9
50 12

Dato che si tratta di una sfida di , vince il numero più basso di byte.



9
Benvenuti in Puzzle di programmazione e Code Golf! Come prima sfida, va bene, ma la prossima volta ti preghiamo di utilizzare Sandbox prima di pubblicare le sfide in modo da poter ricevere feedback!
Betseg,

4
Suggerirei di modificarlo per affermare esplicitamente che stai cercando il numero minimo di quelli richiesti. Altrimenti, semplicemente fornire il numero originale e affermare che è il numero di quelli che è necessario sommare sarebbe una soluzione valida.
Shaggy,

2
Ci sono esempi in cui f(x) != x.primeFactorisation().sum()tranne 1?
jrtapsell,

1
@jrtapsell: si. L'esempio dato di $ f (7) = 6 $ è uno. Per ogni $ p $ primo (abbastanza grande) puoi fattorizzare $ p-1 $ e aggiungerne uno. Potresti essere ancora in grado di fare di meglio.
Ross Millikan,

Risposte:


17

Python 2 , 74 70 byte

f=lambda n:min([n]+[f(j)+min(n%j*n+f(n/j),f(n-j))for j in range(2,n)])

Provalo online!

Versione alternativa, 59 byte (non verificato)

f=lambda n:min([n]+[f(j)+f(n/j)+f(n%j)for j in range(2,n)])

Funziona almeno fino a n = 1.000.000 , ma devo ancora dimostrare che funziona per tutti i n positivi .

Provalo online!


Scusate se mi manca qualcosa di semplice, ma non è ovvio che questo provi ogni albero delle espressioni fattibile. In particolare, abbiamo uno strato esterno n=a*j+bcon b<j, ma potremmo aver bisogno b>=j?
xnor

Hm, fallirebbe solo se entrambi b>=je b>=a. Ma hai ragione, non è ovvio che ciò non accadrà.
Dennis,

Interessante che non ci siano controesempi fino a 1.000.000, mi chiedo se effettivamente funzioni sempre. Il mio pensiero migliore per un controesempio sarebbe una forma a*b+c*dcon a,b,c,dtutte le espressioni di sommatoria e molto efficiente.
xnor

10

Gelatina , 16 14 byte

Grazie Dennis per aver salvato 2 byte!

ÆḌḊ,Ṗ߀€+U$FṂo

Provalo online!


Spiegazione logica

Dato un numero n :

  • Se lo è 1, la risposta è 1. Altrimenti:

La rappresentazione è a + bo a × b, dove ae bsono espressioni.

Considera tutti i possibili valori di ae b:

  • Se la rappresentazione è a + b, quindi ae bsono nell'intervallo [1 .. n-1].
  • Se la rappresentazione è a × b, ae bsono divisori propri di npiù grande di 1.

In entrambi i casi, l'elenco [[<proper divisors of n larger than 1>], [1, 2, ..., n-1]]viene calcolato ( ÆḌḊ,Ṗ), mappa il collegamento corrente su ciascun numero ߀€, aggiungi insieme le coppie corrette ( +U$) e ottieni il valore minimo ( FṂo).

Spiegazione del codice

ÆḌḊ,Ṗ߀€+U$FṂo   Main link. Assume n = 10.
ÆḌ       Proper divisors. [1,2,5]equeue, remove the first element. [2,5]
   ,Ṗ    Pair with op. Auto convert n = 10 to range 
         [1,2,3,4,5,6,7,8,9,10] and remove the last element
         10, get [1,2,3,4,5,6,7,8,9].

߀€      Apply this link over each element.
   +U$   Add with the Upend of itself.

FṂ       Flatten and get the inimum element.
  o      Logical or with n.
         If the list is empty, minimum returns 0 (falsy), so logical or
         convert it to n.

5

JavaScript (ES6), 108 96 byte

f=n=>n<6?n:Math.min(...[...Array(n-2)].map((_,i)=>Math.min(f(++i)+f(n-i),n%++i/0||f(i)+f(n/i))))

Molto inefficiente; Array(n>>1)accelera leggermente al costo di un byte. Spiegazione: n%++iè diverso da zero se inon è un fattore, quindi n%++i/0è Infinity(e quindi verità, e anche sicuramente non minimo) se inon è un fattore, ma NaN(e quindi falsa) se iè un fattore. Modifica: salvato 12 byte con ispirazione da @ edc65.


Ho provato a eseguirlo in background per vedere se era effettivamente in grado di calcolare, f(50)ma sfortunatamente Windows Update ha riavviato il mio PC prima che potesse finire.
Neil

Hai provato una sola passeggiata sull'array?
edc65,

@ edc65 Siamo spiacenti, ma non sono chiaro cosa stai suggerendo e perché.
Neil,

Vedo 2 mappe, ciascuna delle quali esegue la scansione adell'array. Non riesci a unire le valutazioni nei 2 lambda e prendere il minimo?
edc65,

@ edc65 Ah sì, per qualche motivo ho pensato che annidare il min non sarebbe stato più economico, ma devo sostituirlo (i+=2)con un altro, ++iquindi sto risparmiando 12 byte in totale, grazie!
Neil,


4

Pari / GP , 213 byte

Modifica: sono stato duramente picchiato .

f(n)={d;n<6&return(n);if(n<=#a,a[n]&return(a[n]),a=vector(n));for(i=1,n-1,a[i]||a[i]=f(i));a[n]=min(vecmin(vector(n\2,k,a[k]+a[n-k])),if(isprime(n),n,vecmin(vector((-1+#d=divisors(n))\2,i,a[d[i+1]]+a[d[#d-i]]))))}

Provalo online!


3

Python 2 , 181 byte

def F(N,n,s="",r=""):
 try:
	if n<1:return(eval(s)==N)*0**(`11`in s or"**"in s)*s
	for c in"()+*1":r=F(N,~-n,s+c)or r
 except:r
 return r
f=lambda N,n=1:F(N,n).count(`1`)or f(N,-~n)

Provalo online!


@ pizzapants184 La funzione principale fnon deve essere anonima, in quanto si chiama ricorsivamente.
Jonathan Frech,

Ah, scusa, non l'ho visto.
pizzapants184,


1

Perl 5 , -p 78 byte

79 byte nel conteggio vecchio stile ( +1per -p)

Il fatto che il perl debba usare un extra $per tutti gli accessi scalari fa davvero male alla lunghezza dei golf che fanno molta aritmetica ...

Questo metodo è principalmente come gli altri già pubblicati (prova la moltiplicazione e l'aggiunta per creare un numero target, prendi il più economico). Tuttavia non si ripete più volte verso il basso, quindi può essere utilizzato per input relativamente grandi.

Inoltre, non cerca di ridurre al minimo il costo di costruzione di un numero per addizione o moltiplicazione [perl 5 perché non ha incorporato mine l'ordinamento numerico è troppo lungo (come si vede dall'ordinamento ancora nel codice). Invece suppongo solo che se un numero è un fattore del target che userò la moltiplicazione. Questo è sicuro poiché se ad esempio 3è un fattore di 12(quindi somma il costo di 3e 12/3) più avanti nel ciclo considererà 9=12-3quale non sarà un fattore, quindi 9+3con lo stesso costo che 3+9verrà provato comunque. Tuttavia, ciò potrebbe non riuscire per gli obiettivi <= 4(funziona solo per 1e 2). Aggiungendo $_all'elenco per minimizzare le correzioni che. Il che è un peccato dal momento che in realtà non ne ho bisogno per i casi di base perché ho già inizializzato@; con i valori iniziali corretti, quindi costa 3 byte.

#!/usr/bin/perl -p
($_)=sort{$a-$b}$_,map{$;[$_]+$;[$'%$_?$'-$_:$'/$_]}//..$_ for@;=0..$_;$_=pop@

Provalo online!

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.