Yinelenen öğe grupları


10

Meydan okuma açıklaması

Bir öğe listesi / dizisi verildiğinde, ardışık yinelenen öğelerin tüm gruplarını görüntüleyin.

Giriş / çıkış açıklaması

Girişiniz bir liste / öğe dizisidir (hepsinin aynı türde olduğunu varsayabilirsiniz). Dilinizin sahip olduğu her türü desteklemenize gerek yoktur, ancak en az birini desteklemesi gerekir (tercihen int, ancak booleançok ilginç olmasa da, türler de iyidir). Örnek çıktılar:

[4, 4, 2, 2, 9, 9] -> [[4, 4], [2, 2], [9, 9]]
[1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4] -> [[1, 1, 1], [2, 2], [3, 3, 3], [4, 4, 4, 4]]
[1, 1, 1, 3, 3, 1, 1, 2, 2, 2, 1, 1, 3] -> [[1, 1, 1], [3, 3], [1, 1], [2, 2, 2], [1, 1], [3]]
[9, 7, 8, 6, 5] -> [[9], [7], [8], [6], [5]]
[5, 5, 5] -> [[5, 5, 5]]
['A', 'B', 'B', 'B', 'C', 'D', 'X', 'Y', 'Y', 'Z'] -> [['A'], ['B', 'B', 'B'], ['C'], ['D'], ['X'], ['Y', 'Y'], ['Z']]
[True, True, True, False, False, True, False, False, True, True, True] -> [[True, True, True], [False, False], [True], [False, False], [True, True, True]]
[0] -> [[0]]

Boş listelere gelince, çıktı tanımlanmamıştır - golf amaçlarınıza en uygun olan şey hiçbir şey, boş bir liste veya bir istisna olabilir. Ayrı bir liste listesi oluşturmak zorunda değilsiniz, bu yüzden bu da geçerli bir çıktıdır:

[1, 1, 1, 2, 2, 3, 3, 3, 4, 9] ->

1 1 1
2 2
3 3 3
4
9

Önemli olan grupları bir şekilde birbirinden ayırmaktır.


Belki bazı özel ayırıcı değeri olan bir liste çıkarırız?
xnor

@xnor: Bir örnek verebilir misiniz? intÖrneğin s ile ayrılmış bir s dizisi , girişte s 0olabileceğinden kötü bir fikir olacaktır 0...
shooqie

Örneğin, [4, 4, '', 2, 2, '', 9, 9]veya [4, 4, [], 2, 2, [], 9, 9].
xnor

Aslında ne tür desteklememiz gerekiyor. Öğelerin kendileri liste olabilir mi? Bazı dillerin yazdırılamayan veya garip eşitlik denetimi olan yerleşik türlere sahip olduğunu düşünüyorum.
xnor

@xnor: Evet, endişem buydu - eğer girdilerinizde listeler varsa, boş listeyi ayırıcı olarak kullanmak kafa karıştırıcı olabilir. Bu yüzden "tüm öğelerin aynı tür olduğunu varsayabilirsiniz" ifadesini ekledim, böylece ayırıcı olarak farklı bir tür kullanabilirsiniz.
shooqie

Yanıtlar:




8

Retina , 15 8 bayt

Daha basit bir G / Ç formatı önerdiği için Lynn'e teşekkürler.

!`(.)\1*

Girdiye bir karakter listesi gibi davranır (ve grupları ayırmak için satır beslemeleri kullanır).

Çevrimiçi deneyin!

Bu sadece grupları eşleştirip hepsini yazdırarak çalışır (otomatik olarak satır besleme ayırmayı kullanır).


Ben abbcccddda bb ccc dddkabul edilebilir bir G / Ç biçimi hakkında sordum ve OP onayladı, bu yüzden sanırım !`(.)\1*iyi mi?
Lynn

@Lynn Oh, bu gerçekten çok daha basit, teşekkürler.
Martin Ender

4

JavaScript (ES6), 39 37 bayt

f=
s=>s.replace(/(\w+) (?!\1\b)/g,`$1
`)
;
<input oninput=o.textContent=f(this.value);><pre id=o>

Boşluktan ayrılmış sözcük benzeri simgeler üzerinde çalışır. @ MartinEnder ♦ sayesinde 2 bayt tasarruf edildi. Dizi girişi ve dönüş için yapabileceğim en iyi şey 68:

a=>a.reduce((l,r)=>(l==r?c.push(r):b.push(c=[r]),r),b=[c=[a[0]]])&&b

1
56'da dizi cevabı ekledim
edc65

4

MATL , 9 bayt

Y'v"@Z}Y"

Y'     % Take input. Run-length encoding. Gives two row arrays: values and run lengths
v      % Concatenate vertically   
"      % For each column
  @Z}  %   Push column and split into its two elements
  Y"   %   Run-length decoding
       % End for. Implicitly display

Girdi bir sıra dizi numaraları ayırıcı olarak boşluk veya virgül ile.

Çevrimiçi deneyin! Tamsayı olmayan sayılarla test edin .


MATL, 11 bayt

lidgvYsG7XQ

Girdi, ayırıcı olarak kullanılan sayı veya karakterlerden oluşan bir sütun dizisidir ;.

Çevrimiçi deneyin! Rasgele sayılarla test edin . Karakterlerle test edin .

l     % Push 1
i     % Take input, say [4;4;2;2;9;9]
d     % Consecutive differences of input: [0;-2;0;7;0]
g     % Convert to logical: gives 1 if consecutive entries were different: [0;1;0;1;0]
v     % Concatenate vertically with the initial 1: [1;0;1;0;1;0]
Ys    % Cumulative sum. Each value is a group label: [1;1;2;2;3;3]
G     % Push input again
7XQ   % Split into horizontal arrays as indicated by group labels: {[4 4];[2 2];[9 9]}
      % Implicitly display

3

gs2, 2 bayt

c-

Çevrimiçi deneyin!

ctam olarak bunu yapan bir gruplamadır, bu yüzden STDIN (yani bir dize, yani bir karakter listesi) olarak adlandırırız ve dizelerin bir listesini alırız. Ne yazık ki, sonuç girişten ayırt edilemez, bu yüzden ayırıcılar eklememiz gerekiyor! -(boşluklara katıl) hile yapar.

Alternatif bir cevap ( canonim bir fonksiyona saran (2 byte CP437)) .


2

Brachylog , 13 bayt

:{s.dl1}fs.c?

Uyarı: Bu son derece verimsizdir ve açıklamanın nedenini anlayacaksınız.

Bu [1:1:2:2:2]girdi olarak bir liste (örn. ) Bekler. Listedeki öğeler hemen hemen her şey olabilir.

açıklama

:{     }f       Find all ordered subsets of the Input with a unique element in them
  s.                Output is a subset of the input
    dl1             Output minus all duplicates has a length of 1 (i.e. one unique value)
         s.     Output is an ordered subset of those subsets
           c?   The concatenation of those subsets is the Input

Bu sadece s - Subsetbirleşme şekli nedeniyle çalışır : en küçük kümeler sonundadır. Bu nedenle, Girdi ile birleştirilen ilk şey, örneğin [[1:1]:[2:2:2]]değil , en uzun süredir [[1:1]:[2:2]:[2]].


2

J , 13 bayt

<;.1~1,2~:/\]

J düzensiz dizileri desteklemediğinden, eşit elemanların her çalıştırılması kutu içine alınır. Girdi bir değer dizisidir ve çıktı kutulu diziler dizisidir.

kullanım

   f =: <;.1~1,2~:/\]
   f 4 4 2 2 9 9
┌───┬───┬───┐
│4 4│2 2│9 9│
└───┴───┴───┘
   f 1 1 1 3 3 1 1 2 2 2 1 1 3
┌─────┬───┬───┬─────┬───┬─┐
│1 1 1│3 3│1 1│2 2 2│1 1│3│
└─────┴───┴───┴─────┴───┴─┘
   f 'ABBBCDXYYZ'
┌─┬───┬─┬─┬─┬──┬─┐
│A│BBB│C│D│X│YY│Z│
└─┴───┴─┴─┴─┴──┴─┘
   f 0
┌─┐
│0│
└─┘

açıklama

<;.1~1,2~:/\]  Input: s
            ]  Identify function to get s
       2       The constant 2
           \   Operate on each overlapping sublist of size 2
        ~:/      Are the two values unequal, 1 if true else 0
     1,        Prepend a 1 to it
<;.1~          Using the list just made, chop s at each index equal to 1 and box it
               Return this as the result

2

Dyalog APL , 9 bayt

⊢⊂⍨1,2≠/⊢

argüman ilk öğede
⊂⍨bölümlendi ve ardından sonraki çiftlerin argümanda farklı olduğu yerlerde
1
,
2≠/


2

Python 2, 43 bayt

p=-1
for x in input():print"|"[:x^p],x,;p=x

Boolean listelerinde çalışır. Misal:

>> [True,True,False,False,False,True,False,True,False]
 True  True | False  False  False | True | False | True | False

En son görülen öğeyi saklayarak giriş listesinde yinelenir. Bir ayırma çubuğu, öncekinden farklı olan ve bitsel x ^veya 0 olduğu kontrol edilen her öğeden önce yazdırılır . Başlatma p=-1, ilk öğeden önce bir ayırıcıyı önler.


Çok kötü groupbyböyle bir acı ...
Sp3000

2

CJam, 9 bayt

İki çözüm:

{e`:a:e~}
{e`{(*}%}

Burada test edin.

açıklama

e`   e# Run-length encode (gives a list of pairs [run-length value]).
:a   e# Wrap each pair in a singleton list.
:e~  e# Run-length decode each list.

Veya

e`   e# Run-length encode.
{    e# Map this block over each pair...
  (  e#   Pull out the run length.
  *  e#   Repeat the list containing only the value that many times.
}%

2

Haskell, 22 bayt

import Data.List
group

Yerleşik. Eşitliği destekleyen her tür üzerinde çalışır.


2
Bunun topluluk wiki olmasının bir nedeni var mı?
ölümcül


1
Bu asil ama başka hiç kimse bunu yapmadığı için neden metada bunu sormuyorsun?
16'da

2

MATL, 8 7 bayt

@Suever sayesinde 1 bayt kaldırıldı

ly&Y'Y{

Tamsayılar / şamandıralar / karakter / booleans / tek boynuzlu at noktaları / diğer hayali girdilerle çalışır.
Booleanlar için girdiler T/F, çıktılar 1/0.

Çevrimiçi deneyin!


Gruplandırılmış ve Tekrarlanmış

ly&Y'Y{
l          % push 1 onto the stack
 y         % duplicate the input
  &Y'      % run-length encoding (secondary output only)
     Y{    % break up array into cell array of subarrays

1

C #, 117 bayt

void f(List<String>m){Console.Write(m[0]+String.Join("",m.GetRange(1,m.Count()-1).Select((i,j)=>i==m[j]?i:"\n"+i)));}

boyun eğmemiş (gerçekten değil)

    public static void f(List<String>m)
    {
        Console.Write(m[0]+String.Join("",m.GetRange(1,m.Count()-1).Select((i,j)=>i==m[j]?i:"\n"+i)));
    }

1

Pyth, 9 7 bayt

mr9]dr8

2 byte için @LeakyNun'a teşekkür ederiz!

Açıklama:

             input
     r8      run-length decode
m            for each...
   ]d        ...treat each run as standalone encoded form...
 r9          ...decode 
             print

Eski yanıt, 12 bayt

hf.Am!t{dT./

Yerleşik çalışma uzunluğu hakkında unuttum, ama bu iyi bir yaklaşım olduğunu düşünüyorum, bu yüzden sakladım.

Açıklama:

                input
          ./    all possible partitions
 f       T      filter by...
  .A            ...whether all groups of integers...
    m!t{d       ...have length one after deduplication
h               get the first element (first one has no adjacent [1,1] and [1])
                print

Bu 7 bayt
Leaky Nun

@LeakyNun Ah doğru! Çok havalı.
busukxuan

1
İnanıyorum bu 6 için çalışır
FryAmTheEggman

@FryAmTheEggman Güzel taciz m.
Leaky Nun

@FryAmTheEggman Vay canına, anlamıyorum oO
busukxuan

1

Pyth , 36 35 bayt

VQIqNk=hZ).?=+Y]*]kZ=Z1=kN;t+Y]*]kZ

Test bağlantısı

Düzenleme: açıklama:

                                      standard variables: Y=[], Z=0, k='', Q=input
VQ                                    iterate over input
  IqNk                                if the current entity is equal to k:
      =hZ)                            increase Z.
          .?                          else:
               ]*]kZ                  list of length Z filled with k
            =+Y                       add it to Y
                    =Z1               set Z to 1
                       =kN            set k to the current entity
                          ;           end loop
                              ]*]kZ   list of length Z filled with k
                            +Y        add it to Y
                           t          implicitly print the tail of Y (removing the first element)


1

05AB1E, 13 bayt

¬svyÊi¶}yðJ?y

Açıklaması

¬s             # push first element of list to stack and swap with input
  v            # for each X in input
   yÊi¶}       # if X is different from last iteration, push a newline
        yðJ?   # push X followed by a space to stack and join stack to string
            y  # push X to stack for next iterations comparison

Herhangi bir liste için çalışmalıdır.
İnt ve char üzerinde test edilmiştir.

Çevrimiçi deneyin


1

Swift, 43 bayt

var p=0;i.map{print($0==p ?"":",",$0);p=$0}

İ'nin eşitlenebilir nesnelerden oluşan bir dizi olduğunu varsayar; ints'tan dizelere ve özel nesnelere kadar her şey için çalışır. Çıktının çok sayıda yeni satır içermesi, ancak bu güzelliğin baytlara mal olması bakımından biraz arsız.

Daha güzel, çözülmemiş versiyon:

var prev = Int.max // unlikely to be the first element, but not the end of the world if it happens to be.
i.map { n in
    print(n == prev ? " " : "\n•", n, terminator: "")
    prev = n
}

Bu sürüm, her grubu daha fazla kod pahasına yeni bir satıra yazdırır.

İyileştirme Fikirleri

i.reduce(0){print($0==$1 ?"":"•",$1);return $1}

Bu sürümde 47 bayt var, ancak farklı bir yaklaşım var, belki orada optimize etmek için bir şey var mı? En büyük sorun iade beyanıdır.


1

C, 88 77 bayt

Tasarruflu 11 baytın strmcmp içine taşındıprintf

f(char**a){*a++;char*x;for(;*a;x=*a++)printf(strcmp(*a,x)?"\n%s ":"%s ",*a);}

Kullanımı:

f(char**a){*a++;char*x;for(;*a;x=*a++)printf(strcmp(*a,x)?"\n%s ":"%s ",*a);}
main(c,v)char**v;{f(v);}

Örnek Giriş:

(Komut satırı parametreleri)

1 1 1 1 2 2 2 2 3 3 3 3 4 5 6 7777

Örnek Çıktı:

1 1 1 1
2 2 2 2
3 3 3 3
4
5
6
7777

Test tarihi:

gcc 4.4.7 (Red Hat 4.4.7-16)  - OK
gcc 5.3.0 (Cygwin)            - Segmetation Fault
gcc 4.8.1 (Windows)           - OK

5.3.0 Segmetasyon Hatasını düzeltmeye çalışıyorum.

88 Versiyon

f(char**a){*a++;char*x;for(;*a;x=*a++)strcmp(*a,x)?printf("\n%s ",*a):printf("%s ",*a);}

1

Java 134 bayt

void a(String[]a){int i=0,l=a.length;for(;i<l-1;i++)System.out.print(a[i]+((a[i].equals(a[i+1]))?" ":"\n"));System.out.print(a[l-1]);}

yineleme yapar ve yeni bir çizgi veya boşlukla ayrılmaya karar verir.


başlangıç ​​için publicve staticanahtar kelimeleri kaldırabilirsiniz . Ayrıca döngü için kıvrımlı parantez kaldırabilirsiniz
user902383

@ User902383
Rohan Jhunjhunwala

1

ListSharp , 134 bayt

STRG l = READ[<here>+"\\l.txt"]
[FOREACH NUMB IN 1 TO l LENGTH-1 AS i]
{
[IF l[i] ISNOT l[i-1]]
STRG o=o+"\n"
STRG o=o+l[i]
}
SHOW = o

ListSharp işlevleri desteklemez, böylece dizi adlı yerel bir dosyaya kaydedilir l.txt dosya


1

Yakut , 24 bayt

Yakut Arrayörneklerde yerleşik yöntem vargroup_by

Yani çözüm şöyle olacak:

a.group_by{|x| x}.values

0

TSQL, 132 bayt

Bu diğer cevaplardan biraz farklı - sql dizileri yok, sql için bariz girdi bir tablo.

golfed:

DECLARE @ table(i int identity, v varchar(20))
INSERT @ values(1),(1),(1),(3),(3),(1),(1),(2),(2),(2),(1),(1),(3)

SELECT REPLICATE(v+' ',COUNT(*))FROM(SELECT i,i-row_number()over(partition
by v order by i)x,v FROM @)z GROUP BY x,v ORDER BY max(i)

Ungolfed:

DECLARE @ table(i int identity, v varchar(20))
INSERT @ values(1),(1),(1),(3),(3),(1),(1),(2),(2),(2),(1),(1),(3)

SELECT
  REPLICATE(v+' ',COUNT(*))
FROM 
  (
     SELECT
       i,
       i-row_number()over(partition by v order by i)x,
       v
     FROM @
  )z
GROUP BY
  x,v
ORDER BY
  max(i)

Vaktini boşa harcamak


0

Perl 5-39 Bayt

print$_.($/)[$_ eq@a[++$-]]for@a=sort@a

0

Pyke, 2 bayt (rekabetçi değil)

Yalnızca tam sayıları destekler

$f

Burada deneyin!

split_at(input, delta(input))

Split_at düğümü eklendi, 2. arg doğru olduğunda girişi böler


0

sed, 33 23 + 1 = 24 bayt

s/([^ ]+)( \1)* */&\n/g

Seçeneğe ihtiyacı var -r.

Kullanım örneği:

$ echo '1 1 1 2 2 3 3 3 4 9 9' | sed -r 's/([^ ]+)( \1)* */&\n/g'
1 1 1 
2 2 
3 3 3 
4 
9 9

0

JavaScript (ES6), 56

Girdi: sayı dizeleri veya dizeler

Çıktı: dizi dizisi

Golf kodunda ilk defa tam karşılaştırma

a=>a.map(x=>x!==p?o.push(g=[p=x]):g.push(x),p=o=g=[])&&o

0

Clojure, 19 bayt

#(partition-by + %)

Bu yerleşiktir, ancak bir eşleme işlevi gerektirir. Bu durumda, +bir kimlik işlevi olarak işlev görür.


0

Javascript (harici kitaplık kullanarak) (178 bayt)

(s)=>_.From(s).Aggregate((t,e)=>{if(0===t.Items.length)return t.Items.push([e]),t;var s=t.Items[t.Items.length-1];return s[0]===e?(s.push(e),t):(t.Items.push([e]),t)},{Items:[]})

Yasal Uyarı: LINQ C # JS içine uygulamak için yazdığım bir kütüphane kullanıyorum. Tam olarak kazanmama yardımcı olmadı ama oh iyi

görüntü

image2

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.