Compute the Kolakoski sequence

54

6

This is a repost of an old challenge, in order to adjust the I/O requirements to our recent standards. This is done in an effort to allow more languages to participate in a challenge about this popular sequence. See this meta post for a discussion of the repost.

The Kolakoski sequence is a fun self-referential sequence, which has the honour of being OEIS sequence A000002 (and it's much easier to understand and implement than A000001). The sequence starts with 1, consists only of 1s and 2s and the sequence element a(n) describes the length of the nth run of 1s or 2s in the sequence. This uniquely defines the sequence to be (with a visualisation of the runs underneath):

1,2,2,1,1,2,1,2,2,1,2,2,1,1,2,1,1,2,2,1,2,1,1,2,1,2,2,1,1,2,1,1,2,...
= === === = = === = === === = === === = = === = = === === = === =
1, 2,  2, 1,1, 2, 1, 2,  2, 1, 2,  2, 1,1, 2, 1,1, 2,  2, 1, 2, 1,...

Your task is, of course, to implement this sequence. You may choose one of three formats to do so:

  1. Take an input n and output the nth term of the sequence, where n starts either from 0 or 1.
  2. Take an input n and output the terms up to and including the nth term of the sequence, where n starts either from 0 or 1 (i.e. either print the first n or the first n+1 terms).
  3. Output values from the sequence indefinitely.

In the second and third case, you may choose any reasonable, unambiguous list format. It's fine if there is no separator between the elements, since they're always a single digit by definition.

In the third case, if your submission is a function, you can also return an infinite list or a generator in languages that support them.

You may write a program or a function and use any of our standard methods of receiving input and providing output. Note that these loopholes are forbidden by default.

This is , so the shortest valid answer – measured in bytes – wins.

Martin Ender

Posted 2018-03-06T11:42:31.613

Reputation: 184 808

Related, but not a dupe. – Magic Octopus Urn – 2018-03-06T14:22:11.013

Generalization of the problem, but optimizations are probably possible since the initial portion of the sequence is fixed. – Giuseppe – 2018-03-06T14:26:13.510

While we're at it, I've got another generalisation as well.

– Martin Ender – 2018-03-06T14:40:11.940

Answers

17

Jelly, 7 bytes

2Rṁxṁµ¡

This is a full program that prints the first n terms.

Try it online!

How it works

2Rṁxṁµ¡  Main link. Argument: n (integer)

     µ   Combine the preceding links into a monadic chain.
      ¡  Set t = n.  Call the chain n times, updating t with the return value after
         each call. Yield the last value of t.
2R           Set the return value to 2 and take its range. Yields [1, 2].
  ṁ          Mold; cyclically repeat 1 and 2 to match t's length.
             In the first run, ṁ promotes t = n to [1, ..., n].
   x         Repeat the k-th element of the result t[k] times.
             In the first run, x repeats each element t = n times.
    ṁ        Mold; truncate the result to match the length of t.
             In the first run, ṁ promotes t = n to [1, ..., n].                 

Example run

Let n = 5.

The first invocation of the chain repeats 1, 2 cyclically to reach length 5, then each element 5 times, and finally truncates the result to length 5.

  1         2         1         2         1
x 5         5         5         5         5
---------------------------------------------------
  1 1 1 1 1 2 2 2 2 2 1 1 1 1 1 2 2 2 2 2 1 1 1 1 1

  1 1 1 1 1

This yields a list of length 5. The first element is the first element of the Kolakoski sequence.

The second invocation of the chain repeats 1, 2 cyclically to reach length 5, then repeats the kth element j times, where j is the kth element of the previous list, and finally truncates the result to length 5.

   1 2 1 2 1
x  1 1 1 1 1
------------
   1 2 1 2 1

   1 2 1 2 1

This yields another list of length 5. The first two elements are the first two elements of the Kolakoski sequence.

The process continues for three more iterations.

   1 2   1 2   1
x  1 2   1 2   1
----------------
   1 2 2 1 2 2 1

   1 2 2 1 2
   1 2   1   2 1
x  1 2   2   1 2
------------------
   1 2 2 1 1 2 1 1

   1 2 2 1 1
   1 2   1   2 1
x  1 2   2   1 1
----------------
   1 2 2 1 1 2 1

   1 2 2 1 1

These are the first five elements of the Kolakoski sequence.

Dennis

Posted 2018-03-06T11:42:31.613

Reputation: 196 637

12

Python 2, 51 bytes

l=[2]
print 1,2,
for x in l:print x,;l+=x*[l[-1]^3]

Prints indefinitely. Builds the list l as it's being iterated through. For each entry x of l, appends x copies of 1 or 2, whichever is opposite the current last element.

The main difficulty is dealing with the initial self-referential fragment [1,2,2]. This code just prints the initial 1,2 and proceeds from there. The extra printing costs 12 bytes. Without that:

39 bytes, missing first two entries:

l=[2]
for x in l:print x;l+=x*[l[-1]^3]

Another approach is to specially initialize the first two entries. We initialize l as [0,0,2] so that the first two entries don't cause appending, but print x or n makes them be printed as n.

51 bytes

l=[0,0,2]
n=1
for x in l:print x or n;l+=x*[n];n^=3

Another fix is to initialize l=[1], track the alternation manually in n, and correct the printing:

51 bytes

n,=l=[1]
for x in l:print(l==[1,1])+x;l+=x*[n];n^=3

Without the (l==[1,1])+, everything works except the printed sequences starts 1,1,2 instead of 1,2,2. There has to be a better way to recognize we're at this second step.

And another weird fix, also somehow the same byte count:

51 bytes

l=[1];q=2
for x in l:print x;l+=x*[l[-1]^3]*q;q=q<2

xnor

Posted 2018-03-06T11:42:31.613

Reputation: 115 687

12

Wumpus, 13 11 bytes

=[=)O?=!00.

Try it online!

Prints the sequence indefinitely without separators.

I am genuinely surprised by how short this is.

Explanation

The basic idea is to keep the sequence on the stack and repeatedly use the bottom-most element to generate another run and then print it. We're effectively abusing the stack as a queue here. We can also save a couple of bytes by working 0 and 1 (incrementing only for output) instead of 1 and 2, because this way we don't need to explicitly initialise the stack with a 1 and we can use logical negation to toggle between the two values.

     The entire program is run in a loop.
     At the beginning of loop iteration i, a(i)-1 will be at the bottom of the
     stack and the first element of the ith run of values will be on top.
     The caveat is that on the first iteration, the stack is empty, but
     popping from an empty stack produces an implicit zero.
=    Duplicate the top of the stack. Since this is defined as "pop x, push
     x, push x" this will result in 2 zeros when the stack is empty.
     After this we've got two copies of the ith run's value on top of the stack.
[    Pull up a(i)-1 from the bottom of the stack.
=)O  Duplicate, increment to a(i) and print it.
?=   If a(i)-1 is 1 (as opposed to 0), make another copy of the top of the
     stack. We've now got a(i)+1 copies, so one more than the run should be 
     long, but that's great because we can use the additional copy to get 
     the start of the next run.
!    Logical negation which swaps 0 and 1.
00.  Jump back to the beginning of the program.

Martin Ender

Posted 2018-03-06T11:42:31.613

Reputation: 184 808

10

Brachylog, 30 26 25 23 17 16 14 bytes

~a₀{1|2}ᵐḅlᵐ?l

Outputs the first n values. Uses the "output variable" . for input, and outputs to the "input variable" ?. Try it online!

Explanation

I'm pretty happy with how declarative this turned out: the program is basically a high-level description of the output list and its relation to the input.

~a₀{1|2}ᵐḅlᵐ?l  Input is a number N.
                Output is a term that I'll call T.
~a₀             T is a prefix of a list L.
   {   }ᵐ       Each element of L
    1|2         is either 1 or 2.
         ḅ      If you cut L into blocks of equal elements
          lᵐ    and take the length of each block,
            ?   the result is T.
             l  The length of T is N.

Because {1|2}ᵐ tries out lists in lexicographic order, the output will begin with 1.

Zgarb

Posted 2018-03-06T11:42:31.613

Reputation: 39 083

9

Java 10, 155 108 105 100 97 bytes

v->{var s="122";for(int i=1;;s+=(1+i%2)*(s.charAt(i)>49?11:1))System.out.print(s.charAt(++i-2));}

Prints indefinitely without delimiter.

-3 bytes after an indirect tip from @Neil.
-5 bytes thanks to @MartinEnder.
-3 bytes converting Java 8 to Java 10.

Explanation:

Try it online (times out after 60 sec on TIO).

v->{              // Method with empty unused parameter and no return-type
  var s="122";    //  String, starting at "122"
  for(int i=1;;   //  Loop `i` from 1 upwards indefinitely
      s+=         //    After every iteration: Append the String with:
         (1+i%2)  //     1+`i`modulo-2
         *(s.charAt(i)>49?11:1))
                  //     either once or twice depending on the digit at index `i`
    System.out.print(s.charAt(++i-2));}
                  //   Print the character at index `i-2` of the String
                  //   After we've first increased `i` by 1 with `++i`

Kevin Cruijssen

Posted 2018-03-06T11:42:31.613

Reputation: 67 575

1I like how you have made this look so simple. – Erik the Outgolfer – 2018-03-06T12:52:34.463

@EriktheOutgolfer Thanks! :) When I read the challenge I wasn't sure how to even start, but then it hit me (using a list with the initial [1,2,2] and go from there) and I wrote the 155 byte answer (which is now golfed by using a String instead of List). – Kevin Cruijssen – 2018-03-06T12:55:06.837

Why not use (3-i) instead of (1+i%2)? – Erik the Outgolfer – 2018-03-06T12:58:33.667

1@EriktheOutgolfer because i isn't 1 or 2, it's the string index. – Martin Ender – 2018-03-06T12:59:04.260

9

Husk, 10 bytes

Ṡωo↑⁰`Ṙ¢ḣ2

Returns the first n values. Try it online!

Explanation

Ṡωo↑⁰`Ṙ¢ḣ2  Input is an integer N.
        ḣ2  The range [1,2]
       ¢    Cycle: C = [1,2,1,2,1,2...
 ω          Iterate until fixed point is found:
Ṡ    `Ṙ      Replicate the list C element-wise according to the current list,
  o↑⁰        then take first N elements.

For input 20, the process goes like this:

[1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2...
[1,2,2,1,2,2,1,2,2,1,2,2,1,2,2,1,2,2,1,2]
[1,2,2,1,1,2,1,1,2,2,1,2,2,1,1,2,1,1,2,2]
[1,2,2,1,1,2,1,2,2,1,2,1,1,2,2,1,2,2,1,1]
[1,2,2,1,1,2,1,2,2,1,2,2,1,1,2,1,1,2,1,2]
[1,2,2,1,1,2,1,2,2,1,2,2,1,1,2,1,1,2,2,1]
[1,2,2,1,1,2,1,2,2,1,2,2,1,1,2,1,1,2,2,1]

Zgarb

Posted 2018-03-06T11:42:31.613

Reputation: 39 083

1

Here's a variation printing the sequence indefinitely, same byte count but maybe you'll see some golfing opportunities I didn't Try it online!

– Leo – 2018-03-07T00:57:51.477

7

Jelly, 10 bytes

’߀+\<¹SḂ‘

Returns the nth term.

Try it online!

How it works

’߀+\<¹SḂ‘  Main link. Argument: n (positive integer)

’           Decrement; yield n-1.
 ߀         Recursively map the main link over [1, ..., n-1].
   +\       Take the cumulative sum.
            The k-th sum is the combined length of the first k runs.
     <¹     Compare each sum with n.
       S    Sum the Booleans.
            This counts the number of runs that occur before the n-th term.
            If there's an even number (including 0) of runs, the n-th term is 1.
            If there's an odd number of runs, the n-th term is 2.
        Ḃ   Extract the least significant bit of the count.
         ‘  Increment.

Dennis

Posted 2018-03-06T11:42:31.613

Reputation: 196 637

7

Haskell, 33 bytes

r=r%1
~(x:t)%n=n:[n|x>1]++t%(3-n)

Try it online!

Ørjan Johansen saved 7 bytes using an irrefutable pattern to force the prefix.

xnor

Posted 2018-03-06T11:42:31.613

Reputation: 115 687

5

You can save 7 bytes by making it lazier. Try it online!

– Ørjan Johansen – 2018-03-08T02:01:00.677

@ØrjanJohansen That's amazing and the lazy pattern is magic to me. Want to post your own answer? – xnor – 2018-03-08T03:43:01.347

Nah you were most of the way there. By using n: at the start of the expression you don't need to know the x is there to produce the first n. But you need the pattern to be lazy in order to avoid the function checking it before getting to the n:. – Ørjan Johansen – 2018-03-08T03:59:14.740

6

Gol><>, 8 7 bytes

:{:PnKz

Try it online!

Explanation

This is a port of my Wumpus answer. Gol><> is basically the language that has all the necessary features to port the Wumpus answer (specifically, implicit zeros at the bottom of stack, "duplicate" implemented "pop, push, push", and a stack rotation command), but:

  • It has a toroidal grid, which means we don't need the explicit 00. to jump back to the beginning.
  • It has K, which is "pop N, then duplicate the next element N times", which can replace ?=, saving another byte.

So the mapping from Wumpus to Gol><> becomes:

Wumpus   Gol><>
=        :
[        {
=        :
)        P
O        n
?=       K
!        z
00.

Martin Ender

Posted 2018-03-06T11:42:31.613

Reputation: 184 808

6

Shakespeare Programming Language, 594 583 572 bytes

Thanks to Ed Wynn for -10 bytes!

,.Ford,.Puck,.Act I:.Scene I:.[Enter Ford and Puck]Ford:You cat!Open heart!You big cat!Open heart!Puck:Remember you!Remember me!Scene V:.Ford:You is the sum ofI a cat!Puck:Recall!Open heart!Ford:Remember a pig!Is I nicer a cat?If notyou be the sum ofyou a big pig!Scene X:.Puck:Recall!Ford:Is I nicer zero?If soremember I!If solet usScene X!Puck:Is I nicer zero?You is the sum ofI a big cat!If soyou is I!Remember zero!Remember I!Remember you!You be the difference betweena big cat you!Scene L:.Ford:Recall!Is you worse I?If so,let usScene V!Puck:Remember I!Let usScene L!

Try it online!

This is a golfed version of Ed Wynn's ungolfed solution, starting from the 828 byte solution he linked in the comments and going a little nuts from there.

Explanation:

,.Ford,.Puck,.Act I:.Scene I:.[Enter Ford and Puck]    Boilerplate, introducing the characters
Ford:You cat!Open heart!You big cat!Open heart!  Print 1,2 as the first two terms of the sequence

Puck:Remember you!Remember me!  Initialise stack as 0, 2
                                Ford's value is currently 0, representing the value to be pushed to the stack

Scene V:.     Start infinite loop
  Ford:You is the sum ofI a cat!         
  Puck:Recall!Open heart!                 Pop the next value in the stack and print it
  Ford:Remember a pig!                    Push -1 as the end of the stack
  Is I nicer a cat?                       If Ford's value is 2
  If notyou be the sum ofyou a big pig! Subtract 2 from Puck's value to represent making 2 only one copy

        #Reverse the stack until it reaches the terminator value 0 or -1
  Scene X:.Puck:Recall!Ford:Is I nicer zero?If soremember I!If solet usScene X!

  Puck:Is I nicer zero?                          Check if the Puck's value is bigger than 0 (only making one copy)
  You is the sum of Ia big cat!                 Set Ford's value to Puck+2 to counter the change
  If soyou is I!                                But undo it if making one copies
  Remember zero!                                 Push 0 as the stack terminator
  Remember I!                                    Push Ford's value, which is 0 or -1 if this is a single copy, or 1 or 2 for a double copy
  Remember you!                                  Push one copy of Puck's value
  You be the difference betweena big cat you!   Map Ford's value from 1,2 to 1,0

  Scene L:.   #Reverse the stack until it reaches the terminator 0 
     Ford:Recall!Is you worse I?If solet us Scene V!
     Puck:Remember I!Let usScene L!

Jo King

Posted 2018-03-06T11:42:31.613

Reputation: 38 234

Nice! You can save 7 bytes by making the single child be (-1 or 0) instead of the twins. This costs you 1 byte just before Scene X (when "If so" becomes "If not"), and another byte just after the Scene X loop (when "Is I nicer you" becomes "Is I nicer zero"). The saving is that you can replace the "If not,remember you!" with simply "Remember I!" one line earlier. We insert either a second child or a spare terminator. (This is why you need to change the finely-balanced "Is I nicer you?" -- you can no longer rely on Ford==0 after Scene X.) Here is TIO, 587 bytes: https://tinyurl.com/yb9zg4gp

– Ed Wynn – 2018-05-08T17:50:23.733

You can remove the first "If so," in Scene L and move the command to the start of Scene V. This saves you only 1 byte, because you need a new "Ford:". But you save a couple of bytes in Scene I, so long as you can rely on Ford being automatically zero-initialised. You have no right to rely on this, but it might work: here is TIO, 584 bytes: https://tinyurl.com/y9f6vy7u

– Ed Wynn – 2018-05-08T17:55:21.980

5

JavaScript, 67 66 60 58 52 51 50 bytes

Well, that made my brain itch more than it should have! Retruns the nth term, 0-indexed.

s=`122`
x=1
f=n=>s[n]||f(n,s+=s[++x%2]*(s[x]+0-9))

5+1 bytes saved thanks to tsh scratching my itchy brain!


Test it

The snippet below will output the first 50 terms.

s=`122`
x=1
f=n=>s[n]||f(n,s+=s[++x%2]*(s[x]+0-9))
o.innerText=[...Array(50).keys()].map(f).join`, `
<pre id=o></pre>

Explanation

This is one of those rare occasions when we can declare some variables outside the scope of our function, modify them within the function and still be able to reuse them on subsequent calls of the function.

s=`122`       :Initialise variable s as the string "122"
x=1           :Initialise variable x as integer 1
f=n=>         :Named function f taking input as an argument through parameter n
 s[n]         :If s has a character at index n, return it and exit
 ||           :Or
 f(n          :Call f with n again
  ,s+=        :At the same time, append to s
  s[++x%2]    :  Increment x, modulo by 2 and get the character at that index in s
  *           :  Multiplied by (the above gets cast to an integer)
  (s[x]+0-9)  :  Append a 0 to the xth character of s and subtract 9
 )            :  (The above gives "1"+0-9="10"-9=1 or "2"+0-9="20"-9=11)

Shaggy

Posted 2018-03-06T11:42:31.613

Reputation: 24 623

What about n=>(g=s=>s[n]||g(s+(++x%2+1)*(10*s[x]-9)))('122',x=1) – tsh – 2018-03-07T07:00:17.390

Btw, is s='122',x=1,g=n=>s[n]||g(n,s+=(++x%2+1)*(10*s[x]-9)) considered a valid submission? – tsh – 2018-03-07T07:06:19.257

Thanks, @tsh. s[n]|| was a clear case of not seeing the wood for the trees! Your second suggestion wouldn't be valid ,though, as the function could only be called once; s & x need to be initialised with each call. – Shaggy – 2018-03-07T09:12:13.943

the second one does be reusable, as long as s and x not touched by other codes between each invokes (which is by default). – tsh – 2018-03-07T11:42:44.103

1Nice! s[x]+0-9 is a pretty neat trick – JollyJoker – 2018-03-07T13:46:02.493

Wait, hang on; I see what you're saying now, @tsh. Don't know what my pre-caffeinated brain was thinking you were suggesting this morning! Yes, that would be valid as if we call the function a second time with a lower n then s[n] will already exist and if we use a higher n then the building of s will pick up where it left off after the first call. Thanks again. Will update shortly. – Shaggy – 2018-03-07T18:35:19.807

5

><>, 13 12 bytes

0:{:1+n?:0=!

Try it online!

A port of Martin Ender's Wumpus answer. Unfortunately, ><> doesn't have an increment or an invert command nor does it have implicit 0s on the bottom of the stack, so this ends up being a bit longer.

Jo King

Posted 2018-03-06T11:42:31.613

Reputation: 38 234

1Yep, this is what I had before remembering Gol><>. :) – Martin Ender – 2018-03-07T07:48:55.317

4

05AB1E, 12 9 bytes

Saved 3 bytes thanks to Grimy

Prints the first n items.

Δ2LÞsÅΓI∍

Try it online!

Explanation

Δ           # repeat until ToS doesn't change
 2LÞ        # push [1,2,1,2 ...]               
    sÅΓ     # run-length encode with previous value (initially input)
       I∍   # extend/shorten to the length specified by input

Emigna

Posted 2018-03-06T11:42:31.613

Reputation: 50 798

Run-length decoding is now a built-in, so this can simply be 2L[2LÞsÅΓ. – Grimmy – 2019-06-13T13:30:14.853

Or even better: ∞[2LÞsÅΓ. – Grimmy – 2019-06-13T13:35:48.580

Or Δ2LÞsÅΓI∍ for a version that prints the first n items given input n. – Grimmy – 2019-06-13T13:47:14.790

@Grimy: Thanks! I like the first n version since it actually terminates :) – Emigna – 2019-06-14T15:26:43.877

4

Python (2 and 3), 65 60 bytes

f=lambda n:sum([f(i)*[i%2+1]for i in range(2,n)],[1,2,2])[n]

Returns the nth entry, 0-indexed.

Alternative (65 bytes):

f=lambda n:n>1and sum([f(i)*[i%2+1]for i in range(n)],[])[n]or-~n

ManfP

Posted 2018-03-06T11:42:31.613

Reputation: 481

3Welcome to PPCG! – Martin Ender – 2018-03-06T15:45:26.657

1You can (probably, I didn't tested though) save 5 bytes in the alternative version by using [1,2,2] as starting value in the sum – Rod – 2018-03-06T16:06:53.747

4

Haskell, 48 bytes

-1 byte thanks to nimi. -2 bytes thanks to Lynn.

c=1:2:c
l=1:2:drop 2(id=<<zipWith replicate l c)

Try it online!

Repeat every element its position mod 2 + 1 times.

totallyhuman

Posted 2018-03-06T11:42:31.613

Reputation: 15 378

You can save two more by defining c=1:2:c

– Lynn – 2018-03-06T20:45:08.980

4

brainfuck, 61 bytes

+.+.[.[>]>+++>+++<<<[->+>->-<<<]<[[->+<]<]>>--[[>]<,<[<]>+]>]

Try it online!

Prints numbers as char codes indefinitely. For clarity, here's a version that prints in numbers (except for the first two elements, which are easy enough to verify).

How It Works:

+.+. Prints the first two elements. These are the self-referential elements
     This also intitialises the tape with the third element, 2
[ Start infinite loop
   . Print current lowest element
   [>]>+++>+++ Move to end of tape and create two 3s
   <<<[->+>->-<<<] Subtract the last element of the tape from these 3s
   <[[->+<]<]>> Move to the beginning of the tape
   --  Subtract two from the first element
       This leaves 2 as 0 and 1 as -1
   [ If the number was 1
     [>]<,  Delete the excess element from the end of the tape
     <[<]>+ Remove the -1
   ]
   > Move to the next element of the list
]

Jo King

Posted 2018-03-06T11:42:31.613

Reputation: 38 234

3

05AB1E, 15 bytes

ƵLS[DNÌ©èF®É>¸«

Try it online! or with an iteration limit

Explanation

ƵLS               # push our initial list [1,2,2]
   [              # for every N in [0 ...
    D             # duplicate current list of numbers
     NÌ©è         # get the N+2'th element from the list
         F        # that many times do
          ®É>     # push ((N+2)%2==1)+1
             ¸«   # append to current list

Emigna

Posted 2018-03-06T11:42:31.613

Reputation: 50 798

Instead of ¸«, = would print them for 2 bytes saved. ƵLS[NÌ©èF®É>=, no need to dupe if you're not consuming. – Magic Octopus Urn – 2018-03-06T15:52:42.247

@MagicOctopusUrn: I don't produce the first 3 items though, so printing unfortunately doesn't work – Emigna – 2018-03-06T17:12:46.173

3

Python 3, 55 54 bytes

n=h=1;l=[]
while n:print(h);n^=3;h,*l=l+[n]*(l+[2])[0]

Try it online!

ovs

Posted 2018-03-06T11:42:31.613

Reputation: 21 408

3

J, 12 bytes

Single-argument function taking n and producing the first n terms. Try it online!

$(1+2|I.)^:]

Just sprucing up my old answer to the old question.

I. is a verb which takes an array of numbers and spits out a list of indices, so that if the k-th item in the array is n, then the index k appears n times. We'll use it to bootstrap the Kolakowski sequence up from an initial seed. Each step will proceed as follows:

1 2   2   1 1 2   1 2   2   1   (some prefix)
0 1 1 2 2 3 4 5 5 6 7 7 8 8 9   (use I.)
0 1 1 0 0 1 0 1 1 0 1 1 0 0 1   (mod 2)
1 2 2 1 1 2 1 2 2 1 2 2 1 1 2   (add 1) 

If we perform this operation (1+2|I.) over and over starting from 10, it looks something like this:

10
1 1 1 1 1 1 1 1 1 1
1 2 1 2 1 2 1 2 1 2
1 2 2 1 2 2 1 2 2 1 2 2 1 2 2
1 2 2 1 1 2 1 1 2 2 1 2 2 1 1 ...
1 2 2 1 1 2 1 2 2 1 2 1 1 2 2 ...
1 2 2 1 1 2 1 2 2 1 2 2 1 1 2 ...

Notice how we get more and more correct terms each time, and after a while the first n terms are fixed. The number of iterations it takes to settle down is hard to describe precisely, but it looks to be roughly logarithmic in n, so if we just run it n times (^:]) it should be fine. (Check out these other OEIS sequences for more info: generation lengths, partial sums.)

Once we're done that, all we have to do is take the first n terms using $. The construction $v for any verb v is an example of a hook, and giving it n as argument will execute n $ (v n).

Here is the old 13-byte version which is far less wasteful of time and space: ($1+2|I.)^:_~. It truncates the input at every step, so we can run exactly as many times as is needed to settle, instead of linearly many times.

algorithmshark

Posted 2018-03-06T11:42:31.613

Reputation: 8 144

Oh this works perfectly with I.. I've always wanted to see the copy feature of it used in some golf. – miles – 2018-03-11T07:38:27.613

3

C (gcc), 72 71 65 64 62 bytes

-9 bytes thanks to @ceilingcat

x,y;f(z){for(x=y=-1;putchar(49-~x%2);y=-~y|z&x/2)x^=z=y&~-~y;}

Try it online!

Generates values of the sequence indefinitely (option 3 from the challenge)

vazt

Posted 2018-03-06T11:42:31.613

Reputation: 311

Explanation please! I have no idea how this works. There is no array! And the numbers stay too small to contain one as bits. – Ørjan Johansen – 2018-04-19T18:37:10.937

@ØrjanJohansen I have to admit, I have no idea how this works either! :) I took the python implementation from OEIS A000002, ported it to C and golfed it :)

– vazt – 2018-04-19T19:07:08.797

Ah I thought it might have been something there, but didn't look far enough down that page to find the Python. There's a link to an explanation, but it was a bit buried in the link section. This method definitely fits C at least as well.

– Ørjan Johansen – 2018-04-20T00:00:20.010

>

  • 56 bytes in PHP: for($x=$y=-1;;$y=$y+1|$f&.5*$x^=$f=$y&-$y-2)echo$x&1?:2;. 2) 50-x%2 should save one byte for you. 3) I tried to get it running with x=y=1; but couldn´t get the operations right so far. Can you?
  • < – Titus – 2018-10-05T20:24:28.483

    3

    Fueue, 30 bytes

    Fueue is a queue-based esolang in which the running program and its data are both in the same queue, the execution goes around the queue in cycles, and programming requires lots of synchronizing to keep anything from executing at the wrong time.

    1)2:[[2:])~)~:~[[1]:~))~:~~]~]
    

    Try it online!

    The above prints an unending list of digits as control codes. For 34 bytes it can print actual digits:

    49)50:[[50:])~)~:~[[49]:~))~:~~]~]
    

    Try it online!

    The rest of the explanation uses the latter version.

    Summary of Fueue elements

    The Fueue queue can contain the following kind of elements:

    • Integers, which print their Unicode codepoint when executed,
    • Square-bracket delimited subprogram blocks, which are mercifully inactive (just moving to the end of the queue) unless the ) function deblocks them, and
    • Single-character functions, which execute if they are followed by the right type of arguments and remain inactive otherwise.
      • The only functions used in this program are ~ (swap two following elements), : (duplicate next element), and ) (deblock following block).

    High level overview

    During the main loop of the program, the queue consists of:

    • a chain of blocks representing digits to be iterated through;
      • A digit 1 or 2 is represented by the blocks [49] and [50:], respectively.
    • a self-replicating main loop section that traverses the digit blocks and puts alternating 1s and 2s after them, then deblocks them.
      • An deblocked digit block prints its own digit d, and then creates d copies of the following block, thus creating the digits for the run it describes.

    Low level trace of first 10 commands

    Cmds   Explanation              Queue
    49     Print '1'.               )50:[[50:])~)~:~[[49]:~))~:~~]~]
    )      Inactive, move to end.   50:[[50:])~)~:~[[49]:~))~:~~]~])
    50     Print '2'.               :[[50:])~)~:~[[49]:~))~:~~]~])
    :[...] Duplicate block.         )[[50:])~)~:~[[49]:~))~:~~]~][[50:])~)~:~[[49]:~))~:~~]~]
    )[...] Deblock (rmv. brackets). [[50:])~)~:~[[49]:~))~:~~]~][50:])~)~:~[[49]:~))~:~~]~
    [...]  Inactive.                [50:])~)~:~[[49]:~))~:~~]~[[50:])~)~:~[[49]:~))~:~~]~]
    [50:]  Inactive.                )~)~:~[[49]:~))~:~~]~[[50:])~)~:~[[49]:~))~:~~]~][50:]
    )      Inactive.                ~)~:~[[49]:~))~:~~]~[[50:])~)~:~[[49]:~))~:~~]~][50:])
    ~)~    Swap ) and ~.            :~[[49]:~))~:~~]~[[50:])~)~:~[[49]:~))~:~~]~][50:])~)
    :~     Duplicate ~.             [[49]:~))~:~~]~[[50:])~)~:~[[49]:~))~:~~]~][50:])~)~~
    

    Walkthrough of a full main loop iteration

    Optional whitespace has been inserted to separate commands.

    49 ) 50 :[[50:])~)~:~[[49]:~))~:~~]~]
    

    Cycle 1: 49 prints 1. ) is inactive, waiting to be brought together with the main loop block. 50 prints 2. : duplicates the main loop block (which needs a copy for self-replication.)

    ) [[50:])~)~:~[[49]:~))~:~~]~] [[50:])~)~:~[[49]:~))~:~~]~]
    

    Cycle 2: ) deblocks the first main loop block, making it start executing next cycle.

    [50:] ) ~)~ :~ [[49]:~))~:~~] ~[[50:])~)~:~[[49]:~))~:~~]~]
    

    Cycle 3: [50:] represents the first digit produced in the chain, a 2 not yet deblocked. The following ) will eventually do so after the rest of the main loop has traversed it. ~)~:~ is a golfed (using a swap and a copy) one-cycle delay of ~)~~. [[49]:~))~:~~] is inactive. ~ swaps the following main loop block past the [50:] digit block.

    ) ~)~ ~[[49]:~))~:~~][50:] [[50:])~)~:~[[49]:~))~:~~]~]
    

    Cycle 4: ) still waits, ~)~ produces ~), ~ swaps [[49]:~))~:~~] past the [50:] digit block.

    ) ~)[50:] [[49]:~))~:~~] [[50:])~)~:~[[49]:~))~:~~]~]
    

    Cycle 5: ~ swaps ) past the [50:] digit block.

    )[50:] )[[49]:~))~:~~] [[50:])~)~:~[[49]:~))~:~~]~]
    

    Cycle 6: The first ) now deblocks the [50:] digit block, the next ) deblocks the subprogram [[49]:~))~:~~].

    50 :[49] :~ ) ) ~:~ ~[[50:])~)~:~[[49]:~))~:~~]~]
    

    Cycle 7: 50 prints 2, : duplicates the just produced [49] digit block, creating a run of two 1s. :~))~:~ is a one-cycle delay of ~~))~:. ~ swaps the remaining main loop block past the first [49].

    [49] ~~) ) ~:[49] [[50:])~)~:~[[49]:~))~:~~]~]
    

    Cycle 8: ~~)) is a one-cycle delay of )~). ~ swaps : past the currently traversed [49].

    [49] ) ~)[49] :[[50:])~)~:~[[49]:~))~:~~]~]
    

    Cycle 9: ~ swaps ) past [49]. : duplicates the main loop block.

    [49] )[49] )[[50:])~)~:~[[49]:~))~:~~]~] [[50:])~)~:~[[49]:~))~:~~]~]
    

    Cycle 10: The first ) deblocks the [49] digit block just traversed, the second ) restarts the main loop to traverse the next one (above shown at the beginning of the queue.)

    Ørjan Johansen

    Posted 2018-03-06T11:42:31.613

    Reputation: 6 914

    Nice work! The reason I learned some Fueue and answered the HW challenge because I actually looked into it for this challenge, but ended up being too intimidated by the queue-based nature. That's a really great score for Fueue! :) – Martin Ender – 2018-03-20T19:40:45.990

    3

    x86, 41 37 35 33 28 bytes

    I had a lot of fun messing around with different x86 instructions, as this is my first "non-trivial" x86 answer. I actually learned x86-64 first, and I saved many bytes just by converting my program to 32-bit.

    It turns out the algorithm I used from OEIS pushes values to an array, which makes it amenable to x86 and storing values on the stack (note MIPS doesn't have stack instructions).

    Currently the program takes N values as input in ecx and returns an address in ebp of an array with the nth element representing the nth value in the sequence. I assume returning on the stack and computing extra values is valid (we consider what's beyond the array as garbage anyway).

    Changelog

    • -4 bytes by computing x = 2 - n%2 with xor every iteration

    • -2 bytes by using do-while instead of while loop.

    • -2 bytes by pushing initial values 1, 2, 2 using eax

    • -5 bytes by not storing n explicitly and instead running loop N times

    .section .text
    .globl main
    main:
            mov     $10, %ecx           # N = 10 
    
    start:
            mov     %esp, %ebp          # Save sp
            push    $1
            push    $2                  # x = 2
            pop     %eax       
            push    %eax                # push 2
            push    %eax                # push 2
            mov     %esp, %esi          # sn = stack+3 addr
    
    loop:                               
            xor     $3, %al             # flip x between 1 <-> 2 
            push    %eax                # push x      
                                        # maybe use jump by parity?
            cmp     $2, (%esi)          # if *sn == 2 
            jne     loop1
            push    %eax                # push x
    
    loop1: 
            sub     $4, %esi            # sn += 1
            loop    loop                # --N, do while (N)
    end:
            mov     %ebp, %esp          # Restore sp
            ret
    

    Objdump:

    00000005 <start>:
       5:   89 e5                   mov    %esp,%ebp
       7:   6a 01                   push   $0x1
       9:   6a 02                   push   $0x2
       b:   58                      pop    %eax
       c:   50                      push   %eax
       d:   50                      push   %eax
       e:   89 e6                   mov    %esp,%esi
    
    00000010 <loop>:
      10:   34 03                   xor    $0x3,%al
      12:   50                      push   %eax
      13:   83 3e 02                cmpl   $0x2,(%esi)
      16:   75 01                   jne    19 <loop1>
      18:   50                      push   %eax
    
    00000019 <loop1>:
      19:   83 ee 04                sub    $0x4,%esi
      1c:   e2 f2                   loop   10 <loop>
    
    0000001e <end>:
      1e:   89 ec                   mov    %ebp,%esp
      20:   c3                      ret 
    

    qwr

    Posted 2018-03-06T11:42:31.613

    Reputation: 8 929

    2

    Perl 5, 36 bytes

    Still a trivial modification of the classic TPR(0,3) solution:

    Outputs the series from 0 to n

    #!/usr/bin/perl
    use 5.10.0;
    say$_=($n+=!--$_[$n])%2+1for@_=0..<>
    

    Try it online!

    Ton Hospel

    Posted 2018-03-06T11:42:31.613

    Reputation: 14 114

    2

    Javascript ES6 - 71 70 68 bytes

    (_="122")=>{for(x=1;;_+=(1+x%2)*(_[x]>1?11:1))console.log(_[++x-2])}
    

    1 bit saved thanks to Neil

    Tanks to Shaggy for correcting my mistake, also for saving 1 bit.

    f = (_="122") => {
      for(x=1;x<20;_+=(1+x%2)*(_[x]>1?11:1))
        document.getElementById('content').innerHTML += '   ' + _[++x-2]
    }
    f()
    <div id="content"></div>

    Luis felipe De jesus Munoz

    Posted 2018-03-06T11:42:31.613

    Reputation: 9 639

    This looks like a port of my Java 8 answer (except for x=0 instead of x=1), but @Shaggy is indeed right: this doesn't work in its current form (I added the ,i=100;i-->0 temporarily to just see the first 100 items, instead of having to wait 60 sec before seeing an output). No idea why it doesn't work, though. JS is not my thing.

    – Kevin Cruijssen – 2018-03-06T16:19:23.147

    The problems are: 1. initiating x to 0 instead of 1 (as @KevinCruijssen mentioned) and 2. checking if the xth character in the string, which can only ever be 1 or 2, is greater than 49. – Shaggy – 2018-03-06T17:23:42.390

    2

    Here's a golfed down (but not fully tested) version of the fixed solution: https://tio.run/##HctBCoAgEADAvwSBZgbrsbAeEh3ELAppw5XY31t0HZjTPY58Ou6sL1xDcTGkbD1ehDF0EfeyYRJkKzCmatnCMJCyAhTXRjaCZl5GmAB6kPK/HynF2iyylBc

    – Shaggy – 2018-03-06T17:24:39.467

    (_[x]*10-9) than (_[x]>1?11:1) – l4m2 – 2018-03-31T13:48:13.890

    2

    Stax, 12 bytes

    ╦╥2Bïß▄n»-[╒
    

    Run and debug it

    This is the ascii representation of the same program.

    G@}2R;D{|;^]*m$
    

    It expands the sequence x times where x is the input. Then it outputs the xth element, 0-indexed.

    G }             G jumps to trailing } and returns when done
     @              get xth element in array
       2R           [1, 2]
         ;D         repeat the rest x times
           {     m  map array using block
            |;^]    produces [1] and [2] alternately
                *   repeat array specified number of times
                  $ flatten array
    

    Here's a bonus 12-byte solution that produces output as an infinite stream. Press Run to start.

    recursive

    Posted 2018-03-06T11:42:31.613

    Reputation: 8 616

    2

    Appleseed, 89 bytes

    (def K(lambda()(concat(q(1 2))(drop 2(flatten(zip-with repeat-val(cycle(q(1 2)))(K)))))))
    

    Defines a function K that takes no arguments and returns the Kolakoski sequence as an infinite list. Try it online!

    This approach was inspired by totallyhuman's Haskell answer. My original approach was longer and was probably O(2^n). :^P

    Ungolfed

    (def kolakoski
     (lambda ()
      (concat (list 1 2)
       (drop 2
        (flatten
         (zip-with repeat-val
          (cycle (list 1 2))
          (kolakoski)))))))
    

    The return list begins with (1 2). After that, to generate the rest of it (reading from the inside out):

    • Recursively call (kolakoski) to get the Kolakoski sequence list (due to lazy evaluation, it doesn't matter that the list hasn't been fully generated yet)
    • (cycle (list 1 2)) creates an infinite list (1 2 1 2 1 2 ...)
    • Zip the two infinite lists together using the function repeat-val. This will repeat the 1 or 2 from the cycle list either one or two times depending on the associated value in the Kolakoski list. Result: ((1) (2 2) (1 1) ...)
    • flatten that list into (1 2 2 1 1 ...)
    • We've already got the first two terms from (concat (list 1 2), so we drop the first two from the generated list to avoid duplication.

    DLosc

    Posted 2018-03-06T11:42:31.613

    Reputation: 21 213

    2

    R, 63 bytes or 61 bytes

    Implementation 1: prints out the nth term of the sequence.

    x=scan()
    a=c(1,2,2)
    for(n in 3:x)a=c(a,rep(2-n%%2,a[n]))
    a[x]
    

    Implementation 2: prints out the first n terms of the sequence.

    x=scan()
    a=c(1,2,2)
    for(n in 3:x)a=c(a,rep(2-n%%2,a[n]))
    a[1:x]
    

    (The difference is only in the last line.)

    Yes, yes, you may complain that my solution is inefficient, that it computes really more terms than needed, but still...

    Update: Thanks to @Giuseppe for shaving off 9 bytes.

    Andreï Kostyrka

    Posted 2018-03-06T11:42:31.613

    Reputation: 1 389

    1use a=c(a,rep(2-n%%2,a[n])) instead of the second for loop to shave off some bytes. – Giuseppe – 2018-03-23T17:24:07.863

    @Giuseppe Implemented, thanks! – Andreï Kostyrka – 2018-03-23T17:43:44.503

    We don't mind inefficient for golfing solutions here. In fact using a more inefficient algorithm is one of the tips in the code-golf tag wiki.

    – Ørjan Johansen – 2018-03-25T01:37:42.027

    2

    Shakespeare Programming Language, 575 bytes (but defective), or 653 or 623 bytes

    ,.Puck,.Ford,.Act I:.Scene X:.[Enter Puck and Ford]Ford:You big cat!Scene L:.Ford:Is I nicer zero?If so,let us Scene V.Is you nicer a big cat?If so,you is the sum of you a big lie.If so,open heart!Open heart!Scene M:.Puck:Remember you!Is I nicer a cat?You big cat.If so,you cat.Ford:Recall!Is you nicer zero?If not,let us Scene X.Is you nicer a big cat?If not,let us Scene M.You is the sum of you a big lie.Scene V:.Ford:Remember you!Is you worse a big big cat?If not, you big cat.Is you as big as a big cat?If not,you zero.You is the sum of I you.Puck:Recall!Let us Scene L.
    

    In the hotly contested SPL category, this would beat Jo King's current entry (583 bytes), except that it is defective: First, it does not run in the TIO version (implementing the SPL website) -- but it does run in the Perl version, so maybe that is not a serious defect. Second, though, it does not print the first two digits. If we allowed that defect in Jo King's solution, then that defective solution would be 553 bytes, beating my defective solution.

    My solution fails on TIO for two reasons: we try to rely on an empty stack returning zero when popped; and we goto the first scene, with "[Enter Ford and Puck]" even though nobody has left the stage. These are merely warnings in the Perl version. If I fix these errors and put in the first two digits, I reach 653 bytes:

     ,.Puck,.Ford,.Act I:.Scene I:.[Enter Puck and Ford]Ford:You cat!Open heart!You big cat!Open heart!You zero!Scene X:.Ford:Remember you!You big cat!Scene L:.Ford:Is I nicer zero?If so,let us Scene V.Is you nicer a big cat?If so,you is the sum of you a big lie.If so,open heart!Open heart!Scene M:.Puck:Remember you!Is I nicer a cat?You big cat.If so,you cat.Ford:Recall!Is you nicer zero?If not,let us Scene X.Is you nicer a big cat?If not,let us Scene M.You is the sum of you a big lie.Scene V:.Ford:Remember you!Is you worse a big big cat?If not, you big cat.Is you as big as a big cat?If not,you zero.You is the sum of I you.Puck:Recall!Let us Scene L.
    

    Try it online!

    I can generate the full sequence in the Perl implementation using 623 bytes:

    ,.Puck,.Ford,.Act I:.Scene I:.[Enter Puck and Ford]Ford:You cat!Open heart!You big cat!Open heart!Scene L:.Ford:Is I nicer zero?If so,let us Scene V.Is you nicer a big cat?If so,you is the sum of you a big lie.If so,open heart!Open heart!Scene M:.Puck:Remember you!Is I nicer a cat?You big cat.If so,you cat.Ford:Recall!Is you worse a cat?If so,you big cat!If so,let us Scene L.Is you nicer a big cat?If not,let us Scene M.You is the sum of you a big lie.Scene V:.Ford:Remember you!Is you worse a big big cat?If not, you big cat.Is you as big as a big cat?If not,you zero.You is the sum of I you.Puck:Recall!Let us Scene L.
    

    However, I would point out that this solution is fast compared to many other solutions, and uses logarithmic amounts of memory rather than storing the whole list. (This is similar to vazt's C solution, to which it is distantly related.) This makes no difference for golf, but I'm pleased with it even so. You can generate a million digits in about a minute in Perl (for example if you pipe to sed and wc to get a digit count), where the other solution might give you a few thousand digits.

    Explanation

    We store a sequence of variables in order: Puck's stack (bottom to top), Puck's value, Ford's value, Ford's stack (top to bottom). Apart from zero values at the ends (with the zero on the left maybe from popping an empty stack), each value is the digit generated next at that generation, with 2 added if the next generation needs to have another child from that parent. When we have N non-zero values in the sequence, we generate all the children up to and including the N-th generation, in a kind of depth-first tree traversal. We print values only from the N-th generation. When the N-th generation has been completely generated, the stored values are in fact the starting values for generations 2 to (N+1), so we append a 2 at the left and start again, this time generating the (N+1)-th generation.

    So, an outline: Scene X: When we reach here, this the start of a new traversal. Puck==0. We optionally push that zero onto Puck's stack, and set Puck=2. Scene L: If Ford==0, we have reached the printing generation. If not, goto V. For printing, if the value in Puck has had 2 added, remove the 2 and print it twice; if not, print it once. Scene M: This is a loop where we repeatedly toggle the value of Puck and go back through the sequence. We repeat until either we reach the end (Puck==0), in which case goto X, or we reach a value that needs another child (Puck>2), in which case subtract the extra 2 and go forwards in V. Scene V: Here we go forwards. If Puck is 2 or 4, the next generation will contain two children from the current parent, so Ford+=2. Step forwards through the sequence. Goto L to check for termination.

    Ed Wynn

    Posted 2018-03-06T11:42:31.613

    Reputation: 121

    1

    axo, 13 bytes

    [:|[1+{#;1;-_
    

    Try it online!

    Explanation

    This started out as a port of an alternative solution in my Wumpus answer:

    2%)[=]&=[O00.
    

    This resulted in 18 bytes. I ended up golfing it down to the 13 bytes you see above to adjust it more to the way axo works. This 13-byte version then ended up inspiring the improvement down to 11 bytes in Wumpus, so now it's actually closer to that version.

    As in Wumpus, in iteration i, the bottom of the stack holds a(i)-1 and the top holds the first element of the ith run, but we're working with 0 and 1 throughout, except for printing.

    [:    Store a copy of the top of the stack in register A.
    |     Pull up a(i)-1 from the bottom of the stack.
    [1+{  Print a(i).
    #;    If a(i)-1 is 1, push the value in register A.
    1;-   Push another copy of that value and subtract it from 1 to swap
          0 and 1 for the next run.
    _     Jump back to the beginning of the program.
    

    Martin Ender

    Posted 2018-03-06T11:42:31.613

    Reputation: 184 808

    1

    Asone Tuhid

    Posted 2018-03-06T11:42:31.613

    Reputation: 1 944

    1

    Ruby, 44 43 37 bytes

    b=*a=2;loop{b+=[a^=3]*p(b[$.+=1]||a)}
    

    Try it online!

    Prints an infinite sequence of numbers separated by newlines. -1 byte thanks to Martin Ender.

    Kirill L.

    Posted 2018-03-06T11:42:31.613

    Reputation: 6 693

    1

    Br**nfuck, 96 bytes

    +.+..<<+.[.[[>>]<+<[<<]>>-]>>[>>]<[>[>>]+++<<[<]>>-]<[<+>>+<-]>[>->>[-<]<<[<]>-]<<[>+<-]>[<<]>>]
    

    Try it online!

    This prints terms indefinitely.

    Explanation

    +.+..<<+.[                       Initialize the tape with {1, 0, 2} (printing the first four terms). Start an infinite loop.
      .[ [>>] <+< [<<] >>- ]           Print the first value and move it to the end. Let's call it n.
      >> [>>]                          Move to the end of the filled part of the tape.
      <[                               n times:
        > [>>] +++<< [<] >>-             Make a three on the end.
      ]
      < [<+>>+<-]                      Copy the last sequence value calculated, k.
      >[>->>[-<]<<[<]>-]               Subtract k from all the 3s made earlier.
      <<[>+<-]>                        Move the copied k back into place.
      [<<]>>                           Return to the start of the tape.
    ]                                End loop.
    

    I've been trying to save some bytes by including no empty cells between terms. No luck so far, but maybe someday soon...

    Pastebin of the (naïvely) transpiled .java file. Outputs as base-10 numbers, each on a line. Come to think of it, unary is probably the way to go for this challenge...

    Khuldraeseth na'Barya

    Posted 2018-03-06T11:42:31.613

    Reputation: 2 608

    1Why would you censor "brain" but not "fuck"... ? – Esolanging Fruit – 2018-03-08T05:56:34.303

    @EsolangingFruit It seems to be a variant of one of the name variants of BF

    – Conor O'Brien – 2018-03-08T18:18:39.577

    1

    CJam, 31 27 23 bytes

    Prints the first n entries.

    l~H3b{ee{(2%)+}%e~}2$*<
    

    Try online

    Chiel ten Brinke

    Posted 2018-03-06T11:42:31.613

    Reputation: 201

    1You can replace [1 2 2] with H3b (convert 17 to base 3). – Esolanging Fruit – 2018-03-20T05:27:43.520

    Good catch! Answer updated. – Chiel ten Brinke – 2018-03-20T10:01:46.377

    A simple byte save would be ~4+ --> 3^, but you can actually do several bytes better by making use of run-length decoding: l~H3b{ee{(2%)+}%e~}2$*< (I also changed = to < because it's the same byte count but makes it easier to verify the correctness of the solution.) – Martin Ender – 2018-03-20T20:18:06.457

    I'm quite new to code golfing and I hadn't looked into these compression mechanisms like base conversion and runlength encoding yet. Gotta read up I guess :) – Chiel ten Brinke – 2018-03-21T14:27:12.737

    I managed to golf the anwer without ee down to 24 bytes: l~_H3b\{_X2%)a\X)=*+}fX< – Chiel ten Brinke – 2018-03-27T16:05:19.160

    1

    Perl 6, 53 41 bytes

    -12 bytes thanks to nwellnhof!

    {1,2,2,{$/=$++%2+1;|($/xx@_[2+$++])}...*}
    

    Try it online!

    Anonymous code block that returns a lazy infinite sequence of values.

    Explanation:

    {                                       }  # Anonymous code block
     1,2,2,     #Hard-code the self-referential elements
           {                           }...*   # Get the next element based on the previous elements
            $/=$++%2+1;    # Swap the variable keeping track of 1 or 2
                         $/xx   # Repeat that variable
                             @_[2+$++]   # From the next element in the sequence
                       |(             )  # And add those elements to the sequence
    

    Jo King

    Posted 2018-03-06T11:42:31.613

    Reputation: 38 234

    41 bytes (I think it's OK to simply return an infinite sequence. 47 bytes, otherwise.) – nwellnhof – 2018-10-05T09:42:13.943

    @nwellnhof Neat. I didn't know you could add more than one element to the list at a time, thanks! – Jo King – 2018-10-05T09:54:48.947

    1

    APL (Dyalog Unicode), 34 bytes

    1{⎕←⍺⌷⍵⋄(1+⍺)∇⍵,⍵[2+⍺]⍴2-2|⍺}1 2 2
    

    Try it online!

    I'm flabbergasted that there was no APL answer to this challenge yet. This is a full program that outputs the sequence indefinitely.

    Thanks to @dzaima for -3 bytes.

    How

    1{⎕←⍺⌷⍵⋄(1+⍺)∇⍵,⍵[2+⍺]⍴2-2|⍺}1 2 2 ⍝ Full program. Inputs ⍺=1, ⍵=1 2 2
      ⎕←                                ⍝ Print
        ⍺⌷⍵                             ⍝ the ⍺th element of ⍵
           ⋄                            ⍝ Then
            (1+⍺)∇                      ⍝ Recurse with ⍺=⍺+1 and ⍵=
                  ⍵,                    ⍝ append to ⍵
                           2-2|⍺        ⍝ 2 minus ⍺ modulo 2
                          ⍴             ⍝ reshape (repeats right arg, left arg times)
                    ⍵[2+⍺]              ⍝ using the (2+⍺)th element of ⍵
    

    J. Sallé

    Posted 2018-03-06T11:42:31.613

    Reputation: 3 233

    0

    Jelly, 21 bytes

    3_ṪẋŒgL‘ịƲ⁸;
    2Rx`Ç⁸¡ḣ
    

    Try it online!

    Erik the Outgolfer

    Posted 2018-03-06T11:42:31.613

    Reputation: 38 134

    0

    Jelly, 15 bytes

    R€a"JḂ$Fo2
    2Ç¡ḣ
    

    A monadic link accepting an integer n which yields the first n terms.

    Try it online!

    Jonathan Allan

    Posted 2018-03-06T11:42:31.613

    Reputation: 67 804

    0

    Wolfram Language (Mathematica), 59 bytes

    Nest[Flatten@*MapIndexed[Mod[#2,2,1]~Table~#&],{2},#][[#]]&
    

    Try it online!

    alephalpha

    Posted 2018-03-06T11:42:31.613

    Reputation: 23 988

    0

    MIPS, 128 124 108 88 bytes

    Changelog:

    • Mar 24: Fix mod
    • Mar 25: Simplify algorithm (no need to push n)
    • Mar 26: Simpler algorithm using stack

     Address    Code        Basic                     Source
    
    0x00400000  0x24020001  addiu $2,$0,0x00000001    8         li      $v0, 1          # print first 3 vals
    0x00400004  0x2404007a  addiu $4,$0,0x0000007a    9         li      $a0, 122        
    0x00400008  0x0000000c  syscall                   10        syscall
    0x0040000c  0x24180002  addiu $24,$0,0x0000000    12        li      $t8, 2          # const 2
    0x00400010  0xafb8fff4  sw $24,0xfffffff4($29)    13        sw      $t8, -12($sp)   # l[3] = 2
    0x00400014  0x24080003  addiu $8,$0,0x00000003    14        li      $t0, 3          # n = 3
    0x00400018  0x23a9fff4  addi $9,$29,0xfffffff4    15        addi    $t1, $sp, -12   # i = l + 3
    0x0040001c  0x23abfff4  addi $11,$29,0xfffffff    16        addi    $t3, $sp, -12   # ln = l + 3
    0x00400020  0x31040001  andi $4,$8,0x00000001     19        andi    $a0, $t0, 1     # n%2 
    0x00400024  0x03042022  sub $4,$24,$4             20        sub     $a0, $t8, $a0   # x = 2 - n%2
    0x00400028  0xad24fffc  sw $4,0xfffffffc($9)      21        sw      $a0, -4($t1)    # *(i+1) = x
    0x0040002c  0x0000000c  syscall                   24        syscall                 # print x
    0x00400030  0x8d6c0000  lw $12,0x00000000($11)    26        lw      $t4, ($t3)      # temp = *ln
    0x00400034  0x20010002  addi $1,$0,0x00000002     27        bne     $t4, 2, kol2    # if temp == 2
    0x00400038  0x142c0003  bne $1,$12,0x00000003          
    0x0040003c  0xad24fff8  sw $4,0xfffffff8($9)      29        sw      $a0, -8($t1)    # *(i+2) = x
    0x00400040  0x0000000c  syscall                   32        syscall                 # print x
    0x00400044  0x2129fffc  addi $9,$9,0xfffffffc     34        addi    $t1, $t1, -4    # i += 1
    0x00400048  0x2129fffc  addi $9,$9,0xfffffffc     37        addi    $t1, $t1, -4    # i += 1
    0x0040004c  0x21080001  addi $8,$8,0x00000001     38        addi    $t0, $t0, 1     # n += 1
    0x00400050  0x216bfffc  addi $11,$11,0xfffffff    39        addi    $t3, $t3, -4    # ln += 1
    0x00400054  0x08100008  j 0x00400020              40        j       koll
    

    Old solution

     Address    Code        Basic                     Source
    
    0x00400040  0x23bdfff4  addi $29,$29,0xfffffff    32        addi    $sp, $sp, -12           # allocate 3 ints
    0x00400044  0xafbf0000  sw $31,0x00000000($29)    33        sw      $ra, ($sp)              # push $ra
    0x00400048  0x20010001  addi $1,$0,0x00000001     34        bne     $a0, 1, kol1            # if n == 1
    0x0040004c  0x14240002  bne $1,$4,0x00000002           
    0x00400050  0x00041021  addu $2,$0,$4             35        move    $v0, $a0                # return n
    0x00400054  0x08100026  j 0x00400098              36        j       kolret
    0x00400058  0x24100001  addiu $16,$0,0x0000000    39        li      $s0, 1                  # k = 1
    0x0040005c  0x00048821  addu $17,$0,$4            40        move    $s1, $a0                # x = n
    0x00400060  0xafb00004  sw $16,0x00000004($29)    43        sw      $s0, 4($sp)             # push k
    0x00400064  0xafb10008  sw $17,0x00000008($29)    44        sw      $s1, 8($sp)             # push x
    0x00400068  0x00102021  addu $4,$0,$16            45        move    $a0, $s0                # arg1 = k
    0x0040006c  0x0c100010  jal 0x00400040            46        jal     kol                     # f(k)
    0x00400070  0x8fb00004  lw $16,0x00000004($29)    48        lw      $s0, 4($sp)             # pop k
    0x00400074  0x8fb10008  lw $17,0x00000008($29)    49        lw      $s1, 8($sp)             # pop x
    0x00400078  0x02228822  sub $17,$17,$2            51        sub     $s1, $s1, $v0           # x -= f(k)
    0x0040007c  0x20010001  addi $1,$0,0x00000001     52        bgt     $s1, 1, kol4            # if x <= 1
    0x00400080  0x0031082a  slt $1,$1,$17                  
    0x00400084  0x14200007  bne $1,$0,0x00000007           
    0x00400088  0x02301020  add $2,$17,$16            53        add     $v0, $s1, $s0           # r = x + k
    0x0040008c  0x20420001  addi $2,$2,0x00000001     54        addi    $v0, $v0, 1             # r = x + i + 1
    0x00400090  0x30420001  andi $2,$2,0x00000001     55        andi    $v0, $v0, 1             # r = (x + k + 1) % 2
    0x00400094  0x20420001  addi $2,$2,0x00000001     56        addi    $v0, $v0, 1             # ret (x+k+1)%2 + 1
    0x00400098  0x8fbf0000  lw $31,0x00000000($29)    59        lw      $ra, ($sp)              # pop $ra
    0x0040009c  0x23bd000c  addi $29,$29,0x0000000    60        addi    $sp, $sp, 12            # free stack memory
    0x004000a0  0x03e00008  jr $31                    61        jr      $ra
    0x004000a4  0x22100001  addi $16,$16,0x0000000    64        addi    $s0, $s0, 1             # k += 1
    0x004000a8  0x08100018  j 0x00400060              65        j       kolw
    

    Assembly-friendly algorithm I came up with, based on Benoit Cloitre's OEIS formula:

    def f(n):
        if n == 1: return n
        k = 1
        x = n
        while True:
            x -= f(k)
    
            if x <= 1:
                return (x + k + 1)%2 + 1 
    
            k += 1
    
    for n in range(1, 10):
        print(f(n), end=',')
    

    qwr

    Posted 2018-03-06T11:42:31.613

    Reputation: 8 929

    0

    PHP, 61 bytes

    for($v=2;$n<$argn;$s.=$v^=3,$x>1&&$s.=$v)echo$x=$s[$n++]?:$n;
    

    prints the first \$n\$ elements without a separator. Run as pipe with -nr or try it online.

    Titus

    Posted 2018-03-06T11:42:31.613

    Reputation: 13 814