Знайдіть підрядку з найбільшою кількістю 1 у послідовності


16

Вступ

Я хочу знайти підрядку з найбільшою 1в послідовності 0's і 1' s.

Вхідні дані

У вашій програмі є два входи , послідовність і довжина підрядки.

Послідовність є будь-яким числом 0«s і 1» s:

01001010101101111011101001010100010101101010101010101101101010010110110110

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

5

Вихідні дані

Ваша програма повинна виводити початковий індекс першої підрядки заданої довжини, який містить найбільше 1s. З вищевказаним входом вихід:

10

Перший символ у рядку починається з індексу 0.

Оцінка балів

Найкоротший код виграє!

Правила

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

У вашій назві та вступі написано "знайти підрядку з найбільшою кількістю". Але в описі програми говориться, що ви надаєте довжину підрядки і шукаєте індекс першої підрядки. Тож чи слід вважати, що назва та вступ помилкові? Більшість людей, здається, вирішують першу частину. Хто виграє?
swstephe

@swstephe Я не впевнений, що розумію твою плутанину. Якщо для більшості з них підв'язано кілька підрядків, виведете 1першу знайдену підрядку. Ви ідентифікуєте підрядки з індексом першого символу в цій підрядці. Чи допомагає це?
hmatt1

Гаразд, значить, ви порушуєте послідовність у підрядках і повертаєте індекс першої підрядки з найбільшою кількістю 1? Здавалося, ви шукали підрядки 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

Пітон 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

Batch, очевидно, ідеальна мова для такого роду операцій.

@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використовується для перевірки того, який підрядковий рядок мав найбільшу кількість 1. Почніть цикл від 0 до довжини рядка мінус довжина підрядки (змінна l). Отримайте підрядку, починаючи з поточної точки в циклі ( %%a), cзадається як вхідна рядок, починаючи з %%a, і приймаючи %2(задану довжину підрядки) символів. Будь-який0 s видаляються з 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 # (Регекс), 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})): Позицію, як описано вище, не можна знайти для решти рядка, тобто вся позиція має менше або рівне число 1s.

Перший результат дає відповідь, оскільки всі підрядки перед нею мають деяку підрядку з більшою кількістю 1 's, і ми перевіряємо, що будь-який індекс, більший за поточний індекс, має менше або рівне число 1s.

(І я дізнаюся щось приємне: "стек" відновлюється при зворотному треку).


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На жаль, підрахунок рядка не перетворює автоматично те, що ви шукаєте, у рядок :(
FryAmTheEggman

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;

Гольф:

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

4

Хаскелл, 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=...
Zgarb

ви можете використовувати функцію інфіксації для 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

Безумовно

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: спробувати 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слід визначати в командному рядку відповідно до рядка пошуку та довжини підрядки відповідно.

Це також працює на будь-якій мові, подібній С, з відповідними функціями для 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

Scala - 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=

Тестуйте це тут.

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

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), але це було б майже ідентично рішенням пітона вище, тому я спробував замість цього розсувне вікно. Новий тут, тож якщо хтось має вказівники, буде радий їх почути.

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.