最小整数作为给定因子的乘积


17

最近有很多与质数/素数分解相关的挑战,所以我认为走另一条路可能很有趣。

鉴于:

  • 一个正整数n,和
  • 正整数的非空列表 f

编写一个完整的程序或函数以找到最小的整数i,使得i >= nif。中元素的非负整数幂的乘积。

例子:

  • 假设n = 11, f = [2, 3, 5]

    前几个产品是:

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

    同样,前几个产品:

    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
    

测试用例:

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

规则

  • 您可能会假设f它将包含至少一个元素,并且的所有元素都f将大于1。
  • 如果需要,您可以选择假定该列表f按降序/升序排序(但请指定)。
  • 您可以根据需要选择元素的数量f
  • 允许输出为字符串。
  • 这是,因此每种语言的最短答案以字节为单位!
  • 默认的I / O规则适用,并且禁止标准漏洞。
  • 鼓励解释。

Answers:


10

外壳,8字节

ḟṠ€ȯmΠṖṘ

极慢。 在线尝试!

说明

ḟṠ€ȯ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语言(Mathematica)68 65 62 61字节

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

在线尝试!

怎么运行的

将输入作为[n,k,f1,f2,f3,...,fk](例如[11,3,2,3,5]):第一个值是目标n,第二个值是因子数,所有的分数都跟随。

最近其他的数论难题都集中到了精美的内置部件上(至少,他们使用了FactorInteger),所以我想我会尝试只使用基本工具的东西。该解决方案基本上说,要写出n这些因素的乘积,我们要么使用第一个因素f1(然后递归到n/f1,然后乘以f1),要么不使用(并递归到较短的因子列表上),然后取最小值。

当目标小于1或因数为0时,递归触底。我们立即检查#^#2<=1一次,然后在第一种情况下生成1,在后一种情况下Infinity使用1~Max~-Log@#2

除非使用来运行该函数,否则Quiet它会给出一堆警告(但仍会起作用),因为它最终会递归到#3不存在的情况,从而使未使用的第二个分支变得If可悲。


-3字节:以因子数为输入。

@ngenisis:使用-3个字节

-1字节,无歧义:#^#2检查。


2
非常好!在Tr [1 ^ {##}]`上保存3字节,-Log@0 (doesn't work on TIO, but works fine on desktop Mathematica). Also, 该字节短于Length@{##}
ngenisis

我不太确定我对使用TIO不喜欢的优化的感觉,但是可以肯定的是,我会补充一点。并且#2比还要短Tr[1^{##}]。:)
Misha Lavrov

1
我认为您应该Quiet在您的主代码中包含一些内容。此答案输出了太多错误消息。至少问OP他是否可以接受
J42161217

2
似乎与忽略STDERR几乎是另一种语言一样,这是公认的惯例
Misha Lavrov

2
问题似乎是一个错误。我将尝试解决该问题。
丹尼斯,

6

Python 2中91个 88 84字节

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)

在线尝试!

该函数f递归检查是否n是中的元素幂的乘积lg它只是控制迭代的包装器



4

果冻,13 个字节

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

一个二进位链接,该列表f在左边有列表,n在右边有数字,产生一个数字。

在线尝试!高尔夫球效率低下-输入更高n和/或更长时间的输入将超时f

怎么样?

我们知道,各个因素(严格来说是积极因素)的力量永远都不需要超过n-1
...所以让我们来检查所有可能的方式!

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

视网膜,76字节

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

在线尝试!链接不包括最慢的测试用例,但仍然有些慢,因此请不要敲打@Dennis的服务器。



2

Mathematica,85个字节

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

输入项

[{list f},n,f的元素数]
[{57,34,12,21},12532159,4]


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

@ngenisis未显示的符号是什么?您可以建立TIO链接吗?
J42161217

没想到我会在同
一篇

@Jenny_mathy是U+F4A1,长名字\[Function]
ngenisis

使用0~Range~9似乎很保守。应该g[{2,3,5},1001]真的跳过1024并返回1080吗?这不是特别大的输入。
Misha Lavrov

2

Japt,10字节

_k e!øV}aU

在线测试!

由于旨在限制解释器永远运行的迭代限制,因此在最后一个测试用例上不起作用(尽管这里并没有太大帮助,因为它冻结了我的浏览器一个小时...)

说明

_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个字节

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

本质上是Rod的Python 答案的一部分。定义两个二进制运算符±·n±f返回Trueif n是of fFalseelse 元素的乘积。n·f给出最小的整数i。如果有人可以找到消除除数测试的方法,那么我可以使用ISO 8859-1编码节省10个字节。

说明

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个字节

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

在线尝试!

已经三个星期了,所以我想我终于要发布自己的解决方案了。这是蛮力的方法。

但是,有一个内置函数:

R,5个字节

nextn

在线尝试!

从R文档:

nextn返回大于或等于的最小整数,该整数n可以作为中包含的值的幂的乘积获得factorsnextn旨在用于找到合适的长度以将参数to零填充fft,以便快速计算转换。默认值用于factors确保这一点。

但是,如上面的TIO链接所示,一些测试显示了实现中的错误。

nextn(91,c(2,6))应该返回96,但返回128。显然,这仅在factors彼此都不是相对素数时发生。的确,它下面C代码揭示了nextn贪婪地尝试factor依次分割每个对象,直到1达到:

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

这可以通过以降序输入来解决。


1

JavaScript(ES6),53个 50字节

@DanielIndie节省了3个字节

以currying语法接受输入(n)(a)

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

测试用例

怎么样?

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 =函数总是在第一次运行时产生false,因此它与放置+ a基本上相同,现在是51个字节
DanielIndie

@DanielIndie实际上是50个字节。非常感谢!
Arnauld
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.