Der gierige Cutter

27

iBug hat kürzlich eine lange Stange aus zusammengesetzten, aber wertvollen Materialien bekommen. Die Bar ist so lang, dass iBug sie nicht ohne Weiteres für Credits verkaufen kann, also möchte er sie kürzen. Die Stange besteht aus so zerbrechlichen und magischen Materialien, dass bei Bruch eines Teils auch alle Teile der Stange aus demselben Material brechen, was ein willkürliches Schneiden erschwert.

iBug möchte die Leiste in so viele Stücke wie möglich schneiden. Er liebt auch sehr kurze Programme und Code-Golfen, deshalb machte er eine abstrakte Analyse seines Problems.

Die magische Leiste von iBug wird wie folgt als Zeichenfolge dargestellt (oder als Array oder Zeichenfolge, wenn Sie dies bevorzugen):

aaabbccccccbbbaaacccccaabbbaaaaa

Jeder Buchstabe in der Zeichenfolge steht für ein magisches Material. Die Leiste entspricht immer der RegEx ^\w*$, sodass sich möglicherweise bis zu 63 Materialien in der Leiste befinden. Ein "Teil" ist eine fortlaufende Folge von Zeichen, die nicht durch Leerzeichen getrennt sind.

iBug möchte, dass Sie ein Programm schreiben, das die maximale Anzahl der Teile berechnet, die er erhalten kann, wenn null oder mehr Zeichensätze vollständig entfernt (durch Leerzeichen ersetzt) ​​werden, und iBug diese Zahl mitteilen.


Beispiel 1:

In:  aaabbccccccbbbaaacccccaabbbaaaaa
Out: 4

Beschreibung: Wenn bes vollständig von der Leiste entfernt wird, könnte iBug 4 Teile bekommen. Er kann auch 4 Teile durch Entfernen von bund erhalten c, wie unten gezeigt

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

Und das ist die maximale Anzahl von Teilen, die iBug von dieser Leiste erhalten kann

Beispiel 2:

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

Beschreibung: Durch Entfernen nur des Unterstrichs kann iBug 6 Teile aus der Leiste entfernen, und das ist das Maximum.

Beispiel 3:

In:  __________
Out: 1

Beschreibung: Was? Willst du das schneiden? Es ist nur möglich, 1 Teil zu bekommen, wenn Sie es überhaupt nicht schneiden.

Beispiel 4:

In:  
Out: 0

Beschreibung: Es gibt nichts zu schneiden, also null.


Es gibt auch einige Regeln, denen iBug folgen soll:

  1. iBug mag keine Standardlücken und sie sind verboten.

  2. Solange es funktioniert, muss es kein vollständiges Programm sein. Eine Funktion, die Eingaben von einem Parameter entgegennimmt und über den Rückgabewert ausgibt, wird ebenfalls akzeptiert.

  3. Flexible Ein- und Ausgabe sind erlaubt. Ihr Programm oder Ihre Funktion kann eine Zeichenfolge oder ein Array von Zeichen enthalten oder alles, was Sie am einfachsten zu handhaben finden. Sie können die Ausgabe geben, indem Sie die Nummer ausdrucken oder zurücksenden.


Beispiel-Testfälle (aber nicht darauf beschränkt)

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

Da dies ein , gewinnt das kürzeste Programm (in Bytes) in jeder Sprache!


Extra

iBug ist sehr dankbar, wenn Sie eine Erklärung für Ihr Programm angeben können, auch wenn dies keinen Einfluss auf Ihre Bewertung hat (es ist immer noch eine Länge in Byte).

iBug
quelle
2
Wie ergibt sich 1234567895? Und wie ergibt sich aaabcccdedaaabefda6? Für diese beiden Testfälle bekomme ich jeweils 2 und 4.
Mr. Xcoder
@ Mr.Xcoder für das erste entfernen 2468, für das zweite entfernen bd.
Martin Ender
@MartinEnder Oh so jede Subsequenz kann entfernt werden? Wenn eines der Zeichen vollständig entfernt wird, schlagen Sie etwas anderes vor.
Mr. Xcoder
1
@ Mr.Xcoder, wenn ich die Herausforderung richtig verstanden habe, entfernst du 2,4,6,8von der ersten und b,d,fvon der zweiten.
Shaggy
2
@ Mr.Xcoder bedeutet, dass alle Kopien eines Zeichensatzes entfernt werden. Ich denke, das bearbeitete Beispiel zeigt es ganz gut.
Martin Ender

Antworten:

8

Haskell , 73 71 70 Bytes

x#z|z==x=' '|1<2=z
f x=maximum$length(words x):[f$(c#)<$>x|c<-x,c>' ']

Danke an Laikoni für das Speichern von 1 Byte!

Probieren Sie es online!

Cristian Lupascu
quelle
1
maximum$(length$words x):kann auf gekürzt werden maximum$length(words x):.
Laikoni
6

JavaScript (ES6), 109 bis 90 Byte

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

Etwas langsam im 123456789Testfall. Die vorherige 109-Byte-Antwort war nicht beschränkt auf !/\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

Neil
quelle
@AsoneTuhid Oh, ich habe die Einschränkung des Zeichensatzes nicht gesehen. Mein Code funktioniert für jede Zeichenfolge überhaupt.
Neil
Der einzige Charakter, für den es nicht arbeiten muss, ist der Raum, nicht wahr?
Asone Tuhid
@AsoneTuhid Ihr Port funktioniert nur für genau die Zeichen, für die er benötigt wird. Ihr Original scheint für alles außer für Leerzeichen zu funktionieren.
Neil
Welche Zeichen funktioniert Ihre ursprüngliche Antwort, die neue nicht?
Asone Tuhid
4

Python 2 , 111 93 72 Bytes

-21 Bytes danke Kirill L.

f=lambda s:max([len(s.split())]+[f(s.replace(c,' '))for c in s if'/'<c])

Probieren Sie es online!

ovs
quelle
Es sieht so aus, als würde der derzeit von JS und Ruby verwendete Ansatz auch für Python gut funktionieren: 73 Bytes
Kirill L.
@KirillL. danke für die
empfehlung
3

Jelly ,  13  11 Bytes

Zu viele 2-Byte-Anweisungen
-2 dank Zgarb (benutze das äußere Produkt schnellþ>. <)

eþŒPŒr¬S€ṀḢ

Ein monadischer Link, der eine Liste von Zeichen akzeptiert und eine nicht negative Ganzzahl zurückgibt.

Probieren Sie es online!

Wie?

Für jede Untersequenz der Eingabe (die Mengen, die wir entfernen können, plus redundante Äquivalente) wird eine Existenzliste erstellt, um zu identifizieren, welche entfernt werden, und dann wird effektiv ermittelt, wie viele Nullenläufe übrig sind, und das Maximum erhalten. Der letzte Teil funktioniert auf etwas seltsame Weise, da ich fand, dass es mehr Golf als naive Alternativen gibt - es findet die Läufe als [element, count]Paare, negiert, um Nullen als Einsen zu identifizieren, summiert, findet das Maximum und nimmt dann den Kopf (die Summe der Elemente statt der Zählungen) ).

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
Jonathan Allan
quelle
Ich denke €Đ€kann sein þ.
Zgarb
3

Ruby , 98 89 75 64 61 Bytes

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

Probieren Sie es online!

kleiner und langsamer als zuvor!

Grundsätzlich eine Portierung von @ Neils Javascript-Antwort

Ungolfed und kommentiert

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

Probieren Sie es online!

Asone Tuhid
quelle
2

Schale , 12 11 Bytes

▲mȯ#€0gM€¹Ṗ

Probieren Sie es online! Dies funktioniert mit roher Gewalt und ist ziemlich langsam. Ergänzen Sie udas rechte Ende, um die Ausführung zu beschleunigen, ohne die Semantik zu ändern.

Erläuterung

▲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
Zgarb
quelle
2

Perl 5 (ältere Versionen) -p -I., 52 49 43 Bytes

Old style Zählung: +3für -p: 46Bytes (weil es muss in einem Programm sein, es kann nicht ausgeführt werden , unter Verwendung von -e)

barsplit.pl:

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

Führen Sie mit der Zeichenfolge auf STDIN aus:

echo aaabcccdedaaabefda | ./barsplit.pl; echo

Probieren Sie es online!

Die -I.Option ist da, damit dies auch auf neueren Perls funktioniert, in denen standardmäßig .nicht mehr vorhanden ist @INC. In älteren Versionen von Perl wird diese Option nicht benötigt. Ich habe das auf einer älteren Maschine getestet, die es noch gab perl 5.20, also basiert die Punktzahl darauf (ansonsten sollte ich auch das .Argument dazu zählen -I).

Schnelle Version ( 49Bytes):

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