Числа з декількома прогонами одиниць


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 за n = 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

Пітона, 48

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

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

Для того, щоб було два прогони одиниць, праворуч повинен бути а 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', і так тільки, якщо є більше одного запуску 1s. Отже, достатньо перевірити, чи список містить більше, ніж 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. Крім того, ви можете зберегти персонаж, використовуючи інклюзивний діапазон ( 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)

Це створює неназвану функцію, яка приймає ціле число і повертає масив. Він використовує трюк для зворотних зразків гістократів (використовується у відповіді Дорнобба), де 01буде відповідати лише тоді, коли є попередній 1.

Безголовки:

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

@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 ^ х завжди виходить з ладу. Завдяки Томасу Ква і німі

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
Лямбди добре, оскільки в ОП не було вказано написання названої функції чи програми. До речі, ласкаво просимо до PPCG!
lirtosiast

1
Я думаю, ти маєш на увазі, 1..(2^x-1)що може бути, 1.. (2^x)оскільки 2 ^ х завжди виходить з ладу.
lirtosiast

Ви можете замінити константи Falseі Trueна, 1>2і на 1<2. Немає потреби в дужках навколо 2^x-1. (BTW: у вас помилка друку: вона повинна бути 4==1=True).
німі

Дякуємо за виправлення помилок. У мою пору була пізня ніч.
Акангка

приємні хитрощі! Я думаю, ви можете зменшити 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)))

Сьогодні я відкрив новий коротший спосіб динамічного заповнення масивів без використання заливки чи карти. Здійснення 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".

Гольф:

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;}

Безголовки:

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? (Ну не в цьому випадку, але взагалі?)
недолік

Так, 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!

Безголовки:

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 ^ число_офіцій. Ми налаштовані 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-кортежів ( +!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також економить пару байт.

Гольф:

#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);}}

Безголовки:

#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;}

Це ґрунтується на коментарях, які я зробив на іншій відповіді С на це питання щодо можливості використання простих побітових операторів. Він працює, перемикаючи всі проміжні 0 біт на 1 у операторі i | (i-1). Потім він переключає всі кінцеві 1 біт на 0 за допомогою k & (k + 1). Це призведе до нуля, якщо є лише один запуск з них, а не нуль в іншому випадку. Я припускаю, що long є 64-розрядним, але міг би виправити це за рахунок трьох байтів, використовуючи замість int64_t.

Безумовно

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

Щоб число містило два запуски з 1s, воно повинно містити два 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 цифрами точності, а не int чи двійковим поплавком. Тому поділ за потужностями на дві більше, ніж 2^14може бути неточним. Хоча я переконався, що найвибагливіші числа, 3*2^30-1і 2^32-1правильно обробляються, я не виключав можливості помилок округлення. Однак я був би здивований, якщо були б помилки для будь-якого введення.


Як ви рахуєте 32 байти? Мені схоже на 70 (включаючи новинки).
msh210

TI-BASIC є токенізованим; він використовує фірмове кодування символів, у якому всі ці команди - один байт, а інші - два. Оцінка спільноти базується за допомогою цього кодування-- детальніше див. Meta.codegolf.stackexchange.com/a/4764/39328 .
lirtosiast

О, круто. Дякую FYI.
msh210

1
  • це didnt бити відповідь flawr, але я не міг протистояти чарівності питання

матлаб(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 підтверджує цю умову, тому результат є результатом заперечення цього ряду в умови n.

х = 1

x = x + 1 = 01,

x = x + 2 ^ 0 = 11,

x = x + 1 = 001,

x = x + 2 ^ 1 = 011,

x = x + 2 ^ 0 = 111,

x = x + 1 = 0001,

x = x + 2 ^ 2 = 0011,

x = x + 2 ^ 1 = 0111,

x = x + 2 ^ 0 = 0111,

х = х + 1 = 1111...

x + 1, x = x + 2 ^ n, x = x + 2 ^ (n-1) ... x = x + 2 ^ 0

Моя програма друкує діапазон між кожними двома рядками (якщо існує)


Редагувати: на жаль, це не робить його в гольфі більше, але я хотів додати інший підхід до процедури цієї ідеї

після періоду боротьби мені вдалося знайти математичне уявлення для цієї серії, яке:

2 ^ l (0 + 1 + 2 ^ 1 + ... 2 ^ k) з l + k <n

= 2 ^ l (2 ^ k-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

Пітон, 44 байт

Гаразд, це може бути коротше, але це мій перший кодовий гольф:

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

ще одна відповідь матлабу з хорошою оцінкою.

матлаб 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містить багато 1

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.