Kürzer als ein Sekundenbruchteil!

16

Herausforderung

Ihre Aufgabe für diese Frage besteht darin, ein Eingabearray von Ganzzahlen beim zweiten Auftreten jeder Ganzzahl in diesem Array aufzuteilen.

Nicht klar genug? Hier ist ein Beispiel, um zu helfen

Eingangsarray:

[2 1 1 2 3 2 2 4 5 6 7 3 7 0 5]

Ausgabe:

[[2 1] [] [3 2 2 4 5 6 7] [] [0] []]

Erläuterung:

Hier ist das Array, in dem nur das zweite Element fett hervorgehoben ist:

[2 1 1 2 3 2 2 4 5 6 7 3 7 0 5 ]

Nun setzen wir die aufteilenden Array-Blöcke um diese fetten zweiten Vorkommen:

[2 1] 1 [] 2 [3 2 2 4 5 6 7] 3 [] 7 [0] 5 []

und wickeln Sie diese aufgeteilten Arrays in ein Array, um das endgültige zu erhalten

[[2 1] [] [3 2 2 4 5 6 7] [] [0] []]

Beachten Sie, dass beim Auftreten benachbarter zweiter Vorkommen leere Arrays vorhanden sind.

Regeln

Wie üblich müssen Sie ein vollständiges Programm oder eine Funktion schreiben, die das Eingabearray über STDIN, ARGV oder Funktionsargument übernimmt.

Eingang

Die Eingabe besteht aus einem beliebigen geeigneten Array (oder Array-ähnlichen) Format von Ganzzahlen.

Beispielsweise wäre Folgendes akzeptabel:

2 1 1 1 4 5 6
[2 1 1 1 4 5 6]
[2, 1, 1, 1, 4, 5, 6]

Ausgabe

Bei der Ausgabe an STDOUT kann Ihr Array auch in einem beliebigen (verschachtelten) Array-Format gedruckt werden, z

[[2 1] [1 4 5 6]]
[[2, 1], [1, 4, 5, 6]]
{{2, 1}, {1, 4, 5, 6}}

(Dies ist normalerweise die native Zeichenfolgendarstellung von Arrays in Ihrer Sprache.)

Beachten Sie auch, dass nachgestellte leere Arrays als Teil des Arrays gedruckt werden sollten.

Wertung

Dies ist also gewinnen Sie den kürzesten Code in Bytes!

Optimierer
quelle
@PeterTaylor Viele Fragen erlauben unterschiedliche Formate von Arrays sowohl in der Ausgabe als auch in der Eingabe.
Optimierer
5
Was ist der Sinn des Zulassens ""als leeres Array? Dies riecht nach Favourismus gegenüber einer bestimmten Golfsprache.
John Dvorak
@JanDvorak Nach der Diskussion im Chat war es eigentlich beabsichtigt, integrativer zu sein und es den Sprachen im Allgemeinen zu ermöglichen, ihre native Darstellung zu verwenden. Ich habe den Wortlaut jetzt überarbeitet, um das klarer zu machen.
Martin Ender
1
Kann ich einfach ausgeben 2 1, 1 4 5 6?
Jimmy23013
@ user23013 hängt von der ausgewählten Sprache ab.
Optimierer

Antworten:

6

APL 25

1↓¨(1,∨⌿<\2=+\∘.=⍨a)⊂1,a←

Beispiel:

]display 1↓¨(1,∨⌿<\2=+\∘.=⍨a)⊂1,a←2 1 1 2 3 2 2 4 5 6 7 3 7 0 5
┌→──────────────────────────────────────┐
│ ┌→──┐ ┌⊖┐ ┌→────────────┐ ┌⊖┐ ┌→┐ ┌⊖┐ │
│ │2 1│ │0│ │3 2 2 4 5 6 7│ │0│ │0│ │0│ │
│ └~──┘ └~┘ └~────────────┘ └~┘ └~┘ └~┘ │
└∊──────────────────────────────────────┘

Altes:

{1↓¨(1,(⍳⍴⍵)∊,{1↑1↓⍵}⌸⍵)⊂1,⍵}

Dies ist eine schöne Frage für den Key Operator (⌸), der mit Dyalog APL v14 eingeführt wurde. Es verwendet die linke Argumentfunktion ({1 ↑ 1 ↓ ⍵}) und gibt für jedes eindeutige Argument die Indizes im Vektor für dieses Argument an. Hier nehme ich den zweiten Index, überprüfe dann, welcher der Indizes in dieser Liste vorhanden ist ((() ∊) und verwende den resultierenden Booleschen Wert zum Teilen des ursprünglichen Vektors.

Kann hier online ausprobiert werden:

http://tryapl.org

Moris Zucca
quelle
Verdammt. Immer noch nicht weniger als 24?
Optimierer
@Optimizer: 25 ... ich versuche es ;-)
Moris Zucca
Akzeptiere dies anstelle meiner eigenen Lösung :)
Optimierer
Nur 24 und eine ordnungsgemäße Funktion:1↓¨{1,∨⌿<\2=+\∘.=⍨⍵}⊂1∘,
Adám
funktioniert leider nicht ... das omega im dfn ist nicht dasselbe wie "a"
Moris Zucca
9

APL (Dyalog 14) (31)

{1↓¨(1,(⍳⍴⍵)∊2⍳⍨¨↓+\∘.=⍨⍵)⊂0,⍵}

Dies ist eine Funktion, die ein Array annimmt und ein verschachteltes Array zurückgibt.

Prüfung:

      +V← {1↓¨(1,(⍳⍴⍵)∊2⍳⍨¨↓+\∘.=⍨⍵)⊂0,⍵} 2 1 1 2 3 2 2 4 5 6 7 3 7 0 5
┌───┬┬─────────────┬┬─┬┐
│2 1││3 2 2 4 5 6 7││0││
└───┴┴─────────────┴┴─┴┘
      ⍝ this return value is a real nested array:
      ⎕←'Length: ',⍴V ⋄ (⍳⍴V){⎕←'Array #',⍺,': (', ⍵, ')'}¨V 
Length:  6
Array # 1 : ( 2 1 )
Array # 2 : ()
Array # 3 : ( 3 2 2 4 5 6 7 )
Array # 4 : ()
Array # 5 : ( 0 )
Array # 6 : ()

Erläuterung:

  • 0,⍵: Fügen Sie zur einfacheren Verarbeitung ein 0an der Vorderseite von hinzu . (Es zählt nicht als Vorkommen.)
  • (... )⊂: Teilen Sie das Array gemäß der angegebenen Bitmaske auf. In 1der Bitmaske beginnt jeweils eine neue Gruppe .
    • +\∘.=⍨⍵: Finden Sie für jeden Wert in (das Original) alle Vorkommen in . Machen Sie dann eine laufende Summe für jeden Wert und geben Sie eine quadratische Matrix an, die für jede Position angibt, wie viele von jedem Wert bereits aufgetreten sind.
    • : Teilen Sie die Matrix durch ihre Zeilen und geben Sie für jeden Wert ein Array an, das die Häufigkeit angibt, mit der die einzelnen Positionen aufgetreten sind.
    • 2⍳⍨¨: Suchen Sie in jedem dieser Arrays den Index des ersten Arrays 2.
    • (⍳⍴⍵)∊: Prüfen Sie für jeden möglichen Index in , ob er in der Liste der Indizes des zweiten Vorkommens enthalten ist. (Diese starten jede Gruppe mit Ausnahme der ersten.)
    • 1,: Fügen Sie 1vorne ein hinzu, um den Anfang der ersten Gruppe zu markieren.
  • 1↓¨: Entfernen Sie das erste Element aus jeder Gruppe. (Dies sind die addierten 0und die zweiten Vorkommen der einzelnen Werte.)
Marinus
quelle
8

J 28, 24 char

Besonderer Dank geht an randomra .

(1&,<;._1~1,2=+/@(={:)\)

Das funktioniert so. Über alle Präfixe ( \) des Eingabearrays wird angezeigt, wie viele ( +/@) Elemente des Präfixes dem letzten Element ( ={:) dieses Präfixes entsprechen. Wenn diese Zahl 2 ist, wissen wir, dass dies das zweite Vorkommen dieses Elements im Array ist, also teilen wir das Array dort mit auf <;._1.

   a=.2 1 1 2 3 2 2 4 5 6 7 3 7 0 5
   (={:)\ a
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
0 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 0 0 1 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
1 0 0 1 0 1 0 0 0 0 0 0 0 0 0
1 0 0 1 0 1 1 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
0 0 0 0 1 0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 1 0 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 1 0 0 0 0 0 1
   +/@(={:)\ a
1 1 2 2 1 3 4 1 1 1 1 2 2 1 2

Alte Sache mit Art Tricks: (1&,<;._1~1,1=i.~(]-{)/:@/:).

algorithmshark
quelle
(1&,<;._1~1,2=+/@(={:)\)ist 4 Bytes kürzer und viel einfacher. ( /:@/:
Ist
7

Mathematica, 58 51 49 Bytes

Rest/@SplitBy[(f@#=0;#)&/@{a}~Join~#,++f[#]==3&]&

Dies ist eine unbenannte Funktion, die eine Liste wie folgt annimmt

Rest/@SplitBy[(f@#=0;#)&/@{a}~Join~#,++f[#]==3&]&[{2,1,1,2,3,2,2,4,5,6,7,3,7,0,5}]

und gibt eine verschachtelte Liste wie

{{2, 1}, {}, {3, 2, 2, 4, 5, 6, 7}, {}, {0}, {}}

Wie es funktioniert

Dies nutzt etwas ziemlich dunkle Magie mit SplitBy.

Ich verfolge die Vorkommen jeder Zahl in einer Funktion f. In Mathematica können Sie den Wert einer Funktion für jede Eingabe separat definieren, und Sie müssen den Wert nicht für alle möglichen Eingaben angeben (es ist eher eine Hash-Tabelle für Steroide).

Ich beginne mit der Initialisierung fauf 0 für Werte, die in der Eingabe mit vorhanden sind (f@#=0;#)&/@.

Nun SplitBynimmt eine Liste und eine Funktion und „Splits Liste in Unterlisten von Läufen von aufeinanderfolgenden Elementen besteht, die den gleichen Wert zu geben , wenn fangewendet wird“ (Anmerkung , die SplitBynicht der Fall ist entfernen alle Elemente). Aber der (undokumentierte) Haken ist, dass jedes Element zweimalf aufgerufen wird - wenn man es mit seinem Vorgänger und seinem Nachfolger vergleicht. Also wenn wir das tun

 SplitBy[{1,2,3,4},Print]

Wir bekommen nicht nur eine Nummer, sondern diese wird gedruckt

 1
 2
 2
 3
 3
 4

Das sind 6 Aufrufe für 3 Vergleiche.

Wir können die Liste vor jedem zweiten Vorkommen teilen , wenn wir eine Funktion schreiben, die immer zurückgibt, Falseaber zurückgibt, Truewenn ein zweites Vorkommen mit dem Element davor verglichen wird. Dies ist die dritte Überprüfung dieses Elements (zwei Überprüfungen beim ersten Auftreten plus die erste Überprüfung beim zweiten Auftreten). Daher verwenden wir ++f[#]==3&. Das Schöne ist, dass dies bereits Falsebei der zweiten Überprüfung des zweiten Auftretens wieder auftritt, so dass ich Truefür aufeinanderfolgende zweite Vorkommen zurückkehren kann, aber immer noch zwischen diesen aufgeteilt bin . Ebenso dies wird nicht geteilt , nachdem zweite Vorkommen, weil die Funktion bereits kehrt Falsewieder auf die zweite Prüfung.

Jetzt möchte die Frage, dass wir auch diese zweiten Vorkommen entfernen, sodass wir das erste Element aus jeder Liste mit entfernen Rest/@. Aber natürlich wollen wir nicht das allererste Element in der Eingabe entfernen, also fangen wir tatsächlich an, indem wir ein Element aan den Anfang der Liste mit einfügen {a}~Join~#. aist eine undefinierte Variable, die Mathematica nur als unbekannt behandelt, so dass sie keine anderen Werte von beeinflusst f. Dies stellt auch sicher, dass das erste tatsächliche Element in der Eingabe wie jedes andere Element seine zwei Prüfungen erhält.

Martin Ender
quelle
Das ist ziemlich schlau. Das braucht man Booledort eigentlich auch nicht .
Swish
@swish Ah, danke, dass du mich daran erinnert hast ... Das ist mir auf dem Handy aufgefallen, aber ich wollte es testen, bevor ich es ändere.
Martin Ender
5

Python, 148 Bytes

def s(a):z=len(a);x=[-1]+sorted({[i for i in range(z)if a[i]==n][1]for n in a if a.count(n)>1})+[z];return[a[x[i]+1:x[i+1]]for i in range(len(x)-1)]

Ziemlich schreckliche Lösung. Es muss einen besseren Weg geben ...

Mit anrufen s([2, 1, 1, 1, 4, 5, 6]).

Ungolfed-Version

def split(array):
  indices = [-1]
  second_occurrences = set()

  for n in array:
      if array.count(n) > 1:
          occurrences = [i for i in range(len(array)) if array[i] == n]
          second_occurrences.add(occurrences[1])

  indices += sorted(second_occurrences)
  indices += [len(array)]

  return [array[indices[i]+1:indices[i+1]] for i in range(len(indices)-1)]
Sp3000
quelle
1
Was zum was… Könnten Sie in einer nicht golfenen Version bearbeiten? XD 148 Zeichen ist eine sehr lange Zeile;)
Sean Allred
1
@SeanAllred Ich wollte keine Erklärung posten, da ich mir sicher war, dass ich es besser machen könnte, aber da ich Probleme habe, habe ich die ungolfed Version gepostet: P
Sp3000
5

Haskell, 115 113 106 88

f?(x:s)|1<-f x=[]:x%f?s|a:b<-x%f?s=(x:a):b
f?x=[x]
(x%f)h=sum$f h:[1|x==h]
r s=(\_->0)?s

Dies speichert die Menge jedes Elements, die bisher als Funktion von Elementen erschienen ist, zu ihrer jeweiligen Menge, was ein interessanter Trick ist.

Dies funktioniert mit %einer Funktion, die mit einer Funktion f und einem Argument versehen ist. Diese Funktion xgibt eine neue Funktion zurück, fdie auf das Argument angewendet wird, wenn es anders ist als xund 1 + f xansonsten.

Zum Beispiel 3 % const 0ist es eine Funktion, die für jedes Argument 0 zurückgibt, mit Ausnahme von 3, für das 1 zurückgegeben wird. update: fused the foldl, um ein viel kleineres Programm zu erhalten.

stolzer haskeller
quelle
Das sieht interessant aus. Könnten Sie eine ungolfed Version bereitstellen?
Radomaj
4

Ruby 66 Demo

f=->a{c=Hash.new 0
r=[[]]
a.map{|e|2==(c[e]+=1)?r<<[]:r[-1]<<e}
r}

Ruby Stabby Lambda, das ein Array als Parameter verwendet und ein Array von Arrays zurückgibt.

Cristian Lupascu
quelle
4

Python: 100 Byte

def g(l):
 i=j=0;o=[]
 for e in l:
  if l[:i].count(e)==1:o+=[l[j:i]];j=i+1
  i+=1
 return o+[l[j:]]

Einfache Lösung. Ich durchlaufe die Liste, zähle, wie oft ein Zeichen zuvor aufgetaucht ist, und hänge den Teil seit der letzten Prüfung an die Ausgabeliste an.

Jakube
quelle
3

Rubin, 66

f=->a{s=Hash.new 0
r=[[]]
a.map{|e|(s[e]+=1)==2?r<<[]:r[-1]<<e}
r}

Erläuterung

  • eist ein Hash der Anzahl der Vorkommen für jedes Element, rist ein Array, in dem das Ergebnis gespeichert wird.
  • Durchlaufen Sie die Eingabe und erhöhen Sie die Anzahl der Vorkommen für jedes Element um 1.
    • Wenn die Anzahl der Vorkommen gleich ist 2, müssen wir uns aufteilen. Fügen Sie Arraydem Ergebnis ein Leerzeichen hinzu .
    • Andernfalls fügen Sie das Element einfach zum letzten ArrayErgebnis hinzu.
britishtea
quelle
2
Schöner Hut!! Oh, Moment mal.
Optimierer
4
Was für ein unglaublicher Zufall! Die Antwort, die ich Sekunden vor Ihnen gepostet habe, ist fast identisch. :)
Cristian Lupascu
Oh mein Gott, es ist sogar 1 Zeichen kürzer!
Britishtea
Es ist eine Ersparnis, die Sie leicht auf Ihre anwenden können. Ich finde es großartig, dass wir zur gleichen Zeit die gleiche Idee hatten. : D
Cristian Lupascu
3

CJam, 25 24 Bytes

q~{_L+:L1$a/,3=S@?}%Sa/p

Nimmt Eingaben von STDIN wie

[ 2 1 2 1 0 2 2 1 1 3 4 3]

und Ausgänge wie

[[2 1] "" [0 2 2 1 1 3 4] ""]

Im Grunde iteriere ich über alle Elemente des Arrays, eins nach dem anderen, indem ich sie in ein anderes Array lege. Dann erhalte ich die Anzahl des aktuellen Elements im anderen Array. Wenn es 2 ist, starte ich ein anderes Array von diesem Ort. Diese Art des zufälligen Array-Starts kann nur in einer Stack-basierten Sprache erreicht werden.

Code-Erweiterung :

q~{_L+:L1$a/,3=S@?}%Sa/p
q~{               }%             "Evaluate the input array and map it on this block";
   _                             "Copy the current element in iteration";
    L+:L                         "Add the copy to an initially blank array L and update L";
        1$a/                     "Make another copy of the element and split L on it";
            ,3=                  "This checks if the splitted array is of length 3";
                                 "which indirectly means that L contains the element twice";
               S@?               "If the above is true, replace the element by space";
                    Sa/          "Split the final array on space. This final array contains";
                                 "second occurrence of every integer replaced by a space";
                       p         "Print the stringified version of the final nested array";

Probieren Sie es hier online aus

1 Byte aus Martins Tipp im Chat gespeichert

Optimierer
quelle
3

Ruby, 64 Bytes

s=->a{x=[];b=[[]];a.map{|e|x<<e;x.count(e)==2?b<<[]:b[-1]<<e};b}
AlexRath
quelle
3

Perl 5: 36

Nicht sicher, ob dies akzeptabel ist, da hier keine tatsächliche Aufteilung stattfindet.

#!perl -pa
$x{$_}++-1or$_=']['for@F;$_="[[@F]]"

Beispiel:

$ perl spl.pl <<<"2 1 1 2 3 2 2 4 5 6 7 3 7 0 5"
[[2 1 ][ ][ 3 2 2 4 5 6 7 ][ ][ 0 ][]]
nutki
quelle
Völlig akzeptabel.
Optimierer
Gute Antwort. Aber die übliche Praxis ist, denke ich, -paals zwei zusätzliche Bytes zu zählen (weil es nur zwei Bytes "kostet", da Sie es als -paeanstatt schreiben können -e). Das wäre also 38, nicht 36.
msh210
2

CJam, 28 Bytes

Lq~{1$1$a/,3=S2$?@++}/-2%S/`

Nimmt Eingaben auf STDIN wie

[2 1 1 2 3 2 2 4 5 6 7 3 7 0 5]

und druckt die Ausgabe auf STDOUT wie

[[2 1] "" [3 2 2 4 5 6 7] "" [0] ""]

Beachten Sie, dass leere Zeichenfolgen und leere Arrays in CJam dasselbe sind und ""standardmäßig angezeigt werden (dies ist die native Darstellung von leeren Arrays).

(Bevor die Herausforderung veröffentlicht wurde, habe ich angefangen, daran zu arbeiten, weil wir darüber diskutierten, wie schwierig die Herausforderung sein würde.)

Erläuterung

Grundsätzlich dupliziere ich jedes Element im Array, es sei denn, es ist das zweite Vorkommen. In diesem Fall ersetze ich die erste Kopie durch ein Leerzeichen. Aus Golfgründen ist diese modifizierte Anordnung umgekehrt aufgebaut. So [2 1 1 2 3 2 3]wird es

[3 S 2 2 3 3 2 S 1 S 1 1 2 2]

Dann wähle ich jedes zweite Element vom Ende aus, das das ursprüngliche Array ist, wobei jedoch das zweite Vorkommen durch Leerzeichen ersetzt wird, d. H

[2 1 S S 3 2 S]

Schließlich teile ich das Array einfach nach Leerzeichen auf. Hier ist eine Aufschlüsselung des Codes:

L                            "Push empty array.";
 q~                          "Read STDIN an evaluate.";
   {                }/       "For each element of the input.";
    1$1$                     "Copy the array and the element.";
        a/                   "Split the array by that element.";
          ,3=                "Check that it's split into 3 parts.";
             S2$?            "If so, push a space, else, copy the current number.";
                 @++         "Pull up the array from the bottom and add both to the beginning.";
                      -2%    "Pick every second element from the end.";
                         S/  "Split on spaces.";
                           ` "Get the string representation.";
Martin Ender
quelle
Da dies meine eigene Herausforderung ist, gebe ich zuerst eine Chance: P. Ich habe eine 25-Byte-Cjam-Lösung bei mir.
Optimierer
Zeigt leere Arrays nicht korrekt an - offensichtlich ungültig!
Feersum
1
@feersum zeigt leere Arrays an, wie dies ""in der ersten Überarbeitung der Frage ausdrücklich erlaubt ist. In der aktuellen Version heißt es: "Jedes geeignete Format ... normalerweise native Zeichenfolgenwiederholung von Arrays".
John Dvorak
2

Unix-Tools, 100 Bytes

grep -o '[-0-9]*'|awk '{print(++A[$0]-2)?$0:"] ["}'|paste -sd' '|sed -e '/]/s/.*/[\0]/' -e's//[\0]/'

Schließt die Eingabe über stdin aus. Es ersetzt im Grunde nur jedes zweite Vorkommen durch "] [". Funktioniert nicht mit leeren Strings, []gibt einen leeren String aus, was meiner Meinung nach eine praktische Darstellung eines leeren Arrays ist :)

pgy
quelle
Nun, dann entspricht die Antwort nicht der Spezifikation, oder? (über negative ganze Zahlen). Und was ist mit 11? wird es konvertiert 1][?
Optimierer
Es funktioniert gut für 11, aber Sie haben Recht mit negativen Zahlen, das wurde behoben, und es akzeptiert jetzt auch Singleton-Arrays.
Pgy
2

APL, 42 Zeichen

{'(',')',⍨⍵[(2=+/¨(↑=↓)¨⌽¨,\⍵)/⍳⍴⍵]←⊂')('}

Beispiel:

{'(',')',⍨⍵[(2=+/¨(↑=↓)¨⌽¨,\⍵)/⍳⍴⍵]←⊂')('}2 1 1 2 3 2 2 4 5 6 7 3 7 0 5

Ausgabe:

( 2 1  )(   )(  3 2 2 4 5 6 7  )(   )(  0  )(  )

Hier getestet.

Wenn ich eine Zeichenfolge ausgeben muss, die genau als die richtige Struktur in APL interpretiert wird ... 49 Zeichen

{'1↓1(',',⍬)',⍨⍵[(2=+/¨(↑=↓)¨⌽¨,\⍵)/⍳⍴⍵]←⊂',⍬)('}
jimmy23013
quelle
Wie wird eine verschachtelte Liste tatsächlich in APL dargestellt? Möglicherweise müssen Sie die Zeichenfolge nicht bearbeiten
Optimizer
@Optimizer Die ausgegebene Zeichenfolge ist eine gültige Liste in einem APL-Programm. Es wäre jedoch nicht verschachtelt, wenn nur eine Liste enthalten wäre. Es 1↓1schien, als würde das Problem durch das Vorbereiten von behoben , aber das sieht zu seltsam aus.
Jimmy23013
2

Java, 223

Dies funktioniert nur unter Oracle oder OpenJDK JRE, da ich diese Besonderheit bei der Implementierung von Quantifier und Length Check in Look- Behind ausnutze, um Look-Behind mit variabler Länge zu implementieren.

class W{public static void main(String a[]){System.out.print("["+new java.util.Scanner(System.in).nextLine().replaceAll(" *\\b(\\d+)\\b(?=(.*))(?<=^(?=(.*\\b\\1\\b){2}\\2).*)(?<!^(?=(.*\\b\\1\\b){3}\\2).*) *","] [")+"]");}}

Die meiste Arbeit wird in der Regex erledigt, die unten in roher Form gezeigt wird:

 *\b(\d+)\b(?=(.*))(?<=^(?=(.*\b\1\b){2}\2).*)(?<!^(?=(.*\b\1\b){3}\2).*) *

Bevor wir den obigen regulären Ausdruck betrachten, wollen wir uns den äquivalenten regulären Ausdruck in .NET ansehen, der einfacher ist, da er einen Look-Behind mit variabler Länge direkt unterstützt (der Look-Behind in .NET wird höchstwahrscheinlich im Rechts-Links-Modus durchgeführt). :

 *\b(\d+)\b(?<=(.*\b\1\b){2})(?<!(.*\b\1\b){3}) *
  •  *\b(\d+)\bund  *am Ende entspricht eine Zahl und den umgebenden Räumen (falls vorhanden). Die gebundenen Überprüfungen sollen verhindern, dass eine Teilnummer abgeglichen wird, da Leerzeichen auf beiden Seiten optional sind. Außerdem wird die Nummer erfasst, um zu überprüfen, ob es sich um das zweite Auftreten im Array handelt.

  • (?<=(.*\b\1\b){2})Überprüft, ob 2 Instanzen der oben erfassten Nummer gefunden wurden. (?<!(.*\b\1\b){3})Überprüft, ob 3 Instanzen der erfassten Nummer gefunden wurden. In beiden Bedingungen wird zusammengenommen davon ausgegangen, dass es bisher nur zwei Instanzen der Zahl gibt. Die gebundenen Prüfungen dienen dazu, sicherzustellen, dass die gesamte Zahl getestet wird.

Zurück zur Java-Version. Um einen Look Behind mit variabler Länge zu implementieren, transformieren wir

(?<=var-length-pattern)

zu

(?<=^(?=.*var-length-pattern).*)

Ich bin ein bisschen von Hand .bewegt, was die Tatsache betrifft , dass Zeilentrenner nicht enthalten sind, aber es kann leicht behoben werden und ich möchte die Syntax nicht weiter verkomplizieren.

Das Look-Ahead hat immer eine Länge von 0, und die Längenprüfung wird aufgrund der Implementierung des *Quantifizierers bestanden.

Das ^ist nicht notwendig, damit es funktioniert, aber es ist da, damit der fehlerhafte Fall schneller fehlschlägt. In der Oracle / OpenJDK-Implementierung wird ein Rückblick durchgeführt, indem die minimale Länge des Musters zurückgenommen, dann abgeglichen, dann gespült und wiederholt wird, indem die Länge erhöht wird, bis eine Übereinstimmung gefunden wird, oder im schlimmsten Fall auf die maximale Länge des Musters . Mit ^stelle ich sicher, dass die Präfixzeichenfolge nur einmal übereinstimmt.

Die Vorausschau innerhalb des Rückblicks ist jedoch nicht durch die rechte Begrenzung des Rückblicks begrenzt, sodass sie bis zum Ende der Zeichenfolge passen kann. Um die Grenze zu bestätigen, fange ich den Rest der Zeichenfolge in einer Vorschau in einer anderen Erfassungsgruppe ein und benutze sie, um die Herrschaft des Musters mit variabler Länge zu begrenzen.

(?=(.*))(?<=^(?=.*var-length-pattern\m).*)
   ^--^                              ^
   mth capturing group               m is the number of the capturing group marked

Da mein Muster bereits mit beginnt .*, muss ich kein weiteres .*voranstellen.

n̴̖̋h̴̖̋ã̷͉h̷̭̿d̷̰̀ĥ̷̳
quelle
1

Perl 108

map{$e[$_]==1?do{push@a,[@b];@b=();}:push@b,$_;$e[$_]++}split" ";push@a,[@b];s/.*/Data::Dumper->Dump(\@a)/e;

In Aktion:

perl -MData::Dumper -pe '
    $Data::Dumper::Terse = 1;
    $Data::Dumper::Indent = 0;
    @a=@b=@e=();
    map{$e[$_]==1?do{push@a,[@b];@b=();}:push@b,$_;$e[$_]++}split" ";
    push@a,[@b];
    s/.*/Data::Dumper->Dump(\@a)/e;
' <<<$'2 1 1 2 3 2 2 4 5 6 7 3 7 0 5\n2 1 1 1 4 5 6\n'"$(
    sed 's/./& /g;w/dev/stderr' <<< ${RANDOM}${RANDOM}${RANDOM}$'\n'${RANDOM}${RANDOM})"
2 4 4 7 7 2 9 8 8 4 6 0 1 8 
1 0 3 9 3 7 9 
[2,1][][3,2,2,4,5,6,7][][0][]
[2,1][1,4,5,6]
[2,4][7][][9,8][4,6,0,1,8]
[1,0,3,9][7][]

Hinweis: Die beiden ersten Zeilen $Data::...dienen nur der besseren Darstellung und die dritte Zeile @a=@b=@e=();dient dazu, das Werkzeug für mehrere Zeilen zu verwenden.

F. Hauri
quelle
1

R 76

y=scan();r=split(y,cumsum(ave(y,y,FUN=seq)==2));c(r[1],lapply(r[-1],"[",-1))

Ausgabe für das Beispiel: Eine Liste von fünf Elementen, einschließlich drei leerer Vektoren. ( numeric(0)).

$`0`
[1] 2 1

$`1`
numeric(0)

$`2`
[1] 3 2 2 4 5 6 7

$`3`
numeric(0)

$`4`
[1] 0

$`5`
numeric(0)

Übrigens: Der Code generiert eine Warnmeldung, die ignoriert werden kann.

Sven Hohenstein
quelle
1

awk 29

a[$1]++==1{print"-";next}1

Dies lässt sich mit den Eingabe- und Ausgabeformaten ein wenig frei. Eingabe "Array" ist vertikal, eine Zahl pro Zeile. Die Ausgabe erfolgt ebenfalls vertikal (eine Zahl pro Zeile), wobei die Arrays durch Striche getrennt sind.

Eingang:

2
1
1
2
3
2
2
4
5
6
7
3
7
0
5

Ausgabe:

2
1
–
–
3
2
2
4
5
6
7
–
–
0
–
Kevin
quelle
1

Pyth 30 32

Ich experimentiere zum ersten Mal mit Pyth. Es ist die gleiche Lösung wie in meiner Python-Lösung.

VQIq/<QN@QN1~Y]:QZN=ZhN;+Y]>QZ

Sie können es online ausprobieren: Pyth Compiler / Executor

ZB die Eingabe

[2,1,1,2,3,2,2,4,5,6,7,3,7,0,5]

wird gedruckt

[[2, 1], [], [3, 2, 2, 4, 5, 6, 7], [], [0], []]

Erläuterung:

                                 # Q = input(), Y = [], Z = 0
VQ                               # for loop: N iterates over the indices of Q
  I                              # if 
   q\<QN@QN1                     #    Q[N] appears exactly once in Q[:N]
            ~Y]:QZN              #         append the list [Q[Z:N]] to Y
                   =ZhN          #         and assign Z = N + 1
                       ;         # end if and for loop
                        +Y]>QZ   # print Y + [Q[Z:]]
Jakube
quelle
Gibt es eine bessere Alternative für =Y+Y...?
Jakube
Dies ist -~Y...
Optimizer
1

Python 2, 84

l=[[]];p=[]
for x in input():p+=[x];b=p.count(x)==2;l+=[[]]*b;l[-1]+=[x][b:]
print l

Die Liste list die bisherige Ausgabe. Wir iterieren über die Elemente. Wenn es sich bei der aktuellen Version um die zweite handelt, wird eine neue leere Unterliste erstellt. Andernfalls fügen wir es der neuesten Unterliste hinzu. Die Liste der bisher angezeigten Elemente wird in gespeichert p. Seltsamerweise scheint die Rekonstruktion der Liste kürzer zu sein als das Aufteilen der Eingabe.

xnor
quelle
1

Pure Bash 111 94

81 nur zum Teilen:

for i;do [ "${b[i]}" == 7 ]&&c+=("${d# }") d=||d+=\ $i;b[i]+=7;done;c+=("${d# }")
declare -p c

Die zweite Zeile declare -p c nur die Variable ausgegeben

Stichprobe:

splitIntFunc() {
    local b c d i
    for i;do
        [ "${b[i]}" == 7 ]&&c+=("${d# }") d=||d+=\ $i
        b[i]+=7
      done
    c+=("${d# }")
    declare -p c
}

Hinweis: Die Zeile local b c d iwird nur zum mehrmaligen Ausführen der Funktion benötigt.

splitIntFunc 2 1 1 2 3 2 2 4 5 6 7 3 7 0 5
declare -a c='([0]="2 1" [1]="" [2]="3 2 2 4 5 6 7" [3]="" [4]="0" [5]="")'

splitIntFunc 2 1 1 1 4 5 6
declare -a c='([0]="2 1" [1]="1 4 5 6")'

splitIntFunc $(sed 's/./& /g;w/dev/stderr' <<<${RANDOM}${RANDOM}${RANDOM})
1 6 5 3 2 2 4 3 9 4 2 9 7 7 4 
declare -a c='([0]="1 6 5 3 2" [1]="4" [2]="9" [3]="2" [4]="7" [5]="4")'

splitIntFunc $(sed 's/./& /g;w/dev/stderr' <<<${RANDOM}${RANDOM}${RANDOM})
2 4 5 2 9 1 1 4 8 7 8 1 0 3 
declare -a c='([0]="2 4 5" [1]="9 1" [2]="" [3]="8 7" [4]="1 0 3")'

Für die sexieste Präsentation (+26)

splitIntFunc() {
    local b c d i
    for i;do
        [ "${b[i]}" == 7 ]&&c+=("${d# }") d=||d+=\ $i
        b[i]+=7
      done
    c+=("${d# }")
    printf -v l "(%s) " "${c[@]}"
    echo "<$l>"

Wird ungefähr so ​​aussehen:

splitIntFunc 2 1 1 2 3 2 2 4 5 6 7 3 7 0 5
<(2 1) () (3 2 2 4 5 6 7) () (0) () >

splitIntFunc $(sed 's/./& /g;w/dev/stderr' <<<${RANDOM}${RANDOM}${RANDOM})
4 3 8 1 4 5 7 9 2 7 8 4 0 
<(4 3 8 1) (5 7 9 2) () (4 0) >

splitIntFunc $(sed 's/./& /g;w/dev/stderr' <<<${RANDOM}${RANDOM}${RANDOM})
3 1 3 0 2 5 3 6 6 9 2 5 5 
<(3 1) (0 2 5 3 6) (9) () (5) >

splitIntFunc $(sed 's/./& /g;w/dev/stderr' <<<${RANDOM}${RANDOM}${RANDOM})
2 2 2 9 1 9 5 0 2 2 7 6 5 4 
<(2) (2 9 1) (5 0 2 2 7 6) (4) >


}
F. Hauri
quelle
0

Scala, 122, 111

Nimm die Charaktersammlung, drucke in Form von [21][][3224567][][0][], 122 111:

def s(a:Any*)=print((("[","")/:a){case((b,c),d)=>if(b.indexOf(d)==c.indexOf(d))(b+d,c)else(b+"][",c+d)}._1+"]")

... oder nimm eine Charaktersammlung und gib verschachtelte Listen zurück, 135 129:

def s(a:Char*)=(("",List(List[Any]()))/:a){case((b,c),d)=>b+d->(if(b.count(d==)==1)List()::c else(c.head:+d)::c.tail)}._2.reverse

Ich bin sicher, es gibt einige Einsparungen, die ich erzielen könnte, ich habe nicht zu genau nachgesehen.

Chad Retz
quelle
0

Python 220 Bytes

Das Folgende sind 220 Bytes, was im Vergleich zu vielen anderen nicht großartig ist, aber mit größeren ganzen Zahlen schnell genug läuft!

xlist = list(input()); result = []; x = 0
for i in range(len(xlist)):
    if xlist[0:i+1].count(xlist[i]) == 2: result.append(xlist[x:i]);x = i+1
    elif i == len(xlist)-1: result.append(xlist[x:])
print(result)
Rick
quelle
Hallo und willkommen bei PPCG! Ihr Code ist jedoch nicht kurz genug. Ich sehe einige Stellen, an denen man es definitiv verkürzen kann. Bitte golfen Sie weiter.
21.
Hallo! Wenn Sie Hilfe Golf benötigen, können Sie die Räume entfernen um =, ändern xlistund resultzu kürzeren Namen und Leerzeichen entfernen um ==, ;und :. Wenn Sie weitere Hilfe benötigen, geben Sie einfach @NoOneIsHere(oder einen beliebigen Benutzernamen) ein und ich / der Benutzer wird versuchen zu helfen.
NoOneIsHere
-1

Java: 563 Bytes

Beachten Sie, dass dies Java 8 verwendet. Vor JDK8 wären aufgrund von foreach einige Bytes länger.

import java.util.*;public class a{static String c(String[]b){List<String>d=new ArrayList<>(Arrays.asList(b));Set<String>e=new HashSet<>();Set<String>f=new HashSet<>();for(int i=0;i<Integer.MAX_VALUE;i++){String g;try{g=d.get(i);}catch(IndexOutOfBoundsException ex){break;}
if(e.contains(g)&&!f.contains(g)){d.remove(i);d.add(i,"]");d.add(i+1,"[");f.add(g);i++;}else{e.add(g);}}
d.add(0,"[[");d.add(d.size(),"]]");StringBuilder sb=new StringBuilder();d.forEach(sb::append);return sb.toString();}
public static void main(String[]args){System.out.println(c(args));}}
PoweredByRice
quelle
wo sonst kann ich lambda verwenden? Die Schleife bis zur Länge des Arrays ist nicht korrekt, da die Liste erweitert wird, wenn Sie weitere "]" und "[" hinzufügen.
PoweredByRice
Jedes Inkrementieren der Länge ist genauso lang wie das Abfangen der Ausnahme. Ich glaube auch nicht, dass es in Java möglich ist, CEILING in (für i = 0; i <CEILING; i ++) zu ändern.
PoweredByRice
Wirklich ?
Optimierer
hmm wusste das nicht, danke für den Hinweis.
PoweredByRice
Was ist mit der Konvertierung Integer.MAX_VALUEin 2147483647? Es ist der gleiche Wert mit weniger Bytes. Auch IndexOutOfBoundsExceptionzu verkürzen zu könnenException
Charlie