자바 스크립트 (E6) 79 82
F=(n,t,
d=n+n*~-n/4-t/2,
l=1,
q=[for(x of Array(n))d<n--?++l:(d+=~n,--l)]
)=>d?[]:q
모든 튜플을 무차별 적으로 열거하거나 열거 할 필요가 없습니다.
n -1 단계 로 길이 n 의 시퀀스를 참조 하십시오. 각 단계는 증가 또는 감소합니다.
감소에 대해서만 증분을 교환 할 수 있으며 합계는 2 씩 변하므로 주어진 길이에 대해 합계는 항상 짝수이거나 항상 홀수입니다.
모든 증분이 있으면 시퀀스는 0, 1, 2, 3, ..., n-1이고 합은 (n-1) * n / 2임을 알 수 있습니다
. 마지막 단계를 변경하면 합은 2 씩 변경되므로 마지막 단계의 무게는 2입니다. 마지막 단계
의 다음 단계를 변경하면 합계가 4 씩 변경되므로 마지막 단계의 무게는 4입니다. 이는 연속 단계가 지금까지 부분 합계를 기반으로하기 때문입니다.
이전 단계를 변경하면 합계가 6 씩 변경되므로 마지막 단계의 무게는 6입니다 (8이 아니라 이진수가 아님).
...
첫 단계 변경 무게 (n-1) * 2
연산
Find the max sum (all increments)
Find the difference with the target sum (if it's not even, no solution)
Seq[0] is 0
For each step
Compare current difference with the step weight
if is less
we have an increment here, seq[i] = seq[i-1]+1
else
we have a decrement here, seq[i] = seq[i-1]-1.
Subtract we current weight from the current diff.
If remaining diff == 0, solution is Seq[]. Else no solution
Ungolfed 코드
F=(len,target)=>{
max=(len-1)*len/2
delta = max-target
seq = [last=0]
sum = 0
weight=(len-1)*2
while (--len > 0)
{
if (delta >= weight)
{
--last
delta -= weight;
}
else
{
++last
}
sum += last
seq.push(last);
weight -= 2;
}
if (delta) return [];
console.log(sum) // to verify
return seq
}
Firefox / FireBug 콘솔에서 테스트
F(8,4)
산출
[0, -1, 0, -1, 0, 1, 2, 3]
(l-1)*l/2
있고와-(l-1)*l/2
동일한 패리티를 갖는 모든 숫자라는 증거 를 가지고 있습니다(l-1)*l/2
.