задача
Найдите набор чисел, такой, что двоичное представление содержит два или более серий, 1
разделенных хотя бы одним 0
.
Например, для чисел длиной 4 бита:
0 0000 (no ones)
1 0001 (only one run)
2 0010 (only one run)
3 0011 (only one run)
4 0100 (only one run)
5 0101 Valid
6 0110 (only one run)
7 0111 (only one run)
8 1000 (only one run)
9 1001 Valid
10 1010 Valid
11 1011 Valid
12 1100 (only one run)
13 1101 Valid
14 1110 (only one run)
15 1111 (only one run)
вход
Целое число, предоставленное приложению через некоторый вход в диапазоне 3 .. 32
. Это представляет максимальное количество бит для подсчета до.
Ввод n
указывает, что цифры должны быть проверены.0 .. 2n-1
Выход
Разделенный (на ваш выбор) список всех номеров, соответствующих критериям. Числа должны быть представлены в числовом порядке. Допускается дополнительный конечный разделитель. Вложения структуры данных (например, []
и аналогичные) также являются приемлемыми.
пример
Input: 3
Output: 5
Input: 4
Output: 5, 9, 10, 11, 13
Input: 5
Output: 5, 9, 10, 11, 13, 17, 18, 19, 20, 21, 22, 23, 25, 26, 27, 29
Это код-гольф - ответ с наименьшим количеством байтов выигрывает.
\n
разделяет и ставит\n
в последнюю строку, то,
и,
трейлинг должен быть приемлемым. Обновлено.[1, 2, 3]
?Ответы:
Pyth, 12 байт
Попробуйте онлайн.
идея
Двоичное представление любого положительного числа всегда начинается с цикла 1 с, за которым, возможно, следуют другие, чередующиеся последовательности 0 и 1 с. Если есть хотя бы три отдельных цикла, два из них гарантированно будут выполняться в течение 1 с.
Код
источник
Python, 48
Я очень задумался над этим. Нам просто нужно проверить, содержит ли двоичное расширение
'01'
.Для того, чтобы было два прогона, перед правой должна стоять буква a
0
. Если будет только один забег, не будет никаких ведущих0
, так что этого не произойдет.Старый ответ:
Двоичное представление Python работает очень хорошо здесь. Двоичное число пишется как
bin(9)=='0b10110'
. Разделение на'0'
результаты в списке0
, между любыми двумя последовательными0
и справа от любого финала0
b
следует один или несколько ведущих1
, которые не ведутПервые две категории всегда существуют, но последняя существует только в том случае, если есть прогон
1
, в котором нет ведущего'1'
, и так только в том случае, если имеется более одного прогона1
. Таким образом, достаточно проверить, содержит ли список больше, чем2
отдельные элементы.Python 3.5 сохраняет 2 символа, распаковывая
{*_}
вместоset(_)
.источник
/01/
вместо/10+1/
. Я воспользовался этим в Perl .Рубин,
444038 символоввычеркнуто 44 все еще регулярно 44; (
Анонимная функция (фактически, proc), которая принимает целое число и возвращает массив.
Использует регулярное выражение@histocrat указывает, что если/10+1/
: a1
, по крайней мере, один0
, а затем другой1
.01
где-либо в строке, перед ним должно быть1
где-то.источник
/10+1/=~'%b'%x
. Кроме того, вы можете сохранить персонажа с помощью включающего range (0..2**n
), так2**n
как никогда не будет несколько прогонов.=~
. Благодарность!/01/
работает так же хорошо. Если есть,01
то где-то слева должна быть 1.Юлия,
4341 байтЭто создает безымянную функцию, которая принимает целое число и возвращает массив. Он использует трюк регулярных выражений гистократов (используется в ответе Doorknob), где
01
будет совпадать, только если есть предшествующий 1.Ungolfed:
источник
Матлаб,
79 68 6459Идея состоит в том, чтобы интерпретировать двоичное число как массив нулей и единиц, а затем вычислить абсолютную разницу между каждой парой соседей. Если у нас есть разность, равная 1, в два или более раз, то, очевидно, мы имеем два или более раз. Обратите внимание, что это работает, только если мы представляем двоичное число без начальных нулей.
Старые версии:
источник
JavaScript (ES7),
8985726962 байтаСвятая корова, создавать диапазоны в JS не просто.
Возможно, это было бы короче с реальнойНет, я солгал; это на самом деле немного дольше. Ну что ж. Я думаю, мне просто придется согласиться на 27 сохраненных байтов. (7 благодаря Mwr247!)for
петлей.Работает правильно в последних версиях Firefox, но, вероятно, не в любом другом браузере. Попробуйте это:
(Фрагмент взят с этой страницы )
Предложения приветствуются!
источник
.keys()
вместо.fill()
иa
вместо того,i
чтобы связать мой для 62:x=>[for(a of Array(1<<x).keys())if(/01/.test(a.toString(2)))a]
Haskell,
686153 байтаУлучшение от Дэмиена
История:
Это исправляет ошибку (Switched == и =, и квадрат вместо степени двух). И замените true на 2> 1 и false на 1> 2. Также спасибо за то, что 2 ^ x всегда терпит неудачу. Спасибо Томасу Ква и Ними
первоначально
Если это должно быть полная программа,
источник
1..(2^x-1)
что может быть просто,1.. (2^x)
так как 2 ^ х всегда терпит неудачуFalse
иTrue
на1>2
и1<2
. Нет необходимости в круглых скобках2^x-1
. (Кстати: у вас есть опечатка: это должно быть4==1=True
).mod
4 == 1 = x> 4 | 2> 1 = g $ xdiv
2APL,
3427 байтЭто создает неназванную монадическую функцию, которая принимает целое число справа и возвращает массив.
Объяснение:
Сохранено 7 байтов благодаря Денису!
источник
R,
5547 байт(с некоторой помощью @ Alex.A)
В R нет встроенной функции для удобного отображения преобразованных чисел, поэтому я использую
R.utils::intToBin
для этого, в то время как все остальное в значительной степени просто сообщает о местоположении соответствующего выражения регулярного выражения и печатает в STDOUT, будучи разделенным Космос.источник
cat
является пробелом, так что вы можете,sep=","
полностью опустить , сохранив 7 байтов.CJam, 14
На 3 байта короче благодаря Денису. Попробуйте онлайн
источник
2be`,2>
.2be`2>
и2,#)
должен работать так же. Кроме того, ОП пояснил, что вывод может быть напечатан в виде списка.JavaScript (ES6),
69686762 байтаСегодня я обнаружил новый более короткий способ динамического заполнения массивов без использования заливки или карты. Doing
x=>[...Array(x).keys()]
вернет массив в диапазоне от 0 до x. Если вы хотите определить свой собственный диапазон / значения, используйтеx=>[...Array(x)].map((a,i)=>i)
, так как это всего на несколько байтов длиннее.источник
Java,
214165155154148141110 байтЭто представление использует тот факт, что двоичное строковое представление числа в Java никогда не имеет ведущего нуля. Если строка «01» появляется в двоичном представлении числа, это должно отметить второе вхождение числа «1».
Golfed:
Ungolfed:
Вывод программы (помните, что конечные разделители допустимы):
источник
int
для счетчика переменной?long
. Кроме того, использованиеint
фактически увеличит размер кода из-за ссылки наInteger
класс-обертку, который выполняет разбор числа. Я думаю, что вероятным местом для экономии места будет регулярное выражение, но мое тестирование показало, что у меня должны быть ведущие и конечные.*
Long
обертку сint
? (Ну не в этом случае а вообще?)int
будетlong
использоваться при использовании в качестве параметра сLong
. В этом случае, хотя на самом деле нет никакого способа использоватьint
из-за знакового бита, иInteger
он длиннееLong
. Тем не менее, я нашел несколько способов выжать лишнее пространство из языка, столь же многословного, как Java.new Long()
вместоLong.parseLong()
?C (gcc) ,
11199 байтовПопробуйте онлайн!
12 байтов побрились благодаря @ceilingcat!
Ungolfed:
Функция ffsl () дает вам индекс первого бита, который устанавливается в длинное целое число. Таким образом, мы делаем цикл от
i = 1
2 ^ number_of_bits. Мы установилиx
наi
сдвигаются вправо до тех пор, пока не будут удалены все последовательные нулевые биты на младшем конца. Затем мы сдвигаемсяx
вправо, пока не удалим все последовательные 1 бит на самом младшем конце. Если результат все еще ненулевой, мы нашли совпадение.источник
if (popcount(i ^ (i*2))>3)
и расширить popcount () до серии побитовых AND и операций сдвига. Но это привело бы к довольно длинному коду.JavaScript (ES6) 76
источник
,,,,,5,,,,9,10,11,,13,,,,17,18,19,20,21,22,23,,25,26,27,,29,,
К5, 19 байт
Это работает по тем же принципам, что и решение Денниса, но с меньшим количеством встроенных функций.
Сначала сгенерируйте серию двоичных x-tuples (
+!x#2
), затем для каждого кортежа найдите каждую точку, в которой цифра не соответствует предыдущей, если мы будем рассматривать -1-й элемент списка как 0 для этой цели (~0=':'
). Наши решения, где два меньше, чем сумма каждого прогона. (&2<+/'
).Показывать каждый промежуточный шаг понятнее:
И все вместе
источник
Пип, 13 + 1 = 14 байтов
Принимает ввод из командной строки и использует
-s
флаг для пробелов между выходными числами.Довольно просто: строить
range(2**a)
и фильтроватьlambda _: "01" in toBinary(_)
. Я был очень рад придумать01
идею самостоятельно. Кавычки не нужны,01
потому что он сканируется как числовой литерал (числа и строки одного типа в Pip).источник
Юлия, 40 байт
При этом используется несколько иной подход к другому решению Джулии - вместо поиска строки «01» в битовой строке используется некоторая математика, чтобы определить, удовлетворяет ли число условию.
i$i>>1
будут только в тех местах, где цифра меняется с нуля на единицу или с единицы на ноль. Таким образом, должно быть по крайней мере три,i
чтобы переключаться между нулем и достаточным количеством раз.count_ones
находит количество единиц, а затемfilter
удаляет те, которые не имеют достаточно.источник
C ++,
197188141 байтПримечание: это было написано и протестировано с использованием MSVC ++ 2013. Похоже, что
#include
ing<iostream>
включает в себя все необходимые заголовки C для этой работы. Также кажется, что код больше не является по-настоящему C ++, но компиляция с использованием C ++ допускает хитрость заголовка, которая уменьшает размер кода по сравнению с включением большего количества заголовков C.Использование
printf
вместоcout
также сохраняет пару байтов.Golfed:
Ungolfed:
источник
'\n'
вместо std :: endl (в общем), или','
потому что любой разделитель допустим, а завершающий - это нормально.strstr(c,"01")
.1<<atol(b[1])
должно быть1L<<atol(b[1])
, иначе результатом этого выражения будет 32-разрядное целое число со знаком, что означает, что код будет работать только до 2 ^ 30. Функция printf должна использоваться%ld
для правильной печати чисел от 2 ^ 31 до 2 ^ 32.Perl 5,
5553494741 байт5452484640 байт, плюс один для-E
флага вместо-e
.Спасибо xnor за подсказку об использовании
/01/
вместо/10+1/
, которая сэкономила два байта.Спасибо Деннису за совет использовать
<>
вместо$ARGV[0]
, который сэкономил шесть байтов.источник
C,
8481 байтЭто основано на комментариях, которые я сделал к другому ответу C на этот вопрос о возможности использования простых побитовых операторов. Он работает, переключая все завершающие 0 бит на 1 в выражении i | (i-1). Затем он переключает все завершающие 1 бит на 0, используя k & (k + 1). Это приведет к нулю, если есть только один цикл единиц и ненулевой в противном случае. Я делаю предположение, что long является 64-битным, но мог бы исправить это за счет трех байтов, используя вместо этого int64_t.
Ungolfed
источник
int64_t
определяется только если вы#include<stdint.h>
. для обеспечения 64-битной работы требуетсяlong long
тип по стоимости 5 байтов.long i
для%d
формата. Следует также отметить , что()
излишни для&
и|
операторов. Исправление этого экономит 3 байта!long i,j,k;main(){for(scanf("%ld",&j);++i<1L<<j;k&k+1&&printf("%ld ",i))k=i|i-1;}
Pyth,
201716 байтовЖивая демоверсия.
источник
"01"
. За исключением 0, двоичный репр. всегда будет начинаться с 1.Python 2.7, 89 байт
Я думаю, что это может быть немного в гольфе.
источник
0
на выходе.print[i for i in range(2**input())if[n[:1]for n in bin(i)[2:].split("0")].count("1")-1]
на два байта короче. Но с фиксом для0
будет той же длины (89), если вы используетеrange(1,2**input())
.TI-BASIC,
343230 байтДля калькулятора серии TI-83 + / 84 +.
Чтобы число содержало две серии по 1, оно должно содержать два
10
s, когда мы добавляем конечный ноль в двоичное представление.Вместо того, чтобы генерировать двоичное представление и проверять на a
10
, мы тестируем пары бит математически, используя остаток от 4 (int(4fPart(
), который даст,2
где есть10
. Поскольку нас не заботит порядок,randIntNoRep(
это самый короткий способ создать список показателей.Мы используем
log(
для проверки количества прогонов:Если есть хотя бы 2 прогона, то значение
log(
положительное, и отображается номер.Если есть один прогон, то
log(
это 0, и номер не отображается.Если прогонов нет (что вначале происходит при X = 2 ^ Ans), то
log(
выдается ERR: DOMAIN, останавливая вывод в точно правильной точке.Мы используем
e^(Ans
в качестве конечного аргументаFor(
цикла - он всегда больше, чем2^Ans
, ноe^(
это один токен, поэтому он на один байт короче.Вход / выход для N = 4:
Затем калькулятор выдает ошибку; Экран ошибки выглядит следующим образом:
Когда нажата 1, домашний экран снова отображается:
Калькуляторы TI хранят все числа в формате BCD с точностью до 14 цифр, а не в виде целого или двоичного числа. Следовательно, деление на степени двух больше, чем
2^14
может быть неточным. Несмотря на то, что я проверил, что самые хитрые числа3*2^30-1
и2^32-1
обрабатываются правильно, я не исключил возможности округления ошибок. Однако я был бы удивлен, если бы были ошибки для любого ввода.источник
MATLAB
(90)(70)выполнение
4
ANS =
ANS =
ANS =
принцип
Любое число, взятое из интервала] f (n, l), f (n, l) + 2 ^ (l-1) [где l> 1 проверяет это условие, поэтому результат является результатом отрицания этого ряда в условия п.
х = 1
х = х + 1 =
01
,х = х + 2 ^ 0 =
11
,х = х + 1 =
001
,х = х + 2 ^ 1 =
011
,х = х + 2 ^ 0 =
111
,х = х + 1 =
0001
,х = х + 2 ^ 2 =
0011
,х = х + 2 ^ 1 =
0111
,х = х + 2 ^ 0 =
0111
,х = х + 1 =
1111
...x + 1, x = x + 2 ^ n, x = x + 2 ^ (n-1) ... x = x + 2 ^ 0
Моя программа печатает диапазон между каждыми двумя строками (если существует)
после периода борьбы мне удалось найти математическое представление для этой серии:
2 ^ 1 (0 + 1 + 2 ^ 1 + ... 2 ^ k) с l + k <n
= 2 ^ л (2 ^ к-1)
оценка = 90
источник
C,
103102 байтаРасширение (фактически сокращение) записи G.Sliepen, использование примечания xnor к
01
шаблону в двоичном представлении, но с использованием только стандартных функций и некоторого изменения в битах.Безголовая версия:
Внутренний цикл сканирует
i
двоичный шаблон01
, итеративно сдвигаясьx
вправо, если у него осталось 3 бита.printf
возвращает количество напечатанных символов, следовательно, никогда0
, поэтому проверка внутреннего цикла завершается с ошибкой послеprintf
, избегая необходимости вbreak
выражении.C ++,
129128 байтовАдаптируя ту же идею, вариант C ++ находится здесь:
Технически, я должен сделать для обеспечения 64 - разрядной операции и вычисления ДО для дополнительных 5 байт, но современные платформы имеют 64 - битные Интс.
i
long long
2^32
источник
JavaScript ES6, 60 байт
Код
Попробуйте онлайн!
объяснение
источник
C (вроде - компилируется с предупреждениями в GCC) - 103
При этом не используются никакие библиотечные функции, кроме printf. Посмотрев на это, вы увидите, что не было приложено никаких усилий для того, чтобы сделать его совместимым со стандартами или избежать UB.
Чтобы сделать его совместимым, вам нужно будет сделать много вещей, таких как, например, stdio.h, что противоречит духу сделать его как можно меньше.
Если у кого-то есть предложения по его сокращению, пожалуйста, дайте мне знать.
источник
PowerShell, 80 байт
источник
Python, 44 байта
Хорошо, это может быть короче, но это мой первый Codegolf:
Думаю, это отвечает на вопрос, пожалуйста, не голосуйте, если это не так, просто опубликуйте, что с ним не так, ниже.
источник
input()
идеально), чтобы получитьn
, а затем только считать2^n-1
, а не зацикливаться бесконечно. Кроме того, вы можете использовать 1 и 2 пробела для вложения, а не 4 и 8, и использованиеmap
или понимание списка, вероятно, значительно сократит ваш код.еще один отличный ответ на этот вопрос.
MATLAB
60(57)выполнение
ans =
>> ans(5)
ans =
1
пример:
0000111
отклонено, потому что ~ x =1111
, ~ x + 1 =00001
содержит одну цифру = 10100111
принято, потому что ~ x =1011
, ~ x + 1 =0111
содержит много единицисточник