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.