Tapınak Skyline Dizisini Yaratın


39

Aşağıdaki süreci göz önünde bulundurun:

  1. Negatif olmayan bir tamsayı N al.

    örneğin N = 571

  2. Baştaki sıfır olmadan ikili olarak ifade edin. (Sıfır kendisi tek istisna olmaktır 0.)

    örneğin 571= 1000111011ikili olarak

  3. Bu ikili gösterimde art arda gelenleri ve sıfırları ayırın.

    örneğin 10001110111, 000, 111, 0,11

  4. Koşuları en uzundan en kısaya doğru sıralayın.

    örneğin 1, 000, 111, 0, 11000, 111, 11, 1,0

  5. Her bir siradaki tüm basamağın üzerine, her zaman s ile baslayarak, 1s ve 0s ile 1degistirilerek yazin.

    örneğin 000, 111, 11, 1, 0111, 000, 11, 0,1

  6. Yeni bir ikili sayı elde etmek için sonucu birleştirin.

    örneğin 111, 000, 11, 0, 11110001101= 909ondalık

Bu işlem tarafından üretilen değerleri çizdiğinizde oldukça düzenli bir grafik elde edersiniz:

Tapınak manzarası arsa 1024

Ben Oluşan dizisini yüzden arıyorum Ve umarım belirgindir Temple Skyline dizisi :

Tapınak manzarası

Meydan okuma

Negatif olmayan bir tamsayı N alan ve ilgili Temple Skyline sıra numarasını yazdıran veya döndüren bir program veya işlev yazın. Giriş ve çıkışınız her ikisinde de ondalık olmalıdır.

Örneğin, eğer giriş ise 571çıkış olmalıdır 909.

Bayt cinsinden en kısa kod kazanır.

Başvuru için, dizideki terimler 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

İşte 0 ila 1023 arasındaki terimler.

Yanıtlar:


4

Pyth, 20 19 bayt

ACr.BQ8|is*V_SGH2 1

Jakube tarafından kaydedilen 1 bayt

Test odası

Çalışma uzunluğu kodlamasından sonra, işlemlerin çıktıda istenen işlemler olduğu gerçeğini kullanır.

Kayıp 3 bayt özel kasa 0.


14

CJam, 25 23 22 bayt

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

Sadece bir miktar çalışma uzunluğu kodlaması. @ MartinBüttner'a -1 teşekkürler.

Çevrimiçi deneyin / Test paketi .

açıklama

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 bayt

Beni bir bayttan kurtardığın için teşekkürler.

is.em%hk2hb_Sr.BQ8 2

Burada çevrimiçi deneyin .


Bunun .BQyerine kullanabilirsiniz jQ2; bu 8, önceki ve arasındaki boşluğu kaybedebileceğiniz anlamına gelir 2.
Sok,

is*R`s=!Z_ShMr.BQ8 2ilginç, aynı uzunlukta bir çözümdür. Çoğunlukla gönderi çünkü bir harita argümanında çalışmanın gerçekten gerçekleşmesini beklemiyordum.
FryAmTheEggman

1
Değiştir @FryAmTheEggman `sile ]. Bir bayt kaydeder.
Jakube

6

Python 2, 121 bayt 125

121: 4 bayt'ı tıraş etmek için Sp3000'e teşekkürler!

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
Güzel! Ben de yapabileceğine inanıyorum n*`~i%2`foryerine"10"[i%2]*n for
SP3000

Düzenleme için teşekkürler! Çabucak acele etmek zorunda kaldım ama göndermek istedim çünkü bunun güzel bir meydan okuma olduğunu ve ilk başvuru için iyi olduğunu düşündüm. Gönderinizi en kısa zamanda kontrol edeceğim!
enpenax

Kullanmak sorted(...,key=len)yerine bazı baytları saklayabileceğinizi düşünüyorum map(len,...ama şu anda programınızı tam olarak anlamadım, bu nedenle size fayda sağlayacağı konusunda olumlu değilim.
cole,

Hey @Cole Eşleştiriyorum, lençünkü 1 ve 0 miktarını çoğaltmak için ihtiyacım olan tek bilgi lenbu.
enpenax

5

JavaScript ES6, 110 bayt 113 116 119 120

@İntrepidcoder sayesinde 3 bayt kaydedildi

@NinjaBearMonkey sayesinde 3 bayt kaydedildi

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

Dümdüz ileri yaklaşım. Sıralama işlevinin uzunluğu hoşuma gitmedi ama golf oynamak için bir yol düşünemiyorum.


Bunun +yerine kullanabilirsiniz düşünüyorum eval.
intrepidcoder

@intrepidcoder 3 bayt kurtardı!
Downgoat

Bunu test edemiyorum ama split(/(0+)/g)değiştirebilmeliyim match(/(.)\1*/g).
NinjaBearMonkey

@NinjaBearMonkey, 3 bayt kazandı!
Downgoat

Bir bayt kaydetme: +(s=0, ... .map(l=>l.replace(/./g,s^=1))...)
Umarım

5

C ++, 535 527 Bayt

(bazı baytları tıraş ettiğiniz için teşekkürler.)

Şimdi bu baytlardan kurtulduğumuza göre program şimdi rekabetçi.)

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

Golf oynamak için yeniyim, lütfen bana yorumlarda bazı ipuçları verin .

“Bu parantezlere ihtiyacınız yok” veya “printf kullanın” gibi şeyler faydalı olabilir, ancak mantıkla ilgili tavsiyelere de minnettarım. Şimdiden teşekkürler!

Okuma kolaylığı için, unungolfed versiyonunu sunuyorum:

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

EDIT golf sürümü birkaç bayt indirdi, eski sürüm değiştirilmedi


Sen yerine can int a; int b;kullanımı int a,b;. Ayrıca global kapsamdaki değişkenler ile başlatıldı 0. Ayrıca, yürütülecek tek bir komut varken parantez kullanmanız gerekmez. Ayrıca ones=!ones;olarak basitleştirilmiş olabilirones ^= 1;
Zereges

Bazı baytlar kaydedildi teşekkürler
Liam

İlk fordöngünüzü kaydırın 1, yani döngünün içinde for(int i=D;i;i--)kullanın pow(2,i-1).
nimi

@LiamNoronha Aslında tavsiye ettiğim şeyi kaydetmediniz :)
Zereges

1
@LiamNoronha bu Çıkış . Gelişme için hala çok fazla alan var. Örneğin, değişkenleri yeniden kullanmak (tanımı saklamak) onesda olabilir int. Belki de int(pow(i))içine yapıyorum P(i). Tartışmayı burada
Zereges

2

Haskell, 132 131 bayt

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

Kullanım örneği:

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

Nasıl çalışır:

                 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 bayt

İşlev tamsayıyı sağa alıyor. Doğru şekilde 0 işler.

(\:~#2|#\)@(#;.1~1,2~:/\])&.#:
  • #: - İkili gösterimi alın.
  • 1,2~:/\]- Her hane arasında, eğer farklılarsa True’a rapor verin . Bir Önlerine Gerçek liste vardır ki Gerçek her bir "run" başında.
  • (#;.1~...) - Yukarıdaki boolean vektörünü kullanarak her çalışmanın uzunluğunu alın.
  • \:~ - Bu uzunlukları en kısadan en kısaya doğru sıralayın.
  • 2|#\- Uzunluk listesi 1 0 1 0 ...sürece değişimli bir liste yapın .
  • (...#...) - Soldaki her numara için (sıralanmış uzunluklar), sağdaki karşılık gelen öğenin çoğunu al (alternatif 1 ve 0'lar)
  • &. - Bu yeni ikili gösterimi bir sayıya dönüştürün.

Örnekler:

   (\:~#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

Perl 5.10, 121 101

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

Bence sıralama kısmı daha kısa olabilir.

Düzenleme: -20 bayt, sembolik sayesinde!


Sen-ebilmek kurtulmak \nve mdüzenli ifade eşleştirme için gerekli değildir. Yerine, sadece .char grubu yerine kullanın .
simbabque

Parçaya da gerek yok grep. octDüzgün olsa :) olduğunu
simbabque

Teşekkür ederim, bu parçaları yanlışlıkla orijinal koddan çıkardım.
Laposhasú Acsa

1

Python 3, 146 136 bayt

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

Yerine mapbir ile lambda, bunu yapmak için daha iyi olurdu ''.join(... for ... in ...)?
Sp3000,

1

Mathematica, 83 bayt

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

Bu adsız bir işlevi tanımlar.


0

Ruby, 107 104 102 bayt

( nimi sayesinde 3 bayt kaydedildi )

CJam'ın beğenilerini yenmeyeceğim, ama aklı başında bir dil için oldukça küçük buldum.

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

Kaydetmek için birkaç bayt: (i+=1)%2is i=1-i.
nimi

@nimi Ah, teşekkür ederim. Bunu nasıl kısaltacağımı anlamaya çalışıyordum.
Monica iamnotmaynard'ı

0

Java 8, 179 176 bayt

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

İki statik ithalat kullandım: java.util.Integer.highestOneBitve java.util.Arrays.sort.

Okunabilmesi için işte kodun kodu:

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 bayt

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'ye Hoşgeldiniz! Maalesef bunun bazı rakamlar için yanlış değerler verdiğini düşünüyorum, örneğin t(0) = 0ne zaman 1bekleniyor ve t(4) = 16 ne zaman bekleniyor
Sp3000
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.