Menghitung array, mengelompokkan duplikat

24

Tujuan dari tantangan ini adalah untuk mengambil array bilangan bulat positif, dan menghitung indeksnya, mengelompokkan elemen-elemen seperti.

Pencacahan tanpa duplikat dilakukan dengan hanya mengeluarkan array pasangan (value, index), misalnya, [3, 4, 13, 9, 2]=> [[3,1],[4,2],[13,3],[9,4],[2,5]].

Namun, jika elemen yang diberikan muncul kedua kalinya, itu tidak diberikan pasangannya sendiri, tetapi malah ditambahkan ke grup kejadian pertama. Jika dalam contoh di atas kita mengganti 9 dengan 3, maka dalam output kita akan menghapus [9,4]dan mengganti [3,1]dengan [3,1,4].

Dalam output, grup harus dipesan berdasarkan kemunculan pertama mereka, dan indeks harus dalam urutan menaik. Elemen harus terlebih dahulu dalam grup, sebelum indeksnya. Output mungkin 0 atau 1 diindeks. Anda dapat menganggap array memiliki setidaknya satu elemen.

Kasus uji:

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]]

Ini adalah , byte terkecil menang!

Pavel
sumber
Apakah akan diterima untuk data yang akan dihasilkan sebagai string, misalnya [[17,"1"]]? (Belum tahu apakah saya bisa menyimpan byte dengan cara itu, masih bekerja di sana!)
Shaggy
@shaggy yakin, tidak apa-apa
Pavel
1
Bisakah kita menampilkan sesuatu seperti itu [[3, [1, 4]], [2, [2, 3]]]?
Conor O'Brien
1
@Pavel itu bukan alasan: p tapi pasti
Conor O'Brien

Jawaban:

9

Dyalog APL, 5 byte

(⊂,)⌸

Cobalah online!

,⌸untuk 2 byte hampir berfungsi, tetapi memiliki nol di belakangnya: /

dzaima
sumber
Apa yang di dunia lakukan?
Tn. Xcoder
@ Mr.Xcoder mendapatkan indeks masing-masing hal dan memanggil operator kiri dengan benda dan indeks di mana benda itu ada
dzaima
Karena isue dengan ,⌸trailing nol, dan nol tidak akan pernah ada dalam input, apakah mungkin untuk menjatuhkan semua nol dalam waktu kurang dari 3 byte?
Pavel
@Pavel alasan bahwa ada nol adalah bahwa hasilnya adalah matriks, yang harus memiliki dimensi yang tepat, jadi hanya ada 1 byte untuk menjatuhkan nol untuk setiap kenaikan byte. Saya merasa seperti ini mungkin golf.
dzaima
2
format output array "fancy af" : Cobalah secara online!
Adám
7

J , 12 byte

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

Diindeks nol.

Cobalah online!

Jika Anda bisa menghapus semua pekerjaan yang saya lakukan dengan kotak, Anda mungkin dapat mengurangi bytecount sedikit. Saya akan melihat apakah saya bisa mengetahuinya.

Penjelasan

Ini mungkin terlalu dini untuk dijelaskan (seharusnya ada lebih banyak golf).

~. ,&.> <@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
cole
sumber
2
Format keluaran larik itu sangat disukai af
Pavel
@Pavel itu juga membutuhkan banyak byte Π.Π
cole
5

05AB1E , 10 byte

ÙεDIQƶ0K)˜

Cobalah online!

Penjelasan

Ù             # 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
Emigna
sumber
5

Python 3 , 83 82 byte

-1 byte terima kasih kepada Mego

lambda x:[[n]+[j for j,m in enumerate(x)if m==n]for n in sorted({*x},key=x.index)]

Cobalah online!

tongkat
sumber
1
j+1-> j(indeks mungkin tidak diindeks)
Mego
5

Attache , 15 byte

Flat=>Positions

Cobalah online!

Ini adalah kasus yang menarik =>, bentuk operator dari Map. Ketika diberikan dua argumen fungsional fdan g, Mapmengembalikan fungsi f => g[x]lebih x. Artinya, RHS diterapkan pada input, kemudian LHS dipetakan.

Builtin Positionsmenghasilkan larik yang mewakili pengelompokan entri berdasarkan indeks. Secara default, ketika tidak disertakan dengan argumen kedua, Positionsakan menggunakan argumen pertama. Flatkemudian dipetakan di atas setiap item, karena itulah yang dibutuhkan pertanyaan.

Solusi alternatif

31 byte

MapArgs[Concat#~Indices,Unique]

Cobalah online!

Alternatif yang cukup pendek, kurang built-in. MapArgsadalah fungsi seperti Map, kecuali Anda dapat memasukkan argumen tambahan ke dalamnya. Sebagai contoh, MapArgs[{_1 + _2}, 1..3, 3]adalah [4, 5, 6]. Seperti Map, itu menjadi kari ketika dilengkapi dengan dua argumen fungsional. Fungsi yang dipetakan adalah Concat#~Indices, yang merupakan garpu. Garpu ini diterapkan pada Uniqueitem input dan input itu sendiri. Ini diterjemahkan menjadi Concat[_, Indices[_2, _]](dengan argumen Indicesswapped through ~), yang memasangkan elemen yang dipetakan ( _) dengan indeks elemen tersebut _dalam array input, yaitu _2(seperti yang dijelaskan melalui MapArgs).

43 byte

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

Cobalah online!

Ini benar-benar hanya kombinasi yang lebih verbose (namun sedikit lebih mudah dibaca) dari solusi # 1 dan # 2.

Conor O'Brien
sumber
4

Jelly , 6 byte

Q;"ĠṢ$

Cobalah online!

Penjelasan:

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
Erik the Outgolfer
sumber
Tidak berfungsi untuk test case terakhir . Array harus bersarang lapisan lain, output selalu dua dimensi.
Pavel
@Pavel ya , saya hanya lupa menambahkan catatan kaki (jawabannya adalah fungsi)
Erik the Outgolfer
Baiklah kalau begitu, keren. Penjelasannya segera, ya? : P
Pavel
@Pavel menambahkan penjelasan
Erik the Outgolfer
4

Pyth , 7 byte

Diindeks 0.

{+VQxRQ

Coba di sini! Alternatif.

Bagaimana?

{+ VQxRQ - Program lengkap.

     RQ - Untuk setiap elemen ...
    x - Dapatkan semua indeksnya.
 + V - Dan menerapkan penggabungan vektor.
   Q - Dengan input.
{- Deduplicate.
Tuan Xcoder
sumber
4

MATL , 8 byte

u"@tG=fh

Cobalah di MATL Online

Penjelasan

        # 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
Suever
sumber
ooooohhh itu pintar! Saya memiliki 18 byte yang mencoba untuk digunakan &ftetapi tidak pernah berhasil.
Giuseppe
3

Sebenarnya , 24 byte

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

Cobalah online!

Penjelasan:

;;╗⌠╝╜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
Mego
sumber
3

R , 56 byte

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

Cobalah online!


Ini adalah upaya pertama saya di codegolf, jadi setiap umpan balik dipersilahkan!

Florian
sumber
3
Selamat datang di PPCG! Jawaban pertama yang bagus.
Pavel
1
Hai, Florian! Jawaban yang sangat bagus Ini sebenarnya adalah potongan daripada program atau fungsi - ini mengasumsikan input di-hardcode x, tetapi harus ada cara membaca input - biasanya kita menggunakan scanatau mendefinisikan suatu fungsi. Selain itu, harus di-output, jadi harus membungkus ini dengan a printatau a cat.
Giuseppe
1
lihat pertanyaan ini untuk trik golf R yang lebih praktis :)
Giuseppe
1
Terima kasih kawan! Dan tautan ke r tips ini tentu bermanfaat!
Florian
2
@Florian R tidak seburuk yang Anda pikirkan (kecuali pada tantangan string ...) selama Anda ingat Anda bermain golf melawan pegolf R lainnya! Jangan ragu untuk melakukan ping ke saya di chat jika Anda memiliki pertanyaan. Ada beberapa pegolf R yang aktif, dan mereka pasti akan menawarkan saran, dan menghargai saran Anda juga! Selamat datang di golf :)
Giuseppe
3

Bahasa Wolfram (Mathematica) , 40 byte

Menyimpan satu byte berkat Martin Ender.

KeyValueMap[{#,##&@@#2}&]@*PositionIndex

Cobalah online!

alephalpha
sumber
Bagaimana cara @*PositionIndexkerjanya?
Pavel
@Pavel @*adalah komposisi fungsi. PositionIndexpada dasarnya melakukan semua pekerjaan, tetapi mengembalikan asosiasi alih-alih daftar.
alephalpha
1
{#,##&@@#2}&menghemat satu byte.
Martin Ender
3

JavaScript (ES6), 64 byte

0 diindeks

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

Catatan, ini menganggap angka input menjadi positif, jadi v> 0

Tes sedikit dimodifikasi (1 diindeks) untuk mencocokkan kasus uji

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))
})

edc65
sumber
3

APL NARS, 24 byte, 12 karakter

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

-4 byte berkat tes Adam:

  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
└∊───────────┘
RosLuP
sumber
Shave a 4 bytes / 2 chars:{∪⍵,¨⍸¨⍵=⊂⍵}
Adám
3

SWI-Prolog , 165 117 byte

-48 byte berkat tips golf Prolog .

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)).

Cobalah online!

Penjelasan

% 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)
    ).
mercator
sumber
3

K (oK) , 10 byte

Larutan:

(!x),'.x:=

Cobalah online!

Contoh:

(!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)

Penjelasan:

Evaluasi dilakukan dari kanan ke kiri. Saya masih berpikir ini bisa golf lebih jauh ...

(!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)

Catatan:

  • 14 bytes tanpa menyatakan x, (,/)'+(!;.)@'=, menyerah dengan pendekatan ini ...
streetster
sumber
1
Anda dapat mengembalikan hasil yang diindeks 0, jadi saya pikir Anda dapat melewati 1+.
Adám
2

Julia 0,6 , 37 byte

Terima kasih kepada Pavel untuk off 1 byte.

y->[[x;findin(y,[x])]for x=unique(y)]

Cobalah online!

gggg
sumber
Hapus spasi antara ]dan foruntuk -1 byte.
Pavel
2

JavaScript (ES6), 68 byte

Diindeks 0.

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

Uji kasus

Arnauld
sumber
Angka
inputnya
2

PHP 4.1, 88 byte

Ya, ini cukup panjang.

Ini mengasumsikan file default php.ini ( short_open_tag = Ondan register_globals = On).

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

Ini menyajikan array dengan cara yang dapat dibaca manusia.
Nilai-nilai dapat dilewatkan oleh POST, GET dan COOKIE, di dalam kunci "A".


Untuk versi modern, seseorang dapat menggunakan (90 byte):

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

Hasilnya sama, kecuali semua nilai harus melewati parameter GET di dalam kunci "A".

Ismael Miguel
sumber
2

Perl 6 ,  63  61 byte

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

Uji (berbasiskan 0)

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

Uji itu (algoritma yang sama berbasis 0)

Diperluas:

# 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])
Brad Gilbert b2gills
sumber
2

Japt , 14 9 byte

Diindeks 0.

â £ð¶X iX

Cobalah

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

PHP 7.4+ , 71 byte

* 73 byte untuk mengutip $_GETkunci dan menghindari Peringatan.

Cuplikan: ( Demo )

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

Berdasarkan perwakilan, saya menganggap IsmaelMiguel tahu cara terbaik untuk mengirim kode php di komunitas ini jadi saya membangun dari yayasannya . Tidak jelas bagi saya apakah <?akan dimasukkan / dihitung dalam cuplikan saya . Karena ini adalah posting perdana saya, saya senang bagi siapa saja untuk menjelaskan jika ada sintaksis yang tidak perlu. ps Saya juga membaca Tips untuk bermain golf di PHP yang bagi saya sepertinya adalah kandidat yang hebat untuk migrasi ke Meta .

Perbaikan yang dilakukan pada cuplikan Ismael adalah:

  1. Penugasan tanpa syarat dari elemen pertama di setiap subarray (penimpaan nilai)
  2. Splatpacking alih-aliharray_values() mengindeks kembali output.
mickmackusa
sumber
1

Kotlin , 83 byte

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

Yg diperindahkan

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

Uji

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

jrtapsell
sumber
Solusi ini adalah cuplikan, bukan fungsi atau program lengkap. Ini membutuhkan variabel yang isudah ditentukan sebelumnya. Anda dapat menjadikan ini valid dengan mengonversinya menjadi lambda yang mengambil parameter i.
Pavel
Dikerjakan untuk memecahkan masalah yang diangkat oleh @Pavel
jrtapsell
1

Cepat 4, 107 byte

... Astaga.

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

Tidak Disatukan:

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
        }
}

Sayang sekali kamus kehilangan urutan, memaksa saya untuk membuang begitu banyak karakter untuk mengurutkan kembali. Ini semacam pelecehan argumen penutupan implisit ( $0, $1, ...) dan anggota tuple implisit ( .0, .1, ...) adalah Uhhhhh tidak cantik.

Alexander - Pasang kembali Monica
sumber
1

Ruby , 54 52 byte

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

Versi ini memungkinkan nil (53 byte):

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

Cobalah online!

Asone Tuhid
sumber
Tantangan menentukan array hanya akan berisi bilangan bulat positif, dan akan ada setidaknya satu elemen. nilbukan bilangan bulat positif.
Pavel
@Pavel terima kasih, saya memeriksa tetapi entah bagaimana melewatkannya
Asone Tuhid