Alcuni Prime Peerage


20

(Ispirato casualmente da /mathpro//q/339890 )
(Relativo: 1 , 2 )

Dato un elenco di input di numeri primi distinti (ad esempio, [2, 5, 7]) e un numero intero n, emette tutti gli interi positivi strettamente più piccoli di quelli nche contengono solo quei numeri primi come divisori. Per input [2, 5, 7]e n=15questo significa un output di [2, 4, 5, 7, 8, 10, 14].

Ulteriori esempi

[list] n | output

[2, 5, 7] 15 | [2, 4, 5, 7, 8, 10, 14]
[2, 5, 7] 14 | [2, 4, 5, 7, 8, 10]
[2] 3 | [2]
[2] 9 | [2, 4, 8]
[103, 101, 97] 10000 | [97, 101, 103, 9409, 9797, 9991]
[97, 101, 103] 104 | [97, 101, 103]

Regole e chiarimenti

  • L'elenco di input è garantito non vuoto, ma può essere solo un singolo elemento
  • Si può presumere che l'elenco di input sia preordinato nel modo più conveniente
  • n sarà sempre più grande dell'elemento più grande nell'elenco di input
  • Poiché, ad esempio, 2**0 = 1è possibile includere facoltativamente 1nell'elenco di output
  • Input e output possono essere forniti con qualsiasi metodo conveniente
  • È possibile stampare il risultato su STDOUT o restituirlo come risultato di una funzione
  • È accettabile un programma completo o una funzione
  • Se del caso, si può assumere l'ingresso / uscita interi in forma in nativo del linguaggio intgamma
  • Sono vietate le scappatoie standard
  • Si tratta di quindi si applicano tutte le normali regole del golf e vince il codice più breve (in byte)

Possiamo produrre in qualsiasi ordine?
— xnor

@xnor Sì, l'output in qualsiasi ordine va bene.
— AdmBorkBork,

Mi scusi. Solo per essere assolutamente sicuri: "che contengono solo quei numeri primi come divisori" significa "che contiene solo uno di quei numeri primi come divisori primi"?
— AZTECCO,

Avresti dovuto informare le soluzioni esistenti della modifica alla specifica per consentire 1nell'output.
— Shaggy,

@AZTECCO Giusto. Ma, ad esempio, se la tua lista è [2, 3, 7]non puoi usarla 5.
— AdmBorkBork,

Risposte:



5

05AB1E , 6 byte

<LʒfåP

Prende l'intero come primo input, elenca come secondo. Include l'opzionale 1nell'output.

Provalo online o verifica tutti i casi di test .

Spiegazione:

<       # Decrease the (implicit) input by 1
 L      # Create a list in the range [1,input-1]
  ʒ     # Filter it by:
   f    #  Get all prime factors of the current number (without duplicates)
    å   #  Check for each if its in the (implicit) input-list
     P  #  And check if this is truthy for all
        # (after the filter, the result is output implicitly)

Due alternative a 6 byte fornite da @Grimy :

GNfåP–

Provalo online.

G       # Loop `N` in the range [1, (implicit) input):
 Nf     #  Get all prime factors of `N` (without duplicates)
   å    #  Check for each if its in the (implicit) input-list
    P   #  And check if this is truthy for all
     –  #  If it is, output the current `N` with trailing newline

Questo è molto lento (il [2,5,7], 15test case è già scaduto), ma meno simile agli altri due approcci:

sиPÑʒ›

A differenza degli altri due programmi precedenti, accetta l'elenco come primo input e intero come secondo. 1Tuttavia, include anche l' output opzionale .

Provalo online.

s       # Swap so the stack is now [list-input, integer-input]
 и      # Repeat the list (flattened) the integer amount of times
        #  i.e. [2,5] and 10 → [2,5,2,5,2,5,2,5,2,5,2,5,2,5,2,5,2,5,2,5]
  P     # Take the product of this list
        #  → 10000000000
   Ñ    # Get all divisors of this integer
        # (the bottleneck for larger integers in this approach)
        #  → [1,2,4,5,8,10,16,20,25,32,40,50,64,80,100,125,128,160,200,250,256,320,400,500,512,625,640,800,1000,1024,1250,1280,1600,2000,2500,2560,3125,3200,4000,5000,5120,6250,6400,8000,10000,12500,12800,15625,16000,20000,25000,25600,31250,32000,40000,50000,62500,64000,78125,80000,100000,125000,128000,156250,160000,200000,250000,312500,320000,390625,400000,500000,625000,640000,781250,800000,1000000,1250000,1562500,1600000,1953125,2000000,2500000,3125000,3200000,3906250,4000000,5000000,6250000,7812500,8000000,9765625,10000000,12500000,15625000,16000000,19531250,20000000,25000000,31250000,39062500,40000000,50000000,62500000,78125000,80000000,100000000,125000000,156250000,200000000,250000000,312500000,400000000,500000000,625000000,1000000000,1250000000,2000000000,2500000000,5000000000,10000000000]
    ʒ   # Filter these divisors:
     ›  #  And only keep those where the (implicit) input-integer is larger than the divisor
        #  → [1,2,4,5,8]
        # (after the filter, the result is output implicitly)

1
Alternativa 7: sиPѦʒ›. Pensavo di avere un 6, ma non sembra esserci un modo per usare s/ I/¹
— Grimmy il

@Grimy Bella alternativa, ma sicuramente ci vorrà molto tempo per eseguirla. Per il primo caso di test deve trovare tutti i divisori di 4747561509943000000000000000. ;)
— Kevin Cruijssen,

1
Per uscita verticale:GNfåP–
— Grimmy

4

JavaScript (ES6),  64 ... 52  50 byte

Accetta input come (n)(primes)dove primes è un set. Emette modificando il set.

n=>g=(s,q=1)=>{for(p of s)(p*=q)<n&&g(s.add(p),p)}

Provalo online!

Commentate

n =>              // n = maximum value
g = (             // g is a recursive function taking:
  s,              //   s = set of primes
  q = 1           //   q = current product, initialized to 1
) => {            //
  for(p of s)     // for each value p in s:
    (p *= q)      //   multiply p by q
    < n &&        //   if the result is less than n:
      g(          //     do a recursive call:
        s.add(p), //       with p added to the set
        p         //       with q = p
      )           //     end of recursive call
}                 //

4

Python 3 , 68 65 byte

f=lambda s,n,c=1:n//c*s and f(s,n,s[0]*c)+f(s[1:],n,c)or[c][:c<n]

Provalo online!

-3 byte grazie a @xnor

La funzione accetta una sequenza primi e un numero intero n come input. L'output è un elenco che include 1.

Ungolfed:

def f(s, n, c=1):
    if not c < n:
       return []
    elif not s:
       return [c]
    else:
       return f(s,n,s[0]*c) + f(s[1:],n,c)

Provalo online!


Questo è un codice di cortocircuito che hai. Sembra che tu possa combinare le prime due condizioni come c*s<n*s. Modifica: n//c*sè più breve.
— xnor

@xnor Grazie per il miglioramento. Anche il tuo approccio è abbastanza buono.
— Gioele il

3

Haskell , 51 byte

xpmapM((<$>[0..n]).(^))p1,X,X2,...,Xnn è il secondo input appena usato come limite superiore) e quindi il prodotto cartesiano di tutte queste sequenze. Dopo di che calcoliamo producttutte le voci di questo prodotto cartesiano e filtriamo tutte quelle troppo grandi.

np(#p)n

p#n=[k|k<-product<$>mapM((<$>[0..n]).(^))p,k<n,k>1]

Provalo online!


3

Haskell , 39 byte

l%n=[k|k<-[2..n-1],mod(product l^k)k<1]

Provalo online!

Verifica se kè divisibile solo per i numeri primi lvedendo se il prodotto di lun elevato potere è divisibile per k.


3

Python 2 , 65 byte

lambda l,n:[k for k in range(2,n)if reduce(int.__mul__,l)**n%k<1]

Provalo online!

Verifica se kè divisibile solo per i numeri primi lvedendo se il prodotto di lun elevato potere è divisibile per k.

Se lpuò essere preso come una lista di stringhe eval("*".join(l)) di risparmiare 3 byte sopra reduce(int.__mul__,l)e può essere utilizzato in Python 3 che manca reduce.

Python 3 , 64 byte

def f(l,n,P=1):
 for x in l:P*=x
 n-=1;P**n%n or print(n);f(l,n)

Provalo online!

Una funzione stampa in ordine inverso e termina con errore.

La soluzione ricorsiva di seguito sarebbe più breve se nfosse inclusa nell'elenco. Ho provato a calcolare ricorsivamente anche il prodotto l, ma è stato più lungo.

62 byte (non funzionante)

f=lambda l,n:n*[f]and[n][reduce(int.__mul__,l)**n%n:]+f(l,n-1)

Provalo online!


1

Gaia , 10 byte

…@e⟪ḍ‡⁻!⟫⁇

Provalo online!

Non ho mai usato ‡una monade prima d'ora, è abbastanza utile per la manipolazione dello stack.

…		| push [0..n-1]
@e		| push list of primes
  ⟪    ⟫⁇	| filter [0..n-1] for where the following predicate is true:
   ḍ‡		| the list of prime factors
     ⁻		| minus the list of primes
      !		| is empty


1

Gelatina , 7 byte

ṖÆffƑ¥Ƈ

Provalo online!

Un collegamento diadico che prende il limite superiore esclusivo come argomento di sinistra e l'elenco di numeri primi come suo diritto. Restituisce un elenco che include 1 nonché i numeri composti solo dai numeri primi forniti.

Un'alternativa 7 sarebbe ṖÆfḟ¥Ðḟ






0

Retina 0.8.2 , 64 byte

\d+
$*
\G1
$.`,$`;
+`,(1+)(\1)*(?=;.* \1\b)
,1$#2$*
!`\d+(?=,1;)

Provalo online! L'elenco include casi di test più piccoli ( 10000timeout a causa di tutte le stringhe lunghe). Accetta input nell'ordine n f1 f2 f3...(i fattori non devono essere primi ma devono essere coprimi). L'output include 1. Spiegazione:

\d+
$*

Converti in unario.

\G1
$.`,$`;

Genera un elenco da 0 a n-1, sia in decimale che in unario.

+`,(1+)(\1)*(?=;.* \1\b)
,1$#2$*

Dividi ripetutamente l'unario per tutti i fattori disponibili.

!`\d+(?=,1;)

Emette i numeri decimali in cui il numero unario è stato ridotto a 1.


0

Pyth , 10 byte

f!-PThQtUe

Provalo online!

Accetta input come [[primes...], n]

        Ue  # range(0, Q[-1])  (Q is the input, implicit)
       t    #                [1:] -> range(1, Q[-1]), tUe == PSe
f           # filter that on the condition: lambda T:
   PT       # prime_divisors(T)
  -  hQ     #                   - Q[0]
 !          # logical negation (![] == True)


0

Carbone , 22 20 byte

IΦ…²η⬤…·²ι∨﹪ιλ⊙θ¬﹪λν

Provalo online! Il collegamento è alla versione dettagliata del codice. Troppo lento per il test case più grande. Spiegazione:

 Φ                      Filter on
  …                     Range from
   ²                    Literal `2` to
    η                   Input limit
     ⬤                  Where all values
      …·                Inclusive range from
        ²               Literal `2` to
         ι              Filter value
          ∨             Either
             λ          Inner value
           ﹪            Is not a divisor of
            ι           Filter value
              ⊙         Or any of
               θ        Input primes
                   ν    Current prime
                ¬﹪      Is a divisor of
                  λ     Inner value
I                       Cast to string for implicit print

Risposta a 22 byte più veloce precedente:

⊞υ¹FυF×ιθF›‹κη№υκ⊞υκIυ

Provalo online! Il collegamento è alla versione dettagliata del codice. L'output include 1. Spiegazione:

⊞υ¹

Passa 1all'elenco vuoto predefinito.

Fυ

Scorri l'elenco, inclusi tutti gli elementi spinti ad esso durante il ciclo.

F×ιθ

Moltiplica l'articolo corrente per ogni numero primo e passa in rassegna i prodotti.

F›‹κη№υκ

Verifica se il prodotto ha un nuovo valore.

⊞υκ

In tal caso, spingerlo nell'elenco.

Iυ

Stampa l'elenco.


0

C (clang) , 115 byte

#define f(n,l,z){int j,i,k,x[n]={};for(i=x[1]=1;i<n;printf(x[i]+"\0%d ",i++))for(j=z;j--;k<n?x[k]=x[i]:0)k=i*l[j];}

Provalo online!

Una soluzione a base di setaccio di Eratostene.

(Include 1 nell'output)

Grazie al suggerimento di @ceilingcat: printf (x [i] + "\ 0% d", i ++) invece di x [i] && printf ("% d", i), i ++ suppongo che sposta il puntatore del valore letterale ma didn Ho trovato alcuna documentazione, se qualcuno può darmi qualche idea sarebbe gradito.


Grazie ma .. come funziona?
— AZTECCO,

1
Se x[i]==1quindi la stringa è "%d ". Se x[i]==0quindi la stringa è "". Le stringhe C hanno una terminazione nulla quindi un carattere null esplicito termina la stringa. Questo hack viola anche alcuni comportamenti indefiniti in clang relativi al i++.
— ceilingcat,
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.