Trova la sottostringa con il maggior numero di 1 in una sequenza


16

introduzione

Voglio trovare la sottostringa con il massimo 1in una sequenza di 0"se 1".

Ingresso

Il programma ha due input , la sequenza e la lunghezza della sottostringa.

La sequenza è un numero qualsiasi di 0"se 1":

01001010101101111011101001010100010101101010101010101101101010010110110110

La lunghezza della sottostringa è un numero intero diverso da zero positivo:

5

Produzione

Il tuo programma dovrebbe generare l'indice iniziale della prima sottostringa della lunghezza data che contiene il massimo 1. Con l'input sopra, l'output è:

10

Il primo carattere nella stringa inizia con un indice di 0.

punteggio

Vince il codice più corto!

Regole

  • Il tuo programma deve sempre generare l'indice corretto per qualsiasi input valido.
  • Puoi scegliere il tuo metodo di input / output da qualsiasi risposta con punteggio positivo nelle opzioni predefinite . Si prega di specificare il metodo scelto nella risposta.

Il tuo titolo e la tua introduzione dicono "trova la sottostringa con il maggior numero di 1". Ma la descrizione del tuo programma dice che stai dando una lunghezza della sottostringa e stai cercando l'indice della prima sottostringa. Quindi dovremmo presumere che il titolo e l'introduzione siano sbagliati? Molte persone sembrano risolvere la prima parte. Chi vince?
venerdì

@swstephe Non sono sicuro di aver capito la tua confusione. Se ci sono più di una sottostringa legata per la maggior parte 1, ottieni la prima sottostringa che hai trovato. Si identificano le sottostringhe con l'indice del primo carattere in quella sottostringa. Questo aiuta?
hmatt1,

Ok, quindi stai interrompendo la sequenza in sottostringhe e restituendo l'indice della prima sottostringa con il maggior numero di 1? Sembrava che stavi cercando sottostringhe di 1.
venerdì

Il requisito "deve sempre fornire l'indice corretto per ogni dato input" si applica comunque se diamo lunghezze non realizzabili, ad esempio lunghezza = 99?
smci,

@smci si può presumere per un input valido. Non è necessario gestire un caso in cui la lunghezza della sottostringa è più lunga della sequenza.
hmatt1,

Risposte:


11

Dyalog APL, 11

(-∘1+⍳⌈/)+/

Provalo qui. Uso:

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

Spiegazione

Questa è una funzione diadica (che significa binaria) che prende la lunghezza della sottostringa da sinistra e la sequenza da destra. La sua struttura è la seguente:

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

Spiegazione per esplosione:

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

Ad esempio, prendiamo 4e 0 1 1 0 1 1 1 0come input. Per prima cosa applichiamo loro la funzione +/e otteniamo 2 3 3 3 3. Quindi, +e ⌈/applicato a questo array, si dà e 3, e 2 3 3 3 3 ⍳ 3valuta 2, dal 3momento che si presenta come il secondo elemento. Sottraiamo 1e otteniamo 1come risultato finale.


Nel tuo esempio, la lunghezza è 4, ma non ci sono 4 elementi uguali in una riga (01101110), quindi perché produce qualcosa?
Thomas Weller,

@ThomasW. L'esempio della sfida non ha nemmeno 5 elementi uguali in una riga, eppure l'output è 10. Il modo in cui interpreto l'attività è che devo trovare il primo indice di una sottostringa della lunghezza data che ne ha m, dove mè massimale.
Zgarb,

10

Ruby, 42

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

Riceve input chiamandolo, ad es

f['01001010101101111011101001010100010101101010101010101101101010010110110110',5]

Ciò confronta le sottostringhe usando il loro valore ASCII totale e restituisce l'indice del massimo. Non sono sicuro se max_byla specifica di Ruby sia richiesta per essere stabile ma sembra essere nell'implementazione C.


6

Python 2, 56

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

Accetta una matrice di numeri interi, quindi la lunghezza.


Questo ha bisogno di una matrice di numeri interi come input, quindi se inizi con una stringa, devi fare:[int(s) for s in "010010...0"]
smci

Bug: f(ss, 999)restituirà 0 (anziché Nessuno). Puoi sistemarlo? Ciò viola probabilmente la regola 1.
smci del

@smci Non ho idea di cosa tu stia parlando. Come posso sapere cosa c'è nella variabile ss? Nonenon è mai l'output desiderato in ogni caso poiché la risposta è un numero intero.
feersum

5

Lotto - 222

Batch è ovviamente il linguaggio perfetto per questo tipo di operazione.

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

Non golfato / sezionato:

Configurazione iniziale. La variabile sè la stringa di input, e lsarà la lunghezza della stringa di input, meno la lunghezza della sottostringa (inizializzata in negativo %2dove si %2trova la lunghezza della sottostringa).

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

Ottieni la lunghezza dell'input come l, usando una soluzione di lunghezza della stringa Batch pura: questo altera la variabile che scontiene la stringa di input, quindi la impostiamo di nuovo.

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

Il valore di xviene usato per verificare quale sottostringa ha il maggior numero di 1. Inizia un ciclo da 0 alla lunghezza della stringa, meno la lunghezza della sottostringa (variabile l). Ottieni la sottostringa a partire dal punto corrente nel loop ( %%a), cè impostata come stringa di input che inizia da %%ae prende %2(la lunghezza della sottostringa) caratteri. Qualsiasi 0s viene rimosso da c, quindi il valore di cviene confrontato con x- ovvero 111è un numero maggiore di 11così possiamo semplicemente usare la 'stringa' per fare un confronto maggiore. yviene quindi impostato nella posizione corrente nella stringa, che viene infine emessa.

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!

Esempio di utilizzo dei PO:

h:\>sub1.bat 01001010101101111011101001010100010101101010101010101101101010010110110110 5
10

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

Il regex effettivo non è così lungo, ma tutti i fluff necessari per un programma C # per compilare il doppio della dimensione del codice.

L'attuale regex, impostando la lunghezza su 5:

(?=((?<o>1)|0){5})(?!.+(?=[10]{5})(?!((?<-o>1)|0){5}))
  • (?=((?<o>1)|0){5}): Guarda avanti per leggere 5 caratteri senza consumarli e spingere tutti 1in "pila" o.
  • (?=[10]{5})(?!((?<-o>1)|0){5}): In una posizione che ha 5 caratteri davanti, non c'è abbastanza oggetto nello "stack" da ofar apparire, cioè la sottostringa ha rigorosamente più 1di quello che abbiamo nella posizione corrente.
  • (?!.+(?=[10]{5})(?!((?<-o>1)|0){5})): Non è possibile trovare una posizione come descritto sopra per il resto della stringa, ovvero tutte le posizioni hanno un numero minore o uguale di 1's.

Prendendo il primo risultato si ottiene la risposta, dal momento che tutte le sottostringhe davanti hanno una sottostringa che precede con più 1', e abbiamo verificato che qualsiasi indice più grande dell'indice corrente abbia un numero minore o uguale di 1'.

(E imparo qualcosa di carino: lo "stack" viene ripristinato sul backtracking).


1
Molto bello, non avrei immaginato che potresti farlo con una regex.
istocrat

4

Pyth , 12

Mho/<>GNHZUG

Questo definisce una funzione g, che richiede un elenco di numeri e un numero come input. Per esempio

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

Puoi provarlo qui: Pyth Compiler / Executor

Spiegazione:

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)

Alternativa:

Mho_s<>GNHUG

Puoi ottenere una stessa risposta di lunghezza usando un programma che accetta una stringa di valori (01001 ...) quindi il numero: ho/<>zNQ\0UzPurtroppo, contare su una stringa non converte automaticamente ciò che stai cercando in una stringa :(
FryAmTheEggman

4

J, 15 14 caratteri

   ([:(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

Lo trovo interessante quando le lingue reali battono le lingue create appositamente per il golf del codice. La mia voce K è stata mangiata o l'avrei pubblicata, ma è arrivata comunque a 20 caratteri.
JasonN,

4

Matlab (42)

Lasciate sindicare la stringa e nla lunghezza sottostringa. Il risultato è r.

Calcola la convoluzione di scon una sequenza di nquelli, quindi trova il massimo. La convoluzione viene eseguita facilmente con conve la maxfunzione restituisce la posizione del primo massimo. È necessario sottrarre 1al indice risultante, perché Matlab indicizzazione inizia 1, non 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 byte

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

Uso:

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]

È possibile salvare 2 byte definendo una funzione infix:n#l=...
Zgarb

potresti usare una funzione infix per p. inoltre, penso che 0sia ridondante (anche se le parentesi non lo sono, e potresti aver bisogno di uno spazio anziché quello 0).
orgoglioso haskeller

3

JavaScript (ES6) 73

Una funzione che restituisce il valore richiesto. Il ciclo for esegue la scansione della stringa di input mantenendo un totale parziale, salvando la posizione del valore massimo.

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

Test nella console FireFox / FireBug

F("01001010101101111011101001010100010101101010101010101101101010010110110110",5)

Produzione 10


Per ridurre il codice, non è necessario definire le variabili xe r. Ciò dovrebbe ridurre 4 byte, essendo la lunghezza finale di 69 byte. Inoltre, probabilmente potresti essere in grado di sostituirlo &&con &. Ma bello con il ~~trucco!
Ismael Miguel,

@IsmaelMiguel devi inizializzare x, altrimenti errore inizialmente t > x. È necessario avviare r: provare F("00000"). E && è necessario per emulare edif
edc65,

Hai perfettamente ragione. Non ho notato che ti aspettavi che ignorasse (x=t, r=i-n+1)se tfosse inferiore o uguale a x. È un buon uso della valutazione pigra! Vorrei che potesse essere tagliato da qualche parte, ma credo che tu abbia fatto tutto il lavoro.
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

variabili $se $ndovrebbero essere definiti nella riga di comando rispettivamente per la stringa di ricerca e la lunghezza della sottostringa.

Funzionerebbe anche in qualsiasi linguaggio di tipo C con funzioni appropriate per substr_count()e strlen().


3

Mathematica, 38 36

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

Esempio:

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]

Produzione:

10


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

formattato:

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

Accetta input come parametri del metodo.

Cosa fa:

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 byte

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

Ma con nomi di funzioni fintanto che zipWithIndex immagino che Scala non sia la scelta migliore per il codice golf.


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

formattato:

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

Uso:

$ ./m1s 01001010101101111011101001010100010101101010101010101101101010010110110110 5
10

1

CJam, 25 21 byte

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

Provalo qui.

Prende l'input come numero intero per la lunghezza della sottostringa e un array di zero e uno come sequenza:

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]

Spiegazione

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

Il risultato viene stampato automaticamente alla fine del programma.

Si noti che sto prendendo in considerazione anche sezioni che iniziano più vicino alla fine della lunghezza della sottostringa desiderata, ma va bene, perché sono sottostringhe dell'ultima sottostringa valida e quindi non avranno mai più 1s di quell'ultima sottostringa valida.


1

Java 329 byte

stavo per impiantare un .matches (regex), ma sarebbe stato quasi identico alle soluzioni Python sopra, quindi ho provato invece una finestra scorrevole. nuovo qui, quindi se qualcuno ha qualche suggerimento sii felice di ascoltarli.

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

}


Alcuni consigli: è possibile inizializzare inella terza riga. La maggior parte dello spazio bianco può essere rimosso. Usa System.out.print((non è necessaria la nuova riga). Invece di Integer.valueOf(, puoi usare new Integer(.
Ypnypn,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.