Encuentra la subcadena con más 1 en una secuencia

16

Introducción

Quiero encontrar la subcadena con más 1's en una secuencia de 0' sy 1's.

Entrada

Su programa tiene dos entradas , la secuencia y la longitud de la subcadena.

La secuencia es cualquier número de0 'sy 1' s:

01001010101101111011101001010100010101101010101010101101101010010110110110

La longitud de la subcadena es cualquier número entero positivo distinto de cero:

5

Salida

Su programa debería generar el índice de inicio de la primera subcadena de la longitud dada que contiene la mayoría de 1's. Con la entrada anterior, la salida es:

10

El primer carácter de la cadena comienza en un índice de 0 .

Puntuación

¡El código más corto gana!

Reglas

  • Su programa siempre debe generar el índice correcto para cualquier entrada válida.
  • Puede elegir su método de entrada / salida de cualquier respuesta con puntaje positivo en las opciones predeterminadas . Por favor, especifique el método que elija en su respuesta.
hmatt1
fuente
Su título e introducción dice "encuentre la subcadena con la mayoría de los 1". Pero la descripción de su programa dice que está dando una longitud de subcadena y está buscando el índice de la primera subcadena. Entonces, ¿debemos suponer que el título y la introducción están equivocados? La mayoría de las personas parecen estar resolviendo la primera parte. ¿Quién gana?
swstephe
@swstephe No estoy seguro de entender tu confusión. Si hay más de una subcadena ligada para la mayoría 1, se genera la primera subcadena que encontró. Identifica las subcadenas con el índice del primer carácter de esa subcadena. ¿Eso ayuda?
hmatt1
De acuerdo, ¿está rompiendo la secuencia en subcadenas y devolviendo el índice de la primera subcadena con la mayoría de los 1? Parecía que estabas buscando subcadenas de 1's.
swstephe
¿El requisito "siempre debe generar el índice correcto para cualquier entrada dada" todavía se aplica si damos longitudes inviables, por ejemplo, longitud = 99?
smci
@smci puede suponer una entrada válida. No tiene que manejar un caso donde la longitud de la subcadena es más larga que la secuencia.
hmatt1

Respuestas:

11

Dyalog APL, 11

(-∘1+⍳⌈/)+/

Pruébalo aquíUso:

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

Explicación

Esta es una función diádica (que significa binario) que toma la longitud de la subcadena desde la izquierda y la secuencia desde la derecha. Su estructura es la siguiente:

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

Explicación por explosión:

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

Como ejemplo, tomemos 4y 0 1 1 0 1 1 1 0como entradas. Primero les aplicamos la función +/y obtenemos 2 3 3 3 3. Luego, +y ⌈/aplicado a esta matriz se da 3y se 2 3 3 3 3 ⍳ 3evalúa 2, ya que 3primero ocurre como el segundo elemento. Restamos 1y obtenemos 1como resultado final.

Zgarb
fuente
En su ejemplo, la longitud es 4, pero no hay 4 elementos iguales en una fila (01101110), entonces, ¿por qué genera algo?
Thomas Weller
@ThomasW. El ejemplo en el desafío tampoco tiene 5 elementos iguales en una fila, y sin embargo, el resultado es 10. La forma en que interpreto la tarea es que necesito encontrar el primer índice de una subcadena de la longitud dada que tiene munidades, donde mestá máximo.
Zgarb
10

Rubí, 42

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

Toma entrada llamándolo, por ejemplo

f['01001010101101111011101001010100010101101010101010101101101010010110110110',5]

Esto compara las subcadenas usando su valor ASCII total y devuelve el índice del máximo. No estoy seguro de si max_byla especificación de Ruby requiere que sea estable, pero parece estar en la implementación de C.

histocrat
fuente
6

Pitón 2, 56

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

Acepta una serie de enteros, luego la longitud.

Feersum
fuente
Esto necesita una matriz de enteros como entrada, por lo que si comienza con una cadena, debe hacer:[int(s) for s in "010010...0"]
smci
Error: f(ss, 999)devolverá 0 (en lugar de Ninguno). ¿Puedes arreglar eso? Esto posiblemente viola la regla 1.
smci
@smci No tengo idea de lo que estás hablando. ¿Cómo se supone que debo saber qué hay en la variable ss? Nonenunca es una salida deseada en ningún caso ya que la respuesta es un número entero.
fiesta
5

Lote - 222

Batch es obviamente el lenguaje perfecto para este tipo de operación.

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

Sin golf / disecado:

Configuración inicial. La variable ses la cadena de entrada, y lserá la longitud de la cadena de entrada, menos la longitud de la subcadena (inicializada en negativo %2donde %2es la longitud de la subcadena dada).

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

Obtenga la longitud de la entrada como l, usando una solución de longitud de cadena de Batch pura: esto altera la variable que scontiene la cadena de entrada, por lo que luego la configuramos nuevamente.

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

El valor de xse utiliza para verificar qué subcadena tenía el mayor número de 1. Inicie un ciclo desde 0 hasta la longitud de la cadena, menos la longitud de la subcadena (variable l). Obtener la subcadena que comienza desde el punto actual en el bucle ( %%a), cse establece como la cadena de entrada que comienza en %%ay toma %2(la longitud de la subcadena dada) caracteres. Ninguna0 s se elimina de c, luego cse compara el valor de x- 111es decir, es un número mayor que, 11por lo que podemos usar la 'cadena' para hacer una comparación mayor que. yluego se establece en la ubicación actual en la cadena, que finalmente se genera.

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!

Ejemplo de uso de OP:

h:\>sub1.bat 01001010101101111011101001010100010101101010101010101101101010010110110110 5
10
carne sin carne
fuente
5

C # (expresión regular), 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);}}

La expresión regular real no es tan larga, pero todas las pelusas necesarias para que un programa de C # compile el doble del tamaño del código.

La expresión regular real, estableciendo la longitud en 5:

(?=((?<o>1)|0){5})(?!.+(?=[10]{5})(?!((?<-o>1)|0){5}))
  • (?=((?<o>1)|0){5}): Mire hacia adelante para leer 5 caracteres sin consumir y coloque todos 1en "stack" o.
  • (?=[10]{5})(?!((?<-o>1)|0){5}): En una posición que tiene 5 caracteres adelante, no hay suficiente elemento en la "pila" opara aparecer, es decir, la subcadena tiene estrictamente más 1de lo que tenemos en la posición actual.
  • (?!.+(?=[10]{5})(?!((?<-o>1)|0){5})): No se puede encontrar una posición como la descrita anteriormente para el resto de la cadena, es decir, todas las posiciones tienen un número menor o igual de 1's.

Tomar el primer resultado da la respuesta, ya que todas las subcadenas que tiene delante tienen alguna subcadena por delante con más 1 's, y hemos comprobado que cualquier índice más grande que el índice actual tiene un número menor o igual de 1' s.

(Y aprendo algo bueno: la "pila" se restaura al retroceder).

n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
fuente
1
Muy bien, no habría adivinado que podrías hacer esto con una expresión regular.
histocrat
4

Pyth , 12

Mho/<>GNHZUG

Esto define una función g, que requiere una lista de números y un número como entrada. P.ej

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

Puedes probarlo aquí: Pyth Compiler / Executor

Explicación:

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
Jakube
fuente
Puede obtener una respuesta de la misma longitud utilizando un programa que toma una cadena de valores (01001 ...) y luego el número: ho/<>zNQ\0UzLamentablemente, contar con una cadena no convierte automáticamente lo que está buscando en una cadena :(
FryAmTheEggman
4

J, 15 14 caracteres

   ([:(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
fuente
Me parece interesante cuando los idiomas reales superan a los idiomas creados específicamente para el golf de código. Mi entrada K se comió o la habría publicado, pero de todos modos llegó a 20 caracteres.
JasonN
4

Matlab (42)

Dejar s denotar la cadena y nla longitud de la subcadena. El resultado es r.

Calcule la convolución de scon una secuencia de nunos, luego encuentre el máximo. La convolución se realiza fácilmente con conv, y la maxfunción devuelve la posición del primer máximo. Es necesario restar 1al índice resultante, porque la indexación de Matlab comienza en 1, no 0.

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

Golfizado:

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

Haskell, 64 62 Bytes

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]
nimi
fuente
Puede guardar 2 bytes definiendo una función infija:n#l=...
Zgarb
podría usar una función infija para p. Además, creo que 0es redundante (aunque los paréntesis no lo son, y es posible que necesite un espacio en lugar de eso 0).
Haskeller orgulloso
3

JavaScript (ES6) 73

Una función que devuelve el valor solicitado. El bucle for escanea la cadena de entrada manteniendo un total acumulado, guardando la posición del valor máximo.

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

Sin golf

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

Prueba en la consola FireFox / FireBug

F("01001010101101111011101001010100010101101010101010101101101010010110110110",5)

Salida 10

edc65
fuente
Para reducir su código, no necesita definir las variables xy r. Esto debería reducir 4 bytes, siendo la longitud final de 69 bytes. Además, probablemente pueda reemplazarlo &&con &. Pero agradable con el ~~truco!
Ismael Miguel
@IsmaelMiguel necesita iniciar x, de lo contrario error al principio t > x. Necesita iniciar r: intente F("00000"). Se necesita && para emular yif
edc65
Tienes toda la razón. No me di cuenta de que esperabas que ignorara (x=t, r=i-n+1)si tera menor o igual que x. ¡Es un buen uso de la evaluación perezosa! Desearía que se pudiera cortar en alguna parte, pero supongo que hiciste todo el trabajo.
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

variables $sy$n deben definirse en la línea de comando a la cadena de búsqueda y la longitud de la subcadena, respectivamente.

Esto también funcionaría en cualquier lenguaje tipo C con funciones apropiadas para substr_count()y strlen().

Stephen
fuente
3

Mathematica, 38 36

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

Ejemplo:

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]

Salida:

10

alephalpha
fuente
2

C # (Linq), 148 bytes

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

Formateado:

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

Toma datos como parámetros del método.

Que hace:

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
fuente
2

Scala - 70 bytes

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

Pero con nombres de funciones siempre que zipWithIndex supongo que Scala no es la mejor opción para el golf de código.

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

Formateado:

#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
Ari Malinen
fuente
1

CJam, 25 21 bytes

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

Pruébalo aquí.

Toma la entrada como un entero para la longitud de la subcadena, y una matriz de ceros y unos como la secuencia:

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]

Explicación

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

El resultado se imprime automáticamente al final del programa.

Tenga en cuenta que también estoy considerando segmentos que comienzan más cerca del final que la longitud de subcadena deseada, pero está bien, porque son subcadenas de la última subcadena válida y, por lo tanto, nunca tendrán más 1s que esa última subcadena válida.

Martin Ender
fuente
1

Java 329 bytes

iba a implementar un .matches (regex), pero habría sido casi idéntico a las soluciones de python anteriores, así que probé una ventana deslizante. nuevo aquí, así que si alguien tiene algún indicador, me alegra escucharlo.

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
fuente
Algunos consejos: puede inicializar ien la tercera línea. La mayor parte del espacio en blanco se puede eliminar. Uso System.out.print((no se necesita nueva línea). En lugar de Integer.valueOf(, puedes usar new Integer(.
Ypnypn