1000桁以上の数字から最小周期を見つける


10

あなたの仕事は、この数値を入力として受け取ることです(他の数値でも機能するはずです)。

18349570345710975183495703457109751834957034571097518349570345710975183495703457109761834957034571097518349570345710975183495703457109751834957034571097518349570345710976183495703457109751834957034571097518349570345710975183495703457109751834957034571097618349570345710975183495703457109751834957034571097518349570345710975183495703457109761834957034571097518349570345710975183495703457109751834957034571097518349570345710976183495703457109751834957034571097518349570345710975183495703457109751834957034571097618349570345710975183495703457109751834957034571097518349570345710975183495703457109761834957034571097518349570345710975183495703457109751834957034571097518349570345710976183495703457109751834957034571097518349570345710975183495703457109751834957034571097618349570345710975183495703457109751834957034571097518349570345710975183495703457109761834957034571097518349570345710975183495703457109751834957034571097518349570345710976183495703457109751834957034571097518349570345710975183495703457109751834957034571097618349570345710975183495703457109751834957

そして、この場合、最小周期を見つけます:

1834957034571097518349570345710975183495703457109751834957034571097518349570345710976

頑張って楽しんでね!


明確化:

  • 入力番号には、少なくとも1つの期間と1つの部分期間があります
  • 期間は常に入力番号の先頭から始まります
  • ピリオドとは、この場合、それ自体を繰り返す一連の数字を意味します。

入力数の最大サイズは?最大サイズが1000である場合>、間違った方向を向いています。
— Level River St

@steveverrill:いいえ、入力番号自体の最大サイズはありませんが、2 ^ 16桁に制限しましょう(質問したため)。
— Michael Bolli 2014

3
ピリオドとは何ですか?
— FUZxxl 2014

この場合の@FUZxxl:繰り返される一連の番号。
— Michael Bolli 2014

3
あなたが求めていることは明らかですが、それをピリオドと呼ぶべきではありません。数学では、ピリオドは小数点の後に続く数字を無限に繰り返すだけです。反対に、テスト入力は整数であり、桁数が有限です。
— GOTO 0

回答:


4

CJam、20 16バイト

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

STDINから読み取ります。オンラインでお試しください。

上記のコードはO(n 2)メモリを必要とします。ここで、nは入力の長さです。それはなり 2つので動作する16限り、あなたは十分なメモリを持っているように、数字。

これは、余分な5バイトのコストを修正できます。

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かどうかを確認します。そうでない場合は、最初の2文字を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

1
@TimPietzcker質問に対するOPのコメント/編集を参照してください。ピリオドは常に文字列の先頭から始まります。
— マーティンエンダー

Regex Storm .Netも.NETを処理するようであり、Silverlightを必要としません(ほとんどのプラットフォームでは使用できません)。
— デニス

@デニスありがとう、私はそれを知りませんでした!
— マーティンエンダー

1
@tolosこれは、このように文字列の最後に到達できるとは限らないためです。したがって、最初に繰り返されるものだけを使用します。たとえば、繰り返されるため、aabaabaabおそらく一致aします。PCREでそれを解決する方法をまだ見つけていません。デニスは削除された答えを試しましたが、それも完全には機能しませんでした。ところで、あなたは必要ありませんg。
— マーティンエンダー

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

バース、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)))))

基本的に、入力のすべての初期シーケンスを生成し、1 len(z)回ずつ繰り返しz、結果の文字列内に入力が存在するかどうかを確認します。


これは有効な回答ではありませんが、質問が行われた後、12文字のソリューションを可能にする機能がPythに最近追加されました。

<zf}z*lz<zT1

これは整数機能のフィルターを使用します。


0

Japt、8バイト

å+ æ@¶îX

それを試してみてください

-Shaggyのおかげで2バイト!

分解された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
— Shaggy

すばらしい:)以前に、オペレーターをreduce関数に投入するのを見たことがありますが、それを忘れていました。
— dana

0

Java 8、125バイト

文字列以外にJavaで1000以上の数字を表す適切な方法がないため、文字列として入力を受け取ります(BigIntegerを使用しないでください)。

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

オンラインでお試しください!


Stringvarに置き換えることができます。-3バイト
— Adam

@Adam Java 8ただし
— ベンジャミンアー

ああ、見なかった。
— アダム
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.