Các số có nhiều lần chạy


30

Bài tập

Tìm tập hợp các số sao cho biểu diễn nhị phân chứa hai hoặc nhiều lần chạy 1cách nhau ít nhất một 0.

Ví dụ: các số có độ dài 4 bit:

 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)

Đầu vào

Một số nguyên được cung cấp cho ứng dụng thông qua một số đầu vào trong phạm vi 3 .. 32 . Điều này thể hiện số lượng bit tối đa để đếm đến.

Đầu vào của nchỉ ra rằng các số cần phải được kiểm tra.0 .. 2n-1

Đầu ra

Một danh sách phân định (lựa chọn của bạn) của tất cả các số đáp ứng các tiêu chí. Các số sẽ được trình bày theo thứ tự số. Một dấu phân cách thêm là chấp nhận được. Bao vây cấu trúc dữ liệu (ví dụ []và tương tự) cũng được chấp nhận.

Thí dụ

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

Đây là - câu trả lời có số lượng byte thắng ít nhất.


Tôi nghĩ bạn đã bỏ lỡ 23 cho n = 5.
xnor

@xnor bạn đúng rồi. Cảm ơn bạn và vâng, điều đó cũng làm cho nó không tương đương với A094695. Hừm. oeis.org/A101082 vs oeis.org/A166934

@VTCAKAVSMACE có. Nếu một người đang \nphân định và đặt một \ndòng cuối cùng, thì việc ,phân định bằng ,dấu cũng nên được chấp nhận. Cập nhật.

1
Đầu vào có thể ở một định dạng danh sách như thế [1, 2, 3]nào?
kirbyfan64sos

@ kirbyfan64sos có. Cập nhật.

Câu trả lời:


7

Bình thường, 12 byte

f<2r.BT8U^2Q

Hãy thử trực tuyến.

Ý kiến

Biểu diễn nhị phân của bất kỳ số dương nào luôn bắt đầu bằng một lần chạy 1 giây, có thể theo sau là các lần chạy khác, xen kẽ là 0 s và 1 s. Nếu có ít nhất ba lần chạy riêng biệt, hai trong số chúng được đảm bảo là chạy 1 giây.

              (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

Con trăn, 48

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

Tôi đã suy nghĩ rất nhiều về điều này. Chúng ta chỉ cần kiểm tra xem phần mở rộng nhị phân có chứa hay không '01'.

Để có hai lần chạy, một bên phải phải đi trước a 0. Nếu chỉ có một lần chạy, sẽ không có bất kỳ sự lãnh đạo nào 0, vì vậy điều đó sẽ không xảy ra.


Câu trả lời cũ:

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

Biểu diễn nhị phân Python hoạt động rất độc đáo ở đây. Một số nhị phân được viết như thế nào bin(9)=='0b10110'. Chia nhỏ '0'kết quả trong một danh sách

  • Các chuỗi trống ở bên trái của chữ cái đầu 0, giữa hai chuỗi bất kỳ 0và bên phải của bất kỳ trận chung kết nào0
  • Lá thư b theo sau bởi một hoặc nhiều người dẫn đầu
  • Những cuộc chạy đua 1không dẫn đầu

Hai loại đầu tiên luôn tồn tại, nhưng loại cuối cùng chỉ tồn tại nếu có một loại chạy 1không chứa hàng đầu '1', và chỉ khi có nhiều hơn một lần chạy 1. Vì vậy, nó đủ để kiểm tra xem danh sách có chứa nhiều hơn 2các yếu tố riêng biệt hay không.

Python 3.5 lưu 2 ký tự bằng cách giải nén {*_}tại chỗ set(_).


Cảm ơn ý tưởng để sử dụng /01/thay vì /10+1/. Tôi đã tận dụng điều đó ở Perl .
msh210

13

Ruby, 44 40 38 ký tự

gạch bỏ 44 vẫn là 44 thường xuyên; (

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

Một hàm ẩn danh (Proc, thực tế) lấy một số nguyên và trả về một mảng.

Sử dụng regex /10+1/: a 1, ít nhất một 0, và sau đó khác 1. @histocrat chỉ ra rằng nếu 01ở bất kỳ đâu trong chuỗi, thì phải có một 1nơi nào đó trước nó.


1
Sử dụng một chuỗi định dạng ngắn hơn một chút ở đây : /10+1/=~'%b'%x. Ngoài ra, bạn có thể lưu một ký tự bằng cách sử dụng phạm vi bao gồm ( 0..2**n) vì 2**nsẽ không bao giờ có nhiều lần chạy.
lịch sử

@histocrat Huh, tôi không bao giờ biết bạn có thể lật thứ tự của chuỗi và regex với =~. Cảm ơn!
tay nắm cửa

1
Đợi đã, thực sự regex /01/hoạt động tốt như vậy. Nếu có một 01, phải có 1 ở bên trái ở đâu đó.
lịch sử

@histocrat ơi, thật thông minh! Điều đó cứu hai nhân vật.
Doorknob

7

Julia, 43 41 byte

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

Điều này tạo ra một hàm không tên chấp nhận một số nguyên và trả về một mảng. Nó sử dụng thủ thuật regex của histocats (được sử dụng trong câu trả lời của Doorknob), trong đó01 sẽ chỉ khớp nếu có 1 trước đó.

Ung dung:

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

lừa của histocrat, không phải của tôi. :)
Doorknob

@Doorknob Oh này, bây giờ cả hai bạn đều nhận được tín dụng. :)
Alex A.

6

Matlab, 79 68 64 59

Ý tưởng là diễn giải số nhị phân là mảng số 0 và số 0, sau đó tính toán sự khác biệt tuyệt đối giữa mỗi cặp lân cận. Nếu chúng ta có hai hoặc nhiều lần chênh lệch 1, thì rõ ràng chúng ta có một hoặc hai lần trở lên. Lưu ý rằng điều này chỉ hoạt động nếu chúng ta đại diện cho số nhị phân mà không có số 0 đứng đầu.

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

Phiên bản cũ:

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 byte

Holy cow, tạo phạm vi trong JS là không dễ dàng. Có lẽ nó sẽ ngắn hơn với một forvòng lặp thực tế . Không, tôi đã nói dối; nó thực sự dài hơn một chút. Ồ tốt Tôi đoán tôi sẽ phải giải quyết cho 27 byte được lưu. (7 cảm ơn Mwr247!)

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

Hoạt động đúng trong các phiên bản Firefox mới nhất, nhưng có lẽ không phải trong bất kỳ trình duyệt nào khác. Dùng thử:

<!--                               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>

(Đoạn trích được lấy từ trang này )

Gợi ý chào mừng!


Bạn có thể sử dụng .keys()thay vì .fill()athay vì ibuộc tôi trong 62:x=>[for(a of Array(1<<x).keys())if(/01/.test(a.toString(2)))a]
Mwr247

@ Mwr247 Cảm ơn! Tôi tự hỏi nếu nó có thể ở dưới 62 ... :)
Sản phẩm ETH

6

Haskell, 68 61 53 byte

Cải thiện từ Damien

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

Lịch sử:

Điều này sửa lỗi (Switched == và =, và vuông thay vì sức mạnh của hai). Và thay thế đúng bằng 2> 1 và sai bằng 1> 2. Cũng nhờ chỉ ra rằng 2 ^ x luôn thất bại. Cảm ơn Thomas Kwa và nimi

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]

Ban đầu

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

Nếu nó phải là chương trình đầy đủ,

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
Lambdas vẫn ổn, vì OP không chỉ định viết một chức năng hoặc chương trình được đặt tên. Nhân tiện, chào mừng bạn đến với PPCG!
lirtosiast

1
Tôi nghĩ bạn có nghĩa là 1..(2^x-1)có thể chỉ 1.. (2^x)vì 2 ^ x luôn luôn thất bại.
lirtosiast

Bạn có thể thay thế các hằng số FalseTruevới 1>21<2. Không cần dấu ngoặc đơn xung quanh 2^x-1. (BTW: bạn có một lỗi đánh máy: nó phải như vậy 4==1=True).
nimi

Cảm ơn đã sửa lỗi chính tả. Đó là đêm khuya trong thời gian của tôi.
Akangka

Thủ thuật hay! Tôi nghĩ bạn có thể giảm g thành: gx | x mod4 == 1 = x> 4 | 2> 1 = g $ x div2
Damien

5

APL, 34 27 byte

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

Điều này tạo ra một hàm đơn âm không tên, chấp nhận một số nguyên ở bên phải và trả về một mảng.

Giải trình:

                     }¨⍳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

Đã lưu 7 byte nhờ Dennis!


4

R, 55 47 byte

(với một số trợ giúp từ @ Alex.A)

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

R không có chức năng tích hợp để hiển thị các số được chuyển đổi một cách thuận tiện, vì vậy tôi đang sử dụng R.utils::intToBincho việc này, trong khi tất cả phần còn lại chỉ là báo cáo vị trí của biểu thức regex phù hợp và in ra STDOUT trong khi được phân tách bằng một không gian.


Tôi nghĩ rằng dấu tách mặc định cho catlà một khoảng trắng, vì vậy bạn có thể bỏ qua ,sep=","hoàn toàn, tiết kiệm 7 byte.
Alex A.

@AlexA. yeah, vậy tôi có thể sử dụng một không gian ở đây như một sep không? Tôi không chắc chắn
David Arenburg

1
OP cho biết một sự phân định về sự lựa chọn của bạn, vì vậy tôi nghĩ rằng một không gian có vẻ đủ hợp lý. :)
Alex A.

Điều này thực sự cần chức năng mèo? không có nó, đầu ra sẽ được phân định bằng tab. Bộ đếm bên trái là một phần của giao diện người dùng, nếu bạn ghi nó vào một tệp thì điều này sẽ không được bao gồm để nó không phải là một phần của đầu ra.
freekvd

@faletvd mà không được in ra STDOUT, Đôi điều về các quy tắc ngớ ngẩn của trang web này.
David Arenburg


4

JavaScript (ES6), 69 68 67 62 byte

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

Hôm nay tôi phát hiện ra một cách ngắn hơn mới để tự động điền vào các mảng mà không cần sử dụng điền hoặc ánh xạ. Làm x=>[...Array(x).keys()]sẽ trả về một mảng từ 0 đến x. Nếu bạn muốn xác định phạm vi / giá trị của riêng mình, hãy sử dụng x=>[...Array(x)].map((a,i)=>i), vì nó chỉ dài hơn một vài byte.


4

Java, 214 165 155 154 148 141 110 byte

Đệ trình này khai thác thực tế là biểu diễn chuỗi nhị phân của một số trong Java không bao giờ có số 0 đứng đầu. Nếu chuỗi "01" xuất hiện trong biểu diễn nhị phân của một số, thì đó phải đánh dấu lần xuất hiện thứ hai của số "1".

Chơi gôn

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

Ung dung:

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
}

Đầu ra chương trình (hãy nhớ, dấu phân cách dấu được chấp nhận):

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, 

Bạn không sử dụng intcho biến đếm?
flawr

Tất cả các loại số nguyên trong Java là không dấu. Để làm việc với số nguyên dương 32 bit, cần có 64 bit long. Hơn nữa, việc sử dụng một mã intthực sự sẽ làm tăng kích thước của mã do tham chiếu Integerlớp trình bao bọc thực hiện phân tích số. Tôi nghĩ rằng nơi có khả năng tiết kiệm không gian sẽ là regex, nhưng thử nghiệm của tôi cho thấy tôi phải có sự dẫn đầu và theo dõi.*

Ồ đúng, nhưng tôi nghĩ bạn có thể sử dụng Longtrình bao bọc với int? (Cũng không phải trong trường hợp này nhưng nói chung?)
flawr

Có, intsẽ thúc đẩy longkhi được sử dụng như một tham số với Long. Trong trường hợp này mặc dù thực sự không có cách nào để sử dụng intvì bit dấu và Integerdài hơn Long. Tuy nhiên, tôi đã tìm thấy một vài cách để thu hẹp không gian thêm từ một ngôn ngữ dài dòng như Java.

Bạn có thể sử dụng new Long()thay vì Long.parseLong()?
Ypnypn

4

C (gcc) , 111 99 byte

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

Hãy thử trực tuyến!

12 byte được cảm ơn nhờ @ceilingcat!

Ung dung:

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

Hàm ffsl () cung cấp cho bạn chỉ mục của bit đầu tiên được đặt trong một số nguyên dài. Vì vậy, chúng tôi lặp từ i = 12 ^ number_of_bits. Chúng tôi đặt xthành idịch chuyển sang phải cho đến khi chúng tôi đã loại bỏ tất cả các bit 0 liên tiếp ở đầu cuối ít quan trọng nhất. Sau đó, chúng tôi dịch chuyển sang xphải cho đến khi chúng tôi đã loại bỏ tất cả 1 bit liên tiếp ở đầu cuối ít nhất. Nếu kết quả vẫn khác không, chúng tôi đã tìm thấy kết quả khớp.


2
Tôi phải nói rằng tôi thực sự thích rằng ai đó đã thực hiện một câu trả lời thao túng hơn là cách tiếp cận "chuyển đổi thành chuỗi và biểu thức chính quy".

@MichaelT Tôi tự hỏi nếu có một tiến trình ngắn chỉ sử dụng các hoạt động bitwise nguyên thủy.
lirtosiast

@ThomasKwa Đó có thể là một cái gì đó để làm như một thách thức mã .

Hấp dẫn. Bạn cũng có thể viết bài kiểm tra như thế này : if (popcount(i ^ (i*2))>3), và mở rộng popcount () thành một loạt các AND và bit hoạt động theo bit. Nhưng điều đó sẽ dẫn đến mã khá dài.
G. Sliepen

1
@ThomasKwa y = x | (x-1) để bật tất cả 0 bit ngoài cùng bên phải. Sau đó z = y & (y + 1) để tắt tất cả 1 bit trailing. Nếu z khác không, thì số ban đầu có nhiều hơn một lần chạy.
Alchymist

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 không, kết quả sẽ giống như,,,,,5,,,,9,10,11,,13,,,,17,18,19,20,21,22,23,,25,26,27,,29,,
edc65

3

K5, 19 byte

Điều này hoạt động theo các nguyên tắc tương tự như giải pháp của Dennis, nhưng với ít lợi ích hơn để tận dụng.

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

Đầu tiên, tạo một chuỗi các x-tup nhị phân ( +!x#2), sau đó cho mỗi bộ tìm thấy mọi điểm mà một chữ số không khớp với trước đó nếu chúng ta coi phần tử -1 của danh sách là 0 cho mục đích này ( ~0=':'). Giải pháp của chúng tôi là nơi hai ít hơn tổng của mỗi lần chạy. ( &2<+/').

Hiển thị từng bước trung gian rõ ràng hơn:

  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

Và tất cả cùng nhau:

  {&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

Pip, 13 + 1 = 14 byte

Lấy đầu vào từ dòng lệnh và sử dụng -scờ cho khoảng trắng giữa các số đầu ra.

01NTB_FI,2**a

Khá đơn giản: xây dựng range(2**a)và lọc trên lambda _: "01" in toBinary(_). Tôi khá hài lòng về việc nghĩ ra 01ý tưởng một cách độc lập. Không có dấu ngoặc kép nào xung quanh 01vì nó quét dưới dạng chữ số (số và chuỗi là cùng loại trong Pip).


2

Julia, 40 byte

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

Điều này sử dụng một cách tiếp cận hơi khác với giải pháp Julia khác - thay vì thực hiện tìm kiếm chuỗi "01" trong chuỗi bit, nó sử dụng một số toán học để xác định xem số đó có thỏa mãn điều kiện hay không.

i$i>>1sẽ chỉ có những cái mà chữ số thay đổi từ 0 thành một, hoặc một thành 0. Như vậy, phải có ít nhất ba cái iđể chuyển đổi qua lại giữa 0 và một lần đủ. count_onestìm thấy số lượng những cái đó, và sau đó filterloại bỏ những cái không có đủ.


2

C ++, 197 188 141 byte

Lưu ý: điều này đã được viết và kiểm tra bằng MSVC ++ 2013. Có vẻ như #includeing<iostream> bao gồm tất cả các tiêu đề C cần thiết để thực hiện công việc này. Dường như mã không còn thực sự là C ++, nhưng việc biên dịch bằng C ++ cho phép thủ thuật tiêu đề đó làm giảm kích thước mã so với việc bao gồm nhiều tiêu đề C hơn.

Sử dụng printfthay vì coutcũng tiết kiệm một vài byte.

Chơi gôn

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

Ung dung:

#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 có thể sử dụng '\n'thay vì std :: endl (nói chung) hoặc ','vì bất kỳ dấu phân cách nào là hợp lệ và một dấu phân cách là tốt.
G. Sliepen

Thay vì regex, bạn có thể làm điều đó với strstr(c,"01").
G. Sliepen

@ G.Sliepen cảm ơn! Thành thật tôi chỉ sao chép giải pháp Java của mình và chuyển đổi sang C ++, nhưng giải pháp đơn giản thường là tốt nhất. Tôi có lẽ nên làm một cái gì đó tương tự với Java bây giờ.

Hai lỗi nhỏ: 1<<atol(b[1])nên 1L<<atol(b[1]), nếu không, kết quả của biểu thức đó sẽ là số nguyên 32 bit đã ký, có nghĩa là mã sẽ chỉ chạy tối đa 2 ^ 30. Printf nên sử dụng %ldđể in các số từ 2 ^ 31 đến 2 ^ 32 một cách chính xác.
G. Sliepen

2

Perl 5, 55 53 49 47 41 byte

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

54 52 48 46 40 byte, cộng với một cho -Ecờ thay vì -e.


Cảm ơn xnor về gợi ý về việc sử dụng /01/thay vì /10+1/, đã lưu hai byte.

Cảm ơn Dennis vì lời khuyên sử dụng <>thay vì $ARGV[0], đã lưu sáu byte.


2

C, 84 81 byte

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

Điều này dựa trên các nhận xét tôi đã đưa ra về một câu trả lời C khác cho câu hỏi này về khả năng sử dụng các toán tử bitwise đơn giản. Nó hoạt động bằng cách chuyển tất cả 0 bit trailing thành 1 trong câu lệnh i | (i-1). Sau đó, nó chuyển tất cả 1 bit thành 0 bằng cách sử dụng k & (k + 1). Điều này sẽ dẫn đến số 0 nếu chỉ có một lần chạy và không khác không. Tôi thực hiện giả định rằng dài là 64 bit nhưng có thể sửa lỗi này với chi phí là ba byte bằng cách sử dụng int64_t thay thế.

Ung dung

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_tchỉ được xác định nếu bạn #include<stdint.h>. đảm bảo hoạt động 64 bit yêu cầu long longloại với chi phí 5 byte.
chqrlie

Lưu ý rằng bạn gọi hành vi không xác định chuyển long icho %dđịnh dạng. Cũng lưu ý rằng đó ()là thừa đối với các nhà khai thác &|. Sửa lỗi này tiết kiệm 3 byte! long i,j,k;main(){for(scanf("%ld",&j);++i<1L<<j;k&k+1&&printf("%ld ",i))k=i|i-1;}
chqrlie

@chqrlie Tất cả những điểm rất tốt. Cảm ơn bạn.
Alchymist


1

Python 2.7, 89 byte

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

Tôi nghĩ rằng điều này có thể được chơi golf một chút.


@ mbomb007 Tôi đã thử, nó không hoạt động.
Loovjo

@ mbomb007 Bạn có đang sử dụng Python 2.7 không?
Loovjo

Có vấn đề gì với phiên bản 2.7 không? Tôi chạy nó trên repl.it (2.7.2) và nó không hoạt động, nhưng Ideone (2.7.10) thì có. Nó có thể chỉ là một lỗi trong repl.it, không nhất thiết phải là một sự khác biệt về phiên bản.
mbomb007

Chương trình của bạn in không chính xác 0trong đầu ra.
mbomb007

Cũng print[i for i in range(2**input())if[n[:1]for n in bin(i)[2:].split("0")].count("1")-1]là hai byte ngắn hơn. Nhưng với bản sửa lỗi 0sẽ có cùng độ dài (89), nếu bạn sử dụng range(1,2**input()).
mbomb007

1

TI-BASIC, 34 32 30 byte

Đối với máy tính sê-ri TI-83 + / 84 +.

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

Để một số chứa hai lần chạy 1, nó phải chứa hai lần 10 s khi chúng ta giải quyết một số 0 ở trên biểu diễn nhị phân.

Thay vì tạo biểu diễn nhị phân và kiểm tra a 10, chúng tôi kiểm tra các cặp bit bằng toán học bằng cách sử dụng phần còn lại bằng 4 ( int(4fPart(), sẽ đưa ra 2nơi có a 10. Bởi vì chúng tôi không quan tâm đến trật tự, randIntNoRep(là cách ngắn nhất để tạo danh sách số mũ.

Chúng tôi sử dụng log(để kiểm tra số lần chạy:

  • Nếu có ít nhất 2 lần chạy thì số log(dương và số được hiển thị.

  • Nếu có một lần chạy, thì số log(0 và số này không được hiển thị.

  • Nếu không có lần chạy nào (lần đầu tiên xảy ra tại X = 2 ^ Ans), sau đó log(ném ERR: DOMAIN, dừng đầu ra ở đúng điểm.

Chúng tôi sử dụng e^(Anslàm đối số kết thúc của For(vòng lặp, nó luôn lớn hơn 2^Ans, nhưng e^(là một mã thông báo duy nhất, do đó, nó ngắn hơn một byte.

Đầu vào / đầu ra cho N = 4:

4:prgmRUNSONES
               5
               9
              10
              11
              13

Sau đó, máy tính ném một lỗi; màn hình lỗi trông như thế này:

ERR:DOMAIN
1:Quit
2:Goto

Khi nhấn 1, màn hình chính sẽ hiển thị lại:

4:prgmRUNSONES
               5
               9
              10
              11
              13
           Error

Máy tính TI lưu trữ tất cả các số trong một float BCD với độ chính xác 14 chữ số, không phải là số float hoặc nhị phân. Do đó, sự phân chia theo quyền hạn của hai lớn hơn 2^14có thể không chính xác. Mặc dù tôi đã xác minh rằng những con số khó nhất 3*2^30-12^32-1được xử lý chính xác nhưng tôi không loại trừ khả năng xảy ra lỗi làm tròn số. Tuy nhiên tôi sẽ ngạc nhiên nếu có lỗi cho bất kỳ đầu vào.


Làm thế nào để bạn đếm 32 byte? Nó trông giống như 70 đối với tôi (bao gồm cả các dòng mới).
msh210

TI-BASIC được mã hóa; nó sử dụng mã hóa ký tự độc quyền trong đó tất cả các lệnh này là một byte và mỗi lệnh khác là hai byte. Đó là sự đồng thuận của cộng đồng để ghi điểm bằng mã hóa này-- xem meta.codegolf.stackexchange.com/a/4764/39328 để biết chi tiết.
lirtosiast

Ồ tuyệt. Cảm ơn FYI.
msh210

1
  • Điều này không đánh bại câu trả lời của flawr nhưng tôi không thể cưỡng lại sự hấp dẫn của câu hỏi

chiếu(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

chấp hành

4

ans =

5

ans =

9    10    11

ans =

13

nguyên tắc

  • Chuỗi các số là kết quả của dải kết quả là 1, có nghĩa là f (n, l) = 2 ^ l + 2 ^ (l + 1) + .... 2 ^ n

Bất kỳ số nào được lấy từ khoảng] f (n, l), f (n, l) + 2 ^ (l-1) [trong đó l> 1 xác minh điều kiện này, do đó, kết quả là kết quả của việc phủ định chuỗi này trong điều khoản của n.

x = 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,

x = x + 1 = 1111...

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

Chương trình của tôi in phạm vi giữa mỗi hai dòng (nếu tồn tại)


Chỉnh sửa: thật không may, điều đó không làm cho nó được chơi nhiều hơn nhưng tôi muốn thêm một cách tiếp cận khác để thực hiện ý tưởng này

sau một thời gian đấu tranh, tôi đã thành công trong việc tìm ra một đại diện toán học cho loạt bài này:

2 ^ l (0 + 1 + 2 ^ 1 + ... 2 ^ k) với l + k <n

= 2 ^ l (2 ^ k-1)

điểm = 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 byte

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

Mở rộng (thực sự ký hợp đồng) trên mục nhập G.Sliepen, tận dụng nhận xét xnor trên 01mẫu trong biểu diễn nhị phân, nhưng chỉ sử dụng các hàm tiêu chuẩn và một số thao tác xoay đôi.

Phiên bản bị đánh cắp:

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

Vòng lặp bên trong quét icho mẫu nhị phân 01bằng cách dịch chuyển xsang phải miễn là nó có 3 bit trái. printftrả về số lượng ký tự được in, do đó không bao giờ 0, do đó, kiểm tra vòng lặp bên trong thất bại sau printf, tránh sự cần thiết phải phát breakbiểu.

C ++, 129 128 byte

Thích ứng cùng một ý tưởng, biến thể C ++ có ở đây:

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

Về mặt kỹ thuật, tôi nên làm imột long longđể đảm bảo hoạt động 64 bit và tính toán tối đa 2^32cho thêm 5 byte, nhưng các nền tảng hiện đại có ints 64 bit.


1

JavaScript ES6, 60 byte

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

Hãy thử trực tuyến!

Giải trình

[...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 (sắp xếp - biên dịch với các cảnh báo trong GCC) - 103

Điều này sử dụng không có chức năng thư viện của bất kỳ loại nào ngoại trừ printf. Bạn có thể thấy bằng cách nhìn vào điều này rằng không có nỗ lực nào được bỏ ra để làm cho nó tuân thủ các tiêu chuẩn hoặc tránh 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;}}

Để làm cho nó tuân thủ, bạn sẽ cần phải làm nhiều việc như bao gồm cả stdio.h, điều này sẽ trái với tinh thần làm cho nó nhỏ nhất có thể.

Nếu bất cứ ai có đề nghị làm cho nó ngắn hơn xin vui lòng cho tôi biết.


0

PowerShell, 80 byte

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

0

Con trăn, 44 byte

Được rồi, điều này có thể ngắn hơn nhưng đó là codegolf đầu tiên của tôi:

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

Hãy suy nghĩ điều này trả lời câu hỏi, xin vui lòng không bỏ phiếu nếu không, chỉ cần đăng những gì sai với nó bên dưới.


1
Bạn cần lấy đầu vào ( input()là lý tưởng) để có được n, và sau đó chỉ đếm đến 2^n-1, thay vì lặp vô thời hạn. Ngoài ra, bạn có thể sử dụng 1 và 2 khoảng trắng để lồng, thay vì 4 và 8, và sử dụng maphoặc hiểu danh sách có thể sẽ rút ngắn mã của bạn rất nhiều.
Mego

0

một câu trả lời khác của MATLAB về điểm số tốt.

chiếu 60(57)

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

chấp hành

>> @(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

  • Ý tưởng là chọn các số x trong đó biểu diễn nhị phân của - (x) +1 không chỉ chứa một lần xuất hiện của1

thí dụ:

0000111bị từ chối vì ~ x = 1111, ~ x + 1 = 00001chứa một chữ số = 1

0100111được chấp nhận vì ~ x = 1011, ~ x + 1 = 0111chứa nhiều 1

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.