Tell me more ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

Definition1

A Kolakoski sequence is a self-describing infinite sequence {kn} of alternating blocks of 1's and 2's, given by the following rules:

  • k0 = 1
  • kn = the length of the (n+1)'th block

The Task

Given a positive integer n, generate the first n elements of the Kolakoski sequence.

Details

Input will be provided as a single command line argument n. Please write a full program that will print the first n elements of the Kolakoski sequence (in order) to STDOUT, with each element separated by your favorite whitespace.

Scoring

Lets count source code bytes this time with all whitespace included. Fewest number of bytes wins. In the event of a tie, the solution with the earliest submission time wins.

The Sequence2

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, 2, 2, 1, 1, 2, 1, 2, 2, 1, 2, 1, 1, 2, 1, 1, 2, 2, 1, 2, 2, 1, 1, 2, 1, 2, 2, 1, 2, 2, 1, 1, 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, 1, 1, 2, 2, 1, 2, 1, 1, 2, 1, 2, 2, ...


References

  1. John Smith, Ariel Scolnicov, yark. "Kolakoski sequence" (version 3). PlanetMath.org. Freely available at http://planetmath.org/KolakoskiSequence.html.
  2. The Online Encyclopedia of Integer Sequences http://oeis.org/A000002

Other resources

share|improve this question

6 Answers

up vote 3 down vote accepted

GolfScript (48 chars)

You can't test this online because the online GS shell doesn't take command-line arguments, but:

;"#{ARGV[-1]}"~[1 2.]2{.2$=[1$2%)]*@\+\)}3$*;<n*

This takes input from stdin instead and works

~[1 2.]2{.2$=[1$2%)]*@\+\)}3$*;<n*
share|improve this answer
2  
Your 48-char version does work if you change ARVG to ARGV ;o). E.g., golfscript.rb kola.gs 10. – r.e.s. Sep 19 '12 at 14:48
@r.e.s., thanks. – Peter Taylor Sep 19 '12 at 14:55

Ruby (73 characters)

s=[1,2,2];n=2;ARGV[0].to_i.times{puts s[n-2];s[n].times{s+=[1+n%2]};n+=1}
share|improve this answer

Python 93

Adapted from my solution to Calculate the nth term of Golomb's self-describing sequence:

import sys;n=int(sys.argv[1]);a=[1,2,2];
for i in range(3,n):a+=[~i%2+1]*a[i-1]
print a[:n]

Still trying to figure out how to do this with list comprehension which I just learned about today, but I'm running into problems with self-reference.

EDIT: Instead of breaking if list was too long, just printed the appropriate slice.

EDIT: Now pulling arg from command line

share|improve this answer
n is never set prior to being referenced (either hard coded or read in from user). The code fails to run successfully. – IamChuckB Sep 19 '12 at 16:54
It's required to use command-line input of what you call n, which will add some characters; however, you can save some by indenting only one space.) That's a very nice approach! Here's a 69-char Ruby version: s=[1,2,2];n=3;ARGV[0].to_i.times{puts s[n-3];s+=[~n%2+1]*s[n-1];n+=1}. – r.e.s. Sep 19 '12 at 17:04
Reading from command line the way I did it (is there a better way?) would add 28 characters to this code for a total of 93 characters. Still cool and still kills my noob attempt but 65 chars, it ain't. – IamChuckB Sep 19 '12 at 17:26
Yeah, it's the import sys and the lengthy sys.argv that really kills it. thanks for the tips. – scleaver Sep 19 '12 at 17:45

Python (118 characters)

Takes n as a command line argument. Could trim four more characters if the printing of first n requirement is relaxed to first n or n + 1. I can't think of any more fat to trim...will be interested to see what a more experienced Python golfer could do

import sys
k,b=[1,2,2],1
n=int(sys.argv[1])
while len(k)<n:k.extend([2,1][b%2]for z in range(k[b+1]));b+=1
print k[:n]
share|improve this answer

Haskell 157 144

Haskell is kind of verbose so I expect this will be significantly longer than the shortest answer, but here it is.

import System
a=1:2:drop 2(concat.zipWith replicate a.cycle$[1,2])
main=do args<-getArgs;putStr$concatMap((' ':).show)$take(read$args!!0::Int)a

Edit:

Implemented FUZxxl's suggestions and also a few other small fixes.

share|improve this answer
Try to separate the statements in the do block with semicolons instead of newlines. That might help. Ans: (\b->' ':show b) is equal to ((' ':).show). Additionally, you might want to factor out a into a global variable to get rid of the phony let. – FUZxxl Sep 19 '12 at 20:10

Perl, 59 chars

say"@{[map{push@a,(2-$_%2)x($b=$a[$_-1]||$_);$b}1..shift]}"

As usual, run with Perl 5.10+ and the -M5.010 switch to enable the say feature.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.