找到最平滑的数字


59

您的挑战是找到给定范围内最平滑的数字。换句话说,找到最大素因数最小的数。

一个光滑的数字是其最大素因子小。这种类型的数字对于快速傅立叶变换算法,密码分析和其他应用程序很有用。

例如,在该范围内5, 6, 7, 8, 9, 10,8是最平滑的数字,因为8的最大质数为2,而所有其他数字的质数为3或更大。

输入:输入将是两个正整数,它们定义一个范围。该范围的最小整数是2。您可以选择范围是包含范围,排除范围,半排除范围等,只要可以在您的语言范围内指定任意范围即可。您可以通过函数输入,stdin,命令行参数或任何等效的语言方法获取数字。输入中没有编码额外的信息。

输出:在输入范围内返回,打印或等效的一个或多个最大平滑(最小最大因数)的整数。返回多个结果是可选的,但是如果选择这样做,则必须明确分隔结果。本地输出格式适合多种结果。

请在您的答案中说明您如何接受输入并给出输出。

得分:打高尔夫球。如果使用ASCII写入,则按字符计数;如果不使用ASCII,则按8 * bytes / 7计算。

测试用例:

注意:这些是Python样式的范围,包括低端但不包括高端。根据您的程序进行更改。仅需要一个结果。

smooth_range(5,11)
8
smooth_range(9,16)
9, 12
smooth_range(9,17)
16
smooth_range(157, 249)
162, 192, 216, 243
smooth_range(2001, 2014)
2002

是否将范围指定为(start,length)而不是(start,end)?
CodesInChaos

1
@CodesInChaos当然。它包含在“或任何”子句中。
isaacg 2014年

3
我认为惩罚非ASCII答案没有意义。在所有情况下仅计算字节数会更简单。
nyuszika7h 2014年

1
@ nyuszika7h Ascii明显小于一个字节-它仅使用7位。因此,我用7位表示一个字符,并相应地缩放其他语言。但是,如果语言是非ASCII语言,但可以将其所有字符打包成7位,我将不收取附加费。参见J / K与APL。tl; dr字节比较简单,但是提供了APL等。等 微妙但不公平的优势。
isaacg 2014年

3
@isaacg,您鼓励使用较小的字符集创建伪语言。如果我们对7位字符集和8位字符集进行评分,那么有人可以将大多数现代语言打包为6位(64个字符使我们获得AZ,0-9,少数空白,20个标点符号以及一些多余的字符) 。
Sparr

Answers:


99

果酱-13

q~,>{mfW=}$0=

http://cjam.aditsu.net/上尝试

输入2001 2014
示例:输出示例:2002

说明:

q~读取并评估输入,将2个数字压入堆栈(例如min和max),
,使数组[0 1 ... max-1]
>从min开始对数组进行切片,得到[min ... max-1]
{…}$使用该块对数组进行排序以计算排序键,以
mf得到具有所有素数
W=的数组,从而获得数组的最后一个元素(W = -1),从而获得要用作元素的最大素数排序键
0=获取(已排序)数组的第一个元素


38
好吧,我想就是那样。
埃里克·特雷斯勒

5
我需要向pyth添加一个分解函数。
isaacg 2014年

6
这种语言是巫术。
Brobin

8
这几乎只是在不造成漏洞的情况下尽可能多地拉出HQ9 +。太棒了!
IngoBürk2014年

25
ヽ(ຈل͜ຈ)ノmfW有人用13个字符解决了这个问题。
互联网由catz制作,2014年

66

正则表达式(.NET PCRE风味),183129字节

不要在家尝试!

这并不是赢球的真正竞争者。但是埃里克·特雷斯勒(Eric Tressler)建议只用正则表达式解决此问题,而我忍不住尝试一下。这可能在PCRE中实现(甚至更短,请参见下文),但是我选择.NET,因为我的解决方案需要任意长度的后向。开始了:

(?<=^(1+),.*)(?=\1)(?=((11+)(?=.*(?=\3$)(?!(11+?)\4+$))(?=\3+$)|(?!(11+)\5+$)1+))(?!.+(?=\1)(?:(?!\2)|(?=((11+)(?=.*(?=\7$)(?!(11+?)\8+$))(?=\7+$)|(?!(11+)\9+$)1+)).*(?=\2$)(?=\6)))1+

输入被编码为一个包含在内的逗号分隔范围,其中两个数字都使用1s 以一元符号表示。匹配将是范围内最平滑的数字结尾的S1s S。领带被打破,而数量最少。

因此,问题的第二个示例将是以下字符串(带下划线的匹配项)

111111111,1111111111111111
                 =========

它基于(到目前为止相当著名的)素数检查正则表达式,该正则表达式的变体被嵌入其中的次数高达6次。

这是一个使用自由行距和注释的版本,供那些想知道发生了什么的人使用。

# Note that the beginning of the match we're looking for is somewhere
# in the second part of the input.
(?<=^(1+),.*)          # Pick up the minimum range MIN in group 1
(?=\1)                 # Make sure there are at least MIN 1s ahead

                       # Now there will be N 1s ahead of the cursor
                       # where MIN <= N <= MAX.


(?=(                   # Find the largest prime factor of this number
                       # store it in group 2.
  (11+)                # Capture a potential prime factor P in group 3
  (?=                  # Check that it's prime
    .*(?=\3$)          # Move to a position where there are exactly 
                       # P 1s ahead
    (?!(11+?)\4+$)     # Check that the remaining 1s are not composite
  )
  (?=\3+$)             # Now check that P is a divisor of N.
|                      # This does not work for prime N, so we need a 
                       # separate check
  (?!(11+)\5+$)        # Make sure that N is prime.
  1+                   # Match N
))

(?!                    # Now we need to make sure that here is not 
                       # another (smaller) number M with a smaller 
                       # largest prime factor

  .+                   # Backtrack through all remaining positions
  (?=\1)               # Make sure there are still MIN 1s ahead

  (?:
    (?!\2)             # If M is itself less than P we fail 
                       # unconditionally.
  |                    # Else we compare the largest prime factors.
    (?=(               # This is the same as above, but it puts the
                       # prime factor Q in group 6.
      (11+)
      (?=
        .*(?=\7$)
        (?!(11+?)\8+$)
      )
      (?=\7+$)
    |
      (?!(11+)\9+$)
      1+
    ))
    .*(?=\2$)          # Move to a position where there are exactly 
                       # P 1s ahead
    (?=\6)             # Try to still match Q (which means that Q is
                       # less than P)
  )
)
1+                     # Grab all digits for the match

您可以在此处在线进行测试。但是不要尝试太大的输入,我不能保证这个怪物的性能。

编辑:

我最终将其移植到PCRE(仅需两个步骤),并将正则表达式缩短了近三分之一。这是新版本:

^(1+),.*?\K(?=\1)(?=((11+)(?=.*(?=\3$)(?!(11+?)\4+$))(?=\3+$)|(?!(11+)\5+$)1+))(?!.+(?=\1)(?:(?!\2)|(?=((?2))).*(?=\2$)(?=\6)))1+

这基本上是相同的,但有两个更改:

  • PCRE不支持任意长度的lookbehind(我曾经将其MIN放入group 1)。但是,PCRE是否支持\K将匹配的开始位置重置为当前光标位置。因此(?<=^(1+),.*)变为^(1+),.*?\K,它已经节省了两个字节。
  • 真正的节省来自PCRE的递归功能。我实际上并没有使用递归,但是您可以再次使用它(?n)来匹配组n,类似于子例程调用。由于原始正则表达式包含两次查找数字最大质数的代码,因此我能够用一个简单的替换第二个整数的大部分(?2)

37
上帝的圣母
Newb

1
@Timwi我需要检查最大的质数因子(group 37)实际上是质数。这就要求在第一次捕获因子之后再有一个因子副本,质数则不是这种情况。当我在.NET中通过在其中的某个地方放置一个后向位置以使我可以向后移动一点以便进行检查来解决该问题时,由于缺少可变长度的后向隐藏,在较短的PCRE版本中这是不可能的。它可能能够缩短一点,但我不认为只是改变+*的作品。
马丁·恩德

2
@MartinEnder嗨!我想您距离挑战已经很久了,但是我只是冲浪,看到了正则表达式解决方案,并且忍不住完全忽略了您在这篇文章顶部的警告:)我发现很难理解别人的代码,因此,在查看了您的正则表达式并感到困惑之后,我从头开始尝试了此操作,并提出了这个建议: (.*),.*?\K(?=(..+)((?=((?(R)\6|\2))*$).*(?=\4$)(?!(..+)\5+$)))(?!.+(?=\1)(?=(..+)(?3)).*(?!\2)\6).+ PCRE中有99个字节。另外,我在该站点上遇到了很多您的工作,并且我是忠实粉丝:D期待将来的正则表达式之战!
jaytea

1
我当时正在打代码高尔夫,并在其中添加注释:您可以通过以下方法\4$删除4b:取消前瞻并将其粘贴在负前瞻之后,但这会严重影响性能(每个数字子组<= \检查4是否具有综合性,而不仅仅是\ 4本身),并且在输入较长时失败。
jaytea

1
@jaytea很抱歉,花了很长时间与您联系。既然您是从头开始编写东西的,那么我认为您应该发布一个单独的答案。这是一个很好的成绩,您应该为此得到荣誉。:)
Martin Ender's

16

正则表达式(PCRE风味),66(65🐌)字节

看到两位正则表达式天才Martin Enderjaytea都为该代码高尔夫编写了正则表达式解决方案而受到启发,我从头开始编写了自己的解决方案。著名的素数检查正则表达式未出现在我的解决方案中的任何地方。

如果您不希望破坏一元正则表达式魔术,请不要阅读此书。如果您确实想自己弄清楚该魔术,我强烈建议您先解决ECMAScript正则表达式中的一些问题:

  1. 匹配素数(如果您还不熟悉正则表达式)
  2. 匹配2的幂(如果您尚未这样做)。或者只是通过Regex Golf(包括Prime和Powers)进行工作。确保同时完成Classic和Teukon问题集。
  3. 找到最短的方法来匹配N的幂,其中N是可以复合(但不是必需)的某个常数(即,在正则表达式中指定,而不是输入中指定)。例如,匹配的幂为6。

  4. 找到一种匹配第N个幂的方法,其中N是某个常数> = 2。例如,匹配完美的正方形。(要进行热身,请匹配主要力量。)

  5. 匹配正确的乘法语句。匹配三角数。

  6. 匹配斐波那契数字(如果您像我一样疯狂),或者如果您想坚持更短一些,请匹配正确的幂运算语句(对于热身,以2为底的对数以2为底的对数返回-奖金,对任何数字进行相同的处理(根据需要将其四舍五入)或阶乘数(对于热身,匹配原始数)。

  7. 匹配大量数字(如果您像我一样疯狂)

  8. 计算要求的精度的无理数(例如,将输入除以2的平方根,将舍入的结果返回为匹配项)

我编写regex引擎可能会有所帮助,因为它在处理一元数学正则表达式时非常快,并且包括可以测试自然数范围的一元数值模式(但也具有可以评估非一元正则表达式或一元字符串的字符串模式)默认情况下,它与ECMAScript兼容,但是具有可选的扩展名(可以有选择地添加PCRE的子集,甚至可以添加分子前瞻性,而其他正则表达式引擎则没有)。

否则,请继续阅读并阅读此GitHub Gist(警告,许多破坏者),它记录了推动ECMAScript regex处理难度越来越大的自然数函数的旅程(从teukon的一组难题开始,并非都是数学难题,这激发了这一点)旅程)。

与该问题的其他正则表达式解决方案一样,输入以双目一元形式的两个数字形式给出,并用逗号分隔,表示一个包含范围。仅返回一个数字。可以对正则表达式进行修改,以返回所有具有相同最小最大素数的所有数字作为单独的匹配项,但是这将需要变长的后向\K查找,或者提前查找或将结果作为捕获而不是匹配返回。

这里用最小素数重复进行隐式除法的技术与Match字符串中使用的技术相同,Match字符串的长度是我不久前发布的第四次幂次答案。

事不宜迟: ((.+).*),(?!.*(?=\1)(((?=(..+)(\5+$))\6)*)(?!\2)).*(?=\1)\K(?3)\2$

您可以在这里尝试。

以及带有注释的免费版本:

                        # No ^ anchor needed, because this algorithm always returns a
                        # match for valid input (in which the first number is less than
                        # or equal to the second number), and even in /g mode only one
                        # match can be returned. You can add an anchor to make it reject
                        # invalid ranges.

((.+).*),               # \1 = low end of range; \2 = conjectured number that is the
                        # smallest number in the set of the largest prime factor of each
                        # number in the range; note, it is only in subsequent tests that
                        # this is implicitly confined to being prime.
                        # We shall do the rest of our work inside the "high end of range"
                        # number.

(?!                     # Assert that there is no number in the range whose largest prime
                        # factor is smaller than \2.
  .*(?=\1)              # Cycle tail through all numbers in the range, starting with \1.

  (                     # Subroutine (?3):
                        # Find the largest prime factor of tail, and leave it in tail.
                        # It will both be evaluated here as-is, and later as an atomic
                        # subroutine call. As used here, it is not wrapped in an atomic
                        # group. Thus after the return from group 3, backtracking back
                        # into it can increase the value of tail – but this won't mess
                        # with the final result, because only making tail smaller could
                        # change a non-match into a match.

    (                   # Repeatedly divide tail by its smallest prime factor, leaving
                        # only the largest prime factor at the end.

      (?=(..+)(\5+$))   # \6 = tool to make tail = \5 = largest nontrivial factor of
                        # current tail, which is implicitly the result of dividing it
                        # by its smallest prime factor.
      \6                # tail = \5
    )*
  )
  (?!\2)                # matches iff tail < \ 2
)

# now, pick a number in the range whose largest prime factor is \2
.*(?=\1)                # Cycle tail through all numbers in the range, starting with \1.
\K                      # Set us up to return tail as the match.
(?3)                    # tail = largest prime factor of tail
\2$                     # Match iff tail == \2, then return the number whose largest
                        # prime factor is \2 as the match.

通过将子例程调用替换为该子例程的副本,然后将匹配项作为捕获组返回而不是使用\ K,可以轻松地将该算法移植到ECMAScript。结果是80个字节的长度:

((x+)x*),(?!.*(?=\1)((?=(xx+)(\4+$))\5)*(?!\2)).*(?=\1)(((?=(xx+)(\8+$))\9)*\2$)

在线尝试!

请注意,((.+).*)可以将其更改为((.+)+),将大小减小1个字节(从66 个字节减少到65个字节),而不会丢失正确的功能-但是regex呈指数级增长。

在线尝试! (79字节ECMAScript指数减速版本)


11

Python 2、95

i=input()
for a in range(*i):
 s=a;p=2
 while~-a:b=a%p<1;p+=1-b;a/=p**b
 if p<i:i=p;j=s                                        
print j

通过试算找到数字的平滑度,直到数字为1。i存储迄今为止最小的平滑度,j存储给出该平滑度的数字。

感谢@xnor参加高尔夫比赛。


1
if/else必须是可缩短的。我的第一个念头是b=a%p<1;p+=1-b;a/=p**b。或在交错字符串中运行两者之一的执行程序。此外,也许while~-a可行。
xnor 2014年

isaacg-我喜欢这个答案!您发现搜索最大素数的绝佳方式!我已经更新了答案,借用了您的方法,并在此方法上功不可没。
托德·雷曼

很好的解决方案!使用s,p=a,2i,j=p,s@xnor的想法,删除多余的缩进并将while块放在一行中可产生95个字符。不知道你怎么来了98 ...
Falko

这段代码充满了表情符号,:)
Rosenthal 2014年

@Falko这两个更改不保存任何字符。7-> 7。
isaacg 2014年

10

J,22 20 19个字符

({.@/:{:@q:)@(}.i.)

例如

   2001 ({.@/: {:@q:)@(}. i.) 2014
2002

(带有两个参数的函数在J中是中缀。)


我也有一个裂缝,没有得到这么短的答案。静像:(#~ (= <./)@:(i:"1&1)@:*@:(_&q:))@:([ + i.@-~)
ɐɔıʇǝɥʇuʎs

这里{:是一样的>./,节省了1个字节。
Randomra'3

@randomra你是对的,打个好电话!
FireFly

美丽。TIO(如果要添加):在线尝试!
约拿

9

Haskell,96 94 93 86 80个字符

x%y|x<2=y|mod x y<1=div x y%y|0<1=x%(y+1)
a#b=snd$minimum$map(\x->(x%2,x))[a..b]

通过GHCi(Haskell外壳)使用:

>5 # 9
8
>9 # 15
9

编辑:现在更简单的算法。

此解决方案包括范围内的两个数字(因此8 # 97 # 8均为8)

说明:

(%)函数采用两个参数x和y。当y为2时,该函数返回x的平滑度。

这里的算法很简单-获取输入中所有数字平滑度的组合列表,每个平滑度存储对原始数字的引用,然后进行排序以得到最小的数字,并返回其引用数。


这是具有相同算法的非高尔夫javascript版本:

function smoothness(n,p)
{
    p = p || 2
    if (x == 1)
        return p
    if (x % p == 0)
        return smoothness(x/p, p)
    else
        return smoothness(x,p+1);
}
function smoothnessRange(a, b)
{
    var minSmoothness = smoothness(a);
    var min=a;
    for(var i=a+1;i <= b;i++)
        if(minSmoothness > smoothness(i))
        {
            minSmoothness = smoothness(i)
            min = i
        }
    return min;
}

是否可以将最小别名混为短些?看起来它将节省一些字符。
isaacg 2014年

我尝试过,但是由于单态性限制,它实际上花费了一个字符
骄傲的haskeller 2014年

你不能只做m = minimum吗?Haskell仍然是一个谜。
isaacg 2014年

1
@isaacg要绕过单一性限制,您必须写出m l=minimum l
骄傲的haskeller 2014年

2
我打算发布一个Haskell解决方案,直到看到您的解决方案甚至击败了我的不完整版本... +1
nyuszika7h 2014年

9

Mathematica,61 45 39个字符

Range@##~MinimalBy~Last@*FactorInteger&

规范非常直接的实现为未命名函数。

  • 获取范围(含)。
  • 分解所有整数。
  • 查找最小值,按最大质数排序。

8

Lua-166个字符

还没有足够的声誉来评论AndoDaan的解决方案,但这是对他的代码的一些改进

a,b=io.read("*n","*n")s=b for i=a,b do f={}n=i d=2 while n>1 do while n%d<1 do f[#f+1]=d n=n/d end d=d+1 end p=math.max(unpack(f))if p<s then s=p c=i end end print(c)

变化 :

  • 在这种情况下,n%d==0by n%d<1等效
  • 删除了一个空格
  • 替换table.insert(f,d)f[#f+1]=d#f是f的元素数)

啊,很高兴我瞥了一眼。嗯,我应该检查并抓住前两个,但是您的第三个改进对我来说是新的(我的意思是与以往不同)。这将在golf.shinh.com上为我带来很多帮助。谢谢!
2014年

8

Bash + coreutils,56个字节

seq $@|factor|sed 's/:.* / /'|sort -nk2|sed '1s/ .*//;q'

输入恰好来自两个命令行参数(感谢@ nyuszika7h !!!)。输出是打印到STDOUT的单个结果。

  • seq 从命令行参数提供数字范围,每行一个。
  • factor读取这些数字并输出每个数字,然后输出冒号和该数字的主要因子的排序列表。因此,最大质数是每行的结尾。
  • 第一个sed除去冒号和除最后一个/最大的素数以外的所有素数,因此保留每个数字(第1列)及其最大素数(第2列)的列表。
  • sort 按数字升序从第2列开始。
  • 最终sed匹配第1行(最大质数为列表中最小的数字),删除所有内容,包括第一个空格及其之后的内容,然后退出。 sed退出前自动打印此替换的结果。

输出:

$ ./smooth.sh 9 15
12
$ ./smooth.sh 9 16
16
$ ./smooth.sh 157 249
162
$ ./smooth.sh 2001 2014
2002
$ 

在此上下文中的音符范围包括两个端点。


1
seq $@如果可以假设只有两个参数,则它要短3个字节。
nyuszika7h 2014年

@ nyuszika7h好主意-谢谢!
Digital Trauma 2014年

5

蟒蛇2,67

f=lambda R,F=1,i=2:[n for n in range(*R)if F**n%n<1]or f(R,F*i,i+1)

考虑再打高尔夫球给了我一个新的算法来检查平滑度的想法,因此得出了较晚的答案。

阶乘i!的素数分解最多包括正数i。因此,如果n是素数不同的乘积,则其平滑度(最大素数因子)最小in是的除数i!。为了考虑重复的素因子n,我们可以使用足够高的幂i!。特别是(i!)**n就足够了。

该代码尝试增加阶乘F=i!,递归更新。我们F对输入范围内的除数进行过滤,如果有除数,则将其输出,否则移至(i+1)!

测试用例:

>> f([157, 249])
[162, 192, 216, 243]

4

C, 149   95

编辑答案:

我无法为此解决方案争取信用。这个更新的答案借用了isaacg在他的Python解决方案中使用的漂亮方法。我想看看是否有可能将C作为不带花括号的嵌套for/ while循环编写出来,确实如此!

R(a,b,n,q,p,m){for(;a<b;m=p<q?a:m,q=p<q?p:q,n=++a,p=2)while(n>1)if(n%p)p++;else n/=p;return m;}

说明:

  • 函数R(a,b,n,q,p,m)将范围扫描a到,b-1并返回找到的第一个最平滑的数字。调用需要遵循以下形式:R(a,b,a,b,2,0)以便有效地初始化函数内部的变量,如下所示:n=a;q=b;p=2;m=0;

原始答案

这是我最初的答案...

P(n,f,p){for(;++f<n;)p=p&&n%f;return p;}
G(n,f){for(;--f>1;)if(n%f==0&&P(f,1,1))return f;}
R(a,b,p,n){for(;++p;)for(n=a;n<b;n++)if(G(n,n)==p)return n;}

说明:

  • 函数P(n,f,p)测试n素数的值,如果n是素数则返回true(非零),如果不是素数则返回false(零)nf并且p都必须作为1传递。
  • 函数G(n,f)返回的最大素数nf必须作为传递n
  • 函数R(a,b,p,n)将范围扫描a到,b-1并返回找到的第一个最平滑的数字。p必须作为1传递。n可以是任何值。

测试驱动程序:

test(a,b){printf("smooth_range(%d, %d)\n%d\n",a,b,S(a,b,1,0));}
main(){test(5,11);test(9,16);test(9,17);test(157,249);test(2001,2014);}

输出:

smooth_range(5, 11)
8
smooth_range(9, 16)
9
smooth_range(9, 17)
16
smooth_range(157, 249)
162
smooth_range(2001, 2014)
2002

我认为这与“在输入中不编码额外的信息”子句是犯规的。
Alchymist 2014年

@Alchymist —您可能是对的...但是我认为伪参数中没有任何实际的额外信息。至少没有任何关于答案的线索的信息。
托德·雷曼

4

哈斯克尔-120

import Data.List
import Data.Ord
x!y=(minimumBy(comparing(%2)))[x..y]
x%y|x<y=y|x`mod`y==0=(x`div`y)%y|otherwise=x%(y+1)

用法示例:

> 5 ! 10
8
> 9 ! 15
9
> 9 ! 16
16
> 157 ! 248
162
> 2001 ! 2013
2002

1
您不能使用<1代替==0吗?
dfeuer

是的,这将是一个不错的改进。有很多小事情可以做得更好。幸运的是,这个答案已经全部解决了:codegolf.stackexchange.com/a/36461
Taylor Fausak

4

Q,91个字符, K,78个字符

{(x+{where x=min x}{(-2#{x div 2+(where 0=x mod 2_til x)@0}\[{x>0};x])@0}'[(x)_til y+1])@0}

k可能会刮掉十几个字符

编辑:的确,这次将上限视为非包容性

{*:x+{&:x=min x}{*:-2#{6h$x%2+*:&:x={y*6h$x%y}[x]'[2_!x]}\[{x>0};x]}'[(x)_!y]}

4

注意:此答案是不允许的。

提出挑战后,此答案使用了添加的Pyth的多个功能。

我添加了另一个新功能,即在2元素元组上调用一元范围,从而将解决方案缩短了两个字符。

佩斯 7

hoePNUQ

现在输入以逗号分隔。其余部分相同。


这个答案使用了Pyth的功能,该功能是在提出此问题后添加的,特别是在看到@aditsu出色的CJam解决方案之后。话虽如此,我想证明增加该功能的原因。功能是P,这是arity-1函数,该函数在整数输入时返回输入的所有素数的列表,从最小到最大排序。

珀斯 9

hoePNrQvw

使用Python样式的范围,换行符在STDIN上分隔。将最小的解决方案输出到STDOUT。

说明:

      Q = eval(input())                         Implicit, because Q is present.
h     head(                                     First element of
 o         order_by(                            Sort, using lambda expression as key.
                    lambda N:                   Implicit in o
  e                          end(               Last element of
   PN                            pfact(N)),     List containing all prime factors of N.
  r                 range(                      Python-style range, lower inc, upper exc.
   Q                      Q,                    A variable, initialized as shown above.
   vw                     eval(input()))))      The second entry of the range, same way.

测试:

$ newline='
'

$ echo "9${newline}16" | ./pyth.py -c 'hoePNrQvw'
9

$ echo "9${newline}17" | ./pyth.py -c 'hoePNrQvw'
16

$ echo "157${newline}249" | ./pyth.py -c 'hoePNrQvw'
162

$ echo "2001${newline}2014" | ./pyth.py -c 'hoePNrQvw'
2002

@MartinBüttnerYep,正如对CJam解决方案的评论所建议的那样
Adriweb 2014年

@MartinBüttner是的,P是新功能。我将其放在答案中。
isaacg 2014年

1
允许与否,不仅我喜欢它,而且我还认为,如果您注意的话,那些简短的“宏”是可读的-毕竟它们会转换为简单的Python。对于高尔夫语言,必须说一些对高尔夫有益的语言,但不一定会造成混淆。
库巴·奥伯2014年

@KubaOber谢谢,库巴。这一直是我编写Pyth的意图,以使其尽可能地打高尔夫球并使其可读性更高。我很高兴它正在工作。
isaacg 2014年

3

Lua-176个字符

a,b=io.read("*n","*n")s=b for i=a,b do f={}n=i d=2 while n>1 do while n%d==0 do table.insert(f, d)n=n/d end d=d+1 end p=math.max(unpack(f))if p<s then s=p c=i end end print(c)

我真的应该停止在卢阿打高尔夫球。毫无意义。


14
恕我直言,打高尔夫球就像拳击:有重量级。给定的语言可能无法完全取胜,但是在该课程/语言中打高尔夫很有趣,而且很有启发性。
2014年

3

Clojure- 173170个字符

我是Clojure的新手。打高尔夫球:

(defn g[x,d](if(and(= 0(mod x d))(.isProbablePrime(biginteger d) 1))d 0))(defn f[i](apply max-key(partial g i)(range 2(inc i))))(defn s[a,b](first(sort-by f(range a b))))

样品运行:

范围包括低端,但不包括高端:[a,b)如果出现多个,则仅打印最平滑的数字之一。

(println (s 5 11))
(println (s 9 16))
(println (s 9 17))
(println (s 157, 249))
(println (s 2001, 2014))

产量:

bash$ java -jar clojure-1.6.0.jar range.clj
8
9
16
192
2002

取消高尔夫:

(defn g [x,d] (if (and (= 0(mod x d)) (.isProbablePrime (biginteger d) 1)) d 0))
(defn f [i] (apply max-key (partial g i) (range 2 (inc i))))
(defn s [a,b] (first (sort-by f (range a b))))

1
通常将包含低端但不包括高端的范围写为[a,b]。
murgatroid99 2014年

是的,感谢您的来信
迈克尔·

3

红宝石,65 62

require'prime'
s=->a,b{(a..b).min_by{|x|x.prime_division[-1]}}

https://codegolf.stackexchange.com/a/36484/6828致歉,这是该版本的简化版本。使用包含范围,因为它是一个较短的字符。

1.9.3-p327 :004 > s[157,249]
 => 192 
1.9.3-p327 :005 > s[5,11]
 => 8 
1.9.3-p327 :006 > s[9,15]
 => 12 
1.9.3-p327 :007 > s[9,16]
 => 16 

还要感谢YenTheFirst保存了三个字符。


1
实际上,您无需使用[0]就可以摆脱困境,因为无论如何数组比较都会优先考虑第一个元素。这将给出不同但仍然正确的结果。
YenThe2014年

3

C#LINQ:317 303 289 262

using System.Linq;class P{static void Main(string[]a){System.Console.Write(Enumerable.Range(int.Parse(a[0]),int.Parse(a[1])).Select(i=>new{i,F=F(i)}).Aggregate((i,j)=>i.F<j.F?i:j).i);}static int F(int a){int b=1;for(;a>1;)if(a%++b<1)while(a%b<1)a/=b;return b;}}

取消高尔夫:

using System.Linq;

class P
{
  static void Main(string[]a)
  {
    System.Console.Write(
      Enumerable.Range(int.Parse(a[0]), int.Parse(a[1])) //create an enumerable of numbers containing our range (start, length)
        .Select(i => new { i, F = F(i) }) //make a sort of key value pair, with the key (i) being the number in question and the value (F) being the lowest prime factor
        .Aggregate((i, j) => i.F < j.F ? i : j).i); //somehow sort the array, I'm still not entirely sure how this works
  }
  static int F(int a)
  {
    int b=1;
    for(;a>1;)
      if(a%++b<1)
        while(a%b<1)
          a/=b;
    return b;
  }
}

它从命令行开始并输入长度,并将返回最大的平滑数。

我从这里这里都使用答案来做我的答案。

感谢VisualMelon对其进行调整并节省了12个字节!如果节省了2个字节,我也摆脱了花括号,CodeInChaos指出了我错过的一些明显的东西(再次感谢)。


几个通用的小东西,您可以F通过int b在m旁边定义来节省4个字节。在几个地方,你执行比较a%b==0,并 ab始终为正,你可以通过检查削减每一个字节,如果是小于1 a%b<1。您也可以通过增加bif的条件a%++b<0来保存一个字节,而不是通过将其初始化为1 来节省一个字节。在这种情况下,完全限定条件System.Console.WriteLine并避免使用该namespace子句会更便宜。
VisualMelon 2014年

@VisualMelon谢谢,更新了您的想法:)
ldam

m=...:m;件事不在while循环中。因此,您可以删除m=0,和替换return m;return m=b>m?b:m;。然后,您可以m=...:m;完全删除。
tomsmeding

听起来可能很奇怪,但是-对我而言-比CJam和J少可重复使用。我想C#的设计是冗长的,并且尝试使其不那么冗长,从而使它不可读?嗯....
库巴·奥伯2014年

不,我不同意,当您只在这里和那里看到LINQ而从未亲自玩过它时,LINQ看起来就像是一个恶魔。但是,一旦您掌握了它,它就真的很酷了:)话虽如此,我仍然不完全了解它的Aggregate工作原理,我只是在另一个答案中看到它之后才尝试了它,以获取我的新对象,而不是其中的一个字段,并且它恰好工作得很好:)
ldam

2

R,83

library(gmp)
n=a:b
n[which.min(lapply(lapply(lapply(n,factorize),max),as.numeric))]

其中输入范围的底部分配给a,顶部(包括)分配给b

gmp是CRAN上可用的软件包。直到我看到mfCJam中那种荒唐的功能之前,它还是很脏。通过install.packages("gmp")在控制台中键入安装。


1
如果您使用了lapply3次,则可能要对其l=lapply加上别名(即,然后使用l(...)。同样,由于这factorize是您在包gmp中使用的唯一功能,因此可以使用它,gmp::factorize而不是先加载库,然后再使用factorize。这样,您的代码将变为l=lapply;n=a:b;n[which.min(l(l(l(n,gmp::factorize),max),as.numeric))]69个字节。
plannapus

2

PowerShell的-85

($args[0]..$args[1]|sort{$d=2
while($_-gt1){while(!($_%$d)){$m=$d;$_/=$d}$d++}$m})[0]

这将根据每个数字的最大质数对一系列数字(包括该数字)进行排序。它返回最低排序的元素。

> smooth 5 10
8
> smooth 9 15
12
> smooth 9 16
16
> smooth 157 248
243
> smooth 2001 2013
2002

2

J-16个字符

使用注释允许的(startlength)范围样式。

(0{+/:{:@q:@+)i.

用作二元动词:left参数是start,right 参数是length

   5 (+)i. 6              NB. range
5 6 7 8 9 10
   5 (q:@+)i. 6           NB. prime factorizations
5 0 0
2 3 0
7 0 0
2 2 2
3 3 0
2 5 0
   5 ({:@q:@+)i. 6        NB. largest prime factors
5 3 7 2 3 5
   5 (+/:{:@q:@+)i. 6     NB. sort range by smallest factors
8 6 9 5 10 7
   5 (0{+/:{:@q:@+)i. 6   NB. take first entry
8
   f=:(0{+/:{:@q:@+)i.    NB. can also be named
   2001 f 13
2002

startend)解决方案是+2个字符,不包括end;包括末尾+2。但好的一面是,由于我们匹配了所有{花括号},因此它看起来还不错。

(0{}./:{:@q:@}.)i.    NB. excluding
(0{}./:{:@q:@}.)1+i.  NB. including

2

严重的是8 * 14/7 = 16(非竞争性)

,x;`yM`M;m@í@E

认真创建是在挑战之后创建的,但我想发布此答案,因为它体现了认真擅长的挑战类型。

在线尝试!

说明:

,x;`yM`M;m@í@E
,x;             make two copies of range(a,b) (a,b = input())
   `  `M;       make two copies of the result of the map:
    yM            push maximum prime factor
         m@í    push index of minimum element from prime factors
            @E  push element from range with given index

2

Pyth,7个字节

.mePbrF

在这里尝试!

[a,b)[a,b]}r

.mePbrF – Full program with arguments a and b.
     rF – Fold by half-inclusive range. Yields the integers in [a, b).
.m      – Values b in that list which give minimal results when applied f.
  ePb   – function / block f. 
   Pb   – Prime factors of b.
  e     – Last element. This is guaranteed to yield the largest, as they're sorted.

1

眼镜蛇-150

def f(r as vari int)
    x,y=r
    c,o=y,0
    for n in x:y,for m in n:0:-1
        p=1
        for l in 2:m,if m%l<1,p=0
        if n%m<=0<p
            if m<c,c,o=m,n
            break
    print o

甚至不知道为什么我打扰,眼镜蛇只是不能在这里竞争。


1
眼镜蛇看起来和python一样...有什么区别?
Beta Decay

当您为C#提供Python语法时,会发生@BetaDecay Cobra。眼镜蛇网站
2014年

1

红宝石-113个字符

使用stdlib。返回一个结果。在红宝石2.1.2上测试。

require 'prime'
def smooth_range(a,b)
  (a...b).sort_by{|e|e.prime_division.flat_map{|f,p|[f]*p}.uniq.max}[0]
end

1
欢迎使用编程难题和Code Golf Stack Exchange。感谢您发布结果。由于这是一个打高尔夫球的问题,因此请在答案中包括您的字符数。您可以使用这样的工具:javascriptkit.com/script/script2/charcount.shtml
isaacg 2014年

1

Perl(5.10 +),83

for(<>..<>){$n=$_;$p=2;$_%$p&&$p++or$_/=$p while$_>1;$m=$p,$r=$n if$p<$m||!$m}
say$r

(可以删除换行符)。在两行stdin上采用包含范围的两个端点(因为<>比访问便宜ARGV),并向stdout输出最平滑的端点。如果打平领带,则打印最小的领带。可以以一个字符为代价打印最大的字符。

尽管我们独立提出了算法,但该算法基本上是isaacg寻求最大素因的方法。该部分完美地打入了perl中的单个语句,其余部分的开销却比我想要的多。

应下运行perl -E或用use 5.012前导。如果您无法执行此操作,请替换say$rprint$r,$/


1

的Python 2(84)

f=lambda n,p=2:n>1and f(n/p**(n%p<1),p+(n%p>0))or p
print min(range(*input()),key=f)

@isaacg的解决方案,但使用minby功能键代替了显式的min- find查找,而递归函数则充当迭代的角色。

Stackless Python中运行以避免递归限制。

使用带括号的条件看起来很浪费(n%p<1),然后在括号中也重复它的否定(n%p>0),但这是我得到的最好的结果。我尝试了一堆东西,但结果却更糟。

f(n/p**(n%p<1),p+(n%p>0))     # Current for comparison
f(*[n/p,n,p,p+1][n%p>0::2])
n%p and f(n,p+1)or f(n/p,p)
f(*n%p and[n,p+1]or[n/p,p])

我欢迎您能想到的任何改进。


1

Java 8-422454个字符

我正在学习Java 8,并希望对此做一个相对于Java(甚至Java 8流)的镜头。

与其他语言相比,这是残酷但有趣的练习。

打高尔夫球:

import java.util.stream.*;import java.math.*;
class F{int v;int i;public int getV() { return v; }
F(int i){this.i = i;v=IntStream.range(2,i+1).map(j->((i%j==0)&&new BigInteger(""+j).isProbablePrime(1))?j:0).max().getAsInt();}}
public class T{
int s(int a, int b){return IntStream.range(a,b+1).boxed().map(F::new).sorted(java.util.Comparator.comparingInt(F::getV)).collect(java.util.stream.Collectors.toList()).get(0).i;}}

取消高尔夫:

import java.util.stream.*;
import java.math.*;

class F {
    int v;
    int i;
    public int getV() { return v; }
    F (int i) { 
        this.i = i;
        v = IntStream.range(2,i+1)
                     .map( j -> ((i%j==0) && 
                           new BigInteger(""+j).isProbablePrime(1))?j:0)
                     .max()
                     .getAsInt();
    }
}

public class T {
    int s(int a, int b) {
        return IntStream.range(a,b+1)
                    .boxed()
                    .map(F::new)
                    .sorted(java.util.Comparator.comparingInt(F::getV))
                    .collect(java.util.stream.Collectors.toList())
                    .get(0).i;
    }
}

使用以下示例运行:

public static void main(String[] s) {
    System.out.println(new T().s(157,249));
}

192

1

MATL非竞争性),20字节

该语言是在挑战之后设计的

范围包括两端。这些数字被当作两个单独的输入。

2$:t[]w"@YfX>v]4#X<)

在线尝试!

说明

2$:          % implicitly input two numbers. Inclusive range
t            % duplicate                      
[]           % empty array
w            % swap elements in stack         
"            % for each                  
  @          %   push loop variable
  Yf         %   prime factors                  
  X>         %   maximum value
  v          %   vertical concatenation         
]            % end for each                         
4#X<         % arg min 
)            % index with this arg min into initial range of numbers

我想今天是17个字节,&:[]y"@YfX>h]&X<)或者可能是16 个字节:[]y"@YfX>h]&X<)。这&真的是一个好主意(我想y那时候还没有吗?)。
sundar

看起来Yf带有前缀1的广播在这里也很有用,但这可能不足以决定总体上是个好主意。:)
sundar

是的,这是一开始,所以没有y&。对于Suever的非常有用的语义要归功于Suever(我最初的想法是让它表示“输入多于默认值”)。如果我们看到更多的实例,Yf添加实例将很有用,那么添加该功能确实值得。问题是,大约有34个答案在使用Yf(根据此脚本),所以很难说出来
Luis Mendo

1

果冻,7个字节,得分= 7÷7×8 = 8,语言发布日期挑战

rÆfṀ$ÐṂ

在线尝试!

将范围上限和下限作为两个单独的参数。输出该范围内所有最平滑数字的列表。(这可以看作是一个函数,在这种情况下,输出是一个果冻列表,或者可以看作是一个完整程序,在这种情况下,输出恰好使用了与JSON相同的列表表示形式。)

说明

那些时候,您的Jelly程序只是规范的字面翻译……

rÆfṀ$ÐṂ
r        Range from {first argument} to {second argument}
     ÐṂ  Return the elements which have the minimum
   Ṁ$      largest
 Æf          prime factor
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.