17
\$\begingroup\$

A 1D go position on a board of size n is a sequence of length n consisting of the numbers0, 1, 2. Not all numbers need to appear in the sequences.

A sequence is legal if every block of 1's has at least one 0 next to it and every block of 2's has at least one 0 next to it. Think of 1 as white, 2 as black and 0 as empty cells.

Examples:

0         Legal
1         Illegal: `1` has no `0`'s next to it
10        Legal
22        Illegal: `22` has no `0`'s next to it
12022     Illegal: `1` has no `0`'s next to it
1022102   Legal

Input: n

Output: Number of legal sequences of length n. Note that a sequence and its reversal may be different (in which case they are counted as different sequences).

Test cases:

1 1
2 5
3 15
4 41
5 113
6 313
7 867
8 2401
9 6649
10 18413
\$\endgroup\$
3
  • \$\begingroup\$ Could you include the first 10 or so values? \$\endgroup\$ Commented Jan 23 at 4:36
  • \$\begingroup\$ you say "every block of 2's has a 0 next to it" but 1022102 has 1 afther the block of "22" and not a number in the last "2". Pheraps is it that every block of 2 has prec 0 block? \$\endgroup\$ Commented Jan 23 at 11:58
  • 3
    \$\begingroup\$ @Rosario "next to it" as in a zero to the left or right of it, i.e. not surrounded by 1s and the board boundaries \$\endgroup\$ Commented Jan 23 at 12:42

20 Answers 20

15
\$\begingroup\$

Python 3, 44 bytes

f=lambda n:n+7>>n+2or 3*f(n-1)-f(n-2)+f(n-3)

Try it online!

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

Try it online!

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)

Try it online!

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.

\$\endgroup\$
0
9
\$\begingroup\$

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)

Try it online!

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)   //
\$\endgroup\$
6
\$\begingroup\$

R, 45 bytes

f=\(n)`if`(n>1,3*f(n-1)-f(n-2)+f(n-3),3^!n+1)

Attempt This Online!

Uses recursive formula from OEIS A102620, spotted by xnor.

\$\endgroup\$
6
\$\begingroup\$

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.

\$\endgroup\$
4
\$\begingroup\$

Nibbles, 33 nibbles (16.5 bytes)

``;$-$~!=~-*$~~+-*@-$~;3_-@2_-@

Attempt This Online!

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:

  1. define a recursive function = ``;
  2. the initial value, here the input = $
  3. the stop condition, here "n>1" = -$~
  4. the return value for the stop condition, here "abs(2*n-1)" = !=~-*$~~
  5. 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.

\$\endgroup\$
4
\$\begingroup\$

Nekomata + -n, 12 bytes

3$ŧY^¬7Ƃ×itZ

Attempt This Online!

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.

\$\endgroup\$
4
\$\begingroup\$

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.)

\$\endgroup\$
2
  • \$\begingroup\$ Took me a while, but 50 bytes and test suite compatibility \$\endgroup\$ Commented Jan 23 at 18:38
  • 1
    \$\begingroup\$ @UnrelatedString I had already been thinking about how to port this to Retina 0.8.2, and come up with a port of your golf, without realising that if ported back to Retina that it would be golfier... I dodged a bullet there! \$\endgroup\$ Commented Jan 23 at 19:16
3
\$\begingroup\$

Haskell, 33 bytes

((1#1)5!!)
(a#b)c=a:(b#c$3*c-b+a)

Try it online!

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.

\$\endgroup\$
2
  • \$\begingroup\$ I'd be interested to understand how this works. I'm pretty good with normal haskell, but apparently I'm clueless about golfing techniques :) \$\endgroup\$ Commented Jan 24 at 17:25
  • \$\begingroup\$ @ShapeOfMatter I've added an explanation. You can also check out the tips page. \$\endgroup\$ Commented Jan 25 at 14:06
2
\$\begingroup\$

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))``

Try it online!

\$\endgroup\$
2
\$\begingroup\$

C (gcc), 41 bytes

f(n){n=n+7>>n+2?:3*f(n-1)-f(n-2)+f(n-3);}

Try it online!

\$\endgroup\$
2
+100
\$\begingroup\$

Nekomata + -n, 11 bytes

3$ŧY∑,¬çY3<

Attempt This Online!

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?
\$\endgroup\$
2
\$\begingroup\$

cQuents, 13 bytes

=1,1,5:3Z-Y+X

Try it online!

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)
\$\endgroup\$
2
\$\begingroup\$

Python, 43 bytes

f=lambda n,b=-1:n<2or b%3*f(n-b,1)+b*f(n-2)

Attempt This Online!

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.

\$\endgroup\$
1
\$\begingroup\$

APL+WIN, 37 bytes

Prompts for n

v←1 3 1⋄⍎∊⎕⍴⊂'v←(+/3 ¯1 1×3↑v),v⋄'⋄↑v

Try it online! Thanks to Dyalog Classic

\$\endgroup\$
1
\$\begingroup\$

Ruby, 39 bytes

->n{(x=8**n)**n*~x*~x%((x-1)**3-2*x)%x}

Try it online!

Using xnor's non-recursive formula.

\$\endgroup\$
1
\$\begingroup\$

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.

\$\endgroup\$
1
\$\begingroup\$

x86-64 machine code, 18 bytes

6A 01 58 99 89 C1 01 C1 01 D0 8D 14 4A FF CF 75 F5 C3

Try it online!

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ₙ.
\$\endgroup\$
1
  • \$\begingroup\$ Glad someone found a language to use that relation in! I was going to fish for some way to make it work with matrix multiplication 🙃 \$\endgroup\$ Commented Jan 25 at 23:26
0
\$\begingroup\$

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 
\$\endgroup\$
0
\$\begingroup\$

Retina, 38 bytes

.+
*
+%0`_
0$"1$"2
(.)\1*
$1
.?0.?

l`

Try it online!

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.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ This inspired me to golf a further 11 bytes off my answer, but it's still a byte short (or long...) \$\endgroup\$ Commented Jan 23 at 23:02
0
\$\begingroup\$

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.

Try it on Desmos!

Try it on Desmos! - Prettified

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.