Listen schnell neu gruppieren

17

Beim Gruppieren wird eine Liste erstellt und in neue Listen gleicher benachbarter Elemente aufgeteilt. Beispielsweise

[1,1,2,1,1] -> [[1,1],[2],[1,1]]

Wenn Sie dann die Länge dieser Gruppen nehmen, erhalten Sie eine neue Liste von ganzen Zahlen

[1,1,2,1,1] -> [2,1,2]

Ihre Aufgabe ist es, ein Programm zu schreiben, das eine Liste positiver Ganzzahlen erstellt und feststellt, wie oft Sie diese gruppieren und verlängern können, bevor die resultierende Liste ein einzelnes Element enthält. Beispielsweise kann die Liste [1,2,3,3,2,1]viermal neu gruppiert werden

[1,2,3,3,2,1]
[1,1,2,1,1]
[2,1,2]
[1,1,1]
[3]

Dies ist daher werden die Antworten in Bytes bewertet, wobei weniger Bytes besser sind.

Testfälle

[1,2,3,3,2,1] -> 4
[1,2,3,4,5,6,7] -> 2
[1,1,1,1,1,1] -> 1
[2] -> 0
[1,2,4] -> 2
[1,2,2,1,1,2] -> 4
[1,2,2,1,1,2,1,2,2] -> 5
[1] -> 0
Weizen-Assistent
quelle
3
Dies ist im Grunde eine Lauflängencodierung ohne Speichern der Werte.
12. Mai, 21.
[1]ist eine gültige eingabe und sollte geben 0, richtig?
ETHproductions
@ETHproductions Ja, das füge ich hinzu, weil es ein kniffliger Fall ist.
Wheat Wizard

Antworten:

3

Japt , 12 Bytes

ÊÉ©1+ßUò¦ ml

Online testen!

Erläuterung

 Ê É © 1+ßUò¦  ml
Ul -1&&1+ßUò!= ml    Ungolfed
                     Implicit: U = input array
Ul -1                Take U.length - 1.
     &&              If this is non-zero:
          Uò!=         Split U between non-equal elements.
               ml      Take the length of each run of equal elements.
         ß             Run the entire program again on the resulting array.
       1+              Add one to the return value.

Rekursion ist für Japt ein wirklich unkonventioneller Ansatz, scheint aber 4 Byte kürzer zu sein als die nächste Alternative ...

ETHproductions
quelle
@ Shaggy Auf meine 16-Byte-Version mit kann F.a()noch über den Revisionsverlauf zugegriffen werden . Ich würde aber gerne Ihren 14-Byter sehen!
ETHproductions
3

Brachylog , 12 Bytes

;.{ḅlᵐ}ⁱ⁾l1∧

Probieren Sie es online!

Erläuterung

;.{   }ⁱ⁾        Iterate Output times the following predicate on the input:
   ḅ               Group consecutive equal elements together
    lᵐ             Map length
         l1∧     The result of this iteration must have length 1
Tödlich
quelle
2

C (gcc) , 108 Bytes

j,k,n;f(A,l)int*A;{for(j=k=n=0;j<l;j++)if(n++,A[j]-A[k])A[k++]=--n,A[k]=A[j],n=1;A=l>1?-~f(A,k,A[k++]=n):0;}

Probieren Sie es online!

Erläuterung

j,k,n;                // array pos, group pos, group val
f(A,l)int*A;{         // function takes array and length
 for(j=k=n=0;j<l;j++) // initialize, loop through array
  if(n++,             // increase n (*), check if group ended
  A[j]-A[k])          // group ended
   A[k++]=--n,        // advance group pos, decrease n, counteracting (*)
   A[k]=A[j],         // store new group type
   n=1;               // group is at least one long
 A=l>1?               // check if array length is larger than one
  -~f(A,k,A[k++]=n)   // fix last group length, enter recursion
  :0;}                // array length is less than two, return zero

Probieren Sie es online!

Jonathan Frech
quelle
2

JavaScript (ES6), 67 65 63 Bytes

f=a=>a[1]?1+f(q=j=i=[],a.map(x=>x^a[++i]?j=!q.push(++j):++j)):0

Merkwürdigerweise scheinen JavaScript und Japt einmal den gleichen kürzesten Algorithmus zu haben ...

ETHproductions
quelle
2

K (oK) , 20 & ndash ; 19 Bytes

Lösung:

#2_{#:'(&~~':x)_x}\

Probieren Sie es online!

Beispiele:

#2_{#:'(&~~':x)_x}\1 2 3 3 2 1
4
#2_{#:'(&~~':x)_x}\1 2 3 4 5 6 7
2
#2_{#:'(&~~':x)_x}\1 1 1 1 1 1
1
#2_{#:'(&~~':x)_x}\1#2
0
#2_{#:'(&~~':x)_x}\1 2 4
2

Erläuterung:

Dieser ist ziemlich einfach, ich frage mich, ob es einen noch besseren Ansatz gibt ... Finde die Indizes, bei denen sich die Eingabe unterscheidet, teile sie an diesen Indizes auf und zähle dann die Länge jeder Unterliste. Iterieren Sie, bis die Ergebnisse zu 1 konvergieren.

#2_{#:'(&~~':x)_x}\ / the solution
   {             }\ / scan over lambda until results converge
                x   / implicit input
               _    / cut at indices
       (      )     / do this together
         ~~':x      / differ... not (~) match (~) each-previous (':) x)
        &           / indices where true
    #:'             / count (#:) each (')
 2_                 / drop first two results
#                   / count result

Anmerkungen:

Die folgende 14-Byte- Lösung funktioniert mit Ausnahme einer Einzelpostenliste für alle :

#1_(-':&~~':)\

Probieren Sie es online!

Streetster
quelle
2

J , 25 23 Bytes

1 Byte gespart dank Streetster

Dank FrownyFrog wird 1 Byte gespeichert

2#@}.#;.1@(0,2=/\])^:a:

Probieren Sie es online!

Anfangslösung:

_2+[:#(#;.1~1,2~:/\])^:a:

Probieren Sie es online!

Erläuterung

      (               )^:a: - repeat until result stops changing, store each iteration
        ;.1~                - cut the input (args swapped)              
            1,2~:/\]      - where the items are no longer the same
       #                    - and take the length of the sublists
 2+[:#                      - finally subtract 2 from the number of steps
Galen Ivanov
quelle
1
Können Sie zwei löschen und dann zählen, anstatt _2+ein Byte zu speichern?
Streetster
1
Ich denke, #;.1@(0,2=/\])spart 1 Byte.
FrownyFrog
@ FrownyFrog Ja, das tut es. Vielen Dank!
Galen Ivanov
@streetster Ja, es hilft, ein Byte zu speichern. Vielen Dank!
Galen Ivanov
2

Stax , 9 Bytes

ÆÑfá╒]`*Ä

Führen Sie es online aus und debuggen Sie es

Die ASCII-Darstellung des gleichen Programms ist dies.

{D}{|RMHgf%

Dies verwendet eine stax-Funktion, die als Generator bezeichnet wird und Wert gemäß Transformations- und Filterblöcken erzeugt.

{ }            the filter for the generator
 D             tail of array; this is truthy for length >= 2
   {    gf     generator block - termination condition is when the filter fails
    |R         run-length encode into pairs [element, count]
      M        transpose matrix
       H       last element
          %    length of final generated array
rekursiv
quelle
2

Python 2 , 84 Bytes

f=lambda a:len(a)>1and-~f(eval(''.join('1'+',+'[x==y]for x,y in zip(a,a[1:]))+'1,'))

Probieren Sie es online!

Wie?

fist eine rekursive Funktion, deren Eingabe adie Länge 2 oder mehr hat. ( len(a)>1) gibt 1+f(x)* zurück. Dabei xist die Gruppenlänge von a; Wenn die Eingabe jedoch Länge 1 oder 0 ist, wird zurückgegeben False(in Python 0). Dies liegt daran, dass die rechte Seite der andnicht ausgewertet wird, wenn die linke Seite falsch ist.

* -~f(x)ist -(-1 - f(x))aber kann das andanders 1+f(x)oder anstoßenf(x)+1 )

Die Gruppenlängen werden berechnet, indem Code erstellt wird, der dann mit ausgewertet wird eval(...). Der erzeugte Code ist so etwas wie 1,1,1+1+1,1,1+1,1,ein Tupel wie ausgewertet (1,1,3,1,2,1).

Der Code wird durch Komprimieren durch erstellt aund aohne den Kopf ( ...for x, y in zip(a,a[1:])Herstellung xund yjedes der benachbarten Paare in aWenn das Paar gleich sind. x==yErgibt True(1) andernfalls False(0) - Dieses Ergebnis Index in der Zeichenfolge verwendet wird , ,+ ergibt , +und ,jeweils sind und jeweils resultierende Zeichen wird durch ein voran 1( '1'+...) - das ganze dann ein abschließender hat, nachlaufenden 1,. wenn hängten Zum Beispiel awurden [5,5,2,9,9,9]dann die x,ywürden Paare (5,5)(5,2)(2,9)(9,9)(9,9)Herstellung der Gleichheiten10011 dann wären die Zeichen +,,++, das mit dem vorhergehenden 1s wird 1+1,1,1+1+und die letzte nachlauf1, making1+1,1,1+1+1,die nach (2,1,3)Bedarf auswertet .

Beachten Sie, dass das Trailing ,sicherstellt, dass eine Eingabe mit einer einzelnen Gruppe als Tupel und nicht als Ganzzahl ausgewertet wird (dh [3,3]-> 1+1,-> (2)und nicht [3,3]-> 1+1-> 2).

Jonathan Allan
quelle
1

Perl 5 , 53 50 49 45 Bytes

Beinhaltet +3für-p

Geben Sie die Liste der Zahlen als eine Zeile in STDIN an

#!/usr/bin/perl -p
s%%$\+=1<s:\d+:$.++x($'-$&and$.=1):eg%eg}{

Probieren Sie es online!

Tonne Hospel
quelle
1

Schale , 8 Bytes

-1 Byte dank @Zgarb!

←Vε¡(mLg

Probieren Sie es online!

Erläuterung

←Vε¡(mLg)  -- example input: [1,2,3,3,2,1]
   ¡(   )  -- repeatedly apply the function & collect results
    (  g)  -- | group: [[1],[2],[3,3],[2],[1]]
    (mL )  -- | map length: [1,1,2,1,1]
           -- : [[1,2,3,3,2,1],[1,1,2,1,1],[2,1,2],[1,1,1],[3],[1],[1],...
 V         -- index where
  ε        -- | length is <= 1: [0,0,0,0,1,1...
           -- : 5
←          -- decrement: 4
ბიმო
quelle
1
←VεDies ist eine kürzere Überprüfung, um den Index der Singleton-Liste zu finden.
Zgarb
1

Gelee , 10 Bytes

ŒgL€$ḊпL’

Probieren Sie es online!

Dennis
quelle
Dies schlägt fehl für[1] . Sie sollten in der Lage sein, es mit zwei Dequeues / Pops zu beheben, anstatt_2
Mr. Xcoder
ÐĿwar in erster Linie keine gute Wahl ... Ersetzte es durch eine while-Schleife.
Dennis
1

05AB1E , 9 Bytes

[Dg#γ€g]N

Probieren Sie es online!

Erläuterung

[Dg#   ]     # loop until the length of the current value is 1
    γ        # split into groups of consecutive equal elements
     €g      # get length of each
        N    # push the iteration variable N
Emigna
quelle
1

Wolfram-Sprache (Mathematica) , 32 Byte

2 Bytes gespart dank Martin Ender. Bei Verwendung der CP-1252-Codierung ±ist ein Byte erforderlich.

±{_}=0;±x_:=1+±(Length/@Split@x)

Probieren Sie es online!

Alephalpha
quelle
1
Das Definieren eines Operators spart zwei Bytes: ±{_}=0;±x_:=1+±(Length/@Split@x)(unter der Annahme der WindowsANSICodierung)
Martin Ender
1

Ruby , 54 56 55 54 Bytes

g=->l,d=0{l[1]?g[l.chunk(&:i).map{|i,j|j.size},d+1]:d}

Probieren Sie es online!

Asone Tuhid
quelle
1

SmileBASIC, 110 108 Bytes

DEF R L,J
K=LEN(L)FOR I=1TO K
N=POP(L)IF O-N THEN UNSHIFT L,0
INC L[0]O=N
NEXT
IF I<3THEN?J ELSE R L,J+1
END

Funktion aufrufen als R list,0; Die Ausgabe wird auf die Konsole gedruckt.

12Me21
quelle
0

Python 2 , 85 Bytes

from itertools import*
f=lambda a:~-len(a)and-~f([len(list(v))for k,v in groupby(a)])

Probieren Sie es online!

Lynn
quelle
0

R , 51 45 Bytes

f=function(a)"if"(sum(a|1)>1,f(rle(a)$l)+1,0)

Probieren Sie es online!

Nehmen Sie rekursiv die Länge der Lauflängencodierung und erhöhen Sie den Zähler.

Giuseppe
quelle
0

Retina 0.8.2 , 31 Bytes

,.*
$&_
}`(\b\d+)(,\1)*\b
$#2
_

Probieren Sie es online! Link enthält Testfälle. Erläuterung:

,.*
$&_

Wenn es ein Komma gibt, werden wir eine weitere Iteration durchführen. Fügen Sie also ein Zählzeichen an.

}`(\b\d+)(,\1)*\b
$#2

Ersetzen Sie jeden Durchgang durch seine dekrementierte Länge. Die obigen Schritte wiederholen sich, bis keine Kommas mehr vorhanden sind.

_

Zählen Sie die Anzahl der Iterationen.

Neil
quelle
0

Perl 6 , 52 Bytes

{+($_,*.comb(/(\d+)[" "$0»]*/).map(+*.words)...^1)}

Probier es aus

Erweitert:

{  # bare block lambda with implicit parameter 「$_」

  + (              # turn the following into a Numeric (get the count)


      $_,          # seed the sequence with the input

      *.comb(      # turn into a string, and grab things that match:

        /          # regex
          ( \d+ )  # a run of digits (number)
          [
            " "    # a space
                   # (gets inserted between elements of list when stringified)

            $0     # another instance of that number
            »      # make sure it isn't in the middle of a number

          ]*       # get as many as possible
        /
      ).map(
        +*.words  # turn each into a count of numbers
      )

      ...^        # keep doing that until (and throw away last value)

      1           # it gives a value that smart-matches with 1
                  # (single element list)
  )
}
Brad Gilbert b2gills
quelle
0

Kotlin , 123 Bytes

Akzeptiert List<Int>.

{var a=it;var b=0;while(a.size>1){var c=a[0];var d=0;with(a){a=listOf();forEach{if(it!=c){a+=d;d=0};d++;c=it};a+=d};b++};b}

Besser lesbar:

{ l ->
    var input = l
    var result = 0
    while (input.size > 1) {
        var last = input[0]
        var runSize = 0
        with(input) {
            input = listOf()
            forEach { current ->
                if (current != last) {
                    input += runSize
                    runSize = 0
                }
                runSize++
                last = current
            }
            input += runSize
        }
        result++
    }
    result
}

Probieren Sie es online!


131 Bytes, TIO

{l->var a=l;var b=0;while(a.size>1){var c=a[0];var d=0;a.let{a=arrayListOf();for(e in it){if(e!=c){a+=d;d=0};d++;c=e};a+=d};b++};b}

181 Bytes, TIO

Beinhaltet 39 für import kotlin.coroutines.experimental.*.

{l->var a=l;var b=0;while(a.size>1){var c=a[0];var d=0;a=buildSequence{for(e in a){if(e!=c){yield(d);d=0;};d++;c=e};yield(d)}.toList();b++};b}
Moira
quelle
0

Rot , 140 Bytes

func[b][n: 0 while[(length? b)> 1][l: copy[]parse split form b" "[any[copy s[set t string! thru any t](append l length? s)]]b: l n: n + 1]n]

Probieren Sie es online!

Ich wollte Reds Parse-Dialekt nur noch einmal ausprobieren.

Ungolfed

f: func [b] [
    n: 0
    while [(length? b) > 1][
        l: copy []
        parse split form b " " [
            any [copy s [set t string! thru any t]
                (append l length? s)]
        ]
        b: l
        n: n + 1
    ]
    n
]
Galen Ivanov
quelle