Gijswijt 시퀀스의 n 자리 생성 없다고 가정 할 수

소개

Gijswijt의 시퀀스 ( A090822 )는 정말 정말 느립니다. 설명하기 위해 :

  • 첫 번째 3은 9 번째 용어에 나타납니다.
  • 첫 번째 4 개는 220 번째 용어로 먼 거리에 있지만 실현 가능합니다.
  • 처음 5는 10 ^ (10 ^ 23) 번째 항 ( 대략)에 나타납니다 .
  • 아무도 처음 6이 어디에 있는지 알지 못합니다.

    2 ^ (2 ^ (3 ^ (4 ^ 5))) 번째 항입니다.

두 자리 숫자를 다룰 필요가 없다고 가정 할 수 있습니다.

시퀀스는 다음과 같이 생성됩니다.

  1. 첫 번째 용어는 1입니다.
  2. 그 이후의 각 용어는 이전의 반복 “블록”의 양입니다 (반복되는 “블록”이 여러 개인 경우 가장 많은 양의 반복 블록이 사용됨).

명확히하기 위해 처음 몇 가지 용어가 있습니다.

1 -> 1, 1(반복 블록 하나 ( 1)이므로 기록 된 숫자는 1)

1, 1 -> 1, 1, 2(두 개의 반복 블록 ( 1)이므로 기록 된 숫자는 2)

1, 1, 2 -> 1, 1, 2, 1(반복 블록 하나 ( 2또는 1, 1, 2)이므로 기록 된 숫자는 1)

1, 1, 2, 1 -> 1, 1, 2, 1, 1 (당신은 아이디어를 얻는다)

1, 1, 2, 1, 1 -> 1, 1, 2, 1, 1, 2

1, 1, 2, 1, 1, 2 -> 1, 1, 2, 1, 1, 2, 2(두 개의 반복 블록 ( 1, 1, 2)이므로 기록 된 숫자는 2)

직무

질문에 명시된 바와 같이 귀하의 작업은 Gijswijt 시퀀스의 n 자리를 생성하는 것입니다.

명령

  • 입력 값은 정수 n입니다.
  • 코드는 숫자를 모든 형식 (목록, 여러 출력 등)으로 출력 할 수 있습니다.

이것은 코드 골프이므로 바이트 단위의 가장 짧은 코드가 이깁니다.



답변

Pyth, 25 22 21 바이트

t_u+eSmtfxG*Td1._GGQN

OP는 한 자리 숫자 만 처리하면된다는 것을 확인했습니다. 이를 통해 목록을 문자열로 저장할 수있었습니다. -> 3 바이트 저장

온라인으로 사용해보십시오 : 데모

설명:

t_u+...GQN      implicit: Q = input number
         N      start with the string G = '"'
  u     Q       do the following Q times:
    ...            generate the next number
   +   G           and prepend it to G
 _              print reversed string at the end
t               remove the first char (the '"')

그리고 다음 숫자를 생성하는 방법은 다음과 같습니다.

eSmtfxG*Td1._G
           ._G    generate all prefixes of G
  m               map each prefix d to:
    f     1          find the first number T >= 1, so that:
       *Td              d repeated T times
     xG                 occurs at the beginning of G
 S                  sort all numbers
e                   take the last one (maximum)

리스트가있는 21 바이트

_u+eSmhhrcGd8SlGGtQ]1

온라인으로 사용해보십시오 : 데모

Martin과 Peter의 동일한 아이디어를 사용합니다. 각 단계에서 문자열을 길이 1 조각, 길이 2 조각으로 나눕니다 … 그런 다음 길이를 길이로 인코딩하고 최대 첫 실행을 다음 숫자로 사용합니다.

문자열이있는 20 바이트

t_u+eSmhhrcGd8SlGGQN

온라인으로 사용해보십시오 : 데모

위의 두 코드의 아이디어를 결합합니다.


답변

CJam, 33 31 30 27 바이트

1 바이트를 절약 해 준 Peter Taylor에게 감사합니다.

1sri({),:)1$W%f/:e`$W=sc+}

여기에서 테스트하십시오.

설명

1s      e# Initialise the sequence as "1".
ri(     e# Read input N and decrement.
{       e# For each I from 0 to N-1...
  )     e#   Increment to get I from 1 to N.
  ,     e#   Turn into a range [0 1 ... I-1].
  :)    e#   Increment each element to get [1 2 ... I].
  1$    e#   Copy sequence so far.
  W%    e#   Reverse the copy.
  f/    e#   For each element x in [1 2 ... I], split the (reversed) sequence
        e#   into (non-overlapping) chunks of length x. These are the potentially
        e#   repeated blocks we're looking for. We now want to find the splitting
        e#   which starts with the largest number of equal blocks.
  :e`   e#   To do that, we run-length encode each list blocks.
  $     e#   Then we sort the list of run-length encoded splittings, which primarily
        e#   sorts them by the length of the first run.
  W=    e#   We extract the last splitting which starts with the longest run.
  sc    e#   And then we extract the length of the first run by flattening
        e#   the list into a string and retrieving the first character.
  +     e#   This is the new element of the sequence, so we append it.
}/


답변

CJam ( 30 29 27 24 바이트)

'1ri{{)W$W%/e`sc}%$W>+}/

온라인 데모

이것은 Martin과의 공동 노력입니다.

  • e`반복을 식별하기 위해 실행 길이 인코딩 ( )을 영리하게 사용 하는 것은 Martin의 것입니다.
  • 따라서 W$스택 관리를 단순화 하는 데 사용 됩니다
  • $W>+아래 절에서 설명한대로 특수 케이스 를 사용하여 몇 가지 증감 작업을 제거했습니다.

내 첫 30 바이트 접근 방식 :

1ari{,1$f{W%0+_@)</{}#}$W>+}/`

온라인 데모

해부

1a        e# Special-case the first term
ri{       e# Read int n and iterate for i=0 to n-1
  ,1$f{   e#   Iterate for j=0 to i-1 a map with extra parameter of the sequence so far
    W%0+  e#     Reverse and append 0 to ensure a non-trivial non-repeating tail
    _@)</ e#     Take the first j+1 elements and split around them
    {}#   e#     Find the index of the first non-empty part from the split
          e#     That's equivalent to the number of times the initial word repeats
  }
  $W>+    e#   Add the maximal value to the sequence
          e#   NB Special case: if i=0 then we're taking the last term of an empty array
          e#   and nothing is appended - hence the 1a at the start of the program
}/
`         e# Format for pretty printing


답변

하스켈, 97 바이트

f 1=[1]
f n|x<-f$n-1=last[k|k<-[1..n],p<-[1..n],k*p<n,take(k*p)x==([1..k]>>take p x)]:x
reverse.f

세 번째 줄은 정수를 사용하고 정수 목록을 반환하는 익명 함수를 정의합니다.
실제로 참조하십시오.

설명

도우미 함수 f는 이전 시퀀스가 ​​반복 블록으로 시작하는지 여부를 재귀 적으로 확인하여 시퀀스를 역순으로 구성합니다.
k반복 횟수이며 p블록의 길이입니다.

f 1=[1]                                   -- Base case: return [1]
f n|x<-f$n-1=                             -- Recursive case; bind f(n-1) to x.
  last[k|k<-[1..n],                       -- Find the greatest element k of [1..n] such that
  p<-[1..n],                              -- there exists a block length p such that
  k*p<n,                                  -- k*p is at most the length of x, and
  take(k*p)x                              -- the prefix of x of length p*k
    ==                                    -- is equal to
  ([1..k]>>take p x)                      -- the prefix of length p repeated k times.
  ]:x                                     -- Insert that k to x, and return the result.
reverse.f                                 -- Composition of reverse and f.


답변

Pyth, 41 38 바이트

J]1VSQ=J+h.MZmh+fn@c+J0dT<JdSNZSNJ;P_J

온라인으로 사용해보십시오!


답변

망막 , 66 60 바이트

+1`((\d+)?(?<1>\2)*(?<!\3(?>(?<-1>\3)*)(?!.*\2)(.+)))!
$1$#1

입력은 !숫자로 사용하는 단항 정수입니다 (비 숫자가 아닌 다른 문자로 변경 될 수 있음). 출력은 단순히 문자열입니다.

온라인으로 사용해보십시오! (또는 편의상 여기에 10 진수를 입력하는 버전이 있습니다. )

테스트 목적으로, 이것은 약간의 수정 으로 많은 속도를 낼 수 있으며 , 1 분 안에 입력 220을 테스트 할 수 있습니다.

+1`((\d+)?(?<1>\2)*(?=!)(?<!\3(?>(?<-1>\3)*)(?!.*\2)(.+)))!
$1$#1

온라인으로 사용해보십시오! ( 십진수 버전. )

더 큰 숫자를 테스트하려면 대량의 입력을 공급 :하고 초기 다음에을 넣는 것이 가장 좋습니다 +. 이렇게하면 새로운 숫자 계산이 끝날 때마다 Retina가 현재 시퀀스를 인쇄합니다 (모든 숫자가 하나씩 해제 됨).

설명

솔루션은 단일 정규식 대체로 구성되며 결과가 변경을 멈출 때까지 반복적으로 입력에 적용됩니다.이 경우 정규식이 더 이상 일치하지 않기 때문에 발생합니다. +처음에이 루프를 소개합니다. 는 1(이것은 매우 첫 번째 반복 만 관련) 망막은 첫 경기를 교체 알려주는 한계입니다. 각 반복에서 스테이지는 하나의 !(왼쪽에서) 시퀀스의 다음 숫자로 바뀝니다 .

평소와 같이 밸런싱 그룹에 대한 입문서가 필요하면 SO 답변을 참조하십시오 .

다음은 주석이 달린 정규식 버전입니다. 목표는 그룹에서 최대 반복 블록 수를 캡처하는 것입니다 1.

(                 # Group 1, this will contain some repeated block at the end
                  # of the existing sequence. We mainly need this so we can
                  # write it back in the substitution. We're also abusing it
                  # for the actual counting but I'll explain that below.
  (\d+)?          # If possible (that is except on the first iteration) capture
                  # one of more digits into group 2. This is a candidate block
                  # which we're checking for maximum repetitions. Note that this
                  # will match the *first* occurrence of the block.
  (?<1>\2)*       # Now we capture as many copies of that block as possible
                  # into group 1. The reason we use group 1 is that this captures
                  # one repetition less than there is in total (because the first
                  # repetition is group 2 itself). Together with the outer
                  # (unrelated) capture of the actual group one, we fix this
                  # off-by-one error. More importantly, this additional capture
                  # from the outer group isn't added until later, such that the
                  # lookbehind which comes next doesn't see it yet, which is
                  # actually very useful.
                  # Before we go into the lookbehind note that at the end of the
                  # regex there's a '!' to ensure that we can actually reach the
                  # end of the string with this repetition of blocks. While this
                  # isn't actually checked until later, we can essentially assume
                  # that the lookbehind is only relevant if we've actually counted
                  # repetitions of a block at the end of the current sequence.

  (?<!            # We now use a lookbehind to ensure that this is actually the
                  # largest number of repetitions possible. We do this by ensuring
                  # that there is no shorter block which can be matched more
                  # often from the end than the current one. The first time this
                  # is true (since, due to the regex engine's backtracking rules,
                  # we start from longer blocks and move to shorter blocks later),
                  # we know we've found the maximum number of repetitions.
                  # Remember that lookbehinds are matched right-to-left, so
                  # you should read the explanation of the lookbehind from
                  # bottom to top.
    \3            # Try to match *another* occurrence of block 3. If this works,
                  # then this block can be used more often than the current one
                  # and we haven't found the maximum number of repetitions yet.
    (?>           # An atomic group to ensure that we're actually using up all
                  # repetitions from group 1, and don't backtrack.
      (?<-1>\3)*  # For each repetition in group 1, try to match block 3 again.
    )
    (?!.*\2)      # We ensure that this block isn't longer than the candidate
                  # block, by checking that the candidate block doesn't appear
                  # right of it.
    (.+)          # We capture a block from the end into group 3.
  )               # Lookbehind explanation starts here. Read upwards.
)
!                 # As I said above, this ensures that our block actually reaches
                  # the end of the string.

마지막으로,이 작업이 모두 끝나면 그룹의 캡처 횟수와 최대 반복 횟수에 해당하는 캡처 수를 다시 기록합니다 $1(따라서 !) $#1.


답변

루비, 84 바이트

Retina의 대답은 배열에서 시퀀스를 계산하는 대신 최상의 시퀀스를 찾기 위해 정규식 기반 솔루션을 만들도록 영감을 주었지만 천재는 적습니다 (양자화가있는 음수 모양은 루비에서는 허용되지 않는 것 같습니다. 어쨌든 Retina의 답변을 직접 포팅 할 수 있습니다)

->n{s='';n.times{s+=(1..n).map{|i|s=~/(\d{#{i}})\1+$/?$&.size/i: 1}.max.to_s};s[-1]}

이미 생성 된 시퀀스가 ​​주어지면 s모든 ifrom 1에서 s.length( n이 경우 바이트를 절약하기 위해 사용되었습니다)에 매핑 n>=s.length한 다음이 정규 표현식을 사용하여 길이가있는 하위 시퀀스의 반복 횟수를 계산합니다 i.

/(.{#{i}})\1+$/
/(                 # Assign the following to group 1
  .{#{i}}          # Match `i` number of characters
         )         # End group 1
          \1+      # Match 1 or more repetitions of group 1
             $/    # Match the end of string

일치하는 그 길이가 발견되면, 그것은 주어진 매치의 길이로 나누어 반복 수를 계산 $&하여 i서브 시퀀스의 길이; 일치하는 것이 없으면로 취급됩니다 1. 그러면 함수는이 매핑에서 최대 반복 횟수를 찾아 해당 숫자를 문자열 끝에 추가합니다.