템플 스카이 라인 시퀀스 생성


39

다음 프로세스를 고려하십시오.

  1. 음이 아닌 정수 N을 가져옵니다.

    예 : N = 571

  2. 선행 0없이 바이너리로 표현하십시오. (제로 자체 만이 유일한 예외 0입니다.)

    예 571= 1000111011이진수로

  3. 이 이진 표현에서 1과 0의 연속 실행을 분리하십시오.

    예를 들어, 1000111011→ 1, 000, 111, 0,11

  4. 런을 가장 긴 것부터 가장 짧은 것까지 정렬합니다.

    예를 들어 1, 000, 111, 0, 11→ 000, 111, 11, 1,0

  5. 교류와 각 실행에있는 모든 숫자를 덮어 쓰기 1's와 0항상 함께 시작의 1의.

    예를 들어 000, 111, 11, 1, 0→ 111, 000, 11, 0,1

  6. 결과를 연결하여 새로운 이진수를 얻습니다.

    예를 들어 111, 000, 11, 0, 1→ 1110001101= 909진수

이 프로세스에서 생성 된 값을 플로팅하면 매우 깔끔한 그래프가 나타납니다.

1024에 템플 스카이 라인 음모

그리고 결과 시퀀스를 Temple Skyline 시퀀스 라고 부르는 이유는 분명 합니다 .

템플 스카이 라인

도전

음수가 아닌 정수 N을 사용하고 해당하는 Temple Skyline 시퀀스 번호를 인쇄하거나 반환하는 프로그램 또는 함수를 작성하십시오. 입력과 출력은 모두 10 진수 여야합니다.

예를 들어 입력이 571출력 인 경우 909.

바이트 단위의 가장 짧은 코드가 이깁니다.

참고로, N = 0에서 20까지의 시퀀스에있는 용어는 다음과 같습니다.

0   1
1   1
2   2
3   3
4   6
5   5
6   6
7   7
8   14
9   13
10  10
11  13
12  12
13  13
14  14
15  15
16  30
17  29
18  26
19  25
20  26

다음은 0에서 1023까지의 용어입니다.

답변:


4

Pyth, 20 19 바이트

ACr.BQ8|is*V_SGH2 1

Jakube가 1 바이트 절약

테스트 스위트

런 길이 인코딩 후 런은 출력에서 ​​원하는 런이라는 사실을 사용합니다.

3 바이트 특수 케이스 0을 유실했습니다.


14

CJam, 25 23 22 바이트

ri1e>2be`z($W%a\+ze~2b

약간의 실행 길이 인코딩. @ MartinBüttner에게 -1 감사합니다.

온라인 / 테스트 스위트를 사용해보십시오 .

설명

ri        Read n from input as int
1e>       Take max with 1 (special case for n = 0)
2b        Convert n to binary
e`        Run length encode
z         Zip, giving a pair [<counts> <10101.. array>]
($W%      Drop the counts array and sort decending
a\+z      Add it back to the 10101.. array and re-zip
e~        Run length decode
2b        Convert from binary

11

Pyth- 21 20 바이트

1 바이트 절약 해 주신 @sok에게 감사드립니다!

is.em%hk2hb_Sr.BQ8 2

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


.BQ대신 대신 사용할 수 있습니다 . 즉 앞과 jQ2사이의 공간을 잃을 수 있습니다 . 82
— Sok

is*R`s=!Z_ShMr.BQ8 2흥미로운 길이 솔루션입니다. 나는 실제로지도 인수의 할당이 효과가 있다고 기대하지 않았기 때문에 게시했습니다.
— FryAmTheEggman

1
교체 @FryAmTheEggman `s와 함께 ]. 1 바이트를 저장합니다.
— Jakube

6

파이썬 2, 121 바이트 125

121 : 4 바이트를 줄여준 Sp3000에 감사합니다!

import re;print int("".join(n*`~i%2`for i,n in enumerate(sorted(map(len,re.split('(1*|0+)',bin(input())[2:])))[::-1])),2)

125

import re;print int("".join("10"[i%2]*n for i,n in enumerate(sorted(map(len,re.split('(1*|0+)',bin(input())[2:])))[::-1])),2)

1
좋은! 당신도 n*`~i%2`for대신 할 수 있다고 믿습니다"10"[i%2]*n for
— Sp3000

편집 해 주셔서 감사합니다! 나는 빨리 돌진해야했지만 이것이 아름다운 도전이자 첫 번째 제출에 좋은 것이라고 생각했기 때문에 제출하고 싶었다. 제출하신 내용을 곧 확인하겠습니다!
— enpenax 5

나는 당신이 사용하는 sorted(...,key=len)대신 사용하여 약간의 바이트를 절약 할 수 있다고 생각 map(len,...하지만 지금은 프로그램을 완전히 이해하지 못하기 때문에 긍정적 인 것은 아닙니다.
— cole

이봐 @Cole 나는 그것이 len1과 0의 양을 복제하는 데 필요한 유일한 정보이기 때문에 매핑 하고 있습니다. 나는 당신의 제안을 시도하고 2 바이트를 추가합니다 len.
— enpenax

5

자바 스크립트 ES6는 110 바이트 (113) 116 (119) 120

@intrepidcoder 덕분에 3 바이트 절약

@NinjaBearMonkey 덕분에 3 바이트 절약

n=>+('0b'+n.toString(2).split(/(0+)/).sort((b,a)=>a.length-b.length).map((l,i)=>l.replace(/./g,i-1&1)).join``)

직접적인 접근. 정렬 기능의 길이는 마음에 들지 않지만 골프를 치는 방법은 생각할 수 없습니다.


+대신 사용할 수 있다고 생각합니다 eval.
— intrepidcoder

@ intrepidcoder 덕분에 3 바이트를 절약했습니다!
— Downgoat

테스트 할 수는 없지만 split(/(0+)/g)바꿀 수 있어야합니다 match(/(.)\1*/g).
— NinjaBearMonkey

@NinjaBearMonkey 덕분에 3 바이트를 절약했습니다!
— Downgoat

하나의 바이트를 저장 : +(s=0, ... .map(l=>l.replace(/./g,s^=1))...)
— 희망 I 캔 도움말

5

C ++, 535 527 바이트

(일부 바이트를 제거 한 zereges에게 감사드립니다.)

이제 우리는 그 바이트를 제거 했으므로 프로그램은 이제 경쟁력이 있습니다.)

#include<iostream>
#include<cmath>
int main(){int I,D;std::cin>>I;while(I>int(pow(2,D))){D++;}int L[99];int X=0;int Z=0;int O=0;for(int i=D-1;i>=0;i--){if( int(pow(2,i))&I){if(Z>0){L[X]=Z;Z=0; X++;}O++;}else{if(O>0){L[X] = O;O=0;X++;}Z++;}}if(Z>0){L[X]=Z;Z=0;X++;}if(O>0){L[X]=O;O=0;X++;}int P=0;bool B = true;int W = D-1;for(int j=0;j<X;j++){int K=0;int mX=0;for(int i=0;i<X;i++){if(L[i]>K){K=L[i];mX=i;}}L[mX]=0;if(B){for(int k=0;k<K;k++){P+=int(pow(2,W));W--;}}else{for(int k=0;k<K;k++){W--;}}B^=1;}std::cout<<P;return 0;}

나는 골프를 처음 사용하므로 의견에 몇 가지 팁을 알려주십시오 .

"대괄호가 필요하지 않음"또는 "use printf"와 같은 것은 모두 도움이되지만 논리에 대한 조언도 감사합니다. 미리 감사드립니다!

읽기 쉽도록 ungolfed 버전을 제시합니다.

#include<iostream>
#include<cmath>
int main()
{
int input,digits;

std::cin>>input;
while(input > int(pow(2,digits))){digits++;}

int list[99];
int index=0;
int zCounter=0;
int oCounter=0;

for(int i=digits;i>0;i--)
{
    if( int(pow(2,i-1))&input)
    {
        if(zCounter>0)
        {
            list[index] = zCounter;
            zCounter=0;
            index++;
        }
        oCounter++;
    }
    else
    {
        if(oCounter>0)
        {
            list[index] = oCounter;
            oCounter=0;
            index++;
        }
        zCounter++;
    }
}
if(zCounter>0)
{
        list[index] = zCounter;
        zCounter=0;
        index++;
}
if(oCounter>0)
{
        list[index] = oCounter;
        oCounter=0;
        index++;
}

int output = 0;
bool ones = true;
int power = digits-1;
for(int j=0;j<index;j++)
{
    int max=0;
    int mIndex=0;
    for(int i=0;i<index;i++)
    {
        if(list[i]>max){max=list[i];mIndex=i;}
    }
    list[mIndex]=0;

    if(ones)
    {
        for(int k=0;k<max;k++)
        {
            output+=int(pow(2,power));
            power--;
        }
    }
    else
    {
        for(int k=0;k<max;k++)
        {
            power--;
        }
    }
    ones^=1;

}
std::cout<<output;
return 0;
}

골프 버전을 편집 하면 몇 바이트가 내려지고 ungolfed 버전은 변경되지 않았습니다.


대신 int a; int b;사용할 수 있습니다 int a,b;. 또한 전역 범위의 변수는로 초기화됩니다 0. 또한 실행할 명령이 하나 뿐인 경우 중괄호를 사용할 필요가 없습니다. 또한 ones=!ones;간단하게 할 수 있습니다ones ^= 1;
— Zereges

일부 바이트 절약
— Liam

첫 번째 for루프를로 이동합니다 1. 즉 루프 내부에서 for(int i=D;i;i--)사용 pow(2,i-1)하십시오.
— nimi

@LiamNoronha 당신은 실제로 내가 추천 한 것을 저장하지 않았습니다 :)
— Zereges

1
@LiamNoronha 이것을 확인하십시오 . 여전히 개선의 여지가 많습니다. 예를 들어 변수 재사용 (저장 정의) ones도 가능 int합니다. 어쩌면 macroing int(pow(i))에 P(i). 여기
— Zereges

2

하스켈 132 131 바이트

import Data.List
g 0=[]
g n=mod n 2:g(div n 2)
q=[1]:[0]:q
f=foldl((+).(2*))0.concat.zipWith(<*)q.sortOn((-)0.length).group.g.max 1

사용 예 :

> map f [0..20]
[1,1,2,3,6,5,6,7,14,13,10,13,12,13,14,15,30,29,26,25,26]

작동 방식 :

                 max 1         -- fix n=0: f(0) is the same as f(1)
               g               -- turn into binary, i.e. list of 0s and 1s
            group              -- group sequences of equal elements
         sortOn((-)0.length)   -- sort groups on negative length
      zipWith(<*)q             -- map each element in a group to constant 1 or 0 by turns
   concat                      -- flatten all groups into a single list
foldl((+).(2*))0               -- convert back to decimal

2

J-30 바이트

오른쪽에 정수를받는 함수. 0을 올바르게 처리합니다.

(\:~#2|#\)@(#;.1~1,2~:/\])&.#:
  • #: -이진 표현을 취하십시오.
  • 1,2~:/\]-각 숫자 사이 에 다르면 True를 보고하십시오 . 각 "실행"이 시작될 때 목록이 True 가되도록 True를 추가하십시오 .
  • (#;.1~...) -위의 부울 벡터를 사용하여 각 런의 길이를 가져옵니다.
  • \:~ -이 길이를 가장 긴 것부터 가장 짧은 것까지 정렬하십시오.
  • 2|#\- 1 0 1 0 ...길이 목록만큼 교대 목록을 작성하십시오 .
  • (...#...) -왼쪽의 각 번호 (정렬 된 길이)에 대해 오른쪽의 해당 항목을 최대한 많이 가져옵니다 (1과 0을 교대로)
  • &. -이 새로운 이진 표현을 다시 숫자로 변환합니다.

예 :

   (\:~#2|#\)@(#;.1~1,2~:/\])&.#: 571
909
   i.21   NB. zero to twenty
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
   (\:~#2|#\)@(#;.1~1,2~:/\])&.#: every i.21   NB. apply separately to every number
1 1 2 3 6 5 6 7 14 13 10 13 12 13 14 15 30 29 26 25 26

2

펄 5.10 121 101

say oct"0b".join'',map{$|=1-$|;$_=~s/./$|/gr}sort{length$b<=>length$a}(sprintf"%b",shift)=~/(0*|1*)/g

정렬 부분이 더 짧을 수 있다고 생각합니다.

편집 : symbabque 덕분에 -20 바이트!


당신은 제거 할 수 \n하고는 m정규 표현식 일치가 필요하지 않습니다. .대신, char 그룹 대신 사용하십시오 .
— simbabque

grep부품이 필요하지 않습니다 . 는 oct깔끔한하지만 :)입니다
— simbabque

고맙게도 실수로 원래 코드에서 해당 부분을 남겼습니다.
— Laposhasú Acsa

1

파이썬 3, 146136 바이트

import re;print(int(''.join(len(j)*'01'[i%2<1]for i,j in enumerate(sorted(re.findall('1+|0+',bin(int(input()))[2:]),key=len)[::-1])),2))

map와 함께하는 것보다 lambda하는 것이 낫 ''.join(... for ... in ...)습니까?
— Sp3000

1

수학, 83 바이트

Flatten[0#+(d=1-d)&/@SortBy[d=0;Split[#~IntegerDigits~2],-Length@#&]]~FromDigits~2&

명명되지 않은 함수를 정의합니다.


0

루비, 107 (104) 102 바이트

(덕분에 3 바이트 절약 nimi )

CJam을 좋아하지는 않지만 제정신의 언어로는 꽤 작습니다.

p gets.to_i.to_s(2).scan(/((.)\2*)/).map{|e|e[i=0].size}.sort.reverse.map{|e|"#{i=1-i}"*e}.join.to_i 2

저장할 몇 바이트 : (i+=1)%2is i=1-i입니다.
— nimi

@nimi 아, 감사합니다. 나는 그것을 단축시키는 방법을 알아 내려고 노력했다.
— iamnotmaynard

0

자바 8, 179176 바이트

(x)->{int g[]=new int[32],h=0,i=highestOneBit(x);g[0]=1;while(i>1)g[((x&i)>0)^((x&(i>>=1))>0)?++h:h]++;sort(g);for(i=32,h=0;g[--i]>0;)while(g[i]-->0)h=h<<1|i%2;return x<1?1:h;}

두 개의 정적 가져 오기를 사용했습니다 : java.util.Integer.highestOneBit및 java.util.Arrays.sort.

가독성을 높이기 위해 코드는 다음과 같습니다.

java.util.function.ToIntFunction<Integer> f = (x) -> {
  int g[] = new int[32], h = 0, i = java.util.Integer.highestOneBit(x);
  g[0] = 1;
  while (i > 1) {
    g[((x & i) > 0) ^ ((x & (i >>= 1)) > 0) ? ++h : h]++;
  }
  java.util.Arrays.sort(g);
  for (i = 32, h = 0; g[--i] > 0;) {
    while (g[i]-- > 0) {
      h = h << 1 | i % 2;
    }
  }
  return x < 1 ? 1 : h; // handle zero
};

-1

파이썬 2, 170 바이트

def t(n):
  from itertools import groupby;lst=sorted([''.join(g) for n,g in groupby(bin(n)[2:])],key=len)[::-1];s=''
  for i in lst:s+=str(i)
  return int(s,2)

4
PPCG에 오신 것을 환영합니다! 불행하게도 나는 이것이 예를 들어 몇 가지 숫자에 대한 잘못된 값을 제공 생각할 t(0) = 0때 1예상되며, t(4) = 16가 예상되는 경우
— SP3000
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.