Bir diziyi numaralandırmak, çiftleri gruplamak


24

Bu zorluğun amacı, bir dizi pozitif tamsayı almak ve benzer öğeleri gruplayarak endekslerini numaralandırmaktır.

Herhangi bir kopya içermeyen bir numaralandırma, sadece bir çift dizisi çıktısı alınarak yapılır (value, index), örneğin, [3, 4, 13, 9, 2]=> [[3,1],[4,2],[13,3],[9,4],[2,5]].

Bununla birlikte, eğer bir element ikinci kez belirirse, kendi çiftine verilmez, bunun yerine ilk oluşum grubuna eklenir. Biz 3 ile 9 değiştirilir bizim yukarıdaki örnekte ise, çıktıda biz çıkarıyoruz [9,4]ve değiştirme [3,1]ile [3,1,4].

Çıktıda, gruplar ilk oluşumlarına göre sıralanmalı ve endeksler artan düzende olmalıdır. Eleman ilk önce bir grupta, endekslerinden önce olmalıdır. Çıktı 0 veya 1 dizinlenmiş olabilir. Dizinin en az bir elementi olduğunu varsayabilirsiniz.

Test durumları:

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

Bu , en az bayt kazanıyor!


Örneğin, indekslerin dizge olarak çıkması kabul edilebilir mi [[17,"1"]]? (Henüz herhangi bir byte kurtarabilir miyim, hala üzerinde çalışabilir miyim, bilmiyorum!)
Shaggy

@ shaggy elbette, sorun değil
Pavel


1
[[3, [1, 4]], [2, [2, 3]]]Bunun gibi bir şey çıktırabilir miyiz ?
Conor O'Brien,

1
@Pavel bunun bir sebebi yok: p fakat kesin
Conor O'Brien,

Yanıtlar:


9

Dyalog APL, 5 bayt

(⊂,)⌸

Çevrimiçi deneyin!

,⌸2 bayt için neredeyse çalışır, ancak sondaki sıfıra sahiptir: /


Dünyada ne yapar ?
Bay Xcoder

@ Mr.Xcoder her şeyin indekslerini alır ve var olan şeyi ve endeksleri ile sol operatörü çağırır
dzaima

Şununla gelen ,⌸sıfır sıfırdır ve sıfırlar girişe asla girmez, sıfırın tamamını 3 bayttan daha az bırakmak mümkün olur mu?
Pavel

@ Sıfır olmasının sebebi, sonucun kesin boyutlara sahip olması gereken bir matris olmasıdır, bu nedenle herhangi bir bayt kazancının sıfırlarını bırakmak için yalnızca 1 bayt vardır. Bu olsa golf olabilir gibi hissediyorum.
dzaima

2
"fantezi af" dizi çıktı biçimi: Çevrimiçi deneyin!
Ad '22

7

J , 12 bayt

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

Sıfır endekslendi.

Çevrimiçi deneyin!

Kutularla yaptığım tüm çalışmaları kaldırabilirseniz, büyük olasılıkla bayt sayısını biraz azaltabilirsiniz. Bunu çözüp çözemeyeceğimi göreceğim.

açıklama

Bu muhtemelen açıklamak için çok erken (daha fazla golf olması gerekiyor).

~. ,&.> <@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
Bu dizi çıktı biçimi çok güzel
Pavel

@Pavel da çok fazla bayt alıyor Π.Π
cole

5

05AB1E , 10 bayt

ÙεDIQƶ0K)˜

Çevrimiçi deneyin!

açıklama

Ù             # 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

Ataşesi , 15 bayt

Flat=>Positions

Çevrimiçi deneyin!

Bu ilginç bir durumdur =>, operatör şeklidir Map. İki fonksiyonel argümanları verildiğinde fve g, Mapbir işlev döndürür f => g[x]üzerinde x. Yani, RHS girişe uygulanır, ardından LHS haritalanır.

Yerleşik Positions, girişlerin dizinlere göre gruplandırılmasını temsil eden bir dizi oluşturur. Varsayılan olarak, ikinci bir argüman ile sağlanmadığında Positions, ilk argümanı kullanır. FlatDaha sonra sorunun gerektirdiği şekilde her bir öğe üzerinde haritalanır.

Alternatif çözümler

31 bayt

MapArgs[Concat#~Indices,Unique]

Çevrimiçi deneyin!

Oldukça kısa, yerleşik olmayan bir alternatif. MapArgsBunun gibi Mapekstra argümanlar besleyebilmeniz dışında , bunun gibi bir fonksiyon Örneğin, MapArgs[{_1 + _2}, 1..3, 3]bir [4, 5, 6]. Gibi Map, iki fonksiyonel argüman ile tedarik edildiğinde kıvrılmış olur. Eşlenecek olan fonksiyon Concat#~Indicesçataldır. Bu çatal, Uniquegiriş öğelerine ve girişin kendisine uygulanır. Bu, Concat[_, Indices[_2, _]](ile Indicesdeğiştirildi ~) argümanlarıyla ), eşleştirilen öğeyi ( _) _giriş dizisindeki söz konusu öğenin indeksleri ile eşleştirir ( ki _2bunlar üzerinden geçer MapArgs).

43 bayt

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

Çevrimiçi deneyin!

Bu gerçekten sadece # 1 ve # 2 çözümlerinin daha ayrıntılı (henüz biraz daha okunaklı) bir kombinasyonudur.


4

Jöle , 6 bayt

Q;"ĠṢ$

Çevrimiçi deneyin!

Açıklama:

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

Son test durumu için işe yaramaz . Dizi başka bir katmana yuvalanmalıdır, çıktı iki boyutludur.
Pavel

@Pavel evet öyle, sadece bir altbilgi eklemeyi unuttum (cevap bir işlevdir)
Outgolfer Erik

Tamam o zaman, havalı. Açıklama yakında, evet? : P
Pavel

@Pavel açıklama ekledi
Outgolfer Erik

4

Pyth , 7 bayt

0 endeksli.

{+VQxRQ

Burada dene! Alternatif.

Nasıl?

{+ VQxRQ - Tam program.

     RQ - Her eleman için ...
    x - Tüm endekslerini al.
 + V - Ve vektörel birleştirmeyi uygulayın.
   Q - Girişle.
{- kesinti.

4

MATL , 8 bayt

u"@tG=fh

MATL Online'da deneyin

açıklama

        # 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 bu zekice! Kullanmaya çalışan 18 bayt gibiydim &fama işe yaramadı.
Giuseppe

3

Aslında , 24 bayt

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

Çevrimiçi deneyin!

Açıklama:

;;╗⌠╝╜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 bayt

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

Çevrimiçi deneyin!


Bu benim codegolf'deki ilk denemem, bu yüzden herhangi bir geri bildirim bekliyoruz!


3
PPCG'ye Hoşgeldiniz! Güzel ilk cevap.
Pavel

1
Selam Florian! Çok güzel cevap. Bu aslında bir program veya işlevden ziyade bir snippet'tir - girişin kodlanmış olduğunu varsayar x, ancak girişin bir okuma yolu olması gerekir - genellikle scanbir işlevi kullanırız veya tanımlarız. Ek olarak, çıktısını almak zorundadır, bu yüzden bunu a printveya a içine sarmanız gerekir cat.
Giuseppe

1
daha kullanışlı R golf hileci için bu soruyu bakın :)
Giuseppe

1
Teşekkürler beyler! Ve r ipuçları için link kesinlikle faydalıdır!
Florian

2
@Florian R, diğer R golfçülere karşı golf oynadığınızı hatırladığınız sürece (string zorlukları hariç ...) düşündüğünüz kadar kötü değildir! Sorularınız olursa sohbette bana ping atmaktan çekinmeyin. Aktif olan birkaç R golfçü var ve kesinlikle önerilerde bulunacaklar ve sizinkine de teşekkür edecekler!
Giuseppe


3

JavaScript (ES6), 64 bayt

0 dizinlenmiş

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

Bunun giriş numaralarının pozitif olduğunu varsaydığına dikkat edin.

Test durumlarını eşleştirmek için hafifçe değiştirilmiş (1 dizinli) test

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 bayt, 12 karakter

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

Adam testi sayesinde -4 bayt:

  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
└∊───────────┘

4 byte / 2 karakter tıraş:{∪⍵,¨⍸¨⍵=⊂⍵}
18'de

3

SWI-Prolog , 165 117 bayt

Prolog golf ipuçları sayesinde -48 bayt .

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

Çevrimiçi deneyin!

açıklama

% 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 bayt

Çözüm:

(!x),'.x:=

Çevrimiçi deneyin!

Örnekler:

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

Açıklama:

Değerlendirme sağdan sola yapılır. Hala bunun golfle oynayabildiğini düşünüyorum.

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

Notlar:

  • Bildirmeden 14 baytx , (,/)'+(!;.)@'=bu yaklaşımdan vazgeçti ...

1
0 indeksli bir sonuç döndürebilir, böylece atlayabilirsiniz düşünüyorum 1+.
18'de


2

JavaScript (ES6), 68 bayt

0 endeksli.

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

Test durumları


Girdi sayıları! = 0, 1 / x hilesinden kaçınmak için faydalı olabilir
edc65

2

PHP 4.1, 88 bayt

Evet, çok uzun.

Bu varsayar varsayılan php.ini dosya ( short_open_tag = Onve register_globals = On).

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

Bu, diziyi insan tarafından okunabilir bir şekilde sunar.
Değerler "A" anahtarının içinde POST, GET ve COOKIE ile iletilebilir.


Modern bir versiyon için, bir kullanabilirsiniz (90 bayt):

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

Sonuç, tüm değerlerin "A" anahtarının içindeki GET parametreleri üzerinden iletilmesi gerektiği dışında aynıdır.


2

Perl 6 ,  63  61 bayt

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

Dene (0 tabanlı)

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

Test et (0 tabanlı aynı algoritma)

Expanded:

# 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 bayt

0 endeksli.

â £ð¶X iX

Dene

â £ð¶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 bayt

* $_GETAnahtarı alıntılamak ve uyarıları önlemek için 73 bayt .

Metin Parçacığı: ( Demo )

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

Temsilime dayanarak, IsmaelMiguel'in bu toplulukta php kodu göndermenin en iyi yolunu bildiğini farz ediyorum , bu yüzden onun kuruluşundan inşa ediyorum . Snippet'ime dahil edilip<? edilmeyeceği açık değil . Bu benim ilk kızlık görevim olduğundan, herhangi bir gereksiz sözdizimi olup olmadığını açıklamaktan mutluyum. ps Ben de okumak PHP'de golf için ipuçları Meta göçü için müthiş bir aday gibi geliyor bana .

Ismael'in snippet'inde yapılan iyileştirmeler:

  1. Her alt dizideki ilk öğenin koşulsuz atama (değerin üzerine yazılması)
  2. Çıkışı yeniden indekslemek yerinearray_values() sıçramak ambalajlama.


1

Kotlin , 83 bayt

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

Beautified

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

Ölçek

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


Bu çözüm, bir işlevdir, tam bir işlev veya program değildir. Değişkenin iönceden tanımlanmış olmasını gerektirir . Bunu, parametre alan bir lambda'ya dönüştürerek geçerli yapabilirsiniz i.
Pavel

@Pavel
jrtapsell

1

Swift 4, 107 bayt

... Yikes.

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

Sözlüğün sıralama sırasını kaybetmesi, beni tekrar sıralamak için çok fazla karakter harcamam için çok kötü. Örtük kapatma argümanları kötüye (Bu tür $0, $1, ...) ve örtük tanımlama grubu üyeleri ( .0, .1, ...) değil oldukça uhhhhh olduğunu.



1

Ruby , 54 52 bayt

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

Bu sürüm nil izin verir (53 byte):

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

Çevrimiçi deneyin!


Buradaki zorluk, dizinin yalnızca pozitif tamsayıları içereceğini ve en az bir eleman bulunacağını belirtir. nilpozitif bir tamsayı değil.
Pavel

@Pavel teşekkürler, kontrol ettim ama bir şekilde kaçırdım
Asone Tuhid
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.