Il minimo intero come prodotto di determinati fattori


17

Di recente ci sono state molte sfide legate alla fattorizzazione in fattori primi e primi, quindi ho pensato che potrebbe essere interessante andare dall'altra parte.

Dato:

  • un numero intero positivo n e
  • un elenco non vuoto di numeri interi positivi f

scrivere un programma completo o una funzione per trovare il numero intero più piccolo itale che i >= nei è un prodotto di non negativi, potenze intere di elementi in f.

Esempi:

  • supporre n = 11, f = [2, 3, 5] .

    I primi prodotti sono:

    1   = 2^0 * 3^0 * 5^0
    2   = 2^1 * 3^0 * 5^0
    3   = 2^0 * 3^1 * 5^0
    5   = 2^0 * 3^0 * 5^1
    4   = 2^2 * 3^0 * 5^0
    6   = 2^1 * 3^1 * 5^0
    10  = 2^1 * 3^0 * 5^1
    9   = 2^0 * 3^2 * 5^0
    15  = 2^0 * 3^1 * 5^1
    25  = 2^0 * 3^0 * 5^2
    8   = 2^3 * 3^0 * 5^0
    12  = 2^2 * 3^1 * 5^0 => smallest greater than (or equal to) 11, so we output it.
    20  = 2^2 * 3^0 * 5^1
    18  = 2^1 * 3^2 * 5^0
    30  = 2^1 * 3^1 * 5^1
    50  = 2^1 * 3^0 * 5^2
    27  = 2^0 * 3^3 * 5^0
    45  = 2^0 * 3^2 * 5^1
    75  = 2^0 * 3^1 * 5^2
    125 = 2^0 * 3^0 * 5^3
    
  • supporre n=14, f=[9, 10, 7] .

    Ancora una volta, i primi prodotti:

    1 = 7^0 * 9^0 * 10^0
    7 = 7^1 * 9^0 * 10^0
    9 = 7^0 * 9^1 * 10^0
    10 = 7^0 * 9^0 * 10^1
    49 = 7^2 * 9^0 * 10^0  => smallest greater than (or equal to) 14, so we output it.
    63 = 7^1 * 9^1 * 10^0
    70 = 7^1 * 9^0 * 10^1
    81 = 7^0 * 9^2 * 10^0
    90 = 7^0 * 9^1 * 10^1
    100 = 7^0 * 9^0 * 10^2
    

Casi test:

n, f -> output
10, [2, 3, 5]              -> 10
17, [3, 7]                 -> 21
61, [3,5,2,7]              -> 63
23, [2]                    -> 32
23, [3]                    -> 27
23, [2, 3]                 -> 24
31, [3]                    -> 81
93, [2,2,3]                -> 96
91, [2,4,6]                -> 96
1,  [2,3,5,7,11,13,17,19]  -> 1
151, [20,9,11]             -> 180
11616, [23,32]             -> 12167
11616, [23,32,2,3]         -> 11664 = 2^4 * 3^6
5050, [3,6,10,15,21,28,36,45,55,66,78,91,105,120,136,153,171,190,210] -> 5103 = 3^6 * 7
12532159, [57, 34, 12, 21] -> 14183424 = 12^5 * 57

Regole

  • Si può presumere che f conterrà almeno un elemento e che tutti gli elementi di fsaranno maggiori di 1.
  • Opzionalmente si può presumere che f sia ordinato in ordine decrescente / crescente (ma specificare).
  • Puoi facoltativamente prendere il numero di elementi di fSe lo desideri, puoi .
  • L'output come stringa è consentito.
  • Questo è , quindi vince la risposta più breve in byte in ogni lingua!
  • Si applicano le regole I / O predefinite e sono vietate le scappatoie standard.
  • Le spiegazioni sono incoraggiate.

Risposte:


10

Buccia , 8 byte

ḟṠ€ȯmΠṖṘ

Estremamente lento. Provalo online!

Spiegazione

ḟṠ€ȯmΠṖṘ  Implicit inputs, say L=[3,4] and n=5.
ḟ         Find the lowest integer k≥n that satisfies:
       Ṙ   Replicate L by k: [3,3,3,3,3,4,4,4,4,4]
      Ṗ    Powerset: [[],[3],[4],..,[3,3,3,3,3,4,4,4,4,4]]
    mΠ     Product of each: [1,3,4,..,248832]
 Ṡ€ȯ       k is in this list.

7

Wolfram Language (Mathematica) , 68 65 62 61 byte

If[#^#2<=1,1~Max~-Log@#2,Min[#0[#,#2-1,##4],#0[#/#3,##2]#3]]&

Provalo online!

Come funziona

Prende input come [n,k,f1,f2,f3,...,fk](ad es. [11,3,2,3,5]): Il primo valore è il target n, il secondo è il numero di fattori e seguono tutti i frammenti.

Le altre sfide della teoria dei numeri recentemente si sono tutte piegate a fantasiosi built-in (per lo meno, hanno usato FactorInteger), quindi ho pensato di provare qualcosa che utilizzava solo strumenti di base. Questa soluzione sostanzialmente dice che per scrivere ncome un prodotto dei fattori, o usiamo il primo fattore f1(e ricerchiamo n/f1, quindi moltiplichiamo perf1 ) o no (e facciamo ricorso a un elenco più breve di fattori), quindi prendiamo il minimo.

La ricorsione finisce quando l'obiettivo è inferiore a 1 o quando il numero di fattori è 0, che verifichiamo #^#2<=1immediatamente con, e quindi generiamo 1 nel primo caso e Infinitynel secondo con 1~Max~-Log@#2.

La funzione fornisce un sacco di avvertimenti (ma funziona ancora) a meno che tu non lo esegua Quiet, perché alla fine ricorre ai casi in cui #3non esiste, rendendo Iftriste il secondo ramo inutilizzato .


-3 byte: prendendo il numero di fattori come input.

-3 byte grazie a @ngenisis: utilizzo .

-1 byte e nessuna ambiguità: il #^#2controllo.


2
Molto bella! salva 3byte su -Log@0 (doesn't work on TIO, but works fine on desktop Mathematica). Also, Tr [1 ^ {##}] `è un byte più corto di Length@{##}.
ngenisi,

Non sono del tutto sicuro di come mi sento di usare le ottimizzazioni che non piacciono a TIO, ma sicuramente lo aggiungerò. Ed #2è anche più breve di Tr[1^{##}]. :)
Misha Lavrov,

1
Penso che dovresti inserire il Quiettuo codice principale. Questa risposta genera troppi messaggi sbagliati. Almeno chiedi a OP se è d'
accordo

2
Sembra quasi che ignorare STDERR sarebbe in un'altra lingua, che è una pratica accettata .
Misha Lavrov,

2
Il problema sembra essere un bug. Proverò a risolverlo.
Dennis,

6

Python 2 , 91 88 84 byte

f=lambda n,l:n<2or any(n%x<1and f(n/x,l)for x in l)
g=lambda n,l:n*f(n,l)or g(n+1,l)

Provalo online!

La funzione fcontrolla ricorsivamente se nè un prodotto di poteri di elementi in l, gè solo un wrapper per controllare l'iterazione


6

Python, 55 byte

f=lambda n,l,x=1:min(f(n,l,x*e)for e in l)if x<n else x

Provalo online!

Copiato senza pietà il copione del piè di pagina di Rod per il test


4

Gelatina , 13 byte

L⁹ṗ’⁸*P€ḟ⁹Ḷ¤Ṃ

Un collegamento diadico che prende la lista, fa sinistra e il numero n, a destra che produce un numero.

Provalo online! Golfly inefficiente - scadrà per gli input con valori più altine / o più lunghif.

Come?

Sappiamo che i poteri dei singoli fattori (strettamente positivi) non dovranno mai eccedere n-1
... quindi esaminiamo tutti i modi possibili!

L⁹ṗ’⁸*P€ḟ⁹Ḷ¤Ṃ - Link: list, f; number, n
 ⁹            - chain's right argument, n
L             - length of f
  ṗ           - Cartesian power  ...e.g.: len(f)=2; n=3 -> [[1,1],[1,2],[1,3],[2,1],[2,2],[2,3],[3,1],[3,2],[3,3]]
   ’          - decrement (vectorises)
    ⁸         - chain's left argument, f
     *        - exponentiate (vectorises) - that is [f1^a, f2^b, ...] for each [a, b, ...] in the list formed from the Cartesian power
      P€      - product for €ach - that is f1^a * f2^b * ... for each [a, b, ...] in the list formed from the Cartesian power
           ¤  - nilad followed by link(s) as a nilad:
         ⁹    -   chain's right argument, n
          Ḷ   -   lowered range -> [0,1,2,3,...,n-1]
        ḟ     - filter discard - that is remove values less than n
            Ṃ - minimum

2

Retina , 76 byte

\d+
$*
1+;
$&$&
{+`;(1+)(\1)*(?=;.*\b\1\b)
;1$#2$*1
}`(1+);11+;
1$1;1$1;
\G1

Provalo online! Link esclude i casi di test più lenti, ma è ancora un po 'lento, quindi cerca di non martellare il server di Dennis.



2

Mathematica, 85 byte

Min@Select[Flatten[1##&@@(s^#)&/@Tuples[0~Range~⌈Log[Min[s=#],d=#2]⌉,#3]],#>=d&]&

Ingresso

[{list f}, n, numero di elementi di f]
[{57, 34, 12, 21}, 12532159, 4]


{d,s}Min@Select[Flatten[1##&@@(s^#)&/@0~Range~9~Tuples~Tr[1^s]],#>=d&]
ngenisi,

@ngenisis qual è il simbolo che non viene visualizzato? Puoi creare un collegamento TIO invece?
J42161217

Non avrei mai pensato di vedere il giorno in cui "Mathematica" e "TIO" venivano usati nello stesso post: P
caird coinheringaahing,

@Jenny_mathy È U+F4A1, nome lungo \[Function].
ngenisi,

L'uso 0~Range~9sembra molto conservativo. Dovresti g[{2,3,5},1001]davvero saltare 1024e tornare 1080? Questo non è un input particolarmente ampio.
Misha Lavrov,

2

Japt , 10 byte

_k e!øV}aU

Provalo online!

Non funziona sull'ultimo test case a causa di un limite di iterazione progettato per impedire all'interprete di funzionare per sempre (non ha aiutato molto qui, poiché ha bloccato il browser per un'ora ...)

Spiegazione

_k e!øV}aU    Implicit: U = input integer, V = array of factors
_      }aU    Starting at U, find the next integer Z where
 k              the factors of Z
   e            are such that every factor
    !øV         is contained in V (e!øV -> eX{VøX}, where VøX means "V contains X").
              Implicit: output result of last expression



1

Mathematica, 73 byte

1±_=1>0;n_±f_:=Or@@(#∣n&&n/#±f&/@f);n_·f_:=NestWhile[#+1&,n,!#±f&]

Essenzialmente una porta della risposta Python di Rod . Definisce due operatori binari e . ritorna±·n±fTrue if se nè un prodotto di elementi di fe Falsealtrimenti. n·fdà il numero intero più piccolo i. Se qualcuno riesce a trovare un modo per eliminare il test di divisibilità, potrei risparmiare 10 byte usando la codifica ISO 8859-1.

Spiegazione

1±_=1>0;                         (* If the first argument is 1, ± gives True. *)
n_±f_:=Or@@(#∣n&&n/#±f&/@f);     (* Recursively defines ±. *)
                                 (* For each element of f, check to see if it divides n. *)
                                 (* For each element # that does, check if n/# is a product of elements of f. *)
n_·f_:=NestWhile[#+1&,n,!#±f&]   (* Starting with n, keep incrementing until we find an i that satisfies i±f. *)

1

R , 52 byte

function(n,f)min((y=(x=outer(f,0:n,"^"))%o%x)[y>=n])

Provalo online!

Sono passate 3 settimane, quindi ho pensato di pubblicare finalmente la mia soluzione. Questo è un approccio a forza bruta.

Vi è, tuttavia, un builtin:

R , 5 byte

nextn

Provalo online!

Dai documenti R:

nextnrestituisce il numero intero più piccolo, maggiore o uguale a n, che può essere ottenuto come prodotto dei poteri dei valori contenuti in factors. nextnè destinato a essere utilizzato per trovare una lunghezza adeguata per azzerare l'argomento di fftin modo che la trasformazione venga calcolata rapidamente. Il valore predefinito per factorsgarantisce questo.

Alcuni test hanno rivelato un bug nell'implementazione, tuttavia, come mostra il link TIO sopra.

nextn(91,c(2,6))dovrebbe restituire 96, ma restituisce invece 128. Questo ovviamente si verifica solo quando factorsnon sono tutti relativamente primi tra loro. In effetti, il codice C sottostante rivela che nextntenta avidamente di dividere ciascuno factora turno fino a quando non 1viene raggiunto:

static Rboolean ok_n(int n, int *f, int nf)
{
    int i;
    for (i = 0; i < nf; i++) {
    while(n % f[i] == 0) {
        if ((n = n / f[i]) == 1)
        return TRUE;
    }
    }
    return n == 1;
}

static int nextn0(int n, int *f, int nf) { while(!ok_n(n, f, nf)) n++; return n; }

Questo può essere risolto prendendo input in ordine decrescente.


1

JavaScript (ES6), 53 50 byte

Salvato 3 byte grazie a @DanielIndie

Accetta input nella sintassi del curry (n)(a).

n=>m=a=>(g=k=>k<n?a.map(x=>g(k*x)):k>m?0:m=k)(1)|m

Casi test

Come?

n => a => (                 // given n and a
  g = k =>                  // g = recursive function taking k
    k < n ?                 // if k is less than n:
      a.map(x => g(k * x))  //   recursive calls to g with x * k for each x in a
    :                       // else:
      k > m ?               //   if k is greater than m and m is not set to NaN:
        0                   //     ignore this result
      :                     //   else:
        m = k               //     update m to k
  )(                        // initial call to g with:
    1,                      //   k = 1
    m = +a                  //   m = either NaN or the single integer contained in a
  ) | m                     // return m

n => m = a => (g = k => k <n? a.map (x => g (k * x)): k> m? 0: m = k) (1) | mm = funzione produce sempre false al primo avvio, quindi sostanzialmente è lo stesso di mettere + a, ora sono 51 byte
DanielIndie

@DanielIndie Questo è in realtà 50 byte. Molte grazie!
Arnauld,
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.