Жадный резак


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 О, я не видел ограничений на набор символов; мой код работает для любой строки вообще.
Нил

Единственный персонаж, для которого не нужно работать, это пространство, не так ли?
Asone Tuhid

@AsoneTuhid Ваш порт работает только для тех символов, для которых он должен работать; ваш оригинал, кажется, работает для всего, кроме пробелов.
Нил

На каких персонажей работает ваш оригинальный ответ, а на новый - нет?
Asone Tuhid


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}

Попробуйте онлайн!

меньше и медленнее, чем раньше!

В основном порт ответа @ Neil's Javascript

Безголовый и аннотированный

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.