Жадібний різак


27

Нещодавно iBug отримав довгу планку з композитних, але цінних матеріалів. Планка настільки довга, що iBug не може легко продати її за кредити, тому він хоче скоротити її. Пруток виготовлений з таких крихких і магічних матеріалів, що, якщо частина зламана, всі частини бруска, виготовлені з того ж матеріалу, теж зламаються, що ускладнить довільне різання.

iBug хоче розрізати планку на якомога більше шматочків. Він також любить дуже короткі програми та кодовий гольф, тому зробив абстрактний аналіз своєї проблеми.

Чарівна смужка iBug представлена ​​у вигляді рядка (або масиву чи послідовності символів, якщо вам більше зручно), наприклад:

aaabbccccccbbbaaacccccaabbbaaaaa

Кожна літера в рядку являє собою один магічний матеріал. Панель завжди відповідає RegEx ^\w*$, тому в барі може бути до 63 матеріалів. "Частина" - це послідовна послідовність будь-яких символів, які не розділені пробілами.

iBug хоче, щоб ви написали програму, яка обчислює максимальну кількість частин, які він міг отримати, якщо нуль або більше наборів символів повністю видалено (замінено пробілами), і скаже iBug про це число.


Приклад 1:

In:  aaabbccccccbbbaaacccccaabbbaaaaa
Out: 4

Опис: Якщо bповністю зняти з панелі, iBug може отримати 4 частини. Він також може отримати 4 частини, видаливши bі c, як показано нижче

aaabbccccccbbbaaacccccaabbbaaaaa  # Original string
aaa  cccccc   aaacccccaa   aaaaa  # Remove 'b'
aaa           aaa     aa   aaaaa  # Remove 'b' and 'c'

І це максимальна кількість деталей, яку iBug може отримати від цієї панелі

Приклад 2:

In:     111aa___9999____aaa99111__11_a_aa999
Result: 111aa   9999    aaa99111  11 a aa999
Out:    6

Опис: Видаляючи лише підкреслення, iBug може отримати 6 частин з панелі, і це максимум.

Приклад 3:

In:  __________
Out: 1

Опис: Що? Ви хочете вирізати це? Отримати 1 частину можна лише тоді, коли ви її зовсім не виріжете.

Приклад 4:

In:  
Out: 0

Опис: Нічого вирізати, так нуль.


Також є деякі правила, яким iBug хоче, щоб програми дотримувалися:

  1. iBug не любить стандартних лазівки, і вони заборонені.

  2. Поки вона працює, вона не повинна бути повноцінною програмою. Також приймається функція, яка приймає введення параметра і дає вихід через значення повернення.

  3. Допускаються гнучкі введення та виведення. Ваша програма або функція може приймати рядок або масив символів, або все, що вам найлегше мати справу. Ви можете дати вихід, надрукувавши номер або повернувши його.


Зразки тестових випадків (але не обмежуючись ними)

aaabbbaaa           = 2
123456789           = 5
AaAaAaAa            = 4
aaabcccdedaaabefda  = 6
________            = 1
(empty)             = 0

Оскільки це , виграє найкоротша програма (у байтах) на кожній мові!


Додатково

iBug високо цінує, якщо ви можете надати пояснення для вашої програми, навіть якщо це не впливає на ваш рахунок (це все ще довжина в байтах).


2
Як виходить 1234567895? А як виходить aaabcccdedaaabefda6? Я отримую 2 та 4 відповідно для цих двох тестових випадків.
Містер Xcoder

@ Mr.Xcoder для першого, видаліть 2468, для другого, видаліть bd.
Мартін Ендер

@MartinEnder Про так що будь-який підпослідовності можна видалити? якщо будь-який із символів повністю видалено, пропонується інакше.
Містер Xcoder

1
@ Mr.Xcoder, якщо я правильно зрозумів виклик, ви видаляєте його 2,4,6,8з першого та b,d,fдругого.
Кудлатий

2
@ Mr.Xcoder це означає видалення всіх копій будь-якого набору символів. Я думаю, що відпрацьований приклад це доволі добре показує.
Мартін Ендер

Відповіді:



6

JavaScript (ES6), 109 90 байт

f=s=>Math.max((s.match(/\s+/g)||[]).length,...[...s].map(c=>c>` `&&f(s.split(c).join` `)))
<input oninput=o.textContent=/\s/.test(this.value)?``:f(this.value)><pre id=o>0

Дещо повільно на 123456789тестовому випадку. Попередня 109-байтна відповідь не обмежувалася !/\s/:

f=
s=>(g=a=>Math.max(a.filter(s=>s).length,...[...a.join``].map(c=>g([].concat(...a.map(s=>s.split(c)))))))([s])
<input oninput=o.textContent=f(this.value)><pre id=o>0



@AsoneTuhid О, я не бачив обмеження набір символів; мій код взагалі працює для будь-якого рядка
Ніл

Єдиний персонаж, над яким він не повинен працювати, це простір, чи не так?
Асона Тухід

@AsoneTuhid Ваш порт працює лише для тих символів, для яких він повинен працювати; ваш оригінал, здається, працює ні на що, крім пробілів.
Ніл

На які символи працює ваша оригінальна відповідь, що новий не відповідає?
Асона Тухід


3

Желе ,  13  11 байт

Забагато 2-байтних інструкцій
-2 завдяки Zgarb (швидко використовуйте зовнішній продуктþ>. <)

eþŒPŒr¬S€ṀḢ

Монадічне посилання, що приймає список символів і повертає невід'ємне ціле число.

Спробуйте в Інтернеті!

Як?

Для кожної послідовності введення (набори, які ми можемо видалити, плюс зайві еквіваленти) отримує список існування для ідентифікації вилучених, а потім ефективно знаходить, скільки пробіг нулів залишилось і дає максимум. Остання частина працює дещо дивно, оскільки я знайшов це гравцем, ніж більш наївними альтернативами - він вважає, що пробіжки є [element, count]парами, заперечує ідентифікацію нулів як одиниці, сума знаходить максимум, а потім бере голову (сума елементів, а не підрахунок ).

eþŒPŒr¬S€ṀḢ - Link: list of characters        e.g. "aabcde"
  ŒP        - power-set - gets all subsequences    ["","a","a","b",...,"bd",...,"aabcde"]
 þ          - outer-product with:
e           -   exists in?                         [[0,0,0,0,0,0],[1,1,0,0,0,0],[1,1,0,0,0,0],[0,0,1,0,0,0],..,[0,0,1,0,1,0]...,[1,1,1,1,1,1]]
    Œr      - run-length encode                    [[[0,6]],[[1,2],[0,4]],[[1,2],[0,4]],[[0,2],[1,1],[0,3]],...,[[0,2],[1,1],[0,1],[1,1],[0,1]],...,[[1,6]]]
      ¬     - NOT                                  [[[1,0]],[[0,0],[1,0]],[[0,0],[1,0]],[[1,0],[0,0],[1,0]],...,[[1,0],[0,0],[1,0],[0,0],[1,0]],...,[[0,0]]]
        €   - for €ach:
       S    -   sum                                [[1,0],[1,0],[1,0],[2,0],...,[3,0],...,[0,0]]
         Ṁ  - maximum                              [3,0]
          Ḣ - head                                 3

Я думаю, що €Đ€може бути þ.
Згарб

3

Рубі , 98 89 75 64 61 байт

f=->s{[s.split.size,*s.scan(/\w/).map{|c|f[s.tr c,' ']}].max}

Спробуйте в Інтернеті!

менше і повільніше, ніж раніше!

В основному порт відповіді JavaScript на Ніла @ Neil

Недоліковані та зауважені

def f(input_string)
    # splits by / +/ by default
    size0 = input_string.split.size
    # an array of all non-space characters in input_string
    characters = input_string.scan(/\w/)
    size1 = characters.map {|i|
        # all letters and digits and _ are "bigger" than /, space isn't
        if i > '/'
            # tr replaces every occurrence of i in input_string with space
            next_string = input_string.tr(i, ' ')
            f(next_string) # recursive call
        else
            0
        end
    }
    # max value between size0 and any element in size1
    return [size0, *size1].max
end

Спробуйте в Інтернеті!


2

Лушпиння , 12 11 байт

▲mȯ#€0gM€¹Ṗ

Спробуйте в Інтернеті! Це працює грубою силою і відбувається досить повільно. Додайте uдо правого кінця, щоб зробити його швидшим, без зміни семантики.

Пояснення

▲mȯ#€0gM€¹Ṗ  Implicit input, say S = "abddccbdcaab"
          Ṗ  Powerset of S: P = ["","a","b","ab","d","ad"...,"abddccbdcaab"]
 m           Map this function over P:
              Argument is a subsequence, say R = "acc"
       M ¹    Map over S
        €     index of first occurrence in R: [1,0,0,0,2,2,0,0,2,1,1,0]
      g       Group equal elements: [[1],[0,0,0],[2,2],[0,0],[2],[1,1],[0]]
  ȯ#          Count the number of groups
    €0        that contain 0: 3
▲            Take maximum of the results: 4

2

Perl 5 , (старі версії), -p -I., 52 49 43 байт

Підрахунок старого стилю: +3for -p: 46bytes (оскільки він повинен бути в програмі, його не можна запустити за допомогою -e)

barsplit.pl:

#!/usr/bin/perl -pI.
$G[split]+=s%\S%do$0for s/$&/ /rg%eg;$_=$#G

Виконати рядком на STDIN:

echo aaabcccdedaaabefda | ./barsplit.pl; echo

Спробуйте в Інтернеті!

-I.Є варіант , щоб зробити цю роботу також про останні Перлз , де за замовчуванням .є не більше @INC. У старих версіях perl ця опція не потрібна. Я перевірив це на більш старій машині, яка ще була perl 5.20, тому оцінка базується на цьому (інакше я також повинен рахувати. аргумент -I)

Швидка версія ( 49байти):

#!/usr/bin/perl -pI.
$G[split]+=s%.%$$_++||do$0for s/$&/ /rg%eg;$_=$#G

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.