貪欲なカッター


27

iBugは最近、複合材でありながら貴重な素材でできた長いバーを手に入れました。バーは非常に長いので、iBugはクレジットで簡単に販売できないので、彼はそれを削減したいと考えています。バーは、壊れやすい魔法の素材で作られているため、部品が破損すると、同じ素材で作られたバーのすべての部品も破損し、勝手に切断することが難しくなります。

iBugは、バーをできるだけ多くの部分にカットしたいと考えています。彼はまた、非常に短いプログラムとコードゴルフが大好きなので、彼は問題の抽象的な分析を行いました。

iBugのマジックバーは、次のように文字列(または必要に応じて文字列または配列)として表されます。

aaabbccccccbbbaaacccccaabbbaaaaa

文字列の各文字は、1つの魔法の素材を表します。バーは常に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を生成しますか?そして、どのようにしaaabcccdedaaabefdaて6を生成しますか?これら2つのテストケースでそれぞれ2と4を受け取ります。
Mr Xcoder

@ Mr.Xcoderは最初のもの、remove 2468、2番目はremove bdです。
マーティンエンダー

@MartinEnderああ、サブシーケンスを削除できますか?文字のいずれかが完全に削除されている場合は、別の方法で提案れます。
ミスターXcoder

1
@ Mr.Xcoder、チャレンジを正しく理解していれば2,4,6,8、最初とb,d,f2番目のチャレンジを削除します。
シャギー

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]ペアとして見つけ、ゼロを1として識別するために否定し、合計が最大を見つけて頭を取る(カウントではなく要素の合計) )。

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の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 -p46bytes(プログラム内にある必要があるため、を使用して実行することはできません-e

barsplit.pl

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

STDINの文字列を使用して実行します。

echo aaabcccdedaaabefda | ./barsplit.pl; echo

オンラインでお試しください!

-I.オプションは、デフォルトでは、最近のPerlで、このもの作品にするために存在している.にそれ以上です@INC。古いバージョンのperlでは、このオプションは必要ありません。私はまだ持っていた古いマシンでそれをテストしましたperl 5.20ので、スコアはそれに基づいています(そうでなければ、.引数もカウントする必要があります-I

高速バージョン(49バイト):

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.