Найти подстроку с наибольшим числом 1 в последовательности


16

Вступление

Я хочу найти подстроку с самым 1большим в последовательности 0's и 1'.

вход

Ваша программа имеет два входа , последовательность и длину подстроки.

Последовательность является любым числом 0«s и 1» s:

01001010101101111011101001010100010101101010101010101101101010010110110110

Длина подстроки - это любое положительное ненулевое целое число:

5

Выход

Ваша программа должна вывести начальный индекс первой подстроки заданной длины, содержащей наибольшее 1. С учетом вышеприведенного ввода, вывод:

10

Первый символ в строке начинается с индекса 0.

счет

Самый короткий код выигрывает!

правила

  • Ваша программа должна всегда выводить правильный индекс для любых допустимых входных данных.
  • Вы можете выбрать свой метод ввода / вывода из любого ответа с положительным счетом по умолчанию . Пожалуйста, укажите метод, который вы выбрали в своем ответе.

Ваше название и введение гласит: «найдите подстроку с наибольшим количеством единиц». Но в описании вашей программы сказано, что вы задаете длину подстроки и ищете индекс первой подстроки. Так стоит ли считать, что заголовок и введение неверны? Большинство людей, кажется, решают первую часть. Кто выигрывает?
swstephe

@swstephe Я не уверен, что понимаю ваше замешательство. Если есть несколько подстрок, связанных для большинства 1, вы выводите первую найденную подстроку. Вы идентифицируете подстроки с индексом первого символа в этой подстроке. Это помогает?
hmatt1

Итак, вы нарушаете последовательность в подстроках и возвращаете индекс первой подстроки с наибольшим числом единиц? Похоже, вы искали подстроки 1-х.
swstephe

Применяется ли требование «всегда выводить правильный индекс для любых заданных входов», если мы даем недопустимые длины, например, длина = 99?
smci

@smci вы можете принять за правильный ввод. Вам не нужно обрабатывать случай, когда длина подстроки больше, чем последовательность.
hmatt1

Ответы:


11

Дьялог АПЛ, 11

(-∘1+⍳⌈/)+/

Попробуй это здесь. Использование:

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

объяснение

Это двоичная (то есть двоичная) функция, которая берет длину подстроки слева, а последовательность - справа. Его структура следующая:

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

Объяснение взрывом:

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

В качестве примера возьмем 4и в 0 1 1 0 1 1 1 0качестве входных данных. Сначала мы применяем функцию +/к ним и получаем 2 3 3 3 3. Затем +и ⌈/применяется к этому массиву дают себя и 3, и 2 3 3 3 3 ⍳ 3оценивает 2, так как 3первый встречается как второй элемент. Вычитаем 1и получаем 1как конечный результат.


В вашем примере длина равна 4, но в строке нет 4 одинаковых элементов (01101110), так почему он вообще что-либо выводит?
Томас Уэллер

@ThomasW. В примере вызова не имеет 5 одинаковых элементов в строке либо, и все же выход 10. способа интерпретировать задачу в том , что мне нужно найти первый индекс подстроки заданной длины , которая имеет mте, где mесть максимален.
Згарб

10

Руби, 42

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

Принимает ввод, вызывая его, например,

f['01001010101101111011101001010100010101101010101010101101101010010110110110',5]

Это сравнивает подстроки, используя их общее значение ASCII и возвращает индекс максимума. Я не уверен, max_byтребуется ли спецификация Ruby для стабильности, но, похоже, это происходит в C-реализации.


6

Python 2, 56

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

Принимает массив целых чисел, а затем длину.


Для этого нужен массив целых чисел, поэтому если вы начинаете со строки, вам нужно сделать:[int(s) for s in "010010...0"]
smci

Ошибка: f(ss, 999)вернет 0 (вместо None). Вы можете это исправить? Возможно, это нарушает правило 1.
smci

@ SMCI Я понятия не имею, о чем ты говоришь. Как я должен знать, что находится в переменной ss?Noneв любом случае никогда не является желаемым выводом, поскольку ответ является целым числом.
feersum

5

Партия - 222

Пакетный, очевидно, идеальный язык для такого рода операций.

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

Без гольфа / расчлененный:

Начальная настройка. Переменная sявляется входной строкой и lбудет длиной входной строки минус длина подстроки (инициализируется отрицательным значением, %2где %2заданная длина подстроки).

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

Получите длину ввода как l, используя чистое решение для определения длины строки Batch - это искажает переменную, sсодержащую входную строку, поэтому мы затем устанавливаем ее снова.

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

Значение xиспользуется, чтобы проверить, какая подстрока имела наибольшее количество единиц. Начните цикл с 0 до длины строки минус длина подстроки (переменная l). Получить подстроку, начиная с текущей точки в цикле ( %%a), cзадается в качестве входной строки, начиная с %%aи принимая %2(заданную длину подстроки) символы. Любые 0s удаляются из c, затем значениеc сравнивается значение x- т.е. 111это большее число, чем, 11поэтому мы можем просто использовать «строку», чтобы сделать сравнение больше, чем. yзатем устанавливается текущее местоположение в строке - которая в итоге выводится.

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!

Пример использования ОП -

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

Реальное регулярное выражение не так долго, но все пухи, необходимые программе C # для компиляции, удваивают размер кода.

Фактическое регулярное выражение, установив длину до 5:

(?=((?<o>1)|0){5})(?!.+(?=[10]{5})(?!((?<-o>1)|0){5}))
  • (?=((?<o>1)|0){5}): Заблаговременно прочитать 5 символов без использования и поместить все 1в «стек»o .
  • (?=[10]{5})(?!((?<-o>1)|0){5}): На позиции, которая имеет 5 символов впереди, в «стеке» недостаточно элемента, oчтобы выскочить, то есть подстрока имеет строго больше, 1чем у нас в текущей позиции.
  • (?!.+(?=[10]{5})(?!((?<-o>1)|0){5})): Позиция, как описано выше, не может быть найдена для остальной части строки, т.е. все позиции имеют меньше или равное число 1's.

Взятие первого результата дает ответ, так как все подстроки перед ним имеют некоторую подстроку вперед с большим 1 числом, и мы должны проверить, что любой индекс, больший, чем текущий индекс, имеет меньшее или равное число 1единиц.

(И я узнал кое-что приятное: «стек» восстанавливается при возврате).


1
Очень круто, я бы не догадался, что ты мог бы сделать это с помощью регулярного выражения.
гистократ

4

Пиф , 12

Mho/<>GNHZUG

Это определяет функцию g , которая требует список чисел и число в качестве ввода. Например

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

Вы можете проверить это здесь: Pyth Compiler / Executor

Объяснение:

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)

Альтернатива:

Mho_s<>GNHUG

Вы можете получить ответ той же длины, используя программу, которая принимает строку значений (01001 ...), а затем число: ho/<>zNQ\0UzК сожалению, подсчет строки не преобразует автоматически
искомую

4

J, 15 14 символов

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

Мне интересно, когда настоящие языки превосходят языки, специально созданные для гольф-кода. Моя запись K была съедена, или я бы ее опубликовал, но в любом случае она доходила до 20 символов.
JasonN

4

Матлаб (42)

Позвольте sобозначить строку и nдлину подстроки. Результат есть r.

Вычислить свертку sс последовательностью nединиц, а затем найти максимум. Свертка выполняется легко conv, и maxфункция возвращает позицию первого максимума. К 1полученному индексу необходимо вычесть , потому что индексация Matlab начинается с 1, а не с 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 байта

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

Использование:

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]

Вы можете сохранить 2 байта, определив n#l=...
инфиксную

Вы можете использовать инфиксную функцию для p. Кроме того, я думаю, что 0это избыточно (хотя скобки нет, и вам может понадобиться пробел вместо этого 0).
гордый haskeller

3

JavaScript (ES6) 73

Функция, возвращающая запрошенное значение. Цикл for сканирует входную строку, сохраняя промежуточный итог, сохраняя положение максимального значения.

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

F("01001010101101111011101001010100010101101010101010101101101010010110110110",5)

Выход 10


Чтобы уменьшить ваш код, вам не нужно определять переменные xи r. Это должно уменьшить 4 байта, являясь конечной длиной 69 байтов. Кроме того, вы, вероятно, сможете заменить &&на &. Но хороший с ~~подвохом!
Исмаэль Мигель

@IsmaelMiguel вам нужно инициализировать x, иначе сначала ошибка t > x. Вам нужно инициализировать r: try F("00000"). И && необходимо подражать иif
edc65

Вы совершенно правы. Я не заметил, что вы ожидаете, что он проигнорирует, (x=t, r=i-n+1)если он tбыл ниже или равен чем x. Это хорошее использование ленивой оценки! Хотелось бы, чтобы его где-то отрубили, но, думаю, ты сделал всю работу.
Исмаэль Мигель

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

переменные $sи$n должны быть определены в командной строке для строки поиска и длины подстроки соответственно.

Это также будет работать на любом C-подобном языке с соответствующими функциями для substr_count()и strlen().


3

Математика, 38 36

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

Пример:

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]

Выход:

10


2

C # (Linq), 148 байтов

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

отформатирован:

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

Принимает данные как параметры метода.

Что оно делает:

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

Скала - 70 байт

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

Но с именами функций, такими как zipWithIndex, я думаю, Scala - не лучший выбор для гольф-кода.


2

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

отформатирован:

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

Использование:

$ ./m1s 01001010101101111011101001010100010101101010101010101101101010010110110110 5
10

1

CJam, 25 21 байт

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

Проверьте это здесь.

Принимает input как целое число для длины подстроки, а массив нулей и единиц как последовательность:

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]

объяснение

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

Результат распечатывается автоматически в конце программы.

Обратите внимание, что я также рассматриваю срезы, которые начинаются ближе к концу, чем желаемая длина подстроки, но это нормально, потому что они являются подстроками последней допустимой подстроки и поэтому никогда не будут иметь больше 1s, чем эта последняя допустимая подстрока.


1

Java 329 байт

собирался реализовать .matches (regex), но это было бы почти идентично решениям Python выше, поэтому вместо этого я попробовал скользящее окно. новинка здесь, так что если у кого-нибудь есть какие-либо указатели, буду рад их услышать.

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

}


Несколько советов: Вы можете инициализировать iв третьей строке. Большая часть пробела может быть удалена. Используйте System.out.print((новая строка не требуется). Вместо Integer.valueOf(вы можете использоватьnew Integer( .
Ypnypn
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.