Le moindre entier comme produit de facteurs donnés

17

Il y a eu beaucoup de défis liés à la factorisation prime / prime récemment, donc j'ai pensé qu'il pourrait être intéressant d'aller dans l'autre sens.

Donné:

  • un entier positif n, et
  • une liste non vide d'entiers positifs f

écrire un programme complet ou une fonction pour trouver le plus petit entier itel que i >= net iest un produit de puissances entières non négatives d'éléments dans f.

Exemples:

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

    Les premiers produits sont:

    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
    
  • Supposons n=14, f=[9, 10, 7].

    Encore une fois, les premiers produits:

    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
    

Cas de 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

Règles

  • Vous pouvez supposer qu'il fcontiendra au moins un élément et que tous les éléments de fseront supérieurs à 1.
  • Vous pouvez éventuellement supposer que fc'est trié par ordre décroissant / croissant si vous le souhaitez (mais veuillez préciser).
  • Vous pouvez éventuellement prendre le nombre d'éléments de fsi vous le souhaitez.
  • La sortie sous forme de chaîne est autorisée.
  • Il s'agit de , donc la réponse la plus courte en octets dans chaque langue gagne!
  • Les règles d'E / S par défaut s'appliquent et les failles standard sont interdites.
  • Des explications sont encouragées.
Giuseppe
la source

Réponses:

10

Husk , 8 octets

ḟṠ€ȯmΠṖṘ

Extrêmement lent. Essayez-le en ligne!

Explication

ḟṠ€ȯ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.
Zgarb
la source
7

Wolfram Language (Mathematica) , 68 65 62 61 octets

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

Essayez-le en ligne!

Comment ça fonctionne

Prend l'entrée comme [n,k,f1,f2,f3,...,fk](par exemple, [11,3,2,3,5]): la première valeur est la cible n, la seconde est le nombre de facteurs, et tous les frctors suivent.

Les autres défis de la théorie des nombres se sont récemment tous repliés sur des modules intégrés de fantaisie (à tout le moins, ils ont utilisé FactorInteger ), alors j'ai pensé essayer quelque chose qui n'utilisait que des outils de base. Cette solution dit essentiellement que pour écrire en ntant que produit des facteurs, nous utilisons soit le premier facteur f1(et récursif sur n/f1, puis multiplions par f1) ou non (et récursif sur une liste de facteurs plus courte), puis prenons le min.

La récursion se termine lorsque la cible est inférieure à 1 ou lorsque le nombre de facteurs est 0, que nous vérifions #^#2<=1à la fois, puis générons 1 dans le premier cas et Infinitydans le second avec 1~Max~-Log@#2.

La fonction donne un tas d'avertissements (mais fonctionne toujours) à moins que vous ne l' Quietexécutiez avec , car elle revient finalement aux cas où#3 n'existe pas, ce qui rend Iftriste la deuxième branche inutilisée .


-3 octets: prendre le nombre de facteurs en entrée.

-3 octets grâce à @ngenisis: utilisation .

-1 octet, et aucune ambiguïté: le #^#2chèque.

Misha Lavrov
la source
2
Très agréable! enregistre les 3octets sur -Log@0 (doesn't work on TIO, but works fine on desktop Mathematica). Also, Tr [1 ^ {##}] `est un octet plus court que Length@{##}.
ngenisis
Je ne suis pas tout à fait sûr de ce que je ressens à propos des optimisations que TIO n'aime pas, mais bien sûr, j'ajouterai cela. Et #2est encore plus court que Tr[1^{##}]. :)
Misha Lavrov
1
Je pense que vous devriez inclure Quietdans votre code principal. Cette réponse génère trop de mauvais messages. Demandez au moins à OP s'il est d'accord avec cela
J42161217
2
Il semble à peu près la même chose qu'ignorer STDERR serait dans une autre langue, ce qui est une pratique acceptée .
Misha Lavrov
2
Le problème semble être un bogue. Je vais essayer de régler ça.
Dennis
6

Python 2 , 91 88 84 octets

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)

Essayez-le en ligne!

La fonction fvérifie récursivement si elle nest un produit de puissances d'éléments dans l, gest juste un wrapper pour contrôler l'itération

Barre
la source
6

Python, 55 octets

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

Essayez-le en ligne!

Le script de pied de page de Rod copié sans vergogne pour les tests

KSab
la source
4

Gelée , 13 octets

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

Un lien dyadique prenant la liste, fà gauche et le nombre n, à droite qui donne un nombre.

Essayez-le en ligne! Golfily inefficace - expirera pour les entrées avec plusn et / ou plus f.

Comment?

Nous savons que les pouvoirs des facteurs individuels (strictement positifs) n'auront jamais besoin de dépasser n-1
... alors inspectons toutes les voies possibles!

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
Jonathan Allan
la source
2

Rétine , 76 octets

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

Essayez-le en ligne! Link exclut les cas de test les plus lents, mais c'est toujours un peu lent, alors essayez de ne pas marteler le serveur de @ Dennis.

Neil
la source
2

Pyth - 10 octets

Manque de mémoire très rapidement.

f}T*My*QTE

Essayez-le en ligne ici .

Réponse raisonnable pour 16 octets: fsm.A}RQ*Md./PTE

Maltysen
la source
2

Mathematica, 85 octets

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

Contribution

[{liste f}, n, nombre d'éléments de f]
[{57, 34, 12, 21}, 12532159, 4]

J42161217
la source
{d,s}Min@Select[Flatten[1##&@@(s^#)&/@0~Range~9~Tuples~Tr[1^s]],#>=d&]
ngenisis
@ngenisis quel est le symbole qui n'est pas affiché? Pouvez-vous créer un lien TIO à la place?
J42161217
Je n'aurais jamais pensé voir le jour où "Mathematica" et "TIO" étaient utilisés dans le même message: P
caird coinheringaahing
@Jenny_mathy C'est U+F4A1, nom long \[Function].
ngenisis
L'utilisation 0~Range~9semble très conservatrice. Faut-il g[{2,3,5},1001]vraiment sauter 1024et revenir 1080? Ce n'est pas une entrée particulièrement importante.
Misha Lavrov
2

Japt , 10 octets

_k e!øV}aU

Testez-le en ligne!

Ne fonctionne pas sur le dernier cas de test en raison d'une limite d'itération conçue pour empêcher l'interprète de fonctionner indéfiniment (cela n'a pas beaucoup aidé ici, car il a gelé mon navigateur pendant une heure ...)

Explication

_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
ETHproductions
la source
2

Gelée , 9 octets

xŒPP€ḟḶ}Ṃ

O (2 n • longueur (f) ) exécution en et l'utilisation de la mémoire en font une solution théorique.

Essayez-le en ligne!

Dennis
la source
1

Mathematica, 73 octets

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

Essentiellement un portage de la réponse Python de Rod . Définit deux opérateurs binaires et . renvoie si est un produit d'éléments de et autrement. donne le plus petit entier±·n±fTruenfFalsen·fi . Si quelqu'un peut trouver un moyen d'éliminer le test de divisibilité, je pourrais économiser 10 octets en utilisant le codage ISO 8859-1.

Explication

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. *)
ngenisis
la source
1

R , 52 octets

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

Essayez-le en ligne!

Cela fait 3 semaines, j'ai donc pensé publier enfin ma propre solution. Il s'agit d'une approche par force brute.

Il existe cependant une fonction intégrée:

R , 5 octets

nextn

Essayez-le en ligne!

Depuis les documents R:

nextnrenvoie le plus petit entier, supérieur ou égal à n, qui peut être obtenu comme un produit des puissances des valeurs contenues dans factors. nextnest destiné à être utilisé pour trouver une longueur appropriée pour mettre à zéro l'argument de fftafin que la transformation soit calculée rapidement. La valeur par défaut de factorsassure cela.

Cependant, certains tests ont révélé un bogue dans l'implémentation, comme le montre le lien TIO ci-dessus.

nextn(91,c(2,6))devrait renvoyer 96, mais renvoie 128 à la place. Cela ne se produit évidemment que lorsqu'ils factorsne sont pas tous relativement premiers les uns avec les autres. En effet, le code C qui le sous-tend révèle que nextntente avidement de se diviser factortour à tour jusqu'à ce qu'il 1soit atteint:

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

Cela peut être résolu en prenant les entrées dans l'ordre décroissant.

Giuseppe
la source
1

JavaScript (ES6), 53 50 octets

Enregistré 3 octets grâce à @DanielIndie

Prend une entrée dans la syntaxe de curry (n)(a).

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

Cas de test

Comment?

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
Arnauld
la source
n => m = a => (g = k => k <n? a.map (x => g (k * x)): k> m? 0: m = k) (1) | mm = fonction produit toujours false lors de la première exécution, donc c'est essentiellement la même chose que mettre + a, c'est 51 octets maintenant
DanielIndie
@DanielIndie C'est en fait 50 octets. Merci beaucoup!
Arnauld