| Bytes | Lang | Time | Link |
|---|---|---|---|
| 044 | Desmos | 250206T054135Z | DesmosEn |
| 043 | Python | 250129T071651Z | Albert.L |
| 013 | cQuents | 250126T041236Z | Stephen |
| 033 | Haskell | 250123T155843Z | colossus |
| 018 | x8664 machine code | 250124T174112Z | m90 |
| 036 | JavaScript ES7 | 250123T080808Z | Arnauld |
| 011 | Nekomata + n | 250123T232516Z | Dominic |
| 026 | Charcoal | 250123T230503Z | Neil |
| 039 | Retina | 250123T094627Z | Neil |
| 044 | Python 3 | 250123T045232Z | xnor |
| 038 | Retina | 250123T200349Z | Unrelate |
| 039 | Ruby | 250123T171058Z | G B |
| 030 | APLNARS | 250123T163043Z | Rosario |
| 041 | C gcc | 250123T143436Z | jdt |
| 037 | APL+WIN | 250123T131123Z | Graham |
| 012 | Nekomata + n | 250123T121811Z | alephalp |
| 009 | 05AB1E | 250123T101642Z | Kevin Cr |
| nan | Nibbles | 250123T095855Z | Dominic |
| 045 | R | 250123T083254Z | Dominic |
| 070 | JavaScript Node.js | 250123T043845Z | l4m2 |
Desmos, 44 bytes
a(n)=\{n<4:3nn-5n+3,3a(n-1)-a(n-2)+a(n-3)\}
I took the same approach that it seems everyone took, that is looking for an OEIS entry for this sequence. I found this, and based my algorithm on this.
Python, 43 bytes
f=lambda n,b=-1:n<2or b%3*f(n-b,1)+b*f(n-2)
Almost as good as @xnor's ...
How?
Just an equivalent transformation of the OEIS recursion.
Starting from
$$ f_n = 3f_{n-1}-f_{n-2}+f_{n-3} $$
we introduce a second series
$$ g_n =\frac 1 2 ( f_{n-1}+f_{n-3} ) $$
These two then satisfy:
$$ f_n = 2 \times g_{n+1} - f_{n-2} $$
and
$$ g_n = g_{n-1} + f_{n-2} $$
These are similar enough to be rolled into a family with a simple control parameter \$b\$ like so
Define
$$ f_{n,-1}:= f_{n} $$ and $$ f_{n,1}:=g_n $$
Then the two recurrence equations for \$f\$ and \$g\$ become the single
$$ f_{n,b} = (b \mod 3) f_{n-b,1} + b f_{n-2,-1} $$
The last thing to note is that the recursion can be based at \$g_1=f_1=f_0=1\$. This is convenient and allows us to continue using the super cheap anchor n<2or.
cQuents, 13 bytes
=1,1,5:3Z-Y+X
2-indexed. Without any input, outputs the full sequence with an extra 1 term at the beginning.
Explanation
=1,1,5 the first three terms are 1, 1, 5
: given input n, output the nth term in the sequence
each term is
3Z 3 * seq(n-1)
-Y - seq(n-2)
+X + seq(n-3)
Haskell, 33 bytes
((1#1)5!!)
(a#b)c=a:(b#c$3*c-b+a)
Based on the recursive formula from OEIS that xnor found, using the f(2)=5 form
(a#b)c is an infix operator that generates an infinite sequence based on the first three terms a, b, and c (in that order). We yield the first term a, then recur, shifting the second and third terms down one position and calculating the next term as 3*c-b+a. Now all we have to do is initialize the sequence properly with the first three terms ((1#1)5) and take a section of the (!!) operator to create a point-free function that takes in an index and outputs its corresponding value in the sequence.
x86-64 machine code, 18 bytes
6A 01 58 99 89 C1 01 C1 01 D0 8D 14 4A FF CF 75 F5 C3
Following the standard calling convention for Unix-like systems (from the System V AMD64 ABI), this takes \$n\$ as a 32-bit integer in EDI and returns a 32-bit integer in EAX.
Divide the partial sequences of length \$m\$ based on how they end, and let $$ \begin{align} x_m &= \textrm{number ending in 0} \\ y_m &= \textrm{number ending in a 1 or 2 group that has a liberty} \\ z_m &= \textrm{number ending in a 1 or 2 group that has no liberty} \end{align} $$ These values have a recurrence relation: $$ \begin{align} x_{m+1} &= x_m + y_m + z_m \\ y_{m+1} &= 2x_m + y_m \\ z_{m+1} &= y_m + z_m \end{align} $$ Finally, the answer is \$x_n + y_n\$.
The starting values are \$x_1 = 1, y_1 = 0, z_1 = 2\$; running the formulas one step backwards gives \$x_0 = -1, y_0 = 2, z_0 = 0\$, which is nonsensical but works.
Directly implementing this will work, but it is possible to do a little better, by modifying the variables so that one of them equals the answer: let $$ \begin{align} X_m &= x_m + y_m \\ Y_m &= 2x_m + y_m + z_m \\ Z_m &= \frac12y_m + z_m \end{align} $$ and then $$ \begin{align} X_{m+1} &= X_m + Y_m \\ Y_{m+1} &= 2X_m + Y_m + 2Z_m \\ Z_{m+1} &= X_m + Z_m \end{align} $$ and the initial conditions are \$X_0 = 1, Y_0 = 0, Z_0 = 1\$.
In assembly:
f: push 1; pop rax # Set EAX to 1 for X₀.
cdq # Sign-extend EAX to set EDX to 0 for Y₀.
mov ecx, eax # Set ECX to EAX=1 for Z₀.
r: add ecx, eax # In ECX, add Xₘ to Zₘ to get Zₘ₊₁.
add eax, edx # In EAX, add Yₘ to Xₘ to get Xₘ₊₁.
lea edx, [rdx+2*rcx] # Set EDX to Yₘ+2Zₘ₊₁ = Yₘ+2Xₘ+2Zₘ = Yₘ₊₁.
dec edi # Subtract 1 from EDI, counting down from n.
jnz r # Jump back to repeat if it's nonzero.
ret # Return. The return value in EAX is Xₙ.
JavaScript (ES7), 37 36 bytes
Like xnor's answer, this is based on the recursive formula from OEIS.
f=n=>3**-n&3||3*f(n-1)-f(n-2)+f(n-3)
Commented
f = n => // n = input
3 ** -n & 3 // this gives:
// n = -2: 3**2 & 3 -> 1
// n = -1: 3**1 & 3 -> 3
// n = 0: 3**0 & 3 -> 1
// n > 0: 3**-n & 3 -> 0
|| // if the result above is 0 ...
3 * f(n - 1) // ... apply the recursive formula
- f(n - 2) //
+ f(n - 3) //
Nekomata + -n, 11 bytes
3$ŧY∑,¬çY3<
Initial steps stolen from alephalpha's answer, then a different approach.
# for input of n:
3$ŧ # all n-tuples of 0,1,2
Y # run length encode:
# lengths are top of stack,
# values 2nd
∑ # sum the top of stack
# (always equals n)
, # combine 2nd & top of stack
# (gives n appended to non-repeated input values)
¬ # logical not
ç # prepend zero
# (gives zeros for each nonzero group,
# with zeros added at each end.
# Valid 1d GO boards cannot have more
# than 2 adjacent zeros)
Y # run length encode:
# lengths are top of stack
3< # are they all less than 3?
Charcoal, 26 bytes
F131⊞υIιFN⊞υΣ×⮌υ⟦³±¹¦¹⟧I⊟υ
Attempt This Online! Link is to verbose version of code. Explanation: Uses dynamic programming to implement the recurrence relation that @xnor found, but starting at -2, because that's golfier.
F131⊞υIι
Start with a(-2)=1, a(-1)=3 and a(0)=1.
FN
Repeat n times.
⊞υΣ×⮌υ⟦³±¹¦¹⟧
Calculate the next entry from the previous three using the recurrence relation.
I⊟υ
Output the final entry.
Retina, 51 50 39 bytes
.+
*
+%0`_
0$"1$"2
l`((1*|2*)0(1*|2*))+
Try it online! Link includes test cases. Edit: Saved 1 byte thanks to @UnrelatedString. Explanation:
.+
*
Convert to unary.
+%0`_
0$"1$"2
Generate all possible positions of length n.
l`((1*|2*)0(1*|2*))+
Count only legal positions, i.e. those where each run of 1s or 2s is adjacent to a 0. (The l`, shamelessly copied from @UnrelatedString's answer, forces the pattern to match whole lines only.)
Python 3, 44 bytes
f=lambda n:n+7>>n+2or 3*f(n-1)-f(n-2)+f(n-3)
Uses the recursive formula from OEIS A102620
$$ f(n) = 3f(n-1)-f(n-2)+f(n-3)$$
with base cases \$ f(-1) =3, f(0)=1, f(1)=1\$.
(You could use \$f(2)=5\$ instead of \$ f(-1) =3\$.)
44 bytes
lambda n:(x:=8**n)**n*~x*~x%((x-1)**3-2*x)%x
Based on the rational generating function x(1+x)^2/((1-x)^3-2x^2) given in the OEIS. The code replaces // with %, though both work. The base x can be any sufficiently large value; 8**n turns out to suffice for n>0.
Python 3, 42 bytes
f=lambda n:0<-n^1or 3*f(n-1)-f(n-2)+f(n-3)
Using @Jonathan Allan's improvement of a "split" base case of all 1's. Here, $$ f(-4) = f(-3) = f(-2) = f(0) = 1,$$
whereas \$f(-1)=3\$ is obtained by the recursive formula.
Retina, 38 bytes
.+
*
+%0`_
0$"1$"2
(.)\1*
$1
.?0.?
l`
The approach is so comically naive that I'm not even remotely embarrassed by how long I spent trying several far more convoluted options before being inspired by trying something else with overlapping matches... though I do feel a little silly for almost posting this before I realized it doesn't even need those.
Explanation:
.+
*
+%0`_
0$"1$"2
Generate every string of \$n\$ ternary digits. Taken directly from Neil's excellent solution with a small tweak of my own: Starting with one line of \$n\$ underscores, generates three alternatives for each line replacing the first underscore with 0, 1, or 2, repeating until no underscores remain on any line.
(.)\1*
$1
Collapse all runs of consecutive equal characters to a single copy.
.?0.?
Delete every match of 0 surrounded by 0 or 1 of any character. This works without overlapping matches because runs of 0 are collapsed as well as runs of 1 and 2--it can never match a 0 as one of the .? because no 0 is ever adjacent to another 0, so no 1 or 2 adjacent to a 0 ever fails to be matched because of its 0 being taken by another match already.
l`
Count empty lines.
APL(NARS), 30 chars
{⍵≤2:⌈5*⍵-1⋄+/(3,¯1,1)×∇¨⍵-⍳3}
if w is 0 1 2 ceil(5^(w-1)) return 1 1 5. test:
{⍵≤2:⌈5*⍵-1⋄+/(3,¯1,1)×∇¨⍵-⍳3}¨0,⍳10
1 1 5 15 41 113 313 867 2401 6649 18413
APL+WIN, 37 bytes
Prompts for n
v←1 3 1⋄⍎∊⎕⍴⊂'v←(+/3 ¯1 1×3↑v),v⋄'⋄↑v
Nekomata + -n, 12 bytes
3$ŧY^¬7Ƃ×itZ
3$ŧY^¬7Ƃ×itZ Take n=7 as an example
3$ŧ Find an n-tuple of 0, 1, 2
One possible solution is [1,0,2,2,1,0,2]
Y^ Run length encode and then drop the counts
[1,0,2,2,1,0,2] -> [1,0,2,1,0,2]
¬ Logical not; replace 0 with 1 and other numbers with 0
[1,0,2,1,0,2] -> [0,1,0,0,1,0]
7Ƃ× Convolve with [1,1,1]
[0,1,0,0,1,0] -> [0,1,1,1,1,1,1,0]
it Remove the first and last elements
[0,1,1,1,1,1,1,0] -> [1,1,1,1,1,1]
Z Check that all elements are non-zero
[1,1,1,1,1,1] passes the check
-n counts the number of solutions.
05AB1E, 9 bytes
ƵESλè3*α+
Port of @xnor's Python answer, so make sure to upvote that answer as well!
Also uses the recursive function:
\$f(n) = 3f(n-1)-f(n-2)+f(n-3)\$
with base cases \$f(0)=1, f(1)=1, f(2)=5\$.
Try it online or verify the infinite sequence.
Explanation:
λ # Start a recursive environment,
è # to (implicitly) output the 0-based (implicit) input'th term afterwards
ƵES # Starting with a(0)=1,a(1)=1,a(2)=5:
ƵE # Push compressed integer 115
S # Convert it to a list of digits: [1,1,5]
# Where every following a(n) is calculated as:
3* # Multiply the (implicit) previous term a(n-1) by 3
α # Get its absolute difference with the (implicit) term before it a(n-2)
+ # Add it to the (implicit) term before that a(n-3)
See this 05AB1E tip of mine (section How to compress large integers?) to understand why ƵE is 115.
Nibbles, 33 nibbles (16.5 bytes)
``;$-$~!=~-*$~~+-*@-$~;3_-@2_-@
Uses the recursive formula from OEIS A102620:
For n ≥ 4, a(n) = 3*a(n-1) - a(n-2) + a(n-3)
Nibbles recursive functions have 5 parts:
- define a recursive function =
``; - the initial value, here the input =
$ - the stop condition, here "n>1" =
-$~ - the return value for the stop condition,
here "abs(2*n-1)" =
!=~-*$~~ - the body of the function,
here "3*f(n-1)-f(n-2)+f(n-3)"
=
+ - *@-$~3 @-$2 @-$3
Explicit integers are encoded using more-than-one nibble, so we want to minimize them wherever possible.
In this case, we 'save' the 3 the first time we use it (so: ;3). This saves the 2-nibble value 3 into the single-nibble variable $, and shifts all the other variable names (so @ becomes _ and $ becomes @), saving one nibble overall.
R, 45 bytes
f=\(n)`if`(n>1,3*f(n-1)-f(n-2)+f(n-3),3^!n+1)
Uses recursive formula from OEIS A102620, spotted by xnor.
JavaScript (Node.js), 70 bytes
n=>(g=x=>x[n-1]?!/12+1|21+2/.test(1+x+102+x+2):g(x+0)+g(x+1)+g(x+2))``