Alguna nobleza principal

20

(Aleatoriamente inspirado por /mathpro//q/339890 )
(Relacionado: 1 , 2 )

Dada una lista de entrada de números primos distintos (por ejemplo, [2, 5, 7]) y un número entero n, genera todos los números enteros positivos estrictamente más pequeños nque contienen solo los números primos como divisores. Para entrada [2, 5, 7]y n=15esto significa una salida de [2, 4, 5, 7, 8, 10, 14].

Ejemplos adicionales

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

Reglas y aclaraciones

  • La lista de entrada está garantizada como no vacía, pero puede ser solo un elemento
  • Puede suponer que la lista de entrada está ordenada previamente de la forma más conveniente
  • n siempre será más grande que el elemento más grande en la lista de entrada
  • Como, por ejemplo, 2**0 = 1puede incluir opcionalmente 1en su lista de salida
  • La entrada y salida se pueden dar por cualquier método conveniente
  • Puede imprimir el resultado en STDOUT o devolverlo como resultado de una función
  • Un programa completo o una función son aceptables
  • Si corresponde, puede suponer que los enteros de entrada / salida se ajustan al intrango nativo de su idioma
  • Las lagunas estándar están prohibidas
  • Este es el por lo que se aplican todas las reglas habituales de golf, y gana el código más corto (en bytes)
AdmBorkBork
fuente
¿Podemos emitir en cualquier orden?
xnor
@xnor Sí, la salida en cualquier orden está bien.
AdmBorkBork
Disculpe ... Solo para estar absolutamente seguro: "que contiene solo esos primos como divisores" significa "que contiene solo al menos uno de esos primos como divisores primos"?
AZTECCO
Debería haber informado las soluciones existentes del cambio a la especificación para permitir 1en la salida.
Shaggy
@AZTECCO Derecha. Pero, por ejemplo, si su lista es [2, 3, 7]no puede usar 5.
AdmBorkBork

Respuestas:

5

05AB1E , 6 bytes

<LʒfåP

Toma el entero como primera entrada, la lista como segunda. Incluye lo opcional 1en la salida.

Pruébelo en línea o verifique todos los casos de prueba .

Explicación:

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

Dos alternativas de 6 bytes proporcionadas por @Grimy :

GNfåP

Pruébalo en línea.

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

Este es muy lento (el [2,5,7], 15caso de prueba ya se agota), pero se parece menos a los otros dos enfoques:

sиPÑʒ›

A diferencia de los otros dos programas anteriores, toma la lista como primera entrada y el entero como segunda. Sin embargo, también incluye lo opcional 1en la salida.

Pruébalo en línea.

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)
Kevin Cruijssen
fuente
1
Alternativa 7: sиPѦʒ›. Pensé que tenía un 6, pero no parece haber una forma de evitar el uso de s/ I/¹
Grimmy
@Grimy Buena alternativa, pero eso lleva mucho tiempo ejecutarlo, sin embargo. Para el primer caso de prueba tiene que encontrar todos los divisores de 4747561509943000000000000000. ;)
Kevin Cruijssen
1
Para salida vertical:GNfåP–
Grimmy
4

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

Toma entrada como (n)(primes)donde primos es un conjunto. Salidas modificando el conjunto.

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

Pruébalo en línea!

Comentado

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
}                 //
Arnauld
fuente
4

Python 3 , 68 65 bytes

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]

Pruébalo en línea!

-3 bytes gracias a @xnor

La función toma una secuencia principal y un número entero n como entradas. El resultado es una lista que incluye 1.

Sin golf:

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)

Pruébalo en línea!

Joel
fuente
Es un código de cortocircuito ordenado que tiene. Parece que puedes combinar las dos primeras condiciones como c*s<n*s. Editar: n//c*ses más corto.
xnor
@xnor Gracias por la mejora. Tu enfoque también es bastante bueno.
Joel
3

Haskell , 51 bytes

xpmapM((<$>[0..n]).(^))p1,X,X2,...,Xnortenorteproduct

np(# #pag)norte

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

Pruébalo en línea!

falla
fuente
3

Haskell , 39 bytes

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

Pruébalo en línea!

Comprueba si kes divisible solo por números primos lal ver si el producto lllevado a una alta potencia es divisible por k.

xnor
fuente
3

Python 2 , 65 bytes

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

Pruébalo en línea!

Comprueba si kes divisible solo por números primos lal ver si el producto lllevado a una alta potencia es divisible por k.

Si lse puede tomar como una lista de cadenas eval("*".join(l)) ahorra 3 bytes más reduce(int.__mul__,l)y se puede utilizar en Python 3, que carece reduce.

Python 3 , 64 bytes

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

Pruébalo en línea!

Una función que imprime en orden inverso y termina con error.

La solución recursiva a continuación sería más corta si nse incluyera en la lista. Intenté calcular recursivamente el producto ltambién, pero eso fue más largo.

62 bytes (no funciona)

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

Pruébalo en línea!

xnor
fuente
1

Gaia , 10 bytes

…@e⟪ḍ‡⁻!⟫⁇

Pruébalo en línea!

Nunca lo he usado con una mónada antes, es bastante útil para la manipulación de la pila.

…		| 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
Giuseppe
fuente
1

Jalea , 7 bytes

ṖÆffƑ¥Ƈ

Pruébalo en línea!

Un enlace diádico que toma el límite superior exclusivo como argumento izquierdo y la lista de números primos como derecho. Devuelve una lista que incluye 1, así como los números compuestos solo por los primos suministrados.

Una alternativa 7 sería ṖÆfḟ¥Ðḟ

Nick Kennedy
fuente
0

Japt -f , 7 bytes

©k e!øV

Intentalo

Encarnación de la ignorancia
fuente
Esto incluye 1en la salida, que no debería. Comencé con k e!øVmi solución también, pero necesitaba los 2 bytes adicionales para filtrar 0& 1.
Shaggy
Since, e.g., 2**0 = 1, you can optionally include 1 in your output list
Encarnación de la ignorancia
Eso no era parte de la especificación original.
Shaggy
0

Retina 0.8.2 , 64 bytes

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

Pruébalo en línea! La lista incluye casos de prueba más pequeños ( 10000tiempo de espera debido a todas las cadenas largas). Toma información en el orden n f1 f2 f3...(los factores no necesitan ser primos pero sí deben ser primos). La salida incluye 1. Explicación:

\d+
$*

Convierte a unario.

\G1
$.`,$`;

Genere una lista de 0 a n-1, tanto en decimal como en unario.

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

Dividir repetidamente el unario por cualquier factor disponible.

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

Salida de los números decimales donde el número unario se ha reducido a 1.

Neil
fuente
0

Pyth , 10 bytes

f!-PThQtUe

Pruébalo en línea!

Toma entrada como [[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)
ar4093
fuente
0

Carbón , 22 20 bytes

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

Pruébalo en línea! El enlace es a la versión detallada del código. Demasiado lento para el caso de prueba más grande. Explicación:

 Φ                      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

Respuesta anterior más rápida de 22 bytes:

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

Pruébalo en línea! El enlace es a la versión detallada del código. La salida incluye 1. Explicación:

⊞υ¹

Empuje 1a la lista vacía predefinida.

Fυ

Recorra la lista, incluidos los elementos que se le envíen durante el ciclo.

F×ιθ

Multiplique el elemento actual por cada primo y repita sobre los productos.

F›‹κη№υκ

Compruebe si el producto es un nuevo valor.

⊞υκ

Si es así, empújalo a la lista.

Iυ

Imprime la lista.

Neil
fuente
0

C (clang) , 115 bytes

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

Pruébalo en línea!

Una solución basada en el tamiz de Eratóstenes.

(Incluye 1 en la salida)

Gracias a la sugerencia de @ceilingcat: printf (x [i] + "\ 0% d", i ++) en lugar de x [i] && printf ("% d", i), i ++ Supongo que cambia el puntero del literal pero no No encontré ninguna documentación, si alguien me puede dar algunas ideas, sería bienvenido.

AZTECCO
fuente
Gracias pero ... ¿cómo funciona?
AZTECCO
1
Si x[i]==1entonces la cadena es "%d ". Si x[i]==0entonces la cadena es "". Las cadenas C están terminadas en nulo, por lo que un carácter nulo explícito termina la cadena. Este truco también abusa de un comportamiento indefinido en el clang relacionado con el i++.
ceilingcat