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


39

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

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

    예 : N = 571

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

    571= 1000111011이진수로

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

    예를 들어, 10001110111, 000, 111, 0,11

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

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

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

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

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

    예를 들어 111, 000, 11, 0, 11110001101= 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.highestOneBitjava.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) = 01예상되며, t(4) = 16가 예상되는 경우
SP3000
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.