OFFSET
0,3
LINKS
EXAMPLE
68 in binary is 1000100, so it consists of runs of 1, 3, 1 and 2 bits of the same value (alternatively 1 or 0) counted from the most significant end. Swapping these (the first with the second, the third with the fourth, etc.) gives the run lengths of [3,1,2,1], and the reconstructed binary string looks now as 1110110, which is 118 in binary. Thus a(68)=118.
Likewise, 67 in binary is 1000011, so it consists of runs of 1, 4 and 2 counted from the most significant end. Now we can swap just the first and second of these runs, with the remaining third run staying as it is, so we get run lengths of [4,1,2], and the reconstructed binary string looks now as 1111011, which is 123 in binary. Thus a(67)=123.
PROG
(MIT/GNU Scheme)
(define (A166404 n) (let ((runlens (binexp->runcount1list n))) (runcount1list->binexp (interleave (bisect runlens 1) (bisect runlens 0)))))
(define (binexp->runcount1list n) (if (zero? n) (list) (let loop ((n n) (rc (list)) (count 0) (prev-bit (modulo n 2))) (if (zero? n) (cons count rc) (if (eq? (modulo n 2) prev-bit) (loop (floor->exact (/ n 2)) rc (1+ count) (modulo n 2)) (loop (floor->exact (/ n 2)) (cons count rc) 1 (modulo n 2)))))))
(define (runcount1list->binexp lista) (let loop ((lista lista) (s 0) (state 1)) (cond ((null? lista) s) (else (loop (cdr lista) (+ (* s (expt 2 (car lista))) (* state (- (expt 2 (car lista)) 1))) (- 1 state))))))
(define (bisect lista parity) (let loop ((lista lista) (i 0) (z (list))) (cond ((null? lista) (reverse! z)) ((eq? i parity) (loop (cdr lista) (modulo (1+ i) 2) (cons (car lista) z))) (else (loop (cdr lista) (modulo (1+ i) 2) z)))))
(define (interleave a b) (let loop ((z (list)) (a a) (b b)) (cond ((and (null? a) (null? b)) (reverse! z)) ((null? a) (loop (cons (car b) z) a (cdr b))) ((null? b) (loop (cons (car a) z) (cdr a) b)) (else (loop (cons (car b) (cons (car a) z)) (cdr a) (cdr b))))))
(Python)
def a(n):
if n==0: return 0
x=bin(n)[2:]
r=[]
s=1
p=""
for i in range(1, len(x)):
if x[i - 1]==x[i]: s+=1
else:
r+=[s, ]
s=1
l=r+[s]
L=[]
if len(l)%2==0:
for i in range(0, len(l), 2): L+=[l[i + 1], l[i]]
else:
b=l[-1]
for i in range(0, len(l) - 1, 2): L+=[l[i + 1], l[i]]
L+=[b, ]
for i in range(len(L)):
if i%2==0: p+='1'*L[i]
else: p+='0'*L[i]
return int(p, 2)
print([a(n) for n in range(101)]) # Indranil Ghosh, Jun 12 2017
CROSSREFS
KEYWORD
nonn,base
AUTHOR
Antti Karttunen, Oct 20 2009
STATUS
approved