소개
Gijswijt의 시퀀스 ( A090822 )는 정말 정말 느립니다. 설명하기 위해 :
- 첫 번째 3은 9 번째 용어에 나타납니다.
- 첫 번째 4 개는 220 번째 용어로 먼 거리에 있지만 실현 가능합니다.
- 처음 5는 10 ^ (10 ^ 23) 번째 항 ( 대략)에 나타납니다 .
- 아무도 처음 6이 어디에 있는지 알지 못합니다.
2 ^ (2 ^ (3 ^ (4 ^ 5))) 번째 항입니다.
두 자리 숫자를 다룰 필요가 없다고 가정 할 수 있습니다.
시퀀스는 다음과 같이 생성됩니다.
- 첫 번째 용어는 1입니다.
- 그 이후의 각 용어는 이전의 반복 “블록”의 양입니다 (반복되는 “블록”이 여러 개인 경우 가장 많은 양의 반복 블록이 사용됨).
명확히하기 위해 처음 몇 가지 용어가 있습니다.
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.
답변
답변
망막 , 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
모든 i
from 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
. 그러면 함수는이 매핑에서 최대 반복 횟수를 찾아 해당 숫자를 문자열 끝에 추가합니다.