Bir bayt al!


24

Göreviniz, imzasız bir tamsayı verildiğinde n, tek bir bayt veriyi (art arda 8 bit) kaldırarak oluşturulabilecek en büyük sayıyı bulmaktır.


Örnek

Sayı göz önüne alındığında, 7831ilk önce onu ikiliye dönüştürürüz (baştaki sıfırları kaldırarak):

1111010010111

Daha sonra, kaldırıldıklarında en büyük yeni sonucu verecekleri ardışık 8 bit grubunu buluruz. Bu durumda, aşağıda gösterilen 3 çözüm vardır

1111010010111
  ^      ^       
   ^      ^
    ^      ^

Bu verimlerden herhangi birinin çıkarılması 11111, ardından 31cevabın ondalık değerine geri dönmemiz .


Test Kılıfları

256        ->   1
999        ->   3
7831       ->   31
131585     ->   515
7854621    ->   31261
4294967295 ->   16777215 (if your language can handle 32 bit integers)

kurallar

  • Bit uzunluğunun n8'den büyük olacağı garanti edilir .
  • Çözümünüz teorik olarak n8'den büyük herhangi bir bit uzunluğu için çalışmalıdır , ancak pratikte sadece tamsayılar için 255 <n <2 16 çalışmalıdır.
  • Giriş / Çıkış ondalık basamakta olmalıdır.
  • Tam bir program veya bir işlev sunabilirsiniz.
  • Bu , yani en kısa program (bayt cinsinden) kazanır!

1
İnsanların neden ünlem işaretlerini meydan okumaya koyduğunu anlamıyorum! Karakter sınırlaması olabileceğini düşünüyorum! Belki de insanlar mücadeleyi fark etseler de!
dkudriavtsev

1
@Mendeleev Bu zorunlu bir cümledir. Bunlar genellikle ünlem işaretleriyle sonlandırılır. Sadece doğru noktalama işaretleri, neden seni üzdü?
Arthur

1
@Mendeleev İnsanlar bir şakayı belirtmek için sıklıkla ünlem işareti kullanırlar. OP, bir gösteri yaptığını vurgulamaktadır. F. Scott Fitzgerald bundan hoşlanmadı , ama bu bağlamda bana iyi geliyor. Orada olmasaydı, muhtemelen insanları hecelemesinden şikayet ederdi.
bornfromanegg

@Mendeleev kötü bir cinas çünkü ...
FlipTack

@bornfromanegg İnsanların cezayı fark edeceğini hissediyorum
dkudriavtsev

Yanıtlar:


16

Jöle , 6 bayt

BḄ-8ƤṀ

Bir sayı alan ve bir sayı döndüren tek parça bağlantı.

Çevrimiçi deneyin!

Nasıl?

Güzel bir Tarih kullanır çabuk , Ƥtarafından geliştirilen mil ...

BḄ-8ƤṀ - Link: number
B      - convert to a binary list
    Ƥ  - for loop over some slices to be determined...
  -8   - this is a negative nilad, therefore: use overlapping outfixes of length 8
       -   (exactly what the specification asks us to inspect)
 Ḅ     -   convert from a binary list to an integer (vectorises)
     Ṁ - maximum

> _> ... Vay benim 10 bayt tarafından yendi
Sayın Xcoder

8

J , 12 bayt

[:>./8#.\.#:

Çevrimiçi deneyin!

          #:     to binary
     8  \.       remove consecutive groups of eight
      #.         convert each result to decimal
  >./            maximum
[:               do nothing, this lets me avoid parentheses

Orada hangi şık algoritma var? Bir açıklama ekler misiniz?
Bay Xcoder

@Bay. Xcoder FrownyFrog, sayıyı ikili basamakların listesine (#:) dönüştürür, ardından tüm 8 ekleri veya ardışık 8 bitlik ekleri olan listeyi tekrar ondalık sayı sistemine (8 #. \.) Dönüştürür ve sonunda büyük taş. [: basitçe önceki iki fiili kaplar,> ./ monadik olarak gerçekleştirilir (sadece doğru argümanla)
Galen Ivanov

Bugün bana outfix'i öğrettin, bunun için teşekkürler! Bu altında kullanmak daha kısa görünmüyor utanç verici &.; bu onun için mükemmel bir problem.
cole,


6

JavaScript (ES6), 54 bayt

f=(n,v=n>>8,b=1,m=0)=>b>v?m:f(n,(v^n)&b^v,b+b,v>m?v:m)
<input type=number min=256 max=2147483647 oninput=o.textContent=f(this.value)><pre id=o>

2 ** 31-1'e kadar çalışır. Çünkü biri biraz titrek cevap istedi ...





3

Wolfram Dili (Mathematica) , 46 bayt

Floor@If[#<256,0,Max[#/256,2#0[#/2]+#~Mod~2]]&

Çevrimiçi deneyin!

Bu sürüm yalnızca 2 518 -1'e kadar olan girişleri idare edebilir , aksi takdirde Mathematica'nın yığın boyutu sınırına rastlarız. (Sınır Mathematica kurulumları arasında değişebilir.) Bu cevaptaki ikinci çözüm bundan kaçınıyor.

Nasıl çalışır

Aşağıdaki mantığı temel alan özyinelemeli bir yaklaşım:

  • En büyük değer, 0herhangi bir girdi için daha küçük olmalıdır 256, çünkü sayıdan bir bayt alarak sayının tamamını yer. Bu bizim temel durumumuzdur, bu yüzden özellikler bize söz verse de bu tür girdilerle uğraşmayacağız.
  • Aksi takdirde, Maxiki seçeneğe sahip oluruz : en düşük baytı yiyin (bize girdiyi bölerek verin 256) ya da en düşük biti kesin, kalan tamsayıya tekrar gelin ve işimiz bittiğinde en düşük biti geri ekleyin.

Wolfram Dili (Mathematica) , 55 bayt

Max@Table[Mod[#,m=2^k]+Floor[#/m/2^8]m,{k,0,Log2@#-8}]&

Çevrimiçi deneyin!

Özyineleme yerine bir tablo oluşturan alternatif bir sürümdür, böylece Mathematica'nın kullanabileceği her boyuttaki sayı için çalışır.


2
Matematiğin daha büyük sayıları işleyebilmesine rağmen, öznitelik derinliği 10 ^ 160'dan büyük sayılar için aşılmıştır. Ama OP onunla gayet tahmin
J42161217

2

Retina , 71 67 64 bayt

.+
$*
+`(1+)\1
$+0
01
1
.
$`_$'¶
_.{7}

A`_
O^`
1G`
+1`\B
:$`:
1

Çevrimiçi deneyin! Bağlantı, Dennis sunucusunu gereğinden fazla yüklememek için yalnızca daha hızlı test durumlarını içerir. Düzenleme: @ Martininder sayesinde 3 bayt kaydedildi. Açıklama:

.+
$*
+`(1+)\1
$+0
01
1

Ondalıktan ikiliye dönüştürün.

.
$`_$'¶
_.{7}

A`_

Tüm ardışık 8 ardışık basamağı silerek elde edilen dizelerin bir listesini yapın.

O^`
1G`

Bunları ters sırada sıralayın ve ilkini alın (en büyük).

+1`\B
:$`:
1

Ondalık basamağa dönüştür. (Bkz. @ MartinEnder'in açıklaması .)


1
Bir süre önce ondalık dönüşüm için bu kısa ikili sayı ile geldi . Bu cevapta nasıl çalıştığını açıkladım .
Martin Ender


2

ReRegex , 294 275 bayt

Daha iyi 'işlev' tanımlarını kullanarak 19 bayt kaydedildi

Bunun bir Regex sadece dili için oldukça iyi olduğunu söyleyebilirim.

Temel lib, Unary ve Decimal arasında dönüşüm sağlar (Bu, sorun spesifik olarak açıkça belirtildiği için gereklidir), ancak Binary'i desteklemez; Bu yüzden buna 120 byte ekleyen betiğin bir parçası olarak yazmak zorunda kaldım.

#import base
b(\d*):(_*)\2_b/b1$1:$2b/b(\d*):(_+)\2b/b0$1:$2b/b(\d+):b/$1/b:b/0/B(_*):1/B$1$1_:/B(_*):0/B$1$1:/B(_*):B/$1/j(\d*),\1(\d)(\d{7})(\d*):/j$1$2,$1$2$3$4:,B:$1$4B/j(\d*),\1\d{0,7}:,?(.*)/,$2,/,((_+)_+),(\2),/,$1,/,(_+),(\1_*),/,$2,/^,(_*),$/d<$1>/j,b:u<(?#input)>b:

Çevrimiçi deneyin!

Bireysel Regexes tarafından.

#import base
b(\d*):(_*)\2_b/b1$1:$2b/
b(\d*):(_+)\2b/b0$1:$2b/
b(\d+):b/$1/
b:b/0/
B(_*):1/B$1$1_:/
B(_*):0/B$1$1:/
B(_*):B/$1/
j(\d*),\1(\d)(\d{7})(\d*):/j$1$2,$1$2$3$4:,B:$1$4B/
j(\d*),\1\d{0,7}:,?(.*)/,$2,/
,((_+)_+),(\2),/,$1,/
,(_+),(\1_*),/,$2,/
^,(_*),$/d<$1>/
j,b:u<(?#input)>b:

adımlar

İlk olarak, iki regex veren 'base' kütüphanesini içeri aktarıyoruz. Biri u<numbers>birliğe dönüşür . Ve dönüştürend<unary_underlines> ondalığa . Bunun nedeni, meydanın temel10'da IO gerektirmesidir.

Sonra, birliği ikiliye çeviren bir avuç regex tanımlarız.

b(\d*):(_*)\2_b/b1$1:$2b/
b(\d*):(_+)\2b/b0$1:$2b/
b(\d+):b/$1/
b:b/0/

Bunlardan ilki , isteğe bağlı olarak bazı ikili basamaklar, ardından a , Ardından herhangi bir alt çizgi miktarını, ardından aynı alt çizgi alt satırları artı bir ve son olarak bir başkasını b(\d*):(_*)\2_b/b1$1:$2b/arar .b:b

Daha sonra b1bunu önce gelen ikili :sayılarla, ardından alt çizgilerin ilk yarısında ve son olarak sonuncuyla değiştiririz.b .

Bu nedenle, unary ikiye bölünemez olup olmadığını kontrol eder ve eğer öyleyse, 1'i ikilik hanelere hazırlar, sonra eksi ikiye böler.

İkincisi b(\d*):(_+)\2b/b0$1:$2b/, neredeyse kimliği belirsizdir, ancak ekstraları kontrol etmez _, yani sadece ikiye bölünebilirse eşleşir ve bu durumda bir0 bunun yerine .

Üçüncüsü, normal rakamlardan çıkıp çıkmadığımızı kontrol eder ve öyleyse, sadece ikili sayıları bırakmak için dolguyu çıkarır.

Sonuncusu, hiçbir zaman verilen hiçbir ikili rakam olup olmadığını kontrol eder ve bu durumda sadece bırakır 0.

Tanımladığımız bir sonraki Regex grubu, ikiliyi birliğe geri dönüştürmek ve biraz daha basit hale getirmek.

B(_*):1/B$1$1_:/
B(_*):0/B$1$1:/
B(_*):B/$1/

Bu grubun ilki B(_*):1/B$1$1_:/, antitezi gibi, a'yı B, ardından herhangi bir Unary basamağını izliyor :1. BBu durumda eşleşmeyi kontrol etmez , çünkü bir seferde sadece bir rakam arar. Bu eşleştirilirse, daha önce eşleşen tek sayı rakamlarını ikiye katlar ve birini ekler, sonra birini kaldırır.

İkincisi, B(_*):0/B$1$1:/birinciden 0çok eşleşmeler hariç, ilkiyle neredeyse özdeş ve ek bir tekil rakam eklemiyor 1.

Bunlardan sonuncusu, B(_*):B/$1/artık ikili rakam bulunup bulunmadığını kontrol eder ve eğer öyleyse unary uni açar. Antitezinin aksine, bunun özel bir 0 durumuna ihtiyacı yoktur.

Daha sonra j, bölme işlevi olarak işlev gören regex'leri tanımlayacağız .

j(\d*),\1(\d)(\d{7})(\d*):/j$1$2,$1$2$3$4:,B:$1$4B/
j(\d*),\1\d{0,7}:,?(.*)/,$2,/

İlk, j(\d*),\1(\d)(\d{7})(\d*):/j$1$2,$1$2$3$4:,B:$1$4B/ağır kaldırma çoğu yapar. jİsteğe bağlı olarak "artan" olan ikili basamakları, ardından bir virgül, ardından artandan sonra tam olarak 8 ikili basamağı, ardından ikili sayının kalanını izleyen bir virgül arar :. 8 haneden ilki, artırıcıya eklenir, böylece artırır, daha sonra her iki ikili girişten gelen 8 haneden sonra, :a ,. Yani (8 yerine 2 rakam kullanıyor j,1001:olsaydık ) j1:1001:,01o zaman olur j10:1001,01,11. Ek olarak, eklenen dizi öğeleriB onları birleşik duruma dönüştürmek için s'ye .

Diğeri, j(\d*),\1\d{0,7}:,?(.*)/,$2,/artıştan sonra kontrol etmek için geriye kalan 8 haneden az hanenin olup olmadığını kontrol eder ve öyleyse, ,s'ye sarılmış diziden başka her şeyi kaldırır . Örneğin.,_,___,

Dizinin yaratılması sırasında ve sonrasında karşılaştırma regex'lerini tanımlarız.

,((_+)_+),(\2),/,$1,/
,(_+),(\1_*),/,$2,/

Bunlardan ilki, ,((_+)_+),(\2),/,$1,/virgül, ardından bir miktar alt çizgi, ardından bir miktar virgül, ardından da bir virgül, sonra da ilk alt çizgi virgül kontrol eder. Daha sonra ,s ile çevrili ilk elemandaki toplam alt çizgi miktarıyla değiştirilir .

İkincisi, ,(_+),(\1_*),/,$2,/bir virgül olup olmadığını, ardından bir miktar virgül, ardından başka bir virgül, sonra aynı miktarda veya daha fazla altı çizili ve son bir virgül kontrol eder. Bu yerine doğru eleman bırakacaktır.

Sonunda, eşleştirilen eleman kaldığında ^,(_*),$, çevreleyen virgülleri siler ve ondalık karaktere geri dönüştürürüz d<>. O zaman daha fazla regex ateşlenemez ve çıktı sunulur.

Giriş, ilk j,b:u<(?#input)>b:önce ondalık girişi birime, örneğin 5-> dönüştüren şablona yerleştirilir j,b:_____b:, daha sonra elde edilen ikili, j,101:ikiye katlanır, Sonra ikili dosyayı böler (örnek için çalışmaz), en büyük elemanı alır, dönüştürür ondalık basamağa geri döndü ve bitti.


2

C (gcc), 91 bayt

j;m;t;f(x){for(j=m=0;t=x>>j+8;m<t?m=t:j++)t=t<<j|x%(1<<j);return m;}

-23 Colera Su'dan bayt

Kadar destekler 2**31-1

Çevrimiçi deneyin!

Düşük 8 bit ile başlar (j=0), sonra artar, eğer [j,j+8)kesilen sayı bizim akımımızdan büyükse çıktıyı değiştirir ve x'in üstünde hiçbir bit olmayana kadar devam ederj+8


2
Mağaza x>>j+8ve x>>j+8<<j|x%(1<<j)bir değişkene (parantez kaldırıldı) bunu azaltacaktır 68 bayt .
Colera Su,


1

JavaScript (ES6), 94 91 bayt

Justin Mariner sayesinde -3 bayt

f=(n,d='',c=n.toString(2).match(`(${d}).{8}(.*)`))=>c?Math.max('0b'+c[1]+c[2],f(n,d+'.')):0

Sadece JavaScript string tabanlı bir çözüm atmak, ancak birinin bitsel tabanlı ayrı bir çözüm göndermesini umuyorum, böylece bir şeyler öğrenebilirim.

Benim çözümüm tekrarlı bir şekilde dizgiden 8 bitlik bir öbek yakalar ve bulunan maksimum değeri alır.


1
Sanırım bunu bir sayıya +(...)çevirirsiniz '0b'+c[1]+c[2], çünkü bunu Math.maxzaten yapar. Çevrimiçi deneyin! ( gelecekteki referans için spec )
Justin Mariner

@JustinMariner, tatlı, teşekkürler!
Rick Hitchcock

1

C # (.NET Core) , 122 + 13 = 135 120 + 13 = 133 bayt

n=>{int m=0,i=0,t;for(var b=Convert.ToString(n,2);i<b.Length-7;m=t>m?t:m)t=Convert.ToInt32(b.Remove(i++,8),2);return m;}

Çevrimiçi deneyin!

İçin +13 using System;

Bunu yapmanın bir yolu olduğunu hayal ediyorum Convert. Her iki durumda da, bu azaltılabilir eminim.

Teşekkür

Kevin Cruijssen sayesinde -2 bayt

UnGolfed

n=>{
    int m=0,
        i=0,
        t;

    // convert n to a binary string,
    // go through removing each possible byte,
    // check if this is the biggest int so far
    for (var b=Convert.ToString(n,2); i<b.Length-7; m=t>m?t:m)
        t=Convert.ToInt32(b.Remove(i++,8),2); // remove 8 bits from position i, then convert from binary string to int

    return m;
}

Sen değiştirerek byte kaydedebilirsiniz whileiçin forve koyarak var bonun içinde:for(var b=Convert.ToString(n,2);i<b.Length-7;)
Kevin Cruijssen

Ve yeni bir int değişkeni ekleyerek 1 byte daha kaydedebilirsiniz ,tkullanarak değil Math.Max, ancak bunun yerine manuel kontrol: n=>{int m=0,i=0,t;for(var b=Convert.ToString(n,2);i<b.Length-7;m=t>m?t:m)t=Convert.ToInt32(b.Remove(i++,8),2);return m;}( 120 + 13 bayt )
Kevin Cruijssen

1

PHP, 67 + 1 bayt

do$r=max($r,$argn&($x=2**$i++-1)|$z=$argn>>8&~$x);while($z);echo$r;

Pipe ile çalıştırın -nRveya çevrimiçi deneyin .


1

Pyth, 19 bayt

eSmi.>>.<.BQd8d2a6l

Alternatif cevap:

eSmi.<<8.>.BQdd2a6l

Açıklama:

eSmi.>>.<.BQd8d2a6lQ | Implicit Q at the end, where Q = input
  m             a6lQ | Map the over [0, 1, 2, ... , floor(log base 2 of Q) - 7]
         .BQ         |  Convert Q to binary string
       .<   d        |  Cyclically rotate left by d
      >      8       |  Get string from position 8 to end.
    .>        d      |  Cyclically rotate right by d
   i           2     |  Convert from binary string to integer
eS                   | Find the last element of sorted list (maximum value)

Diğer cevap, ilk önce sağa dönmesi dışında benzer bir yaklaşım kullanır ve son 8 dışındaki tüm bitleri alır.


1

MATL , 23 21 bayt

Bn8-:"GB[]@8:q+(XBvX>

Çevrimiçi deneyin!

B                       % Implicitly grab input, convert to binary
 n8-:                   % Create list of 1,2,... n-8, with n the size of the binary string
     "                  % Loop over this list
      GB                % Grab the input again, convert to binary once more.
        @8:q+           % Create indices of a slice of length 8
             [](        % Index into binary string, delete the slice
                XB    % Convert the remainder from binary to integer
                  vX> % Get the maximum number so far.

Ne yazık ki, Bn8-:8:!+q&)yalnızca kaldırmak istediğimiz dilimleri üretiyoruz, kalanları da tutmak istemiyoruz.


Bu bayt bir çift kaydeder Bn8-:"GB[]@8:q+(XBvX>(atama []ile (kullanmak yerine &), ve değiştirme &:ile :ve ekleme)
Luis Mendo

@LuisMendo Teşekkürler. Belgeleri yanlış okudum, bir yerde boş atamalar için yalnızca tek bir dizin kullanabileceğinizi, ancak farklı bir durum için kullanabileceğinizi söyledim.
Sanchises


0

Octave , 81 80 bayt

@(x)max(bin2dec(dec2bin(x*(c=2.^(0:(b=nextpow2(x+1)-8))))(:,[1:b b+9:end]))'./c)

Çevrimiçi deneyin!

Bu, benim ilk girişime göre, 14 baytı daha tasarruf ederek farklı bir çözüm.

Kod aşağıdaki gibi bozulmuştur:

@(x)max(                                                                       )
        bin2dec(                                                          )'./c
                                                         (:,[1:b b+9:end])
                dec2bin(x*(                            ))
                           c=2.^(0:                   )
                                   (b=nextpow2(x+1)-8)

Altıncı satırda, grupların sayısı girişten daha büyük bir sonraki iktidarın üssünü (giriş sayısındaki bit sayısı) bulmak ve her gruptan 8 bit çıkarırken 7'yi çıkarmakla hesaplanır - sonuçtaki sayı bsonradan saklanır .

Ardından, beşinci satırda, kaldırılabilecek tüm olası gruplar için yeterince büyük olan iki güç dizisini hesaplıyoruz. Bunu değişkene kaydederizc daha sonra saklıyoruz.

Bir sonraki satırda (dördüncü satır) girdiyi iki güç dizisi ile çarptırırız (esas olarak her sayıyı yukarı kaydırırız) ve sonucu ikiliye dönüştürürüz. 7831 örneğini alırsak, bu aşağıdakileri içeren bir 2D dizisine neden olur:

000001111010010111
000011110100101110
000111101001011100
001111010010111000
011110100101110000
111101001011100000

Daha sonra 8 bitlik merkezi kesersek, bu 8 bitlik grupların her birinin çıkarılmasına eşdeğerdir. Bu üçüncü satır tarafından yapılır.

Ortaya çıkan dizi, ikinci satırda ondalık basamağa dönüştürülür. cBaşlangıçta her gruba yapılan ölçeklendirmeyi geri almak için de bölünmek zorundayız .

Sonunda ilk satırda adsız bir işlev bildirilir ve tüm gruplardan elde edilen maksimum değer hesaplanır.


  • Kullanılarak 1 byte tasarruf nextpow2(x+1)yerinennz(bin2dec(x))


Orijinal deneme - 120 98 95 bayt

@(x)max(bin2dec(reshape(repmat(a=(d=@dec2bin)(x)',1,b=nnz(a)-7)(d(255*2.^(0:b-1))'<49),[],b)'))

Çevrimiçi deneyin!

Kod aşağıdaki gibi ayrılmıştır:

@(x)max(                                                                                      )
        bin2dec(                                                                             )
                reshape(                                                              ,[],b)'
                        repmat(a=(d=@dec2bin)(x)',1,b=nnz(a)-7)(                     )
                                                                d(255*2.^(0:b-1))'<49

Temel olarak, kaldırılabilecek muhtemel değer gruplarını içeren bir matris hesaplar ve ardından en büyük sayıyı veren bitmek üzere çalışır.

Satır satır çalışma, beşinci satır kaldırılabilecek grupları hesaplar. Örneğin, 7831'i alın. Bu, grupları veren 13bit bir sayıdır:

1111100000000
1111000000001
1110000000011
1100000000111
1000000001111
0000000011111

Beşinci satırın sonucu, indeksleme için kullanılabilecek bir 2B mantıksal dizidir.

Kodun dördüncü satırı girişi bir bit dizisine dönüştürür ('0' ve '1' karakterleriyle temsil edilir) ve ardından her olası gruplama için bir satır vererek onu n-7 kez ( nbit sayısında) kopyalar . Yukarıdaki grup maskesi, olası grupların her birini kaldırmak için kullanılır.

Üçüncü satırda, sonuç grup maskesinin uygulanmasından kaynaklanan istenmeyen düzleşmeyi geri almak için yeniden şekillendirilir. İkinci satır, sonuçta oluşan ondalık sayılar dizisine geri döner. İlk satır, adsız işlevi, olası grup dizisinin maksimum değeri olarak tanımlar.


  • Matematik kullanarak grupların matrisini üreterek 22 bayt kurtardı.
  • İkili dizgilerden mantıksal grup maskesine dönüşüm olarak 3 bayt kaydedildi.



0

Perl, 53 bayt

( use 5.10.15.10.1 dil seviyesine kadar perl getirmek ücretsizdir)

Giriş numarasını STDIN'e verin. Büyük numaralar için hafıza tükenir, ancak girişteki 32 bitlik sayı henüz sorun değil

#!/usr/bin/perl
use 5.10.1;
$_=sprintf"%b",<>;/.{8}(?{\$F[oct"0b$`$'"]})^/;say$#F
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.