# 分形烟雾序列

33

## 介绍

A229037有一个非常吸引人的情节（至少在前几个条款中）： ### 如何构造此序列？

`a(1) = 1, a(2) = 1`然后为每个`n>2`变量定义一个最小的正整数，`a(n)`这样对于每个算术3项`n,n+k,n+2k`索引序列，该序列的对应值`a(n),a(n+k),a(n+2k)`不会算术序列。

## 挑战

### 前几个测试用例：

``````1, 1, 2, 1, 1, 2, 2, 4, 4, 1, 1, 2, 1, 1, 2, 2, 4, 4, 2, 4, 4, 5, 5, 8, 5, 5, 9, 1, 1, 2, 1, 1, 2, 2, 4, 4, 1, 1, 2, 1, 1, 2, 2, 4, 4, 2, 4, 4, 5, 5, 8, 5, 5, 9, 9, 4, 4, 5, 5, 10, 5, 5, 10, 2, 10, 13, 11, 10, 8, 11, 13, 10, 12, 10, 10, 12, 10, 11, 14, 20, 13
``````

### 更多测试用例：

``````  a(100)  =   4
a(500)  =   5
a(1000)  =  55
a(5000)  =  15
a(10000)  = 585
``````

`n=100000`此处提供所有可用的条款：https : //oeis.org/A229037/b229037.txt

2

12

4

v=o8c4uYnnNnc

2

Luis Mendo

12

## Python 2，95个字节

``````l=[];n=input()
exec"a=min(set(range(n))-{2*b-c for b,c in zip(l,l[1::2])});print-~a;l=[a]+l;"*n``````

``````? 4 2 2 1 1 2 1 1   a b c
^ ^ ^               ? 4 2
^   ^   ^           ? 2 1
^     ^     ^       ? 2 2
^       ^       ^   ? 1 1``````

8

## Mathematica，95个字节

``````For[n_~s~k_=0;n=0,n<#,For[i=n,--i>0,s[2n-i,2f@n-f@i]=1];For[++n;i=1,n~s~i>0,++i];Print[f@n=i]]&
``````

`````` max = 1000;
ClearAll[sieve, f];
sieve[n_, k_] = False;
For[n = 0, n < max,
temp = f[n];
For[i = n - 1, i > 0 && 2 n - i <= max, --i,
sieve[2 n - i, 2 temp - f[i]] = True;
];
++n;
i = 1;
While[sieve[n, i], ++i];
f@n = i;
]
``````

3

``````a n|n<1=0|n<3=1|1<2=[x|x<-[1..],and[x/=2*a(n-k)-a(n-k-k)||a(n-k-k)<1|k<-[1..n]]]!!0
``````

``````a n | n<1        = 0
| n<3        = 1
| otherwise  = head (goods n)

goods n = [x | x <- [1..], isGood x n]

isGood x n = and [ x - a(n-k) /= a(n-k) - a(n-k-k) || a(n-k-k) == 0 | k <- [1..n] ]
``````

``````t n <= sum[ sum[2*t(n-k) + 2*t(n-k-k) | k <- [1..n]] | x <- [1..(n+1)/2]]
<= sum[ sum[4*t(n-1)              | k <- [1..n]] | x <- [1..(n+1)/2]]
<= sum[     4*t(n-1)*n                         ] | x <- [1..(n+1)/2]]
<=          4*t(n-1)*n*(n+1)/2
->
O(t(n)) == O(2^(n-2) * n! * (n+1)!)
``````

1

@flawr在帖子中添加了一些时间复杂度分析
Michael Klein

3

# Brachylog，33 31字节

``````;Ė{~b.hℕ₁≜∧.¬{ġh₃hᵐs₂ᶠ-ᵐ=}∧}ⁱ⁽↔
``````

### 说明

``````ġ            Group the list into equal-length sublists (with the possible exception of
the last sublist, which might be shorter)
h₃          Get the first 3 sublists from that list
hᵐ        and get the head of each of those 3 sublists
We now have a list containing a(n),a(n-k),a(n-2k) for some k
s₂ᶠ     Find all 2-element sublists of that list: [a(n),a(n-k)] and [a(n-k),a(n-2k)]
-ᵐ   Find the difference of each pair
=  Assert that the two pairwise differences are equal
``````

``````ġ has possible outputs of
[,,,,,,]
[[1,2],[1,1],[2,1],]
[[1,2,1],[1,2,1],]
[[1,2,1,1],[2,1,1]]
[[1,2,1,1,2],[1,1]]
[[1,2,1,1,2,1],]
[[1,2,1,1,2,1,1]]
h₃ has possible outputs of
[,,]
[[1,2],[1,1],[2,1]]
[[1,2,1],[1,2,1],]
hᵐ has possible outputs of
[1,2,1]
[1,1,2]
[1,1,1]
s₂ᶠ has possible outputs of
[[1,2],[2,1]]
[[1,1],[1,2]]
[[1,1],[1,1]]
-ᵐ has possible outputs of
[-1,1]
[0,-1]
[0,0]
= is satisfied by the last of these, so the predicate succeeds.
``````

``````~b.hℕ₁≜∧.¬{...}∧
~b.                 The input is the result of beheading the output; i.e., the output is
the input with some value prepended
.h                The head of the output
ℕ₁              is a natural number >= 1
≜             Force a choice as to which number (I'm not sure why this is necessary,
but the code doesn't work without it)
∧           Also,
.          the output
¬{...}    does not satisfy the nested predicate (see above)
I.e. there is no k such that a(n),a(n-k),a(n-2k) is an arithmetic sequence
∧   Break unification with the output
``````

``````;Ė{...}ⁱ⁽↔
;           Pair the input number with
Ė          the empty list
{...}ⁱ⁽   Using the first element of the pair as the iteration count and the second
element as the initial value, iterate the nested predicate (see above)
↔  Reverse, putting the sequence in the proper order
``````

3

# 红宝石，71个字节

``->n,*a{a.fill(0,n){|s|([*1..n]-(1..s/2).map{|o|2*a[s-o]-a[s-2*o]})}}``

1
-1字节：可以使用and`a[s-o]``a[s-2*o]``a[s-=1]``a[s-o]`
GB

3

# APL（Dyalog扩展），37 字节SBCS

``⌽{⍵,⍨⊃(⍳1+≢⍵)~-¯2⊥⍵[2×⍀⍥⍳⌊2÷⍨≢⍵]}⍣⎕,⍬``

``````{⍵,⍨⊃(⍳1+≢⍵)~-¯2⊥⍵[2×⍀⍥⍳⌊2÷⍨≢⍵]}  ⍵ is our right argument, the sequence S

⌊2÷⍨≢⍵    We start by calculating X = ⌊len(S)÷2⌋
⍳          Get a range [1, X]
2×⍀⍥           With that we can get S[:X] and S[:X×2:2]
or S up to halfway and every 2nd element of S
-¯2⊥⍵[           ]   And with that we can get 2*S[:X] - S[:X×2:2]
Which is C=2*B-A of a progression A B C
(⍳1+≢⍵)~                     We remove these Cs from our possible a(n)s
I use range [1, len(S)+1]
⊃                             Get the first result, which is the minimum
⍵,⍨                              And then prepend that to S

⌽{...}⍣⎕,⍬

{...}⍣⎕    We iterate an "input" ⎕ times
,⍬  with an empty list ⍬ as the initial S
⌽           and reversing S at the end as we have built it backwards``````

# APL（Dyalog Unicode），43 39 38字节SBCS

``⌽{⍵,⍨⊃(⍳1+≢⍵)~-⌿⍵[1 2 1∘.×⍳⌊2÷⍨≢⍵]}⍣⎕,⍬``

2

## MATLAB 156 147字节

``````N=input('');s=[0;0];for n=1:N,x=s(n,~~s(n,:));try,a(n)=find(~ismember(1:max(x)+1,x),1);catch,a(n)=1;end,s(n+1:2*n-1,end+1)=2*a(n)-a(n-1:-1:1);end,a
``````

``````N=input('');                                   % read N from stdin

s=[0;0];
for n=1:N,
x=s(n,~~s(n,:));                           % x=nonzeros(s(n,:));
try,
a(n)=find(~ismember(1:max(x)+1,x),1);  % smallest OK number
catch,
a(n)=1;                                % case of blank page for n
end,

s(n+1:2*n-1,end+1)=2*a(n)-a(n-1:-1:1);     % determined new forbidden values
end,
a                                              % print ans=...
``````

``````%pre-alloc
s = zeros([N,fix(N*0.07+20)]); %strict upper bound, needs adjusting later
i = zeros(1,N);

a = 1;
for n = 2:N,
x = s(n,1:i(n));
if isempty(x),
a(n) = 1;
else
a(n) = find(~ismember(1:max(x)+1,x),1);
end,

j = n+1:min(2*n-1,N);
i(j) = i(j)+1;
s(N,max(i(j))) = 0;   %adjust matrix size if necessary
b = a(n-1:-1:1);
s(sub2ind([N,size(s,2)+1],j,i(j))) = 2*a(n)-b(1:length(j));
end
``````

MATLAB的一个令人讨厌的功能是，尽管您可以说出`M(1,end+1)=3;`并自动扩展矩阵，但使用线性索引却无法做到这一点。这样做是有道理的（MATLAB应该如何知道最终的数组大小，并在此框架内解释线性索引？），但仍然让我感到惊讶。这就是多余线的原因`s(N,max(i(j))) = 0;`：这将`s`在需要时为我们扩展矩阵。起始尺寸猜测`N*0.07+20`顺便说一句，来自对前几个元素的线性拟合。

• v1：高尔夫版本
• v2：低启动大小，防呆版本和
• v3：大的起始大小，对于大N版本可能会失败。

1. `N=100`
• v1： `0.011342 s`
• v2： `0.015218 s`
• v3： `0.015076 s`
2. `N=500`
• v1： `0.101647 s`
• v2： `0.085277 s`
• v3： `0.081606 s`
3. `N=1000`
• v1： `0.641910 s`
• v2： `0.187911 s`
• v3： `0.183565 s`
4. `N=2000`
• v1： `5.010327 s`
• v2： `0.452892 s`
• v3： `0.430547 s`
5. `N=5000`
• v1：不适用（没有等待）
• v2： `2.021213 s`
• v3： `1.572958 s`
6. `N=10000`
• v1：不适用
• v2： `6.248483 s`
• v3： `5.812838 s`

`M=1;M(end+1)=2;`对我来说完美吗？

@flawr适用于标量和向量。请尝试`M=rand(2); M(end+1)=2`：)
Andras Deak

2

# 果冻，24 岁 19字节

``````Ḋm2ɓṁḤ_
ŻJḟÇṂ;
1Ç¡U
``````

``````Ḋm2ɓṁḤ_  First link. Takes our current sequence S as our left argument.

We are trying to calculate, of an arithmetic progression A B C,
the C using the formula, C = 2*B - A
Ḋ        Remove the first element of S.
m2      Get every element at indices 0, 2, 4, ...
This is equivalent to getting every second element of S, a list of As.
ɓ     Starts a dyad with reversed arguments.
The arguments here are S and As.
ṁ    This molds S in the shape of As, giving us a list of Bs.
Ḥ   We double the Bs.
_  And subtract As from 2 * Bs.

ŻJḟÇṂ;  Second link. Takes S as our left argument.

Ż       Append a 0 to S.
J      Range [1, len(z)]. This gets range [1, len(S) + 1].
ḟÇ    Filter out the results of the previous link, our Cs.
Ṃ   Take the minimum of Cs.
;  And concatenate it with the rest of the sequence so far.

1Ç¡U  Third link. Where we feed our input, n.

1     A list with the element 1.
Ç¡   Run the previous link n times.
U  Reverse everything at the end.
``````

`ḟ`将和`œ-`保存字节一样好

`Œœị@2`可能打高尔夫以`Ḋm2`节省两个。

`L‘R`可能打高尔夫以`ŻJ`节省一个。

@JonathanAllan整个五个字节！谢谢！

1

## ES6，114个字节

``````n=>[...r=Array(n)].map((x,i,s)=>{for(y=1;x&&x[y];y++);r[i]=y;for(j=i;++j<n;s[j][y+y-r[i+i-j]]=1)s[j]=s[j]||[]}&&r
``````

``````function smoke(n) {
result = [];
sieve = [];
for (i = 1; i <= n; i++) {
value = 1;
if (sieve[i]) {
while (sieve[i][value]) {
value++;
}
}
result[i] = value;
for (j = 1; j < i && i + j <= n; j++) {
if (!sieve[i + j]) sieve[i + j] = [];
sieve[i + j][value + value - result[i - j]] = true;
}
}
return result;
}
``````