神殿のスカイラインシーケンスを生成する


39

次のプロセスを検討してください。

  1. 負でない整数Nを取ります。

    例:N = 571

  2. 先行ゼロなしでバイナリで表現します。(ゼロ自体は唯一の例外で、になり0ます。)

    571= 1000111011バイナリで

  3. このバイナリ表現で1と0の連続した実行を分割します。

    例えば10001110111000111011

  4. 実行を最長から最短に並べ替えます。

    例えば10001110110001111110

  5. 各実行のすべての数字を、常にで始まる「」10「」を交互に使用して上書きします1

    例えば00011111101110001101

  6. 結果を連結して、新しい2進数を取得します。

    例えば11100011011110001101= 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

ジャクベが保存した1バイト

テストスイート

run-length-encoding後の実行は、出力で望ましい実行であるという事実を使用します。

3バイトの特殊なケーシング0が失われました。


14

CJam、25 23 22バイト

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

ほんの少しのランレングスエンコーディング。-1 @MartinBüttnerに感謝します。

オンラインで試す / テストスイート

説明

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つまり、8との間のスペースを失う可能性があり2ます。
ソク

is*R`s=!Z_ShMr.BQ8 2興味深い同じ長さのソリューションです。ほとんどの場合、マップ引数のassignが機能するとは思っていなかったため、投稿しました。
FryAmTheEggman

1
置き換え@FryAmTheEggman `s]。1バイト節約します。
ジャクベ

6

Python 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

使用するsorted(...,key=len)代わりに使用することでいくつかのバイトを節約できると思いますがmap(len,...、私は今あなたのプログラムを完全に理解していないので、私はあなたに利益をもたらすとは確信していません。
コール

ちょっと@Cole len1と0の量をレプリケートする必要がある唯一の情報であるため、私はマッピングしています。私はあなたの提案を試して、それから2バイトを追加しますlen
enpenax

5

JavaScript 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バイト節約しました!
ダウンゴート

これをテストすることはできませんが、split(/(0+)/g)を置き換えることができるはずmatch(/(.)\1*/g)です。
NinjaBearMonkey

@NinjaBearMonkeyありがとう、3バイト節約しました!
ダウンゴート

1バイトの保存: +(s=0, ... .map(l=>l.replace(/./g,s^=1))...)
役立つことを願って

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

私はゴルフが初めてなので、コメントでいくつかのヒントを教えてください

「これらの括弧は必要ありません」や「printfを使用する」などはすべて役に立ちますが、ロジックに関するアドバイスもありがたいです。前もって感謝します!

読みやすくするために、私は無料版を提示します:

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

ゴルフバージョンを編集すると、数バイトがダウンし、ゴルフバージョンは変更されませんでした


代わりにint a; int b;使用できますint a,b;。また、グローバルスコープ内の変数はで初期化され0ます。また、実行するコマンドが1つしかない場合は、中括弧を使用する必要はありません。また、次のones=!ones;ように簡略化することもできますones ^= 1;
-Zereges

おかげで数バイト節約できました
リアム

最初のforループを1、つまりループ内for(int i=D;i;i--)で使用pow(2,i-1)します。
nimi

@LiamNoronhaあなたは実際に私がお勧めしたものを保存しませんでした:)
Zereges

1
@LiamNoronha これをチェックしてください。まだ改善の余地がたくさんあります。たとえば、変数を再利用する(定義を保存する)onesこともできますint。たぶんマクロint(pow(i))P(i)ここで
ゼレゲス

2

Haskell、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を報告します。前に付加真のリストが持っているので、真の各「実行」の開始時に。
  • (#;.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

ソート部分は短くなると思います。

編集:-20バイト、symbabqueのおかげで!


あなたは取り除くことができ\n、およびm正規表現マッチングのために必要とされていません。置換で.は、charグループの代わりに使用します。
シンバク

grep部品も必要ありません。しかしoct、きちんとしている:)
シンバク

ありがとう、私は誤って元のコードからそれらの部分を残した。
LaposhasúACSA

1

Python 3、146 136バイト

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

むしろよりmaplambda、何をする方が良いだろうか''.join(... for ... in ...)
Sp3000

1

Mathematica、83バイト

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

これは、名前のない関数を定義します。


0

ルビー、107 104 102バイト

nimiのおかげで3バイト保存されました)

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

Java 8、179 176バイト

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

2つの静的インポートを使用しました: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

Python 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.