Numbers with multiple runs of ones
Python, 48
lambda n:[i for i in range(2**n)if'01'in bin(i)]
I had been vastly overthinking this. We just need to check if the binary expansion contains '01'
.
For there to be two runs of ones, the one on the right must be preceded by a 0
. If there's only one run, there won't be any leading 0
's, so that won't happen.
Old answer:
lambda n:[i for i in range(2**n)if len(set(bin(i).split('0')))>2]
The Python binary representation works very nicely here. A binary number is written like bin(9)=='0b10110'
. Splitting at '0'
results in a list of
- Empty strings to the left of the initial
0
, between any two consecutive0
's, and to the right of any final0
- The letter
b
followed by one or more leading ones - Runs of
1
's that are not leading
The first two categories always exist, but the last one only exists if there is a run one 1
's that doesn't contain the leading '1'
, and so only if there's more than one run of 1
's. So, it suffices to check if the list contains more than 2
distinct elements.
Python 3.5 saves 2 chars by unpacking {*_}
in place of set(_)
.
Ruby, 44 40 38 chars
crossed out 44 is still regular 44 ;(
->n{(0..2**n).select{|x|/01/=~'%b'%x}}
An anonymous function (proc, actually) that takes an integer and returns an array.
Uses the regex @histocrat points out that if /10+1/
: a 1
, at least one 0
, and then another 1
.01
is anywhere in the string, there must be a 1
somewhere before it.
Julia, 43 41 bytes
n->filter(i->ismatch(r"01",bin(i)),1:2^n)
This creates an unnamed function that accepts an integer and returns an array. It uses histocrats's regex trick (used in Doorknob's answer), where 01
will only match if there's a preceding 1.
Ungolfed:
function f(n::Int)
# Take the integers from 1 to 2^n and filter them down to
# only those such that the binary representation of the integer
# matches the regex /01/.
filter(i -> ismatch(r"01", bin(i)), 1:2^n)
end