Числа с несколькими сериями единиц


30

задача

Найдите набор чисел, такой, что двоичное представление содержит два или более серий, 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

Это - ответ с наименьшим количеством байтов выигрывает.


Я думаю, что вы пропустили 23 для п = 5.
xnor

@xnor ты прав. Спасибо, и да, это также делает его не эквивалентным A094695. Хм. oeis.org/A101082 vs oeis.org/A166934

@VTCAKAVSMoACE да. Если кто-то \nразделяет и ставит \nв последнюю строку, то ,и ,трейлинг должен быть приемлемым. Обновлено.

1
Может ли ввод быть в виде списка как [1, 2, 3]?
kirbyfan64sos

@ kirbyfan64sos да. Обновлено.

Ответы:


7

Pyth, 12 байт

f<2r.BT8U^2Q

Попробуйте онлайн.

идея

Двоичное представление любого положительного числа всегда начинается с цикла 1 с, за которым, возможно, следуют другие, чередующиеся последовательности 0 и 1 с. Если есть хотя бы три отдельных цикла, два из них гарантированно будут выполняться в течение 1 с.

Код

              (implicit) Store the evaluated input in Q.
         ^2Q  Calculate 2**Q.
f       U     Filter; for each T in [0, ..., 2**Q-1]:
    .BT         Compute T's binary representation.
   r   8        Perform run-length encoding.
                This returns a list of character/run-length pairs.
 <2             Discard the trailing two pairs.
                This returns a non-empty array if there are more than 2 runs.
              Keep T if the array was truthy (non-empty).

22

Python, 48

lambda n:[i for i in range(2**n)if'01'in bin(i)]

Я очень задумался над этим. Нам просто нужно проверить, содержит ли двоичное расширение '01'.

Для того, чтобы было два прогона, перед правой должна стоять буква a 0. Если будет только один забег, не будет никаких ведущих 0, так что этого не произойдет.


Старый ответ:

lambda n:[i for i in range(2**n)if len(set(bin(i).split('0')))>2]

Двоичное представление Python работает очень хорошо здесь. Двоичное число пишется как bin(9)=='0b10110'. Разделение на '0'результаты в списке

  • Пустые строки слева от инициала 0, между любыми двумя последовательными 0и справа от любого финала0
  • За буквой bследует один или несколько ведущих
  • Беги 1, которые не ведут

Первые две категории всегда существуют, но последняя существует только в том случае, если есть прогон 1, в котором нет ведущего '1', и так только в том случае, если имеется более одного прогона 1. Таким образом, достаточно проверить, содержит ли список больше, чем 2отдельные элементы.

Python 3.5 сохраняет 2 символа, распаковывая {*_}вместо set(_).


Спасибо за идею использовать /01/вместо /10+1/. Я воспользовался этим в Perl .
msh210

13

Рубин, 44 40 38 символов

вычеркнуто 44 все еще регулярно 44; (

->n{(0..2**n).select{|x|/01/=~'%b'%x}}

Анонимная функция (фактически, proc), которая принимает целое число и возвращает массив.

Использует регулярное выражение /10+1/: a 1, по крайней мере, один 0, а затем другой 1. @histocrat указывает, что если 01где-либо в строке, перед ним должно быть 1где-то.


1
Используя формат строки немного короче здесь: /10+1/=~'%b'%x. Кроме того, вы можете сохранить персонажа с помощью включающего range ( 0..2**n), так 2**nкак никогда не будет несколько прогонов.
гистократ

@histocrat Да, я никогда не знал, что вы можете изменить порядок строк и регулярных выражений с помощью =~. Благодарность!
Дверная ручка

1
Подождите, на самом деле регулярное выражение /01/работает так же хорошо. Если есть, 01то где-то слева должна быть 1.
гистократ

@histocrat О, это умно! Это спасает двух персонажей.
Дверная ручка

7

Юлия, 43 41 байт

n->filter(i->ismatch(r"01",bin(i)),1:2^n)

Это создает безымянную функцию, которая принимает целое число и возвращает массив. Он использует трюк регулярных выражений гистократов (используется в ответе Doorknob), где 01будет совпадать, только если есть предшествующий 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

Трюк гистократа, а не мой. :)
Дверная ручка

@ Doorknob О, эй, теперь вы оба получили кредит. :)
Алекс А.

6

Матлаб, 79 68 64 59

Идея состоит в том, чтобы интерпретировать двоичное число как массив нулей и единиц, а затем вычислить абсолютную разницу между каждой парой соседей. Если у нас есть разность, равная 1, в два или более раз, то, очевидно, мы имеем два или более раз. Обратите внимание, что это работает, только если мы представляем двоичное число без начальных нулей.

@(n)find(arrayfun(@(k)sum(~~diff(dec2bin(k)+0))>1,1:2^n-1))

Старые версии:

k=1:2^input('')-1;k(arrayfun(@(k)sum(~~diff(dec2bin(k)+0))>1,k))

for k=1:2^input('')-1;if sum(~~diff(dec2bin(k)+0))>1;disp(k);end;end

for k=1:2^input('')-1;if sum(~~conv(dec2bin(k)+0,[-1,1],'v'))>1;disp(k);end;end

6

JavaScript (ES7), 89 85 72 69 62 байта

Святая корова, создавать диапазоны в JS не просто. Возможно, это было бы короче с реальной forпетлей. Нет, я солгал; это на самом деле немного дольше. Ну что ж. Я думаю, мне просто придется согласиться на 27 сохраненных байтов. (7 благодаря Mwr247!)

x=>[for(a of Array(1<<x).keys())if(/01/.test(a.toString(2)))a]

Работает правильно в последних версиях Firefox, но, вероятно, не в любом другом браузере. Попробуйте это:

<!--                               Try the test suite below!                              --><strong id="bytecount" style="display:inline; font-size:32px; font-family:Helvetica"></strong><strong id="bytediff" style="display:inline; margin-left:10px; font-size:32px; font-family:Helvetica; color:lightgray"></strong><br><br><pre style="margin:0">Code:</pre><textarea id="textbox" style="margin-top:5px; margin-bottom:5px"></textarea><br><pre style="margin:0">Input:</pre><textarea id="inputbox" style="margin-top:5px; margin-bottom:5px">5</textarea><br><button id="testbtn">Test!</button><button id="resetbtn">Reset</button><br><p><strong id="origheader" style="font-family:Helvetica; display:none">Original Code Output:</strong><p><div id="origoutput" style="margin-left:15px"></div><p><strong id="newheader" style="font-family:Helvetica; display:none">New Code Output:</strong><p><div id="newoutput" style="margin-left:15px"></div><script type="text/javascript" id="golfsnippet">var bytecount=document.getElementById("bytecount");var bytediff=document.getElementById("bytediff");var textbox=document.getElementById("textbox");var inputbox=document.getElementById("inputbox");var testbtn=document.getElementById("testbtn");var resetbtn=document.getElementById("resetbtn");var origheader=document.getElementById("origheader");var newheader=document.getElementById("newheader");var origoutput=document.getElementById("origoutput");var newoutput=document.getElementById("newoutput");textbox.style.width=inputbox.style.width=window.innerWidth-50+"px";var _originalCode="x=>[for(a of Array(1<<x).keys())if(/01/.test(a.toString(2)))a]";function getOriginalCode(){if(_originalCode!=null)return _originalCode;var allScripts=document.getElementsByTagName("script");for(var i=0;i<allScripts.length;i++){var script=allScripts[i];if(script.id!="golfsnippet"){originalCode=script.textContent.trim();return originalCode}}}function getNewCode(){return textbox.value.trim()}function getInput(){try{var inputText=inputbox.value.trim();var input=eval("["+inputText+"]");return input}catch(e){return null}}function setTextbox(s){textbox.value=s;onTextboxChange()}function setOutput(output,s){output.innerHTML=s}function addOutput(output,data){output.innerHTML+='<pre style="background-color:'+(data.type=="err"?"lightcoral":"lightgray")+'">'+escape(data.content)+"</pre>"}function getByteCount(s){return(new Blob([s],{encoding:"UTF-8",type:"text/plain;charset=UTF-8"})).size}function onTextboxChange(){var newLength=getByteCount(getNewCode());var oldLength=getByteCount(getOriginalCode());bytecount.innerHTML=newLength+" bytes";var diff=newLength-oldLength;if(diff>0){bytediff.innerHTML="(+"+diff+")";bytediff.style.color="lightcoral"}else if(diff<0){bytediff.innerHTML="("+diff+")";bytediff.style.color="lightgreen"}else{bytediff.innerHTML="("+diff+")";bytediff.style.color="lightgray"}}function onTestBtn(evt){origheader.style.display="inline";newheader.style.display="inline";setOutput(newoutput,"");setOutput(origoutput,"");var input=getInput();if(input===null){addOutput(origoutput,{type:"err",content:"Input is malformed. Using no input."});addOutput(newoutput,{type:"err",content:"Input is malformed. Using no input."});input=[]}doInterpret(getNewCode(),input,function(data){addOutput(newoutput,data)});doInterpret(getOriginalCode(),input,function(data){addOutput(origoutput,data)});evt.stopPropagation();return false}function onResetBtn(evt){setTextbox(getOriginalCode());origheader.style.display="none";newheader.style.display="none";setOutput(origoutput,"");setOutput(newoutput,"")}function escape(s){return s.toString().replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}window.alert=function(){};window.prompt=function(){};function doInterpret(code,input,cb){var workerCode=interpret.toString()+";function stdout(s){ self.postMessage( {'type': 'out', 'content': s} ); }"+" function stderr(s){ self.postMessage( {'type': 'err', 'content': s} ); }"+" function kill(){ self.close(); }"+" self.addEventListener('message', function(msg){ interpret(msg.data.code, msg.data.input); });";var interpreter=new Worker(URL.createObjectURL(new Blob([workerCode])));interpreter.addEventListener("message",function(msg){cb(msg.data)});interpreter.postMessage({"code":code,"input":input});setTimeout(function(){interpreter.terminate()},1E4)}setTimeout(function(){getOriginalCode();textbox.addEventListener("input",onTextboxChange);testbtn.addEventListener("click",onTestBtn);resetbtn.addEventListener("click",onResetBtn);setTextbox(getOriginalCode())},100);function interpret(code,input){window={};alert=function(s){stdout(s)};window.alert=alert;console.log=alert;prompt=function(s){if(input.length<1)stderr("not enough input");else{var nextInput=input[0];input=input.slice(1);return nextInput.toString()}};window.prompt=prompt;(function(){try{var evalResult=eval(code);if(typeof evalResult=="function"){var callResult=evalResult.apply(this,input);if(typeof callResult!="undefined")stdout(callResult)}}catch(e){stderr(e.message)}})()};</script>

(Фрагмент взят с этой страницы )

Предложения приветствуются!


Вы можете использовать .keys()вместо .fill()и aвместо того, iчтобы связать мой для 62:x=>[for(a of Array(1<<x).keys())if(/01/.test(a.toString(2)))a]
Mwr247

@ Mwr247 Спасибо! Интересно, возможно ли это в возрасте до 62 ... :)
ETHproductions

6

Haskell, 68 61 53 байта

Улучшение от Дэмиена

g x|x`mod`4==1=x>4|2>1=g$x`div`2
a x=filter g[1..2^x]

История:

Это исправляет ошибку (Switched == и =, и квадрат вместо степени двух). И замените true на 2> 1 и false на 1> 2. Также спасибо за то, что 2 ^ x всегда терпит неудачу. Спасибо Томасу Ква и Ними

g x|x<5=1>2|x`mod`4==1=2>1|2>1=g$x`div`2
a x=filter g[1..2^x]

первоначально

g x|x<5=False|x`mod`4=1==True|2>1=g$x`div`2
a x=filter g[1..(x^2-1)]

Если это должно быть полная программа,

g x|x<5=False|x`mod`4==1=True|2>1=g$x`div`2
main=interact$show.a
a x=filter g[1..2^(read x)]

1
Лямбды в порядке, так как OP не указывает на написание именованной функции или программы. Кстати, добро пожаловать в PPCG!
lirtosiast

1
Я думаю, вы имеете в виду, 1..(2^x-1)что может быть просто, 1.. (2^x)так как 2 ^ х всегда терпит неудачу
lirtosiast

Вы можете заменить константы Falseи Trueна 1>2и 1<2. Нет необходимости в круглых скобках 2^x-1. (Кстати: у вас есть опечатка: это должно быть 4==1=True).
Ними

Спасибо за исправление опечатки. В мое время была поздняя ночь.
Akangka

хорошие трюки! Я думаю, вы можете уменьшить g до: gx | x mod4 == 1 = x> 4 | 2> 1 = g $ x div2
Дэмиен

5

APL, 34 27 байт

{0~⍨{⍵×2<+/2≢/⍵⊤⍨⍵/2}¨⍳2*⍵}

Это создает неназванную монадическую функцию, которая принимает целое число справа и возвращает массив.

Объяснение:

                     }¨⍳2*⍵}  ⍝ For each integer from 1 to 2^input...
              ⍵⊤⍨⍵/2         ⍝ Get the binary representation as a vector
           2≢/                ⍝ Pairwise non-match, yielding a boolean vector
       2<+/                   ⍝ Check whether the number of trues is >2
     ⍵×                       ⍝ Yield the integer if so, otherwise 0
{0~⍨{                         ⍝ Remove the zeros from the resulting array

Сохранено 7 байтов благодаря Денису!


4

R, 55 47 байт

(с некоторой помощью @ Alex.A)

cat(grep("10+1",R.utils::intToBin(1:2^scan())))

В R нет встроенной функции для удобного отображения преобразованных чисел, поэтому я использую R.utils::intToBinдля этого, в то время как все остальное в значительной степени просто сообщает о местоположении соответствующего выражения регулярного выражения и печатает в STDOUT, будучи разделенным Космос.


Я думаю, что разделитель по умолчанию для catявляется пробелом, так что вы можете ,sep=","полностью опустить , сохранив 7 байтов.
Алекс А.

@AlexA. да, так что я могу использовать пробел здесь как сеп? Я не был уверен
Дэвид Аренбург

1
ОП назвал разделитель по вашему выбору, поэтому я думаю, что пространство кажется достаточно разумным. :)
Алекс А.

Это действительно нуждается в функции кошки? без него вывод будет разделен табуляцией. Левый счетчик является частью пользовательского интерфейса, если вы запишите его в файл, он не будет включен, поэтому он не является частью вывода.
freekvd

@freekvd без него не будет печататься в STDOUT, что-то о глупых правилах этого сайта.
Дэвид Аренбург


4

JavaScript (ES6), 69 68 67 62 байта

a=>[...Array(1<<a).keys()].filter(i=>/01/.test(i.toString(2)))

Сегодня я обнаружил новый более короткий способ динамического заполнения массивов без использования заливки или карты. Doing x=>[...Array(x).keys()]вернет массив в диапазоне от 0 до x. Если вы хотите определить свой собственный диапазон / значения, используйте x=>[...Array(x)].map((a,i)=>i), так как это всего на несколько байтов длиннее.


4

Java, 214 165 155 154 148 141 110 байт

Это представление использует тот факт, что двоичное строковое представление числа в Java никогда не имеет ведущего нуля. Если строка «01» появляется в двоичном представлении числа, это должно отметить второе вхождение числа «1».

Golfed:

String f(int l){String r="";for(long i=5;i<1L<<l;++i)if(Long.toString(i,2).contains("01"))r+=i+", ";return r;}

Ungolfed:

public class NumbersWithMultipleRunsOfOnes {

  public static void main(String[] a) {
    // @formatter:off
    String[][] testData = new String[][] {
      { "3", "5" },
      { "4", "5, 9, 10, 11, 13" },
      { "5", "5, 9, 10, 11, 13, 17, 18, 19, 20, 21, 22, 23, 25, 26, 27, 29" }
    };
    // @formatter:on

    for (String[] data : testData) {
      System.out.println("Input: " + data[0]);
      System.out.println("Expected: " + data[1]);
      System.out.print("Actual:   ");
      System.out.println(new NumbersWithMultipleRunsOfOnes().f(Integer.parseInt(data[0])));
      System.out.println();
    }
  }

  // Begin golf
  String f(int l) {
    String r = "";
    for (long i = 5; i < 1L << l; ++i)
      if (Long.toString(i, 2).contains("01")) r += i + ", ";
    return r;
  }
  // End golf
}

Вывод программы (помните, что конечные разделители допустимы):

Input: 3
Expected: 5
Actual:   5, 

Input: 4
Expected: 5, 9, 10, 11, 13
Actual:   5, 9, 10, 11, 13, 

Input: 5
Expected: 5, 9, 10, 11, 13, 17, 18, 19, 20, 21, 22, 23, 25, 26, 27, 29
Actual:   5, 9, 10, 11, 13, 17, 18, 19, 20, 21, 22, 23, 25, 26, 27, 29, 

Не могли бы вы использовать intдля счетчика переменной?
flawr

Все целочисленные типы в Java без знака. Для работы с 32-битным натуральным числом требуется 64-битное long. Кроме того, использование intфактически увеличит размер кода из-за ссылки на Integerкласс-обертку, который выполняет разбор числа. Я думаю, что вероятным местом для экономии места будет регулярное выражение, но мое тестирование показало, что у меня должны быть ведущие и конечные.*

Ах да, но я думал, что вы можете использовать Longобертку с int? (Ну не в этом случае а вообще?)
flawr 21.10.15

Да, intбудет longиспользоваться при использовании в качестве параметра с Long. В этом случае, хотя на самом деле нет никакого способа использовать intиз-за знакового бита, и Integerон длиннее Long. Тем не менее, я нашел несколько способов выжать лишнее пространство из языка, столь же многословного, как Java.

Вы можете использовать new Long()вместо Long.parseLong()?
Ypnypn

4

C (gcc) , 111 99 байтов

long i,x;main(a,b)char**b;{for(;++i<1L<<atol(b[1]);x>>ffsl(~x)-1&&printf("%ld,",i))x=i>>ffsl(i)-1;}

Попробуйте онлайн!

12 байтов побрились благодаря @ceilingcat!

Ungolfed:

int main(int a, char **b) {
  for(long i = 0, x = 0; ++i < (1LL << atol(b[1])); ) {
    x = i >> (ffsl(i) - 1);
    if (x >> (ffsl(~x) - 1))
      printf("%ld,", i);
  }
}

Функция ffsl () дает вам индекс первого бита, который устанавливается в длинное целое число. Таким образом, мы делаем цикл от i = 12 ^ number_of_bits. Мы установили xна iсдвигаются вправо до тех пор, пока не будут удалены все последовательные нулевые биты на младшем конца. Затем мы сдвигаемся xвправо, пока не удалим все последовательные 1 бит на самом младшем конце. Если результат все еще ненулевой, мы нашли совпадение.


2
Я должен сказать, что мне действительно нравится, что кто-то сделал немного манипулятивный ответ, а не подход "преобразовать в строку и регулярное выражение".

@MichaelT Интересно, есть ли короткое решение, использующее только примитивные побитовые операции?
lirtosiast

@ThomasKwa Это может быть что-то сделать, как вызов кода .

Интересный. Вы также можете написать тест следующим образом: if (popcount(i ^ (i*2))>3)и расширить popcount () до серии побитовых AND и операций сдвига. Но это привело бы к довольно длинному коду.
Г. Слипен

1
@ThomasKwa y = x | (x-1), чтобы включить все самые правые 0 битов. Тогда z = y & (y + 1), чтобы отключить все завершающие 1 бит. Если z не равен нулю, то исходное число имело более одного прогона.
Алхимик

3

JavaScript (ES6) 76

f=n=>Array(1<<n).fill().map((_,x)=>/01/.test(x.toString(2))?x+',':'').join``

//TEST
for(i=1;i<16;i++)O.innerHTML+=i+' -> '+f(i)+'\n'
<pre id=O></pre>


@DLosc нет, результат будет что-то вроде,,,,,5,,,,9,10,11,,13,,,,17,18,19,20,21,22,23,,25,26,27,,29,,
edc65

3

К5, 19 байт

Это работает по тем же принципам, что и решение Денниса, но с меньшим количеством встроенных функций.

{&2<+/'~0=':'+!x#2}

Сначала сгенерируйте серию двоичных x-tuples ( +!x#2), затем для каждого кортежа найдите каждую точку, в которой цифра не соответствует предыдущей, если мы будем рассматривать -1-й элемент списка как 0 для этой цели ( ~0=':'). Наши решения, где два меньше, чем сумма каждого прогона. ( &2<+/').

Показывать каждый промежуточный шаг понятнее:

  4#2
2 2 2 2

  !4#2
(0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1
 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1
 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1)

  +!4#2
(0 0 0 0
 0 0 0 1
 0 0 1 0
 0 0 1 1
 0 1 0 0
 0 1 0 1
 0 1 1 0
 0 1 1 1
 1 0 0 0
 1 0 0 1
 1 0 1 0
 1 0 1 1
 1 1 0 0
 1 1 0 1
 1 1 1 0
 1 1 1 1)

  ~0=':'+!4#2
(0 0 0 0
 0 0 0 1
 0 0 1 1
 0 0 1 0
 0 1 1 0
 0 1 1 1
 0 1 0 1
 0 1 0 0
 1 1 0 0
 1 1 0 1
 1 1 1 1
 1 1 1 0
 1 0 1 0
 1 0 1 1
 1 0 0 1
 1 0 0 0)

  +/'~0=':'+!4#2
0 1 2 1 2 3 2 1 2 3 4 3 2 3 2 1

  2<+/'~0=':'+!4#2
0 0 0 0 0 1 0 0 0 1 1 1 0 1 0 0

  &2<+/'~0=':'+!4#2
5 9 10 11 13

И все вместе

  {&2<+/'~0=':'+!x#2}'3 4 5 
(,5
 5 9 10 11 13
 5 9 10 11 13 17 18 19 20 21 22 23 25 26 27 29)

2

Пип, 13 + 1 = 14 байтов

Принимает ввод из командной строки и использует -sфлаг для пробелов между выходными числами.

01NTB_FI,2**a

Довольно просто: строить range(2**a)и фильтровать lambda _: "01" in toBinary(_). Я был очень рад придумать 01идею самостоятельно. Кавычки не нужны, 01потому что он сканируется как числовой литерал (числа и строки одного типа в Pip).


2

Юлия, 40 байт

n->filter(i->count_ones(i$i>>1)>2,1:2^n)

При этом используется несколько иной подход к другому решению Джулии - вместо поиска строки «01» в битовой строке используется некоторая математика, чтобы определить, удовлетворяет ли число условию.

i$i>>1будут только в тех местах, где цифра меняется с нуля на единицу или с единицы на ноль. Таким образом, должно быть по крайней мере три, iчтобы переключаться между нулем и достаточным количеством раз. count_onesнаходит количество единиц, а затем filterудаляет те, которые не имеют достаточно.


2

C ++, 197 188 141 байт

Примечание: это было написано и протестировано с использованием MSVC ++ 2013. Похоже, что #includeing <iostream>включает в себя все необходимые заголовки C для этой работы. Также кажется, что код больше не является по-настоящему C ++, но компиляция с использованием C ++ допускает хитрость заголовка, которая уменьшает размер кода по сравнению с включением большего количества заголовков C.

Использование printfвместо coutтакже сохраняет пару байтов.

Golfed:

#include<iostream>
int main(int a,char**b){char c[34];for(long i=5;i<1L<<atol(b[1]);++i){_ltoa(i,c,2);if(strstr(c,"01"))printf("%ld\n",i);}}

Ungolfed:

#include <iostream>
int main(int a, char **b) {
  char c[34];
  for (long i = 5; i < 1L << atol(b[1]); ++i) {
    _ltoa(i, c, 2);
    if (strstr(c, "01"))
      printf("%ld\n", i);
  }
}

Yoiu может использовать '\n'вместо std :: endl (в общем), или ','потому что любой разделитель допустим, а завершающий - это нормально.
Г. Слипен

Вместо регулярных выражений, вы можете просто сделать это с strstr(c,"01").
Г. Слипен

@ G.Sliepen спасибо! Честно говоря, я просто скопировал свое Java-решение и преобразовал в C ++, но простое решение часто лучше. Я, наверное, сейчас должен сделать нечто подобное с Java.

Две небольшие ошибки: 1<<atol(b[1])должно быть 1L<<atol(b[1]), иначе результатом этого выражения будет 32-разрядное целое число со знаком, что означает, что код будет работать только до 2 ^ 30. Функция printf должна использоваться %ldдля правильной печати чисел от 2 ^ 31 до 2 ^ 32.
Г. Слипен

2

Perl 5, 55 53 49 47 41 байт

sprintf("%b",$_)=~/01/&&say for 0..2**<>

54 52 48 46 40 байт, плюс один для -Eфлага вместо -e.


Спасибо xnor за подсказку об использовании /01/вместо /10+1/, которая сэкономила два байта.

Спасибо Деннису за совет использовать <>вместо $ARGV[0], который сэкономил шесть байтов.


2

C, 84 81 байт

long i,j,k;main(){for(scanf("%ld",&j);++i<1L<<j;k&k+1&&printf("%ld ",i))k=i|i-1;}

Это основано на комментариях, которые я сделал к другому ответу C на этот вопрос о возможности использования простых побитовых операторов. Он работает, переключая все завершающие 0 бит на 1 в выражении i | (i-1). Затем он переключает все завершающие 1 бит на 0, используя k & (k + 1). Это приведет к нулю, если есть только один цикл единиц и ненулевой в противном случае. Я делаю предположение, что long является 64-битным, но мог бы исправить это за счет трех байтов, используя вместо этого int64_t.

Ungolfed

long i,j,k;
main()
{
    for(scanf("%ld",&j);++i<1L<<j;)
    {
        k=i|(i-1);
        if((k&(k+1)) == 0)
            printf("%d ",i);
    }
}

int64_tопределяется только если вы #include<stdint.h>. для обеспечения 64-битной работы требуется long longтип по стоимости 5 байтов.
Chqrlie

Обратите внимание, что вы вызываете неопределенное поведение, передаваемое 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;}
Chqrlie

@chqrlie Все очень хорошие моменты. Спасибо.
Алхимик


1

Python 2.7, 89 байт

print[i for i in range(1,2**input())if[n[:1]for n in bin(i)[2:].split("0")].count("1")-1]

Я думаю, что это может быть немного в гольфе.


@ mbomb007 Я попробовал это, это не сработало.
Loovjo

@ mbomb007 Вы используете Python 2.7?
Loovjo

Имеет ли значение какая версия 2.7? Я запускаю его на repl.it (2.7.2), и он не работает, но Ideone (2.7.10) работает. Это может быть просто ошибка в repl.it, но не обязательно разница в версии.
mbomb007

Ваша программа неправильно печатает 0на выходе.
mbomb007

Также 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()).
mbomb007

1

TI-BASIC, 34 32 30 байт

Для калькулятора серии TI-83 + / 84 +.

For(X,5,e^(Ans
If log(sum(2=int(4fPart(X/2^randIntNoRep(1,Ans
Disp X
End

Чтобы число содержало две серии по 1, оно должно содержать два 10s, когда мы добавляем конечный ноль в двоичное представление.

Вместо того, чтобы генерировать двоичное представление и проверять на 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:

4:prgmRUNSONES
               5
               9
              10
              11
              13

Затем калькулятор выдает ошибку; Экран ошибки выглядит следующим образом:

ERR:DOMAIN
1:Quit
2:Goto

Когда нажата 1, домашний экран снова отображается:

4:prgmRUNSONES
               5
               9
              10
              11
              13
           Error

Калькуляторы TI хранят все числа в формате BCD с точностью до 14 цифр, а не в виде целого или двоичного числа. Следовательно, деление на степени двух больше, чем 2^14может быть неточным. Несмотря на то, что я проверил, что самые хитрые числа 3*2^30-1и 2^32-1обрабатываются правильно, я не исключил возможности округления ошибок. Однако я был бы удивлен, если бы были ошибки для любого ввода.


Как вы считаете 32 байта? Для меня это выглядит как 70 (включая переводы строк).
msh210

TI-BASIC маркируется; он использует собственную кодировку символов, в которой все эти команды составляют один байт, а остальные - две. Сообщество согласилось оценивать эту кодировку - подробности см. В meta.codegolf.stackexchange.com/a/4764/39328 .
lirtosiast

О, круто. Спасибо, к вашему сведению.
msh210

1
  • это не бьет ответ Flawr, но я не мог устоять перед очарованием вопроса

MATLAB(90)(70)

j=input('');for l=2:j-1,a=1;for k=l:-1:2,a=a+2^k;a:a+2^(k-1)-2,end,end

выполнение

4

ANS =

5

ANS =

9    10    11

ANS =

13

принцип

  • Ряд чисел является результатом последовательной полосы 1, что означает f (n, l) = 2 ^ l + 2 ^ (l + 1) + .... 2 ^ n

Любое число, взятое из интервала] 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

@(n)setdiff(0:2^n-1,arrayfun(@(x)2^mod(x,(n+1)-fix(x/(n+1)))*(2^fix(x/(n+1))-1),0:(n+1)^2))

1

C, 103 102 байта

long i,x;main(int a,char**b){for(;++i<1L<<atoi(b[1]);)for(x=i;x>4&&(x%4!=1||!printf("%ld,",i));x/=2);}

Расширение (фактически сокращение) записи G.Sliepen, использование примечания xnor к 01шаблону в двоичном представлении, но с использованием только стандартных функций и некоторого изменения в битах.

Безголовая версия:

long i, x;
main(int a, char**b) {
    for (; ++i < 1L << atoi(b[1]);) {
        for (x = i; x > 4 && (x % 4 != 1 || !printf("%ld,", i)); x /= 2)
            ;
    }
}

Внутренний цикл сканирует iдвоичный шаблон 01, итеративно сдвигаясь xвправо, если у него осталось 3 бита. printfвозвращает количество напечатанных символов, следовательно, никогда 0, поэтому проверка внутреннего цикла завершается с ошибкой после printf, избегая необходимости в breakвыражении.

C ++, 129 128 байтов

Адаптируя ту же идею, вариант C ++ находится здесь:

#include<iostream>
long i,x;int main(int a,char**b){for(;++i<1L<<atoi(b[1]);)for(x=i;x>4&&(x%4!=1||!(std::cout<<i<<','));x/=2);}

Технически, я должен сделать для обеспечения 64 - разрядной операции и вычисления ДО для дополнительных 5 байт, но современные платформы имеют 64 - битные Интс.ilong long2^32


1

JavaScript ES6, 60 байт

Код

n=>[...Array(1<<n).keys()].filter(g=x=>x>4?x%4==1|g(x>>1):0)

Попробуйте онлайн!

объяснение

[...Array(1<<n).keys()]                                          Create an array of numbers from 0 to 2^n-1
                       .filter(                                  Find the numbers which meet criteria
                               g=x=>x>4?                  :0     If x is less than or equal to four return zero (false/invalid)
                                        x>4?x%4==1|              If the binary pattern ends with 01 return one (true/valid)
                                                   g(x>>1)       Otherwise bitshift right by one and try again

0

C (вроде - компилируется с предупреждениями в GCC) - 103

При этом не используются никакие библиотечные функции, кроме printf. Посмотрев на это, вы увидите, что не было приложено никаких усилий для того, чтобы сделать его совместимым со стандартами или избежать UB.

x,c;main(n,v){n--;for(;c<1<<n;c++)for(v=0;v<32;v++)if(c&1<<v){if(x&&x<v&&printf("%d ",c))break;x=v+1;}}

Чтобы сделать его совместимым, вам нужно будет сделать много вещей, таких как, например, stdio.h, что противоречит духу сделать его как можно меньше.

Если у кого-то есть предложения по его сокращению, пожалуйста, дайте мне знать.


0

PowerShell, 80 байт

while([Math]::Pow(2,$args[0])-gt$n++){$n|?{[Convert]::ToString($n,2)-match"01"}}

0

Python, 44 байта

Хорошо, это может быть короче, но это мой первый Codegolf:

x=1
while True:
    if '01' in bin(x):
        print(x)
    x+=1

Думаю, это отвечает на вопрос, пожалуйста, не голосуйте, если это не так, просто опубликуйте, что с ним не так, ниже.


1
Вам нужно взять вход ( input()идеально), чтобы получить n, а затем только считать 2^n-1, а не зацикливаться бесконечно. Кроме того, вы можете использовать 1 и 2 пробела для вложения, а не 4 и 8, и использование mapили понимание списка, вероятно, значительно сократит ваш код.
Мего

0

еще один отличный ответ на этот вопрос.

MATLAB 60(57)

@(n)find(mod(log2(bitcmp(1:2^n,fix(log2(1:2^n)+1))+1),1))

выполнение

>> @(n)find(mod(log2(bitcmp(1:2^n,fix(log2(1:2^n)+1))+1),1))

ans =

@(n)find(mod(log2(bitcmp(1:2^n,fix(log2(1:2^n)+1))+1),1))

>> ans(5)

ans =

 5     9    10    11    13    17    18    19    20    21    22    23    25    26    27    29

  • Идея состоит в том, чтобы собирать числа x, где двоичное представление - (x) +1 не содержит только одного случая1

пример:

0000111отклонено, потому что ~ x = 1111, ~ x + 1 = 00001содержит одну цифру = 1

0100111принято, потому что ~ x = 1011, ~ x + 1 = 0111содержит много единиц

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.