Temukan substring dengan jumlah terbanyak 1 dalam urutan

16

pengantar

Saya ingin mencari substring dengan yang paling banyak 1dalam urutan 0's dan 1' s.

Memasukkan

Program Anda memiliki dua input , urutan dan panjang substring.

The urut adalah sejumlah 0's dan 1' s:

01001010101101111011101001010100010101101010101010101101101010010110110110

The panjang substring adalah setiap positif non-zero integer:

5

Keluaran

Program Anda harus menampilkan indeks awal substring pertama dari panjang yang diberikan yang berisi paling banyak 1. Dengan input di atas, outputnya adalah:

10

Karakter pertama dalam string dimulai pada indeks 0.

Mencetak gol

Kode terpendek menang!

Aturan

  • Program Anda harus selalu menampilkan indeks yang benar untuk setiap input yang valid.
  • Anda dapat memilih metode input / output dari jawaban apa pun dengan skor positif pada opsi default . Silakan tentukan metode yang Anda pilih dalam jawaban Anda.
hmatt1
sumber
Judul dan kata pengantar Anda mengatakan "temukan substring dengan terbanyak 1's". Tapi deskripsi program Anda mengatakan Anda memberikan panjang substring dan mencari indeks substring pertama. Jadi haruskah kita berasumsi bahwa judul dan pengantar salah? Kebanyakan orang tampaknya akan menyelesaikan bagian pertama. Yang menang?
swstephe
@swepephe saya tidak yakin saya mengerti kebingungan Anda. Jika ada lebih dari satu substring yang terikat untuk sebagian besar 1, Anda output substring pertama yang Anda temukan. Anda mengidentifikasi substring dengan indeks karakter pertama dalam substring itu. Apakah itu membantu?
hmatt1
Oke, jadi Anda melanggar urutan dalam substring dan mengembalikan indeks substring pertama dengan paling 1? Kedengarannya seperti Anda mencari substring 1's.
swstephe
Apakah persyaratan "harus selalu menampilkan indeks yang benar untuk setiap input yang diberikan" masih berlaku jika kami memberikan panjang yang tidak layak, mis. Panjang = 99?
smci
@smci Anda dapat mengasumsikan input yang valid. Anda tidak harus menangani kasing yang panjangnya lebih panjang dari urutannya.
hmatt1

Jawaban:

11

Dyalog APL, 11

(-∘1+⍳⌈/)+/

Coba di sini. Pemakaian:

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

Penjelasan

Ini adalah fungsi diad (artinya biner) yang mengambil panjang substring dari kiri, dan urutan dari kanan. Strukturnya adalah sebagai berikut:

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

Penjelasan demi ledakan:

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

Sebagai contoh, mari kita ambil 4dan 0 1 1 0 1 1 1 0sebagai input. Pertama, kita terapkan fungsi itu +/pada mereka dan dapatkan 2 3 3 3 3. Kemudian, +dan ⌈/diterapkan ke array ini memberikan dirinya sendiri dan 3, dan 2 3 3 3 3 ⍳ 3mengevaluasi 2, sejak 3pertama terjadi sebagai elemen kedua. Kami kurangi 1dan dapatkan 1sebagai hasil akhir.

Zgarb
sumber
Dalam contoh Anda, panjangnya adalah 4, tetapi tidak ada 4 item yang sama berturut-turut (01101110), jadi mengapa itu menghasilkan sesuatu?
Thomas Weller
@ Thomas. Contoh dalam tantangan tidak memiliki 5 item yang sama berturut-turut baik, namun output adalah 10. Cara saya menafsirkan tugas adalah bahwa saya harus mencari indeks pertama dari substring dari panjang mengingat bahwa memiliki morang-orang, di mana madalah maksimal.
Zgarb
10

Ruby, 42

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

Mengambil input dengan memanggilnya, mis

f['01001010101101111011101001010100010101101010101010101101101010010110110110',5]

Ini membandingkan substring menggunakan nilai ASCII total dan mengembalikan indeks maksimum. Saya tidak yakin apakah max_bydiperlukan oleh spesifikasi Ruby agar stabil tetapi tampaknya dalam implementasi C.

histokrat
sumber
6

Python 2, 56

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

Menerima array bilangan bulat, lalu panjangnya.

feersum
sumber
Ini membutuhkan array bilangan bulat sebagai input, jadi jika Anda mulai dengan sebuah string, Anda perlu melakukan:[int(s) for s in "010010...0"]
smci
Bug: f(ss, 999)akan mengembalikan 0 (bukan Tidak ada). Bisakah kamu memperbaikinya? Ini bisa dibilang melanggar aturan 1.
smci
@smci Saya tidak tahu apa yang Anda bicarakan. Bagaimana saya bisa tahu apa yang ada di variabel ss? Nonebagaimanapun juga tidak pernah merupakan output yang diinginkan karena jawabannya adalah integer.
feersum
5

Gelombang - 222

Batch jelas merupakan bahasa yang sempurna untuk operasi semacam ini.

@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!

Tidak golf / dibedah:

Pengaturan awal. Variabelnya sadalah string input, dan lakan menjadi panjang string input, dikurangi panjang sub-string (diinisialisasi pada negatif di %2mana %2panjang sub-string yang diberikan).

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

Dapatkan panjang input sebagai l, menggunakan solusi panjang Batch string murni - ini mangles variabel yang sberisi string input, jadi kami kemudian mengaturnya lagi.

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

Nilai xdigunakan untuk memeriksa sub-string mana yang memiliki jumlah terbesar 1's. Mulai loop dari 0 hingga panjang string, minus panjang sub-string (variabel l). Dapatkan sub-string mulai dari titik saat ini di loop ( %%a), cditetapkan sebagai string input mulai dari %%a, dan mengambil %2(panjang sub-string yang diberikan) karakter. Apa pun 0yang dihapus dari c, maka nilai cdibandingkan dengan x- yaitu 111adalah jumlah yang lebih besar daripada 11jadi kita bisa menggunakan 'string' untuk melakukan yang lebih besar daripada perbandingan. ykemudian diatur ke lokasi saat ini di string - yang akhirnya dikeluarkan.

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!

Menggunakan contoh OPs -

h:\>sub1.bat 01001010101101111011101001010100010101101010101010101101101010010110110110 5
10
hapus clemeat
sumber
5

C # (Regex), 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);}}

Regex sebenarnya tidak terlalu panjang, tetapi semua bulu yang dibutuhkan untuk program C # untuk mengkompilasi dua kali lipat ukuran kode.

Regex yang sebenarnya, atur panjangnya menjadi 5:

(?=((?<o>1)|0){5})(?!.+(?=[10]{5})(?!((?<-o>1)|0){5}))
  • (?=((?<o>1)|0){5}): Lihat ke depan untuk membaca 5 karakter tanpa mengkonsumsi, dan dorong semua 1ke dalam "tumpukan" o.
  • (?=[10]{5})(?!((?<-o>1)|0){5}): Pada posisi yang memiliki 5 karakter di depan, tidak ada item yang cukup di "tumpukan" ountuk muncul, yaitu substring memiliki lebih 1dari apa yang kita miliki di posisi saat ini.
  • (?!.+(?=[10]{5})(?!((?<-o>1)|0){5})): Posisi seperti yang dijelaskan di atas tidak dapat ditemukan untuk sisa string, yaitu semua posisi memiliki jumlah kurang dari atau sama 1.

Mengambil hasil pertama memberikan jawaban, karena semua substring di depannya memiliki beberapa substring di depan dengan lebih banyak 1, dan kami telah memeriksa bahwa setiap indeks lebih besar dari indeks saat ini memiliki kurang dari atau sama dengan jumlah 1.

(Dan saya belajar sesuatu yang bagus: "stack" dikembalikan pada backtracking).

n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
sumber
1
Sangat keren, saya tidak menyangka Anda bisa melakukan ini dengan regex.
histokrat
4

Pyth , 12

Mho/<>GNHZUG

Ini mendefinisikan fungsi g, yang memerlukan daftar angka dan angka sebagai input. Misalnya

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

Anda dapat mengujinya di sini: Pyth Compiler / Executor

Penjelasan:

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
Jakube
sumber
Anda bisa mendapatkan jawaban dengan panjang yang sama menggunakan program yang mengambil string nilai (01001 ...) kemudian nomornya: ho/<>zNQ\0UzSedihnya, mengandalkan string tidak secara otomatis mengubah apa yang Anda cari ke string :(
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
randomra
sumber
Saya merasa menarik ketika bahasa nyata mengalahkan bahasa yang khusus dibuat untuk golf kode. Entri K saya sudah dimakan atau saya akan mempostingnya, tapi itu sampai 20 karakter.
JasonN
4

Matlab (42)

Biarkan smenunjukkan string dan npanjang substring. Hasilnya adalah r.

Hitung konvolusi sdengan urutan nyang, kemudian temukan maksimum. Konvolusi dilakukan dengan mudah conv, dan maxfungsi mengembalikan posisi maksimum pertama . Ini perlu untuk mengurangi 1indeks yang dihasilkan, karena pengindeksan Matlab dimulai pada 1, bukan 0.

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

Golf:

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

Haskell, 64 62 Bytes

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

Pemakaian:

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]
nimi
sumber
Anda dapat menyimpan 2 byte dengan mendefinisikan fungsi infiks:n#l=...
Zgarb
Anda dapat menggunakan fungsi infix untuk p. juga, saya pikir 0itu berlebihan (meskipun tanda kurung tidak, dan Anda mungkin membutuhkan ruang, bukan itu 0).
haskeller bangga
3

JavaScript (ES6) 73

Fungsi mengembalikan nilai yang diminta. Loop for memindai string input yang menjaga total berjalan, menyimpan posisi nilai maks.

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

Tidak disatukan

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

Uji di konsol FireFox / FireBug

F("01001010101101111011101001010100010101101010101010101101101010010110110110",5)

Keluaran 10

edc65
sumber
Untuk mengurangi kode Anda, Anda tidak perlu mendefinisikan variabel xdan r. Ini harus mengurangi 4 byte, menjadi panjang akhir 69 byte. Juga, Anda mungkin bisa menggantikannya &&dengan &. Tapi yang bagus dengan ~~triknya!
Ismael Miguel
@ IsmaelMiguel Anda harus init x, kalau tidak kesalahan pada awalnya t > x. Anda perlu init r: coba F("00000"). Dan && diperlukan untuk meniru danif
edc65
Anda sepenuhnya benar. Saya tidak memperhatikan bahwa Anda mengharapkannya untuk mengabaikan (x=t, r=i-n+1)jika tlebih rendah atau sama dengan x. Itu penggunaan evaluasi malas yang bagus! Saya berharap itu bisa dipotong di suatu tempat, tapi saya kira Anda melakukan semua pekerjaan.
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

variabel $sdan$n harus didefinisikan pada baris perintah ke string pencarian dan panjang substring, masing-masing.

Ini juga akan berfungsi dalam bahasa seperti-C dengan fungsi yang sesuai untuk substr_count()dan strlen().

Stephen
sumber
3

Mathematica, 38 36

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

Contoh:

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]

Keluaran:

10

alephalpha
sumber
2

C # (Linq), 148 byte

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

Diformat:

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

Mengambil input sebagai params metode.

Apa fungsinya:

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
Krzysztof
sumber
2

Scala - 70 Bytes

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

Tetapi dengan nama fungsi selama zipWithIndex saya kira Scala bukan pilihan terbaik untuk kode golf.

Dominik Müller
sumber
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);}

Diformat:

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

Pemakaian:

$ ./m1s 01001010101101111011101001010100010101101010101010101101101010010110110110 5
10
Ari Malinen
sumber
1

CJam, 25 21 byte

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

Uji di sini.

Mengambil input sebagai bilangan bulat untuk panjang substring, dan array nol dan yang sebagai urutan:

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]

Penjelasan

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.";

Hasilnya dicetak secara otomatis di akhir program.

Perhatikan bahwa saya juga mempertimbangkan irisan yang mulai lebih dekat ke akhir daripada panjang substring yang diinginkan, tetapi tidak apa-apa, karena mereka adalah substring dari substring valid terakhir dan karenanya tidak akan pernah memiliki lebih 1dari substring valid terakhir.

Martin Ender
sumber
1

Java 329 byte

akan menanamkan .matches (regex), tetapi itu akan menjadi identik dengan solusi python di atas, jadi saya mencoba jendela geser sebagai gantinya. baru di sini, jadi jika ada yang punya petunjuk senang mendengarnya.

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

}

Bryan Devaney
sumber
Beberapa tips: Anda dapat menginisialisasi idi baris ketiga. Sebagian besar ruang putih dapat dihapus. Gunakan System.out.print((tidak perlu baris baru). Alih-alih Integer.valueOf(, Anda bisa menggunakan new Integer(.
Ypnypn