75 lines
2.1 KiB
Python
75 lines
2.1 KiB
Python
def solution(n):
|
|
# 1. *0: /= 2
|
|
# 2. *01: -= 1
|
|
# 3. *11: += 1
|
|
|
|
# state 0: *0
|
|
# state 1: *1
|
|
# state 2: *11
|
|
result = 0
|
|
state = 0
|
|
count = 0
|
|
b = bin(int(n))[2:]
|
|
for c in bin(int(n))[:1:-1]:
|
|
if c == '0':
|
|
if state == 0: # 0*
|
|
count += 1
|
|
elif state == 1: # 01
|
|
result += 1 + 2 # remove one, divide by 2 twice
|
|
count = 0
|
|
state = 0 # .*01 => .*00 => .*
|
|
elif state == 2: # 01*
|
|
result += 1 + count # add one, divide by 2 count times
|
|
count = 1
|
|
state = 1 # .*01* => .*10* => .*1
|
|
if c == '1':
|
|
if state == 0: # 10*
|
|
result += count # divide by 2 count times
|
|
count = 1
|
|
state = 1 # .*10* => .*1
|
|
elif state == 1: # 11
|
|
count += 1
|
|
state = 2
|
|
elif state == 2: # 1*
|
|
count += 1
|
|
if state == 2: # 11*
|
|
if count == 2: # 11
|
|
result += 2
|
|
else:
|
|
result += 1 + count # add one, devide by 2 count times
|
|
return result
|
|
|
|
|
|
tests = [
|
|
('15', 5),
|
|
('4', 2),
|
|
(str(int('1', 2)), 0),
|
|
(str(int('10', 2)), 1),
|
|
(str(int('11', 2)), 2),
|
|
(str(int('100', 2)), 2),
|
|
(str(int('101', 2)), 3),
|
|
(str(int('110', 2)), 3),
|
|
(str(int('111', 2)), 4),
|
|
(str(int('1000', 2)), 3),
|
|
(str(int('1001', 2)), 4),
|
|
(str(int('1010', 2)), 4),
|
|
(str(int('1011', 2)), 6),
|
|
(str(int('1100', 2)), 4),
|
|
(str(int('1101', 2)), 5),
|
|
(str(int('1110', 2)), 5),
|
|
(str(int('1111', 2)), 5),
|
|
(str(int('10001', 2)), 5),
|
|
(str(int('111110', 2)), 7),
|
|
(str(int('101111', 2)), 7),
|
|
(str(int('1101111', 2)), 9),
|
|
(str(int('10001000', 2)), 8),
|
|
(str(int('11001100', 2)), 10),
|
|
(str(int('10101010', 2)), 10),
|
|
(str(int('11011000', 2)), 10),
|
|
(str(int('10000000', 2)), 7),
|
|
]
|
|
|
|
for i, o in tests:
|
|
result = solution(i)
|
|
print (i, result == o, result, o)
|