从> 1000位数字中查找最小的周期


10

您的工作是将此数字作为输入(尽管它也应该与任何其他数字一起使用):

18349570345710975183495703457109751834957034571097518349570345710975183495703457109761834957034571097518349570345710975183495703457109751834957034571097518349570345710976183495703457109751834957034571097518349570345710975183495703457109751834957034571097618349570345710975183495703457109751834957034571097518349570345710975183495703457109761834957034571097518349570345710975183495703457109751834957034571097518349570345710976183495703457109751834957034571097518349570345710975183495703457109751834957034571097618349570345710975183495703457109751834957034571097518349570345710975183495703457109761834957034571097518349570345710975183495703457109751834957034571097518349570345710976183495703457109751834957034571097518349570345710975183495703457109751834957034571097618349570345710975183495703457109751834957034571097518349570345710975183495703457109761834957034571097518349570345710975183495703457109751834957034571097518349570345710976183495703457109751834957034571097518349570345710975183495703457109751834957034571097618349570345710975183495703457109751834957

并找到最小周期,在这种情况下为:

1834957034571097518349570345710975183495703457109751834957034571097518349570345710976

祝好运并玩得开心点!


说明

  • 输入的数字至少有一个周期和一个局部周期
  • 句号始终从输入数字的开头开始
  • 在这种情况下,句号表示重复的数字序列。

输入数字的最大大小是多少?如果您的意思是最大大小>为1000,那么您的做法是错误的。
级圣河

@steveverrill:不,输入数字本身没有最大大小,但是让我们将其限制为2 ^ 16位数字(因为您询问了)。
Michael Bolli 2014年

3
什么时期?
FUZxxl 2014年

在这种情况下,@ FUZxxl:重复的数字序列。
Michael Bolli 2014年

3
您要的内容很明确,但您实际上不应该将其称为句点:在数学中,句点仅指无数次重复小数点的数字。相反,您的测试输入是整数,并且具有有限的位数。
GOTO

Answers:


4

CJam,20 16字节

Ll:Q{+_Q,*Q#!}=;

从STDIN读取。在线尝试。

上面的代码将需要O(n 2内存,其中n是输入的长度。只要您有足够的内存,它将可以使用2 个16位数字。

这可以解决五个额外字节的开销:

Ll:Q{+_Q,1$,/)*Q#!}=;

运行示例

$ cjam <(echo 'Ll:Q{+_Q,*Q#!}=;') <<< 18349570345710975183495703457109751834957034571097518349570345710975183495703457109761834957034571097518349570345710975183495703457109751834957034571097518349570345710976183495703457109751834957034571097518349570345710975183495703457109751834957034571097618349570345710975183495703457109751834957034571097518349570345710975183495703457109761834957034571097518349570345710975183495703457109751834957034571097518349570345710976183495703457109751834957034571097518349570345710975183495703457109751834957034571097618349570345710975183495703457109751834957034571097518349570345710975183495703457109761834957034571097518349570345710975183495703457109751834957034571097518349570345710976183495703457109751834957034571097518349570345710975183495703457109751834957034571097618349570345710975183495703457109751834957034571097518349570345710975183495703457109761834957034571097518349570345710975183495703457109751834957034571097518349570345710976183495703457109751834957034571097518349570345710975183495703457109751834957034571097618349570345710975183495703457109751834957; echo
1834957034571097518349570345710975183495703457109751834957034571097518349570345710976
$ cjam <(echo 'Ll:Q{+_Q,*Q#!}=;') <<< 12345123451; echo
12345
$ cjam <(echo 'Ll:Q{+_Q,*Q#!}=;') <<< 1234512345; echo
12345
$ cjam <(echo 'Ll:Q{+_Q,*Q#!}=;') <<< 123451; echo
12345

怎么运行的

对于输入Q,想法是重复第一个字符len(Q)并检查结果中Q的索引是否为0。如果不是,请重复前两个字符len(Q)等等。

L                   " Push L := [].                                                       ";
 l:Q                " Read one line from STDIN and save the result in Q.                  ";
    {        }=     " Find the first element q ∊ Q that yields a truthy value:            ";
     +              "   Execute L += [q].                                                 ";
      _Q,*Q#        "   Push (L * len(Q)).index(Q).                                       ";
            !       "   Compute the logical NOT of the index.                             ";
               ;    " Discard the last q. This leaves L on the stack.                     ";

8

正则表达式(.NET风格),23 22字节

.+?(?=(.*$)(?<=^\1.*))

这将与所需的时间段匹配为子字符串。

在这里测试。

它是如何工作的?

# The regex will always find a match, so there's no need to anchor it to
# the beginning of the string - the match will start there anyway.
.+?        # Try matching periods from shortest to longest
(?=        # Lookahead to ensure that what we've matched is actually
           # a period. By using a lookahead, we ensure that this is
           # not part of the match.
  (.*$)    # Match and capture the remainder of the input in group 1.
  (?<=     # Use a lookahead to ensure that this remainder is the same
           # as the beginning of the input. .NET lookaheads are best
           # read from right to left (because that's how they are matched)
           # so you might want to read the next three lines from the 
           # bottom up.
    ^      # Make sure we can reach the beginning of the string.
    \1     # Match group 1.
    .*     # Skip some characters, because the capture won't cover the
           # entire string.
  )
)

1
不过,这仅在句点从字符串的开头开始时才有效。碰巧是这种情况,但我在规格中看不到。对?
Tim Pietzcker 2014年

1
@TimPietzcker参见OP对以下问题的评论/编辑:句点始终始于字符串的开头。
Martin Ender 2014年

Regex Storm .Net似乎也可以处理.NET,它不需要Silverlight(在大多数平台上不可用)。
丹尼斯

@丹尼斯,谢谢,我不知道那个!
Martin Ender 2014年

1
@tolos这是因为您不能确保可以到达这样的字符串末尾。因此,它将只使用第一个重复的东西。例如,aabaabaab可能会匹配,a因为它会重复。我还没有找到解决PCRE问题的方法。丹尼斯尝试了一个现已删除的答案,但是那个答案也没有完全起作用。顺便说一句,您不需要g
Martin Ender 2014年

3

Python 60

s 是数字字符串

[s[:i]for i in range(len(s))if(s[:i]*len(s))[:len(s)]==s][0]

例如:

>>> s = '18349570345710975183495703457109751834957034571097518349570345710975183495703457109761834957034571097518349570345710975183495703457109751834957034571097518349570345710976183495703457109751834957034571097518349570345710975183495703457109751834957034571097618349570345710975183495703457109751834957034571097518349570345710975183495703457109761834957034571097518349570345710975183495703457109751834957034571097518349570345710976183495703457109751834957034571097518349570345710975183495703457109751834957034571097618349570345710975183495703457109751834957034571097518349570345710975183495703457109761834957034571097518349570345710975183495703457109751834957034571097518349570345710976183495703457109751834957034571097518349570345710975183495703457109751834957034571097618349570345710975183495703457109751834957034571097518349570345710975183495703457109761834957034571097518349570345710975183495703457109751834957034571097518349570345710976183495703457109751834957034571097518349570345710975183495703457109751834957034571097618349570345710975183495703457109751834957'
>>> [s[:i]for i in range(len(s))if(s[:i]*len(s))[:len(s)]==s][0]
'1834957034571097518349570345710975183495703457109751834957034571097518349570345710976'

1

Pyth,14个字符

hf}z*lzTm<zdUz

说明:

implicit:      z = input()
h              head(
 f                  filter(lambda T:
  }z                                z in
    *lz                                  len(z) * 
       T                                          T,
  m                        map(lambda d:
   <zd                                  z[:d],
   Uz                                   range(len(d)))))

本质上,它会生成输入的所有初始序列,每重复一次len(z),然后查看z输入是否位于结果字符串中。


这不是有效的答案,但是在提出问题后,Pyth最近添加了一项功能,该功能允许使用12个字符的解决方案:

<zf}z*lz<zT1

这将使用整数过滤器。


0

Japt,8字节

å+ æ@¶îX

尝试一下

-2个字节,感谢Shaggy!

Transpiled JS解释:

// U is the input string representation of the number
U
 // cumulative reduce using the '+' operator
 // the result is an array of strings length 1, 2, ..., N
 // all substrings start with the first character from input
 .å("+")
 // find the first match
 .æ(function(X, Y, Z) {
  // repeat the substring until it is as long as the input
  // and compare it to the input
  return U === U.î(X)
 })

1
8个字节:å+ æ@¶îX
蓬松的

太好了:)我之前见过将运算符扔进reduce函数,但是却忘了它。
丹娜

0

Java 8,125字节

将输入作为字符串,因为除了字符串(没有BigInteger,请使用BigInteger)之外,没有其他合理的方法来表示Java中的1000位数以上的数字。

s->{String o="";for(int i=0;java.util.Arrays.stream(s.split(o+=s.charAt(i++))).filter(b->!b.isEmpty()).count()>1;);return o;}

在线尝试!


您可以替换String为var。-3个字节
亚当

@Adam Java 8不过
Benjamin Urquhart

哦,没看到。
亚当
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.