Bir dizide en fazla 1 içeren alt dizeyi bulun


16

Giriş

En 1's 0' ve 1's bir dizi ile alt dize bulmak istiyorum .

Giriş

Programınızın sırası ve alt dize uzunluğu olmak üzere iki girişi vardır .

Sekansı, herhangi bir sayıda olduğunu 0sitesindeki ve 1's:

01001010101101111011101001010100010101101010101010101101101010010110110110

Alt dize uzunluğu , sıfır olmayan herhangi bir pozitif tamsayıdır:

5

Çıktı

Programınız, belirtilen uzunluğu en çok içeren ilk alt dizenin başlangıç ​​dizinini vermelidir 1. Yukarıdaki giriş ile çıkış:

10

Dizedeki ilk karakter bir dizinde başlar 0.

puanlama

En kısa kod kazanır!

kurallar

  • Programınız geçerli girişler için her zaman doğru dizini çıkarmalıdır.
  • Giriş / çıkış yönteminizi varsayılan seçeneklerde pozitif puan alan herhangi bir cevaptan seçebilirsiniz . Lütfen cevabınızda seçtiğiniz yöntemi belirtin.

Başlığınız ve tanıtımınız "en fazla 1'e sahip alt dizeyi bulun" diyor. Ancak program açıklamanız bir alt dize uzunluğu verdiğinizi ve ilk alt dize dizinini aradığınızı söylüyor. Peki, başlığın ve tanıtımın yanlış olduğunu varsaymalıyız? Çoğu insan ilk kısmı çözüyor gibi görünüyor. Kim kazanır?
15'te

@swstephe Karışıklıklarınızı anladığımdan emin değilim. Çoğu için bağlı birden fazla alt 1dize varsa, bulduğunuz ilk alt dize çıktısını alırsınız. Alt dizeleri, o alt dizedeki ilk karakterin diziniyle tanımlarsınız. Bu yardımcı olur mu?
hmatt1

Peki, alt dizelerde diziyi kırıyor ve ilk alt dizenin dizinini en çok 1 ile geri mi veriyorsunuz? Sanki 1'lerin alt dizelerini aramış gibisin.
swstephe

Eğer mümkün olmayan uzunluklar verirsek, örneğin length = 99?
smci

@smci geçerli girdi için kabul edebilirsiniz. Alt dize uzunluğunun diziden daha uzun olduğu bir durumu ele almanız gerekmez.
hmatt1

Yanıtlar:


11

Dyalog APL, 11

(-∘1+⍳⌈/)+/

Burada deneyin. Kullanımı:

   f ← (-∘1+⍳⌈/)+/
   4 f 0 1 1 0 1 1 1 0 0 0 0 1 1
1

açıklama

Bu, alt dize uzunluğunu soldan ve diziyi sağdan alan ikili (ikili anlamına gelir) işlevidir. Yapısı aşağıdaki gibidir:

   ┌───┴────┐
 ┌─┴──┐     /
 ∘  ┌─┼─┐ ┌─┘
┌┴┐ + ⍳ / +  
- 1   ┌─┘    
      ⌈      

Patlama ile açıklama:

(-∘1+⍳⌈/)+/
(       )+/  ⍝ Take sums of substrings of given length, and feed to function in parentheses
    + ⌈/     ⍝ The array of sums itself, and its maximum
     ⍳       ⍝ First index of right argument in left
 -∘1         ⍝ Subtract 1 (APL arrays are 1-indexed)

Bir örnek olarak, en alalım 4ve 0 1 1 0 1 1 1 0girdi olarak. Önce işlevi +/onlara uygularız ve alırız 2 3 3 3 3. Daha sonra, +ve ⌈/bu diziye uygulandığında kendisini verir 3ve 2 3 3 3 3 ⍳ 3değerlendirir 2, çünkü 3ilk olarak ikinci eleman olarak gerçekleşir. Çıkarır 1ve 1nihai sonuç olarak alırız.


Örneğinizde, uzunluk 4'tür, ancak art arda 4 aynı öğe yoktur (01101110), neden bir şey çıktı?
Thomas Weller

@ThomasW. Meydan örnek ya bir satırda hiçbir 5 aynı öğeleri vardır ve henüz çıkış Ben görev yorumlamak yolu ben sahiptir verilen uzunlukta bir alt dizenin ilk indeksini bulmak gerekir ki 10'dur molanlar, molup maksimal.
Zgarb

10

Ruby, 42

f=->s,n{(0..s.size).max_by{|i|s[i,n].sum}}

Bunu arayarak girdi alır, ör.

f['01001010101101111011101001010100010101101010101010101101101010010110110110',5]

Bu, toplam ASCII değerlerini kullanarak alt dizeleri karşılaştırır ve maksimum dizini döndürür. max_byRuby spec kararlı olması gerekiyorsa emin değilim ama C uygulama gibi görünüyor.


6

Python 2, 56

lambda s,l:max(range(len(s)),key=lambda i:sum(s[i:i+l]))

Bir tamsayılar dizisini, ardından uzunluğu kabul eder.


Bu, girdi olarak bir tamsayılar dizisine ihtiyaç duyar, bu nedenle bir dize ile başlarsanız şunları yapmanız gerekir:[int(s) for s in "010010...0"]
smci

Hata: f(ss, 999)0 döndürür (Yok yerine). Bunu düzeltebilir misin? Bu tartışmalı bir şekilde kural 1'i ihlal ediyor.
smci

@smci Neden bahsettiğiniz hakkında hiçbir fikrim yok. Değişkende neler olduğunu nasıl bilebilirim ss? Nonecevap bir tamsayı olduğu için hiçbir zaman istenen bir çıktı değildir.
feersum

5

Parti - 222

Toplu iş, bu tür operasyonlar için mükemmel bir dildir.

@echo off&setLocal enableDelayedExpansion&set s=%1&set l=-%2
:c
if defined s set/Al+=1&set "s=%s:~1%"&goto c
set s=%1&set x=0&for /l %%a in (0,1,%l%)do set c=!s:~%%a,%2!&set c=!c:0=!&if !c! GTR !x! set x=!c!&set y=%%a
echo !y!

Golfsüz / disseke:

İlk kurulum. Değişken s, giriş dizesidir ve giriş dizesinin luzunluğu, eksi alt dizgi uzunluğu (negatif olarak belirtilen alt dizgi uzunluğunun %2bulunduğu yerde sıfırlanır %2) olacaktır.

@echo off
setLocal enableDelayedExpansion
set s=%1
set l=-%2

lSaf bir Batch dize uzunluğu çözümü kullanarak girişin uzunluğunu alın - bu s, giriş dizesini içeren değişkeni yönetir , bu yüzden daha sonra tekrar ayarlarız.

:c
if defined s (
    set /A l += 1
    set "s=%s:~1%"
    goto c
)
set s=%1

Değeri, xhangi alt dizenin en fazla 1'e sahip olduğunu kontrol etmek için kullanılır. 0'dan dizenin uzunluğuna, ek olarak alt dizenin uzunluğuna (değişken l) bir döngü başlatın . Döngüdeki ( %%a) geçerli noktadan başlayarak alt dizeyi al, cbaşlangıç %%ave %2(verilen alt dizgi uzunluğu) karakterlerini alarak giriş dizesi olarak ayarlanır . Herhangi bir 0s kaldırılır c, sonra değeri cile karşılaştırılır x- yani 111daha büyük bir sayıdır, 11bu yüzden karşılaştırmadan daha büyük yapmak için 'string' i kullanabiliriz. ysonra dize içinde geçerli konuma ayarlanır - bu nihayet çıktı olarak verilir.

set x=0
for /l %%a in (0, 1, %l%) do (
    set c=!s:~%%a,%2!
    set c=!c:0=!
    if !c! GTR !x! (
        set x=!c!
        set y=%%a
    )
)
echo !y!

OP örneği kullanma -

h:\>sub1.bat 01001010101101111011101001010100010101101010101010101101101010010110110110 5
10

5

C # (Normal İfade), 196

class Test{static void Main(string[]a){System.Console.Write(System.Text.RegularExpressions.Regex.Match(a[1],"(?=((?<o>1)|0){"+a[0]+"})(?!.+(?=[10]{"+a[0]+"})(?!((?<-o>1)|0){"+a[0]+"}))").Index);}}

Gerçek regex o kadar uzun değil, ama bir C # programı kod boyutunu iki katına derlemek için gereken tüm tüyler.

Uzunluğu 5 olarak ayarlayan gerçek normal ifade:

(?=((?<o>1)|0){5})(?!.+(?=[10]{5})(?!((?<-o>1)|0){5}))
  • (?=((?<o>1)|0){5}): 5 karakteri tüketmeden okumak için ileriye bakın ve hepsini bir 1yığın haline getirino .
  • (?=[10]{5})(?!((?<-o>1)|0){5}): Önünde 5 karakter olan bir konumda, "yığın" içinde yeteri kadar öğe oyok, yani alt dize kesinlikle daha fazla1 mevcut konumda sahip olduğumuzdan fazlasına .
  • (?!.+(?=[10]{5})(?!((?<-o>1)|0){5})): İpin geri kalanı için yukarıda açıklandığı gibi bir konum bulunamaz, yani tüm konumların sayısı eşit veya daha azdır 1.

İlk sonucu almak cevabı verir, çünkü önündeki tüm alt dizelerin önünde daha fazla alt dizesi vardır 1ve geçerli dizinden daha büyük herhangi bir dizinin eşit veya daha az sayıda1 .

(Ve güzel bir şey öğreniyorum: "yığın" geri izleme üzerine geri yüklendi).


1
Çok güzel, bunu bir regex ile yapabileceğinizi tahmin edemezdim.
histokrat

4

Pyth , 12

Mho/<>GNHZUG

Bu, ggirdi olarak bir sayı listesi ve bir sayı gerektiren bir işlevi tanımlar . Örneğin

Mho/<>GNHZUGg[0 1 0 0 1 0 1 0 1 0 1 1 0 1 1 1 1 0 1 1 1 0 1 0 0 1 0 1 0 1 0 0 0 1 0 1 0 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 0 1 1 0 1 0 1 0 0 1 0 1 1 0 1 1 0 1 1 0)5

Burada test edebilirsiniz: Pyth Derleyici / Yönetici

Açıklama:

Mho/<>GNHZUG
M             defines a function g(G,H), G is the sequence, H the sequence length
  o       UG  orders the numbers between 0 and len(G)-1 according to the following key
    <>GNH     take the subsequence G[N:N+5]
   /     Z    count the zeros in this subsequence (this is the key)
 h            return the first value of the sorted list (minimum)

Alternatif:

Mho_s<>GNHUG

Bir değer dizesi (01001 ...) alan bir programı kullanarak aynı uzunlukta bir cevap alabilirsiniz, sonra sayı: ho/<>zNQ\0UzNe yazık ki, bir dize saymak aradığınızı otomatik olarak bir dizeye dönüştürmez :(
FryAmTheEggman

4

J, 15 14 karakter

   ([:(i.>./)+/\)

   5 ([:(i.>./)+/\) 0 1 0 0 1 0 1 0 1 0 1 1 0 1 1 1 1 0 1 1 1 0 1 0 0 1 0 1 0 1 0 0 0 1 0 1 0 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 0 1 1 0 1 0 1 0 0 1 0 1 1 0 1 1 0 1 1 0
10

Gerçek diller özellikle kod golf için yapılan dilleri yendiğinde ilginç buluyorum. K girişim yenildi ya da ben onu gönderirdi, ama yine de 20 karakter geldi.
JasonN

4

Matlab (42)

Izin sdize ve ifade nalt dize uzunluğunu. Sonuç r.

sBir dizi ile evrimi hesaplayın n, sonra maksimumu bulun. Konvolüsyon ile kolayca yapılır convve maxfonksiyon ilk maksimumun pozisyonunu döndürür . Bu çıkarmak için gerekli 1Matlab indeksleme başlar çünkü, ortaya çıkan endekse 1değil 0.

[~, r] = max(conv(s, ones(1,n), 'valid'));
r = r-1;

golfed:

[~,r]=max(conv(s,ones(1,n),'valid'));r=r-1

4

Haskell, 64 62 Bayt

n#l=0-(snd$maximum[(sum$take n$drop x l,-x)|x<-[0..length l]])

Kullanımı:

5#[0,1,0,0,1,0,1,0,1,0,1,1,0,1,1,1,1,0,1,1,1,0,1,0,0,1,0,1,0,1,0,0,0,1,0,1,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,0,1,1,0,1,0,1,0,0,1,0,1,1,0,1,1,0,1,1,0]

Bir infix işlevi tanımlayarak 2 bayt kaydedebilirsiniz:n#l=...
Zgarb

için bir infix işlevi kullanabilirsiniz p. Ayrıca, bence 0gereksiz (parantez olmamasına rağmen, bunun yerine bir yere ihtiyacınız olabilir 0).
gururlu haskeller

3

JavaScript (ES6) 73

İstenen değeri döndüren bir işlev. For döngüsü giriş dizesini tarar ve maksimum değeri kaydeder.

F=(a,n)=>(x=>{for(r=t=i=x;a[i];t>x&&(x=t,r=i-n))t+=a[i]-~~a[i++-n]})(0)|r

Ungolfed

F=(a, n) => {
   for(x = r = t = i = 0; a[i]; i++)
     t += a[i] - ~~a[i-n], // ~~ convert undefined values (at negative index) to 0
     t > x && (x=t, r=i-n+1);
   return r;
}

FireFox / FireBug konsolunda test et

F("01001010101101111011101001010100010101101010101010101101101010010110110110",5)

Çıktı 10


Kodunuzu azaltmak için değişkenleri tanımlamak gerekmez xve r. Bu, 69 baytlık son uzunluk olan 4 baytı azaltmalıdır. Ayrıca, muhtemelen yerine &&geçebilirsiniz &. Ama ~~hile ile güzel bir tane !
Ismael Miguel

@IsmaelMiguel x'i başlatmanız gerekiyor, ilk başta hata t > x. R: denemelisiniz F("00000"). Ve & & öykünmek için gereklidir veif
edc65

Tamamen haklısın. Daha düşük veya eşit (x=t, r=i-n+1)olup olmadığını görmezden gelmeyi beklediğinizi fark etmedim . Bu tembel değerlendirmenin iyi bir kullanımı! Keşke bir yerde kesilebilir, ama sanırım bütün işi sen yaptın. tx
Ismael Miguel

3

PHP (96)

for($a=$b=$c=0;(($d=@substr_count($s,1,$a,$n))>$c&&($b=$a)&&($c=$d))||$a++<strlen($s););echo $b;

http://3v4l.org/J4vqa

değişkenleri $sve $nkomut satırında sırasıyla arama dizesi ve alt dize uzunluğu olarak tanımlanmalıdır.

Bu ayrıca substr_count()ve için uygun işlevlere sahip herhangi bir C benzeri dilde de çalışır strlen().


3

Mathematica, 38 36

f=#-1&@@Ordering[-MovingAverage@##]&

Misal:

f[{0,1,0,0,1,0,1,0,1,0,1,1,0,1,1,1,1,0,1,1,1,0,1,0,0,1,0,1,0,1,0,0,0,1,0,1,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,0,1,1,0,1,0,1,0,0,1,0,1,1,0,1,1,0,1,1,0},5]

Çıktı:

10


2

C # (Linq), 148 bayt

using System.Linq;class C{int F(string s,int l){return s.IndexOf(s.Skip(l-1).Select((c,i)=>s.Substring(i,l)).OrderBy(p=>-p.Sum(c=>c)).First());}}

biçimlendirilmiş:

using System.Linq;

class C
{
    int F(string s, int l)
    {
        return s.IndexOf(
            s
                .Skip(l - 1)
                .Select((c, i) => s.Substring(i, l))
                .OrderBy(p => -p.Sum(c => c))
                .First()
        );
    }
}

Girdiyi yöntem parametreleri olarak alır.

Bu ne yapar:

string result = s // string is also char collection
    .Skip(l - 1) // make it collection shorter by l-1
    .Select((c, i) => s.Substring(i, l)) // so we can iterate, and select all substrings
    .OrderBy(p => -p.Sum(c => c)) // order substrings descending by sum of characters
    .First() // take first (most ones)

return s.IndexOf(result); // find index of result string

2

Scala - 70 Bayt

readLine.sliding(readInt).zipWithIndex.maxBy(x=>x._1.count(_=='1'))._2

Ancak zipWithIndex kadar fonksiyon isimleri ile sanırım Scala kod golf için en iyi seçim değildir.


2

Cı, 245 185

#include <stdio.h>
main(int argc,char **argv){char *p,*q;int i,s,m=0;for(p=argv[1];*p;p++){for(s=0,q=p;q-p<atoi(argv[2])&&*q;q++)s+=*q-'0';if(s>m){m=s;i=p-argv[1];}}printf("%d\n", i);}

biçimlendirilmiş:

#include <stdio.h>
main(int argc, char **argv) {
        char *p, *q;
        int i, s, m = 0;
        for (p = argv[1]; *p; p++) {
                for (s = 0, q = p; q - p < atoi(argv[2]) && *q; q++)
                        s += *q - '0';
                if (s > m) {
                        m = s;
                        i = p - argv[1];
                }
        }
        printf("%d\n", i);
}

Kullanımı:

$ ./m1s 01001010101101111011101001010100010101101010101010101101101010010110110110 5
10

1

CJam, 25 21 bayt

q~_,,{1$>2$<:+~}$(]W=

Burada test edin.

Girdiyi alt dize uzunluğu için bir tamsayı ve sırayla bir sıfır ve bir dizi olarak alır:

5 
[0 1 0 0 1 0 1 0 1 0 1 1 0 1 1 1 1 0 1 1 1 0 1 0 0 1 0 1 0 1 0 0 0 1 0 1 0 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 0 1 1 0 1 0 1 0 0 1 0 1 1 0 1 1 0 1 1 0]

açıklama

q~_,,{1$>2$<:+~}$(p];
q~                    "Read and evaluate the input.";
  _,                  "Duplicate the sequence and get its length N.";
    ,                 "Get an array [0 1 ... N-1].";
     {         }$     "Sort this array stably by the result of the given block.";
      1$              "Copy the sequence.";
        >             "Slice off the first i bits.";
         2$           "Copy the substring length.";
           <          "Truncate the sequence.";
            :+        "Get the sum to find the number of 1s.":
              ~       "Bitwise complement in order to sort from highest to lowest.";
                 (    "Shift off the first index from the sorted list.";
                  ]   "Wrap the entire stack in an array.";
                   W= "Extract the last element (the result), discarding the rest.";

Sonuç, programın sonunda otomatik olarak yazdırılır.

Ayrıca, istenen alt dize uzunluğundan daha yakın bir şekilde başlayan dilimleri de göz önünde bulundurduğumu unutmayın, ancak bu son geçerli alt dizenin alt dizeleri olduğundan ve bu nedenle asla geçerli son alt dizeden daha fazla 1s içermeyeceği için sorun değil.


1

Java 329 bayt

bir .matches (regex) implent olacaktı, ama yukarıdaki python çözümleri ile aynı olurdu, bu yüzden bunun yerine sürgülü bir pencere denedim. burada yeni, eğer herhangi bir işaretçi varsa onları duymak mutluluk duyuyoruz.

public class ssMostOnes{
public static void main(String[] a){
    int b=0,w=0;
    for(int i=0;i<a[0].length()-Integer.valueOf(a[1]);i++){
        int c=a[0].substring(i,i+Integer.valueOf(a[1])).length() - a[0].substring(i,i+Integer.valueOf(a[1])).replace("1","").length();
        if(c>w){w=c;b=i;}
    }
    System.out.println(b);
}

}


Bazı ipuçları: iÜçüncü satırdan başlatabilirsiniz . Boşluğun çoğu kaldırılabilir. Kullanım System.out.print((yeni satır gerekmez). Bunun yerine Integer.valueOf(kullanabilirsiniz new Integer(.
Ypnypn
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.