xkcd 스타일 페이지 번호 매기기


65

랜달 먼로의 책 "xkcd, volume 0"은 페이지 번호에 다소 홀수 시스템을 사용합니다. 처음 몇 페이지 번호는

1, 2, 10, 11, 12, 20, 100, 101, 102, 110, 111, 112, 120, 200, 1000, 1001, ...

이 원처럼 조금 보이지만, 그가에서 건너 뛰는 것을 알 20직선로 100에서 120까지 200와에서 200까지 1000. 이 순서를 정의하는 한 가지 방법은 최대 1 개를 포함하고 그 이후로는 포함 2하지 않는 모든 3 진수를 열거하는 것 1입니다 2. 이 항목은 OEIS 항목 A169683 에서 찾을 수 있습니다 . 이 숫자 체계를 이진법이라고 합니다.

당신의 임무는 N이 숫자 체계에서 주어진 양의 정수의 표현을 찾는 것 입니다.

STDIN (또는 가장 가까운 대안), 명령 행 인수 또는 함수 인수를 통해 입력을 받고 STDOUT (또는 가장 가까운 대안), 함수 리턴 값 또는 함수 (out) 매개 변수를 통해 결과를 출력하는 프로그램 또는 함수를 작성할 수 있습니다.

출력은 문자열, 기울이기 이진 표현과 같은 소수 표현 또는 숫자 목록 (정수 또는 문자 / 문자열) 일 수 있습니다. 선행 0을 반환해서는 안됩니다.

이것은 코드 골프이므로 가장 짧은 대답 (바이트)이 이깁니다.

재미있는 사실 : 실제로이 숫자 체계에는 몇 가지 장점이 있습니다. 숫자를 증가 시키면 항상 최대 두 개의 인접한 숫자가 변경됩니다. 전체 숫자를 통해 변경을 수행 할 필요는 없습니다. O (1)에서 증분 할 수있는 올바른 표현.

테스트 사례

1 => 1
2 => 2
3 => 10
6 => 20
7 => 100
50 => 11011
100 => 110020
200 => 1100110
1000 => 111110120
10000 => 1001110001012
100000 => 1100001101010020
1000000 => 1111010000100100100
1048576 => 10000000000000000001

1000000000000000000 => 11011110000010110110101100111010011101100100000000000001102

마지막 테스트 사례 (및 비슷한 규모의 다른 입력을 하드 코딩에 대해 생각하지 마십시오)를 해결할 수있는 가장 짧은 대답에 현상금을 줄 것입니다.

리더 보드

다음은 일반 리더 보드와 언어 별 수상자 개요를 생성하는 스택 스 니펫입니다.

답변이 표시되도록하려면 다음 마크 다운 템플릿을 사용하여 헤드 라인으로 답변을 시작하십시오.

# Language Name, N bytes

N제출물의 크기는 어디에 있습니까 ? 점수를 높이면 헤드 라인을 쳐서 오래된 점수를 유지할 수 있습니다. 예를 들어 :

# Ruby, <s>104</s> <s>101</s> 96 bytes

<script>site = 'meta.codegolf'; postID = 5314; isAnswer = true; QUESTION_ID = 51517</script><script src='https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js'></script><script>jQuery(function(){var u='https://api.stackexchange.com/2.2/';if(isAnswer)u+='answers/'+postID+'?order=asc&sort=creation&site='+site+'&filter=!GeEyUcJFJeRCD';else u+='questions/'+postID+'?order=asc&sort=creation&site='+site+'&filter=!GeEyUcJFJO6t)';jQuery.get(u,function(b){function d(s){return jQuery('<textarea>').html(s).text()};function r(l){return new RegExp('<pre class="snippet-code-'+l+'\\b[^>]*><code>([\\s\\S]*?)</code></pre>')};b=b.items[0].body;var j=r('js').exec(b),c=r('css').exec(b),h=r('html').exec(b);if(c!==null)jQuery('head').append(jQuery('<style>').text(d(c[1])));if (h!==null)jQuery('body').append(d(h[1]));if(j!==null)jQuery('body').append(jQuery('<script>').text(d(j[1])))})})</script>


32
나는 그 책이 처음 나온 이후로 책 번호를 매기 지 않았지만 그 책을 가지고있었습니다.
Alex A.

2
@AlexA. 재미있는 페이지 번호 매기기를 할 수없는 Kindle에 있습니다.
LegionMammal978

21
@ LegionMammal978 : 비극적입니다.
Alex A.

1
@ SuperJedi224 컨센서스는 no로 보입니다. 죄송합니다 (언어가 처리 할 수있는 유일한 입력 인 경우 컨센서스에서 예외를 만들지 만, 그렇지 않은 것 같습니다).
Martin Ender 2016 년

4
이것은 내가 3 살 때 어떻게 계산했는지를 떠올리게한다. 나는 "오십이 없어, 아홉 후에는 백 백이되어야한다"고 추론했다. 59->60109->1100 사이의 차이를 보았을 때 실수 만 깨달았습니다.
Cyoce

답변:


12

Pyth, 17 바이트

Ljb3ye.f!-P-yZ01Q

이것은 다소 엄청나게 느리다 O(output^log_2(3)). 입력 길이는 지수이지만 페이지의 일부 답변과 같이 이중 지수는 아닙니다. @Dennis의 답변에서 가져온 아이디어, here .

데모.

그것은 사용하게 .f기능을 "n 개의 일치가 발견 될 때까지 루프"Pyth의를.


32

CJam, 24 23 22 21 19 바이트

ri_)2b,,W%{2\#(md}/

이것은 O (log n) 방식이며, 여기서 n 은 입력이며 마지막 테스트 사례를 즉시 완료합니다. 숫자 1 값으로 모듈 식 나누기를 사용하여 n 을 스큐 이진수 로 직접 변환 합니다.

이 코드는 Java 인터프리터를 사용하여 STDERR로 이동하는 오류로 끝나며 Meta 에 대한 합의에 따라 허용됩니다 .

CJam 인터프리터 에서이 코드를 시도 하면 마지막 출력 줄을 제외한 모든 것을 무시하십시오.

오류가 앞에 추가하여, 2 바이트의 비용으로 제거 할 수 2>W%.

1 바이트를 골라 낸 @ MartinBüttner에게 감사합니다.

배경

스큐 이진 표현 k는 ... 0 정수에 대응하고 , N = (2 K + 1 -1)은 K + ... + (2 1 -1) 0 .

두 사람 (2 K -1) + ... + (2 1 -1) = 2 K + 1 - (K + 2)(2 K -1) + ... + 2 (2 , J -1) = 2 K + 1 - (2- J + 1 - 2 J + K + 1) 이다 미만 2 1 + K -1 의 값 K0 으로 연속 모듈 분할에 의해 회수 될 수있다 (2) K + 1 -1 , 2 k -1

시작하려면 먼저 2 k + 1 -1 값을 찾아야합니다 . 이후 , n이 최대 인 2 (2 K + 1 -1) , 정수 N + 1 보다 확실히 작아야 2 K + 2 .

따라서 n + 1 의 이진 로그의 정수 부분을 취 하면 k + 1이 됩니다.

마지막으로, 정수 n + 1밑이 2에 ⌊log 2 (n + 1) ⌋있음 을 관찰합니다 .

작동 원리

ri    e# Read an integer N from STDIN.
2b,   e# Push the number of binary digits of N + 1, i.e, K + 2 = log(N + 1) + 1.
,W%   e# Push the range [K+1 ... 0].
{     e# For each J in the range:
  2\# e#   J -> 2**J
  (   e#     -> 2**J - 1
  md  e#   Perform modular division of the integer on the stack (initially N)
      e#   by 2**J - 1: N, 2**J - 1 -> N/(2**J - 1), N%(2**J - 1)
}/    e#

마지막 두 번의 반복에서 10으로 모듈 식 나누기를 수행 합니다. 첫 번째는 스택 에서 원하지 않는 0 을 푸시합니다 . 마지막 실행 시도 는 스택에서 0 0 md원치 않는 0을 모두 팝하고 아무것도 밀지 않고 즉시 종료하고 스택을 STDOUT에 덤프합니다.


28

파이썬 2, 67 바이트

def f(n):x=len(bin(n+1))-3;y=2**x-1;return n and n/y*10**~-x+f(n%y)

주어진 테스트 사례에서 작동하는 것 같습니다. 내가이 권리를 가지고 있다면 이것은 대략이어야 O(place values set in output)하므로 마지막 경우가 쉽습니다.

처럼 전화하십시오 f(100). 기울이기 이진과 같은 십진수 표현을 반환합니다.

파이썬 3, 65 바이트

def g(n,x=1):*a,b=n>x*2and g(n,x-~x)or[n];return a+[b//x,b%x][:x]

약간 덜 효율적이지만 여전히 로그이므로 마지막 사례는 거의 즉각적입니다.

처럼 전화하십시오 g(100). 자릿수 목록을 반환합니다.


않습니다 2and3 컴파일? 나는 2에 ​​있고 2and2구문 오류가 발생합니다
TankorSmash

3
@TankorSmash는 2and2이 같은 분석 얻을 것 때문에 작동하지 않을 것입니다 2 and2시도 - 2and 2파이썬 버전 (파이썬 2.7.10에서 테스트) 충분히 새로운 경우 작동해야하는
SP3000

오, 네 말이 맞아 2.7.3에서도 작동합니다.
TankorSmash

12

CJam, 22 21 20 바이트

ri_me,3fb{0-W<1-!},=

이것은 O (e n n) 접근 방식이며, 여기서 n 은 입력입니다. 그것은 제 나열 ⌊e N ,베이스 (3)의 음이 아닌 정수를 제거 것들 2 개 (S) 또는 1 개 제 후에들 (2) (있는 경우)를 선택하고, N + 1 번째를 .

CJam 통역사 에서 온라인으로 사용해보십시오 .

작동 원리

ri    e# Read an integer N from STDIN.
_me,  e# Push [0 ... floor(exp(N))-1].
3fb   e# Replace each integer in the range by the array of its digits in base 3.
{     e# Filter; for each array A:
  0-  e#   Remove all 0's.
  W<  e#   Remove the last element.
  1-  e#   Remove all 1's.
  !   e#   Logical NOT. Pushes 1 iff the array is empty.
},    e#   If ! pushed 1, keep the array.
=     e# Select the (N+1)th element of the filtered array.

9

Pyth, 20 바이트

Jt^2hslhQ#p/=%QJ=/J2

최종 테스트 케이스의 경우 1 초 미만인 O (log (input ()))에서 실행됩니다. 오류 루프까지 실행을 기준으로합니다. 후행 줄 바꿈이 없습니다.

데모.

설명:

Jt^2hslhQ#p/=%QJ=/J2
                        Implicit: Q is the input.
      lhQ                          log(Q+1,2)
     slhQ                    floor(log(Q+1,2))
    hslhQ                    floor(log(Q+1,2))+1
  ^2hslhQ                 2^(floor(log(Q+1,2))+1)
 t^2hslhQ                 2^(floor(log(Q+1,2))+1)-1
Jt^2hslhQ               J=2^(floor(log(Q+1,2))+1)-1
         #              until an error is thrown:
            =%QJ        Q=Q%J
                =/J2    J=J/2
           /            The value Q/J, with the new values of Q and J.
          p             print that charcter, with no trailing newline.

J는 입력보다 큰 가장 작은 스큐 이진수 위치 값으로 초기화됩니다. 그런 다음 루프를 통과 할 때마다 다음을 수행합니다.

  • 값의 각 숫자를 제거 J에서 Q=%QJ. 예를 들어 if Q=10J=7, Q3에서 110로 바뀌는 기울이기 바이너리에 해당 합니다 10. 이것은 첫 번째 반복에는 영향을 미치지 않습니다.
  • J을 사용하여 다음으로 작은 이진 기본 값으로 변경하십시오 =/J2. 이 변경에 의해 2 분할되어 낭패 J=7J=3들면. 이것은 첫 번째 숫자가 출력되기 전에 발생하기 때문에 J필요한 것보다 한 자리 높은 위치에 초기화됩니다.
  • /QJ(실제로) 실제 숫자 값을 찾으십시오 .
  • p후행 줄 바꿈을 피하기 위해 Pyth의 기본 인쇄 대신으로 해당 값을 인쇄하십시오.

이 루프는 J0이 될 때까지 반복 되어 0으로 나누기 오류가 발생하고 루프가 종료됩니다.


8

ES6, 105 바이트

f=n=>{for(o=0;n--;c?o+=Math.pow(3,s.length-c):o++)s=t(o),c=s.search(2)+1;return t(o);},t=a=>a.toString(3)

사용법은 f(1048576)=>` "10000000000000000001"

자신의 위험에 따라 마지막 논증을 테스트하십시오. 나는 5 초 후에 포기했다.

그리고 주석과 함께 예쁜 인쇄!

f=n=>{ //define function f with input of n (iteration)
    for(o=0; //define o (output value in decimal)
        n--; //decrement n (goes towards falsy 0) each loop until 0
        c?o+=Math.pow(3,s.length-c):o++) //if search finds a 2, increment output by 3^place (basically moves the 2 to the left and sets the place to 0), else ++
        s=t(o), //convert output to base 3      
        c=s.search(2)+1; //find the location of 2, +1, so a not-found becomes falsy 0.
    return t(o); //return the output in base 3
},

t=a=>a.toString(3);  //convert input a to base 3

5
Btw, 명명되지 않은 함수는 완벽하게 수용 가능하므로 필요하지 않습니다 f=.
Martin Ender 2016 년

2
-16 바이트 :f=n=>{for(o=0;~n--;o+=c?Math.pow(3,s.length+c):1)s=o.toString(3),c=~s.search(2);return s}
nderscore

@nderscore 꽤 멋진 : D
Compass

1
-7 바이트 당신은 ES7를 사용하는 경우 : 교체 Math.pow(3,s.length+c)와 함께 3**(s.length+c).
Gustavo Rodrigues

3
@GustavoRodrigues ES6 학습을 마치지 못했습니다! @ _ @
나침반

7

레티 나, 55 바이트

^
0a
(+`12(.*a)1
20$1
0?2(.*a)1
10$1
0a1
1a
)`1a1
2a
a
<empty line>

단항으로 입력합니다.

각 줄은 자체 파일로 이동해야하지만 -s플래그를 사용하여 코드를 하나의 파일로 실행할 수 있습니다 . 예 :

> echo 11111|retina -s skew
12

방법 : 문자열에서 시작하여 문자열 입력 횟수만큼 증분을 실행합니다 0.

다음과 같은 증분 규칙을 사용합니다.

  • 포함하는 경우 2: ^2 -> ^12; 02 -> 12;12 -> 20
  • 다음을 포함하지 않는 경우 2: 0$ -> 1$;1$ -> 2$

(이 최대 하나가 될 수 있습니다 2문자열, ^그리고 $규칙에 문자열의 시작과 끝을 표시합니다.)

Retina에 대한 추가 정보.


7

자바, 154 (148)

n->{String s="0";for(;n-->0;)s=s.contains("2")?s.replaceAll("(^|0)2","10").replace("12","20"):s.replaceAll("1$","2").replaceAll("0$","1");return s;}

이 답변은 정수 인수를 사용하여 답변을 문자열로 반환하는 단일 익명 함수의 형태를 취합니다. 아래는이 솔루션을 테스트하기위한 완벽한 클래스입니다.

import java.util.function.Function;
public class Skew {
    public static void main(String[] args){
        Function<Integer,String> skew = n->{String s="0";for(;n-->0;)s=s.contains("2")?s.replaceAll("(^|0)2","10").replace("12","20"):s.replaceAll("1$","2").replaceAll("0$","1");return s;};

        for(String s:args){
            System.out.println(skew.apply(Integer.parseInt(s)));
        }
    }
}

5

배쉬 + 코어 유틸리티, 52

dc -e3o0[r1+prdx]dx|grep -v 2.\*[12]|sed -n $1{p\;q}

이것은 무차별 강제이므로 큰 숫자의 경우 속도가 느립니다.

산출:

$ ./xkcdnum.sh 1000
111110120
$ 

5

자바, 337 335 253 246 244 바이트

색인을 a로 가져 와서 long결과를 문자열로 리턴하는 메소드

long인덱스에 a 를 사용 하므로 이론적 으로 마지막 테스트 사례를 처리 할 수 있지만 실제로 제안하지는 않습니다.

String f(long i){List<Long>l=new ArrayList<>();l.add(0L);for(;i-->0;){int j=l.indexOf(2);if(j!=-1){l.set(j,0L);if(j==0){l.add(0,1L);}else{l.set(j-1,l.get(j-1)+1);}}else{j=l.size()-1;l.set(j,l.get(j)+1);}}String s="";for(long q:l)s+=q;return s;}

4
전체 프로그램 대신 함수로 만들고 (스캐너 대신 인수로 입력을 사용하여)이를 약간 단축 할 수 있습니다.
Geobits 2016 년

2
if(j == 0) 명령문에 중괄호가 필요하지 않습니다 (4 바이트). 선언 할 필요는 없습니다 k. j다시 사용할 수 있습니다 (4 개 이상). List 선언 ( new ArrayList<>();) (또 다른 4)에 일반 유형 유추 (Java 7)를 사용할 수 있습니다.
durron597

4

하스켈, 73 72

1 바이트의 @nimi에게 감사드립니다!

이 솔루션은 현상금을 얻지 못할 것입니다. 마지막 몇 테스트는 실행하는 데 많은 시간이 걸리지 만 골프를 잘했다고 생각합니다.

i(2:b)=1:0:b
i[b]=[b+1]
i(b:2:c)=b+1:0:c
i(b:c)=b:i c
s=(iterate i[0]!!)

이 솔루션은 n0 n배 증가 하여 기울이기 이진수를 계산하는 다소 순진한 방법입니다 .


4

CJam, 24 바이트

Q{0\+2a/())+a\+0a*}ri*si

이것은 O (n log n) 접근법이며, 여기서 n 은 입력입니다. 스큐 이진 표현 0으로 시작 하여 해당 정수를 n 배 증가시킵니다 .

CJam 통역사 에서 온라인으로 사용해보십시오 .

배경

비대칭 이진수로 숫자를 늘리려면 다음 두 단계를 수행하면됩니다.

  1. 결과적으로 20 으로 바꿉니다 .

  2. 경우 (2) 대체되었다, 그 왼쪽에있는 숫자를 증가.

    그렇지 않으면 마지막 숫자를 증가시킵니다.

작동 원리

Q     e# Push an empty array.
{     e# Define an anonymous function:
  0\+ e#   Prepend a 0 to the array.
  2a/ e#   Split the array at 2's.
  (   e#   Shift out the first chunk of this array.
  )   e#   Pop the last digit.
  )+  e#   Increment it and append it to the array.
  a\+ e#   Prepend the chunk to the array of chunks.
  0a* e#   Join the chunks, using [0] as separator.
      e#   If there was a 2, it will get replaced with a 0. Otherewise, there's
      e#   only one chunk and joining the array dumps the chunk on the stack.
}     e#
ri*   e# Call the function int(input()) times.
si    e# Cast to string, then to integer. This eliminates leading 0's.

4

VBA, 209 (147) 142 바이트

Sub p(k)
For i=1To k
a=StrReverse(q)
If Left(Replace(a,"0",""),1)=2Then:q=q-2*10^(InStr(a,2)-1)+10^InStr(a,2):Else:q=q+1
Next
msgbox q
End Sub

수학은 비효율적이며 골프는 일을 할 수 있습니다. 그러나 그것은 PoG에서 처음 시도한 것이며 이것으로 시도해 볼 것이라고 생각했습니다. 그래도 무차별 대입 방식.

마지막 숫자가 2가 아니라면 2 씩 뒤로 이동하고 10을 앞으로 건너 뛰지 않는 한 1로 계산됩니다.

VBA는 과학적 표기법으로 출력을 요구하기 때문에 65534에서 작동을 멈 춥니 다.

골프 제안을 기대할 때 VBA는 골프 친화적이지 않지만 자주 표현되지는 않으며 Java를 오랫동안 이길 수 있다고 생각합니다.

EDIT1가 : 감사 마누을 돕는 62 바이트를 면도

Edit2 : 출력으로 교체 debug.print했습니다 msgbox. 5 바이트 저장


1
에서 괄호를 제거 할 수 있습니다 Debug.Print (q). 또한 대부분의 공백을 제거 할 수 있습니다 (편집기는이를 다시 배치하지만 필요하지는 않습니다). 선언 할 필요없이 k as Long간단히 쓰십시오 k. Variant 유형의 변수이며 코드는 여전히 작동합니다. 이 팁을 사용하면 ~ 165 바이트까지 줄어 듭니다.
CommonGuy

더 많은 생각 :의 첫 번째와 마지막 주장을 InStr생략 할 수 있으며 선택 사항입니다. Trim()공백이 없기 때문에 필요하지 않습니다. 올바르게 적용 하면 147 바이트가 됩니다.
CommonGuy

1
한 가지 간단한 질문 인 도움말 Manu에 감사합니다. 출력은 표준 출력이어야합니다. VBA에 무엇이 있는지 잘 모르겠습니다. debug.print q표준 출력입니까? msgbox q짧지 만 다시 표준 출력이 아닌 것 같습니다. 일반적인 출력 Sheet1.cells(1,1)처럼 보이지만 Excel에서 실행되는 것으로 가정합니다. 나는 이런 종류의 것들에 대해 얼마나 엄격한 코드 골프가 있는지 잘 모르겠습니다.
JimmyJazzx 2016 년

축하합니다. Java 답변을 이겼습니다 MsgBox.
CommonGuy 2016 년

4

자바 스크립트 ES6, 99 86 78 76 72 자

f=n=>{for(s="1";--n;s=s.replace(/.?2|.$/,m=>[1,2,10][+m]||20));return s}

// Old version, 76 chars:
f=n=>{for(s="1";--n;s=s.replace(/02|12|2|.$/,m=>[1,2,10][+m]||20));return s}

// Old version, 86 chars:
f=n=>{for(s="1";--n;s=s.replace(/(02|12|2|.$)/,m=>[1,2,10,,,,,,,,,,20][+m]));return s}

// Old version, 99 chars:
f=n=>{for(s="1";--n;s=s.replace(/(^2|02|12|20|.$)/,m=>({0:1,1:2,2:10,12:20,20:100}[+m])));return s}

테스트:

;[1,2,3,6,7,50,100,200,1000,10000,100000,1000000,1048576].map(f) == "1,2,10,20,100,11011,110020,1100110,111110120,1001110001012,1100001101010020,1111010000100100100,10000000000000000001"

재미있는 사실 : 실제로이 숫자 체계에는 몇 가지 장점이 있습니다. 숫자를 증가 시키면 항상 최대 두 개의 인접한 숫자가 변경됩니다. 전체 숫자를 통해 변경을 수행 할 필요는 없습니다. O (1)에서 증분 할 수있는 올바른 표현.

사실에 감사드립니다-그것은 내 솔루션의 기초입니다 :)


정규식에 불필요한 괄호를 어떻게 남길 수 있습니까? o_O
Qwertiy

3

옥타브, 107101 바이트

내가 이것을 올바르게 이해한다면 O (log n) 이어야합니다 ...

function r=s(n)r="";for(a=2.^(uint64(fix(log2(n+1))):-1:1)-1)x=idivide(n,a);r=[r x+48];n-=x*a;end;end

예쁜 인쇄 :

function r=s(n)
  r="";
  for(a=2.^(uint64(fix(log2(n+1))):-1:1)-1)
    x=idivide(n,a);
    r=[r x+48];
    n-=x*a;
  end
end

Octave는 기본적으로 모든 것을 부동 소수점 숫자로 취급하고 마지막 숫자를 계산하는 데 필요한 정밀도가 없기 때문에 최종 과제를 해결하는 데 다소 어려움을 겪었습니다. 나는 모든 것을 부호없는 정수로 만들기 위해 소중한 바이트를 소비함으로써 그 문제를 해결했습니다. 마지막 것의 결과는 숫자로 취급하기에 너무 커서 결과는 문자열입니다.

출력 (나는 그것을 1e18 - 1정확하게 할 수 있음을 보여주기 위해 포함 하고 있으며 마지막 출력 세트는 그 값을 계산하는 데 걸리는 시간을 보여줍니다) :

octave:83> s(uint64(1e18))
ans = 11011110000010110110101100111010011101100100000000000001102

octave:84> s(uint64(1e18)-1)
ans = 11011110000010110110101100111010011101100100000000000001101

octave:85> tic();s(uint64(1e18)-1);toc()
Elapsed time is 0.0270021 seconds.

3

T-SQL, 221 189 177 바이트

편집 :이 코드의 원래 버전은 일부 숫자에 대해 잘못된 출력을 생성합니다.이 수정되었습니다.

여기에 모든 쿼리마다 첫 번째 쉼표 앞에 계산할 숫자를 추가하십시오.

누구나 T-SQL이 최고의 골프 ​​언어라는 것을 알고 있습니다. 마지막 테스트 사례까지 계산할 수있는 버전이 있습니다. 내가 테스트 한 컴퓨터에서 1 초 안에 실행되었으므로 다른 사람이 어떻게 작동하는지 관심이 있습니다.

DECLARE @ BIGINT=,@T VARCHAR(MAX)='';WITH M AS(SELECT CAST(2AS BIGINT)I UNION ALL SELECT I*2FROM M WHERE I<@)SELECT @T += STR(@/(I-1),1),@%=(I-1)FROM M ORDER BY I DESC SELECT @T

그리고 여기 다시 읽을 수 있지만 읽을 수 있습니다.

DECLARE 
    @ BIGINT=,
    @T VARCHAR(MAX)='';

WITH M AS
(
    SELECT
        CAST(2 AS BIGINT) I

    UNION ALL

    SELECT I * 2
    FROM M
    WHERE I < @
)

SELECT 
    @T+=STR(@/(I-1),1),
    @%=(I-1)
FROM M 
ORDER BY I DESC

SELECT @T

int 만 사용하면 약간 더 짧을 수 있으며 157 바이트로 나옵니다.

DECLARE @ INT=,@T VARCHAR(MAX)='';WITH M AS(SELECT 2I UNION ALL SELECT I*2FROM M WHERE I<@)SELECT @T+=STR(@/(I-1),1),@%=(I-1)FROM M ORDER BY I DESC SELECT @T

그리고 다시 한 번 더 읽기 쉽습니다.

DECLARE 
    @ INT=,
    @T VARCHAR(MAX)='';

WITH M AS
(
    SELECT
        2I

    UNION ALL

    SELECT 
        I * 2
    FROM M
    WHERE I < @
)

SELECT 
    @T+=STR(@/(I-1),1),
    @%=(I-1)
FROM M 
ORDER BY I DESC

SELECT @T

@sql에서 유효한 식별자임을 기억 하면 Char(8000) nvarchar (max)보다 여전히 저렴한 것을 사용할 수 있습니다 . char대신 로 변환 varchar하거나 str함수를 사용할 수도 있습니다.
Michael B

@MichaelB 오, 나는 @바보 같은 나를 사용했다고 생각했다 . CHAR(8000)조언은 아주 좋은 것입니다, 나는 그것을 시도 할 것이다. 나는 항상 STR()감사 의 존재를 잊어 버리는 것 같습니다 .
PenutReaper 2016 년

실제로 도움이되지 않습니다. 그러나 CTE 다음에 부품을 다시 쓸 수 있습니다 select @t=concat(@t,@/i). 그래도 sql2012가 필요합니다.
Michael B

@MichaelB 아. CONCATSQL 2008을 사용하지 않으면 테스트 할 수 없습니다. 그래도 좋은 전화.
PenutReaper 2016 년

3

튜링 머신 코드, 333 293 바이트

here 사용 된 인코딩을 사용하고 있습니다 .

이 기계는 9 가지 상태와 11 가지 색상을 사용합니다.

이진 입력이 허용되는 경우 이는 단지 4 색으로 줄어들어 프로세스에서 수십 바이트를 절약 할 수 있습니다.

0 _ _ l 1
0 * * r 0
1 9 8 l 2 
1 8 7 l 2
1 7 6 l 2
1 6 5 l 2
1 5 4 l 2
1 4 3 l 2
1 3 2 l 2
1 2 1 l 2
1 1 0 l 2
1 0 9 l 1
1 _ _ r 8
2 _ _ l 3
2 * * l 2
3 _ 1 r 4
3 * * l 5
4 _ _ r 0
4 * * r 4
5 * * l 5
5 _ _ r 6
6 _ _ l 7
6 2 0 l 7
6 * * r 6
7 _ 1 r 4
7 0 1 r 4
7 1 2 r 4
8 _ _ * halt
8 * _ r 8

위의 링크가 작동하지 않으면 (때로는 작동하지 않고 때로는 페이지로드를 거부하는 경우) 이 Java 구현을 사용하여 테스트 할 수도 있습니다 .


2

펄, 66 바이트

STDIN을 통해 숫자를 입력해야합니다.

$_=1;$c=<>;s/(.*)(.?)2(.*)/$1.$2+1 .$3.0/e||$_++while(--$c);print;

솔루션 작동 방식을 설명해 주시겠습니까? 나는 당신이 필요로 표시되지 않습니다 (.?)에서 $2이후 (.*)에이 $1욕심과 먼저 문자를 받아야합니다. 그러나 코드가 제거되면 더 이상 올바른 결과를 얻지 못합니다! 그건 그렇고, 당신은 마지막이 필요하지 않습니다 ;.
CJ 데니스

@CJDennis 바이트를 저장해 주셔서 감사합니다. 어쨌든.? 숫자가 없으면 (예 : 20) 두 숫자 바로 앞에 숫자가 표시됩니다. 120 또는 10020과 같은 경우 정규식 그룹은 () (1) 2 (0) 및 (10) (0) 2 (0)과 같습니다. 그런 다음 첫 번째 그룹은 단순히 무시되고 두 번째 그룹 (가능한 경우 항상 한 자리 수이거나 비어 있음)이 증가하고 세 번째 그룹 (항상 0으로 구성됨)이 무시되고 0이 추가됩니다. 나는이 정규식의 가이드로 OEIS 항목을 사용했습니다.
frederick

코드를 53 바이트로 줄 $c=<>;s/(.*)2(.*)/$1+1 .$2.0/e||$_++while($c--);print였습니다. 나는 옳았다 (.?).
CJ 데니스

로 최적화 할 수 있습니다 ( $_=1;$c=<>;s/(.?)2/1+$1.0/e||$_++while(--$c);print50 바이트). .*원래 텍스트로 바꾸면 시작 또는 끝 부분을 최적화 할 수 있습니다. 또한 original에 항상 0 만 있기 때문에 끝에 0을 추가 할 이유가 없습니다 $3.
Thraidh

2

Pyth, 19 바이트

m/=%Qtydtd^L2_SslhQ

대수의 복잡성. 필요한 시간 내에 쉽게 완료됩니다. 숫자 목록 형식으로 출력됩니다.

데모 .


2

펄, 84 70 67 바이트

$n=<>;$d*=2while($d++<$n);$_.=int($n/$d)while($n%=$d--,$d/=2);print

골프 는 아니지만 더 나아지지만 빨리 작동합니다!

Dennis의 제안은 51로 줄입니다 (50 바이트 + -p 스위치)

$d*=2while$d++<$_;$\.=$_/$d|0while$_%=$d--,$d/=2}{

그것은 해야한다 처럼 호출 할 perl -p skew_binary.pl num_list.txtnum_list.txt그것을 인코딩 할 수있는 한 줄이 포함되어 있습니다.


@frederick 우리는 우리 좌석의 가장자리에 2를 기다리고 있습니다.
Robert Grant

@RobertGrant 그는 두 가지에서 한 가지로 자신의 의견을 골랐다!
CJ 데니스

두 가지 : 1. $ ARGV [0]을 사용하는 대신 <>를 입력으로 사용하십시오. 인수로 파일이 없으면 stdin에서 입력을받습니다. 2. 이와 같은 홀수 계산 체계의 경우 정규식을 사용하십시오. 홀수 수학 연산을 수행하는 대신 숫자처럼 숫자를 문자열처럼 바꿀 수 있습니다. 가장 좋은 부분은 숫자로 완전히 구성된 문자열이라면 수학 연산 (증분과 같은)을 동시에 사용할 수 있다는 것입니다. 많은 경우에 매우 유용 할 수 있으므로 정규식 연산자에 대한 문서를 확인하십시오.
frederick

죄송합니다. 입력을 누르면 주석이 완료되기 전에 저장되었습니다.
frederick

@frederick은 겸손하지 않습니다. 우리는 무슨 일이 있었는지 알고 있습니다!
Robert Grant

1

매스 매 티카, 65

나는 이것을하기 전에 다른 제출물을 들여다보아야하지만, 충분히 빠르지 않아야합니다.

f = (n = #;
     l = 0; 
     While[n > 0,
      m = Floor[Log2[1 + n]];
      l += 10^(m - 1);
      n -= 2^m - 1
     ]; l)&

용법:

f[1000000000000000000]

산출:

11011110000010110110101100111010011101100100000000000001102

10 ^ 228을 지난 어딘가에 MaxExtraPrecision 오류 메시지를 표시하기 시작합니다 (내 컴퓨터에서 .03 초로 결과 계산).

MaxExtraPrecision 제한을 제거한 후에는 초당 약 10 ^ 8000까지의 숫자를 처리합니다.

입력:

Timing[Block[{$MaxExtraPrecision = Infinity}, f[10^8000]];]

산출:

{1.060807, Null}

1

C, 95 바이트

void f(unsigned long i,int*b){for(unsigned long a=~0,m=0;a;a/=2,b+=!!m)m|=*b=i/a,i-=a**b;*b=3;}

이것은 정수와 숫자를 반환하는 버퍼를 허용합니다. 결과는에 저장되고 b값으로 종료됩니다 3(출력에서 발생할 수 없음). 우리는 0(질문이 양의 정수로 지정된) 입력을 처리 할 필요가 없으므로 빈 출력을 피하기위한 특별한 경우가 없습니다.

확장 코드

void f(unsigned long i,int*b)
{
    for (unsigned long a=~0, m=0;  a;  a/=2, b+=(m!=0)) {
        *b = i/a;               /* rounds down */
        i -= *b * a;
        m = m | *b;             /* m != 0 after leading zeros */
    }
    *b=3;                       /* add terminator */
}

우리는 가장 중요한 숫자부터 시작하여 연속 뺄셈으로 작동합니다. 유일한 합병증은 변수 m를 사용하여 선행 0을 인쇄하지 않는 것입니다. unsigned long long원하는 경우 10 바이트의 비용으로 자연스럽게 확장 할 수 있습니다.

테스트 프로그램

명령 인수로 변환 할 패스 번호. int배열 버퍼를 인쇄 가능한 숫자 문자열 로 변환합니다 . 입력 시간이 1 밀리 초 미만 1000000000000000000입니다.

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char**argv)
{
    while (*++argv) {
        unsigned long i = strtoul(*argv, NULL, 10);
        int result[1024];
        f(i,result);

        /* convert to string */
        char s[1024];
        {char*d=s;int*p=result;while(*p!=3)*d++=*p+++'0';*d=0;}
        printf("%lu = %s\n", i, s);
    }

    return EXIT_SUCCESS;
}

시험 결과

$ ./51517 $(seq 20)
1 = 1
2 = 2
3 = 10
4 = 11
5 = 12
6 = 20
7 = 100
8 = 101
9 = 102
10 = 110
11 = 111
12 = 112
13 = 120
14 = 200
15 = 1000
16 = 1001
17 = 1002
18 = 1010
19 = 1011
20 = 1012

C ++ 버전도 비슷하지만 auto a=~0ull약간의 이점을 위해 사용할 수 있습니다 ...
Toby Speight


0

CoffeeScript, 92 69 바이트

Qwertiy의 답변 과 업데이트를 바탕으로 :

f=(n)->s='1';(s=s.replace /(.?2|.$)/,(m)->[1,2,10][+m]||20)while--n;s

# older version, 92 bytes
f=(n)->s='1';(s=s.replace /(^2|02|12|20|.$)/,(m)->{0:1,1:2,2:10,12:20,20:100}[+m])while--n;s

2
정규 표현식에서 불필요한 중괄호를 제거하여 간단한 최적화없이 다른 언어로 변환하는 것은 나에게 멋진 것처럼 보이지 않습니다 ...
Qwertiy

@Qwertiy 귀하의 답변에 귀속을 제공했으며 두 답변 모두 정규 표현식에 괄호가 없으면 동일한 결과를 얻을 수 없습니다
rink.attendant.6

전체 발생이 대체됩니다. 왜 그룹 내부에 있어야합니까? JS 버전은 대괄호없이 Firefox에서 작동합니다.
Qwertiy

0

Japt , 31 바이트

_r/?2|.$/g_÷C ç20 ª°Zs3}}gU['0]

온라인으로 사용해보십시오!

이 JS 솔루션 의 거의 직접 포트 . 더 나은 방법이 있는지 모르겠습니다.

포장 풀기 및 작동 방식

X{Xr/?2|.$/gZ{Z÷C ç20 ||++Zs3}}gU['0]

X{     Declare a function...
Xr       Accept a string, replace the regex...
/?2|.$/g   /.?2|.$/   (g is needed to match *only once*, opposite of JS)
Z{       ...with the function... (matched string will be 0,1,2,02 or 12)
Z÷C        Implicitly cast the matched string into number, divide by 12
ç20        Repeat "20" that many times (discard fractions)
||         If the above results in "", use the next one instead
++Z        Increment the value
s3         Convert to base-3 string (so 0,1,2 becomes 1,2,10)
}}
gU['0] Repeatedly apply the function on "0", U (input) times

0

Stax , 16 바이트

üxëàè£öΦGΩ│Je5█ò

실행 및 디버깅

공식적인 복잡성 클래스가 정확히 무엇인지 잘 모르겠지만이 컴퓨터에서 1/10 초 안에 모든 테스트 사례를 수행 할 수있을 정도로 빠릅니다.

포장을 풀고 포장을 풀고 주석을 달았습니다. 이 프로그램에서 x 레지스터는 원래 입력을 포함합니다.

z       push []
{       start block for while loop
 |X:2N  -log2(++x)
 {^}&   increment array at index (pad with 0s if necessary)
 xc:G-X unset high bit of x; write back to x register
w       while; loop until x is falsy (0)
$       convert to string

이것을 실행

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.