Auflisten eines Arrays, Gruppieren von Duplikaten


24

Das Ziel dieser Herausforderung ist es, eine Reihe positiver Ganzzahlen zu nehmen und ihre Indizes zu zählen, wobei ähnliche Elemente gruppiert werden.

Eine Aufzählung ohne Duplikate erfolgt durch einfache Ausgabe eines Arrays von Paaren (value, index), z. B. [3, 4, 13, 9, 2]=> [[3,1],[4,2],[13,3],[9,4],[2,5]].

Wenn ein bestimmtes Element jedoch ein zweites Mal angezeigt wird, erhält es kein eigenes Paar, sondern wird stattdessen zur Gruppe seines ersten Auftretens hinzugefügt. Wenn in unserem Beispiel wir die 9 mit 3, dann in der Ausgabe ersetzt würden wir entfernen [9,4]und ersetzen [3,1]mit [3,1,4].

In der Ausgabe müssen die Gruppen nach ihrem ersten Vorkommen geordnet sein und die Indizes müssen in aufsteigender Reihenfolge vorliegen. Das Element muss sich zuerst in einer Gruppe befinden, bevor seine Indizes angezeigt werden. Der Ausgang kann 0 oder 1 indiziert sein. Sie können davon ausgehen, dass das Array mindestens ein Element enthält.

Testfälle:

Input           | Output (One-indexed)
[3, 2, 2, 3]    | [[3, 1, 4], [2, 2, 3]]
[17]            | [[17, 1]]
[1, 1]          | [[1, 1, 2]]
[1, 1, 2]       | [[1, 1, 2], [2, 3]]
[1, 2, 3, 4]    | [[1, 1], [2, 2], [3, 3], [4, 4]]
[1, 1, 1, 1]    | [[1, 1, 2, 3, 4]]

Das ist , die wenigsten Bytes gewinnen!


Wäre es akzeptabel, wenn die Indides beispielsweise als Zeichenfolgen ausgegeben würden [[17,"1"]]? (Ich weiß noch nicht, ob ich auf diese Weise Bytes speichern kann, während ich noch daran arbeite!)
Shaggy

@ shaggy sicher, das ist in Ordnung
Pavel


1
Können wir [[3, [1, 4]], [2, [2, 3]]]stattdessen so etwas ausgeben ?
Conor O'Brien

1
@Pavel das ist kein Grund: p aber sicher
Conor O'Brien

Antworten:


9

Dyalog APL, 5 Bytes

(⊂,)⌸

Probieren Sie es online!

,⌸für 2 Bytes funktioniert fast , hat aber nachgestellte Nullen: /


Was in aller Welt macht das?
Mr. Xcoder

@ Mr.Xcoder ruft die Indizes für jedes Ding ab und ruft den linken Operator mit dem Ding und den Indizes auf, wo es existiert
dzaima

Wäre ,⌸es möglich, alle Nullen in weniger als 3 Bytes zu löschen, da die Isue mit nachgestellten Nullen und Nullen niemals in der Eingabe sein werden?
Pavel

@Pavel Der Grund dafür, dass es Nullen gibt, ist, dass das Ergebnis eine Matrix ist, die exakte Dimensionen haben muss. Es gibt also nur 1 Byte, um die Nullen für eine Byte-Verstärkung zu löschen. Ich fühle mich wie dies aber Golf sein könnte.
Dzaima


7

J , 12 Bytes

~.,&.><@I.@=

Null indexiert.

Probieren Sie es online!

Wenn Sie die ganze Arbeit, die ich mit Boxen mache, entfernen können, können Sie den Bytecount wahrscheinlich um einiges reduzieren. Ich werde sehen, ob ich das herausfinden kann.

Erläuterung

Dies ist wahrscheinlich zu früh, um es zu erklären (es sollte mehr Golf geben).

~. ,&.> <@I.@=
             =  Self-classify (comparison of each unique element to array)
            @   Composed with
          I.    Indices of ones (where it's equal)
         @      Composed with
        <       Boxed (how we deal with arrays of unequal length)
   ,&.>         Joined with
      >          Unbox each
   ,             Concatenate
    &.           Box again
~.              Unique elements

2
Dieses Array-Ausgabeformat ist schick für
Pavel

@Pavel es dauert auch eine Menge Bytes Π.Π
Cole

5

05AB1E , 10 Bytes

ÙεDIQƶ0K)˜

Probieren Sie es online!

Erläuterung

Ù             # remove duplicates
 ε            # apply to each element
  D           # duplicate
   IQ         # compare for equality with input
     ƶ        # multiply each element by its index (1-based)
      0K      # remove zeroes
        )˜    # wrap in a flattened list



5

Attache , 15 Bytes

Flat=>Positions

Probieren Sie es online!

Dies ist ein interessanter Fall =>der Operatorform von Map. Wenn zwei funktionelle Argumente gegeben fund g, Mapgibt eine Funktion f => g[x]über x. Das heißt, der RHS-Wert wird auf den Eingang angewendet, und dann wird der LHS-Wert zugeordnet.

Das Builtin Positionsgeneriert ein Array, das die Gruppierung von Einträgen nach Indizes darstellt. Wenn kein zweites Argument angegeben ist, Positionswird standardmäßig das erste Argument verwendet. Flatwird dann über jedes Element abgebildet, da dies für die Frage erforderlich ist.

Alternativlösungen

31 Bytes

MapArgs[Concat#~Indices,Unique]

Probieren Sie es online!

Eine ziemlich kurze, eingebaute Alternative. MapArgsist eine Funktion wie Map, mit der Ausnahme, dass Sie zusätzliche Argumente eingeben können. Zum Beispiel MapArgs[{_1 + _2}, 1..3, 3]ist [4, 5, 6]. Wie Mapwird es mit zwei funktionalen Argumenten geliefert curried. Die abzubildende Funktion ist Concat#~Indices, welches eine Gabel ist. Diese Verzweigung wird auf die UniqueElemente der Eingabe und die Eingabe selbst angewendet . Dies führt zu Concat[_, Indices[_2, _]](mit den Argumenten Indicesgetauscht durch ~), die paarweise das Element (abgebildet wird _) mit dem Indizes des Elements _in dem Eingangsfeld, das ist _2(wie durch FFED MapArgs).

43 Bytes

{Flat=>Zip[Unique[_],Indices[_,Unique[_]]]}

Probieren Sie es online!

Dies ist wirklich nur eine ausführlichere (und doch ein bisschen besser lesbare) Kombination der Lösungen Nr. 1 und Nr. 2.


4

Gelee , 6 Bytes

Q;"ĠṢ$

Probieren Sie es online!

Erläuterung:

Q;"ĠṢ$
Q      Keep the first occurrence of each element
     $ Last two links as a monad
   Ġ    Group indices of equal elements, then sort the resulting list of groups by the element they point to
    Ṣ   Sort; used to re-order the list of groups based on first occurrence instead
  "    Vectorize link between two arguments (the first occurrences and the group list)
 ;      Concatenate

Funktioniert nicht für den letzten Testfall . Das Array sollte auf einer anderen Ebene verschachtelt sein, die Ausgabe ist immer zweidimensional.
Pavel

@Pavel Ja, das stimmt , ich habe nur vergessen, eine Fußzeile hinzuzufügen (Antwort ist eine Funktion)
Erik the Outgolfer

Ok dann, cool. Erklärung bald, ja? : P
Pavel

@ Pavel hinzugefügt Erklärung
Erik der Outgolfer


4

MATL , 8 Bytes

u"@tG=fh

Probieren Sie es bei MATL Online aus

Erläuterung

        # Implicitly get the input
u       # Compute the unique values
"       # For each unique value, N
  @     # Push the value N to the stack
  t     # Duplicate N
  G     # Grab the input
  =f    # Get the 1-based indices of the elements that equal N
  h     # Horizontally concatenate N with the indices
        # Implicitly display the result

ooooohhh das ist schlau! Ich hatte 18 Bytes, die ich zu benutzen versuchte, &faber nie zum Laufen brachte.
Giuseppe

3

Eigentlich 24 Bytes

;;╗⌠╝╜r⌠╜E╛=⌡░⌡M@Z⌠♂i⌡M╔

Probieren Sie es online!

Erläuterung:

;;╗⌠╝╜r⌠╜E╛=⌡░⌡M@Z⌠♂i⌡M╔
;;                        make two copies of input
  ╗                       save a copy to register 0
   ⌠╝╜r⌠╜E╛=⌡░⌡M          map over input:
    ╝                       save the element in register 1
     ╜r                     indices for input
       ⌠╜E╛=⌡░              filter:
        ╜E                    element in input at index
          ╛=                  equals element for outer map (from register 1)
                @Z        swap, zip input with map result
                  ⌠♂i⌡M   flatten each element in zipped list
                       ╔  uniquify

3

R , 56 Bytes

function(x)lapply(unique(x),function(y)c(y,which(x==y)))

Probieren Sie es online!


Dies ist mein erster Versuch mit Codegolf, daher ist jedes Feedback willkommen!


3
Willkommen bei PPCG! Schöne erste Antwort.
Pavel

1
Hallo Florian! Sehr nette Antwort. Dies ist eigentlich eher ein Snippet als ein Programm oder eine Funktion - es wird vorausgesetzt, dass die Eingabe fest codiert ist x, aber es muss eine Möglichkeit zum Lesen der Eingabe geben - normalerweise verwenden scanoder definieren wir eine Funktion. Außerdem muss es ausgegeben werden, also muss es in a printoder a eingeschlossen werden cat.
Giuseppe

1
Weitere nützliche R-Golftricks finden Sie in dieser Frage :)
Giuseppe

1
Danke Leute! Und der Link zu den r-Tipps ist auf jeden Fall hilfreich!
Florian

2
@Florian R ist nicht so schlecht, wie Sie denken (außer bei Saitenherausforderungen ...), solange Sie sich daran erinnern, dass Sie gegen andere R-Golfer spielen! Wenn Sie Fragen haben, können Sie mich gerne im Chat anrufen. Es gibt ein paar R-Golfer, die aktiv sind, und sie werden definitiv Vorschläge unterbreiten und auch Ihre schätzen! Willkommen zum Golfen :)
Giuseppe


3

JavaScript (ES6), 64 Byte

0 indiziert

a=>a.map((v,i)=>a[-v]?a[-v].push(i):a[-v]=[v,i]).filter(x=>x[0])

Beachten Sie, dass dies voraussetzt, dass die Eingangsnummern positiv sind, also v> 0

Test leicht modifiziert (1 indiziert), um den Testfällen zu entsprechen

var F=
a=>a.map((v,i)=>a[-v]?a[-v].push(i+1):a[-v]=[v,i+1]).filter(x=>x[0])

test = [ // output 1 indexed
  [3, 2, 2, 3],//    | [[3, 1, 4], [2, 2, 3]]
  [17], //           | [[17, 1]]
  [1, 1], //         | [[1, 1, 2]]
  [1, 1, 2], //      | [[1, 1, 2], [2, 3]]
  [1, 2, 3, 4], //   | [[1, 1], [2, 2], [3, 3], [4, 4]]
  [1, 1, 1, 1] //    | [[1, 1, 2, 3, 4]] 
]

test.forEach(t => {
  x = F(t)
  console.log(JSON.stringify(t)+ ' -> ' + JSON.stringify(x))
})


3

APL NARS, 24 Byte, 12 Zeichen

{∪⍵,¨⍸¨⍵=⊂⍵}

-4 Bytes dank Adam Test:

  f←{∪⍵,¨⍸¨⍵=⊂⍵}

  ⎕fmt f 3 2 2 3
┌2────────────────┐
│┌3─────┐ ┌3─────┐│
││ 3 1 4│ │ 2 2 3││
│└~─────┘ └~─────┘2
└∊────────────────┘
  ⎕fmt f 17
┌1──────┐
│┌2────┐│
││ 17 1││
│└~────┘2
└∊──────┘
  ⎕fmt f 1 1
┌1───────┐
│┌3─────┐│
││ 1 1 2││
│└~─────┘2
└∊───────┘
  ⎕fmt f 1 2 3 4
┌4──────────────────────────┐
│┌2───┐ ┌2───┐ ┌2───┐ ┌2───┐│
││ 1 1│ │ 2 2│ │ 3 3│ │ 4 4││
│└~───┘ └~───┘ └~───┘ └~───┘2
└∊──────────────────────────┘
  ⎕fmt f 1 1 1 1
┌1───────────┐
│┌5─────────┐│
││ 1 1 2 3 4││
│└~─────────┘2
└∊───────────┘

Rasieren Sie 4 Bytes / 2 Zeichen:{∪⍵,¨⍸¨⍵=⊂⍵}
Adám

3

SWI-Prolog , 165 117 Bytes

-48 Bytes dank Prolog Golftipps .

h(I):-I+[]-1.
[H|T]+R-N:-(select([H|A],R,[H|L],S),!,append(A,[N],L);append(R,[[H,N]],S)),O is N+1,(T+S-O,!;write(S)).

Probieren Sie es online!

Erläuterung

% The predicate that prints the grouped duplicates. It's a wrapper because we
% need some extra arguments to keep state:
enumerate_duplicates(Input) :- enumerate(Input, [], 1).

% In the golfed code, operators are used to represent this predicate.
% See /codegolf//a/153160
% Go through the input, build up the result on the way and print it.
enumerate([Head|Tail], Result, Index) :-
    (
        % If our current Result already contains a list that starts with the
        % current first element in our input, Head, NewIndexes will become the
        % new "tail" of that list in our next result list:
        select([Head|OldIndexes], Result, [Head|NewIndexes], NextResult),
        % Don't backtrack before this if goals below this fail:
        !,
        % The as-yet-unknown NewIndexes above should in fact be the same as
        % OldIndexes with our current Index appended:
        append(OldIndexes, [Index], NewIndexes)
    % Use ; instead of separate predicate rules.
    % See /codegolf//a/67032
    ;
        % If our current Result did not already contain Head, append a new list
        % for it with the current index:
        append(Result, [[Head, Index]], NextResult)
    ),
    % Increment our index counter:
    NextIndex is Index + 1,
    (
        % And continue with the rest of our input:
        enumerate(Tail, NextResult, NextIndex),
        % Don't backtrack if the above succeeded:
        !
    ;
        % If Tail is no longer a multi-element list, we're done. Print:
        write(NextResult)
    ).

3

K (ok) , 10 Bytes

Lösung:

(!x),'.x:=

Probieren Sie es online!

Beispiele:

(!x),'.x:=,17
,17 0
(!x),'.x:=1 1
,1 1 2
(!x),'.x:=1 0 1
(1 1 2
2 3)
(!x),'.x:=1 2 3 4
(1 0
2 1
3 2
4 3)

Erläuterung:

Die Auswertung erfolgt von rechts nach links. Ich denke immer noch, dass dies weiter golffähig ist ...

(!x),'.x:= / the solution
         = / group input into dictionary, item!indices
       x:  / save as variable x
      .    / value of x (the indices)
    ,'     / concatenate (,) each-both (') with
(  )       / do this together
 !x        / the key of x (i.e. the items)

Anmerkungen:

  • 14 Bytes ohne zu deklarieren x, (,/)'+(!;.)@'=gaben mit diesem Ansatz auf ...

1
Sie können ein 0-indiziertes Ergebnis zurückgeben, also können Sie das überspringen 1+.
Adám


2

JavaScript (ES6), 68 Byte

0-indiziert.

a=>a.map(p=(x,i)=>1/p[x]?b[p[x]].push(i):b.push([x,p[x]=i]),b=[])&&b

Testfälle


Eingabenummern sind! = 0, das könnte nützlich sein, um den 1 / x-Trick zu vermeiden
edc65 20.01.18

2

PHP 4.1, 88 Bytes

Ja, es ist ziemlich lang.

Dies setzt eine Standarddatei php.ini ( short_open_tag = Onund register_globals = On) voraus .

<?foreach($A as$k=>$v){!$b[$v]&&$b[$v]=array($v);$b[$v][]=$k;}print_r(array_values($b));

Dies stellt das Array auf eine für den Menschen lesbare Weise dar.
Die Werte können per POST, GET und COOKIE in der Taste "A" übergeben werden.


Für eine moderne Version kann man (90 Bytes) verwenden:

<?foreach($_GET[A]as$k=>$v){if(!$b[$v])$b[$v]=[$v];$b[$v][]=$k;}print_r(array_values($b));

Das Ergebnis ist das gleiche, außer dass alle Werte innerhalb des Schlüssels "A" über GET-Parameter übergeben werden müssen.


2

Perl 6 ,  63  61 Bytes

*.pairs.classify(*.value).map({.key,|.value».key}).sort(*.[1])

Teste es (0-basiert)

{sort *.[1],map {.key,|.value».key},classify *.value,.pairs}

Testen Sie es (0-basierter gleicher Algorithmus)

Erweitert:

# WhateverCode lambda (this is the parameter) 
*\                                            # [3,2,2,3]

# get a list of Pairs (zero based index => value)
.pairs                                        # (0=>3,1=>2,2=>2,3=>3)

# classify based on the values (unordered result)
.classify(*.value)                            # {2=>[1=>2,2=>2],3=>[0=>3,3=>3]}

# simplify the structure
.map({
  .key,         # the value
  |.value».key  # slip in the indexes
})                                            # ((3,0,3),(2,1,2))

# sort based on first index
.sort(*.[1])

2

Japt , 14 9 Bytes

0-indiziert.

â £ð¶X iX

Versuch es

â £ð¶X iX
â             :Deduplicate
  £           :Map each X
   ð          :  Get 0-based indices of elements in the input
    ¶X        :    That are equal to X
       iX     :  Prepend X

2

PHP 7.4+ , 71 Bytes

* 73 Bytes, um den $_GETSchlüssel in Anführungszeichen zu setzen und Warnungen zu vermeiden.

Snippet: ( Demo )

<?foreach($_GET[A]as$k=>$v){$b[$v][0]=$v;$b[$v][]=$k;}print_r([...$b]);

Basierend auf rep, gehe ich davon aus IsmaelMiguel dem besten Weg zu einem post PHP - Code in dieser Gemeinschaft weiß , damit ich aus bin der Aufbau seiner Stiftung . Es ist mir nicht klar, ob <?es in meinem Snippet enthalten sein soll . Da dies mein erster Beitrag ist, kann mir jeder erklären, ob es eine unnötige Syntax gibt. ps Ich habe auch Tipps zum Golfen in PHP gelesen, was mir als großartiger Kandidat für die Migration zu Meta erscheint .

Die Verbesserungen an Ismaels Snippet sind:

  1. Bedingungslose Zuordnung des ersten Elements in jedem Subarray (Wertüberschreibung)
  2. Splatpacking anstattarray_values() die Ausgabe neu zu indizieren.


1

Kotlin , 83 Bytes

{it.mapIndexed{i,c->c to i}.groupBy({(a,b)->a},{(a,b)->b}).map{(a,b)->listOf(a)+b}}

Verschönert

{
    it.mapIndexed { i, c -> c to i }
        .groupBy({ (a, b) -> a }, { (a, b) -> b })
        .map { (a, b) -> listOf(a) + b }
}

Prüfung

var f: (List<Int>) -> List<List<Int>> =
{it.mapIndexed{i,c->c to i}.groupBy({(a,b)->a},{(a,b)->b}).map{(a,b)->listOf(a)+b}}

data class Test(val input: List<Int>, val output: List<List<Int>>)

val tests = listOf(
        Test(listOf(3, 2, 2, 3), listOf(listOf(3, 0, 3), listOf(2, 1, 2))),
        Test(listOf(17), listOf(listOf(17, 0))),
        Test(listOf(1, 1), listOf(listOf(1, 0, 1))),
        Test(listOf(1, 1, 2), listOf(listOf(1, 0, 1), listOf(2, 2))),
        Test(listOf(1, 2, 3, 4), listOf(listOf(1, 0), listOf(2, 1), listOf(3, 2), listOf(4, 3))),
        Test(listOf(1, 1, 1, 1), listOf(listOf(1, 0, 1, 2, 3)))
)

fun main(args: Array<String>) {
    for (c in tests) {
        val o = f(c.input)
        if (o != c.output) {
            throw AssertionError("${c.input} -> $o != ${c.output}")
        }
    }
}

TIO

TryItOnline


Diese Lösung ist ein Ausschnitt, keine vollständige Funktion oder ein Programm. Die Variable imuss vordefiniert sein. Sie können dies gültig machen, indem Sie es in ein Lambda konvertieren, das einen Parameter annimmt i.
Pavel

Überarbeitet, um das von @Pavel
jrtapsell am

1

Schnelle 4, 107 Bytes

... Huch.

{a in Dictionary(grouping:a.enumerated()){$0.1}.sorted{$0.1.first!.0<$1.1.first!.0}.map{[$0]+$1.flatMap{$0.0}}}

Ungolfed:

let f = { (input: [Int]) -> [[Int]] in
    return Dictionary(grouping: input.enumerated(), by: { $0.element })
        .sorted { pairA, pairB in // Sort by order of first appearence (lowest offset)
            return pairA.value.first!.offset < pairB.value.first!.offset
        }.map { element, pairs in
            return [element] + pairs.map{ $0.offset /* +1 */} // add 1 here for 1 based indexing
        }
}

Es ist schade, dass das Wörterbuch die Reihenfolge verliert, was mich dazu zwingt, so viele Zeichen beim erneuten Sortieren zu verschwenden. Diese Art von Missbrauch von impliziten Schließung Argumente ( $0, $1, ...) und implizite Tupel Mitglieder ( .0, .1, ...) ist uhhhhh nicht schön.



1

Ruby , 54 52 Bytes

->a{a.map{|i|[i]+(0..a.size).select{|j|a[j]==i}}|[]}

Diese Version erlaubt nil (53 Bytes):

->a{a.map{|i|[i]+(0...a.size).select{|j|a[j]==i}}|[]}

Probieren Sie es online!


Die Abfrage gibt an, dass das Array nur positive Ganzzahlen enthält und mindestens ein Element vorhanden ist. nilist keine positive ganze Zahl.
Pavel

@Pavel danke, ich habe es überprüft, aber irgendwie verpasst
Asone Tuhid
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.