Listeleri hızlı bir şekilde yeniden gruplandırma


17

Gruplama bir liste alır ve onu eşit bitişik elemanlardan oluşan yeni listelere böler. Örneğin

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

Daha sonra bu grupların uzunluğunu alırsanız yeni bir tamsayı listesi alırsınız

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

Göreviniz, pozitif tamsayıların listesini alan bir program yazmak ve sonuçta ortaya çıkan listede tek bir öğe bulunmadan önce kaç kez gruplayabileceğinizi ve bu süreyi uzatabileceğinizi bulmaktır. Örneğin, liste [1,2,3,3,2,1]4 kez yeniden gruplandırılabilir

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

Bu bu nedenle cevaplar daha az bayt daha iyi olacak şekilde bayt cinsinden puanlanır.

Test senaryoları

[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

3
Bu temel olarak değerleri kaydetmeden çalışma uzunluğu kodlamasıdır.
12Me21

[1]geçerli bir girdi ve vermeli 0, doğru mu?
ETHproductions

@ETHproductions Evet, ekleyeceğim çünkü biraz zor bir durum.
Post Rock Garf Hunter

Yanıtlar:




3

Japt , 12 bayt

ÊÉ©1+ßUò¦ ml

Çevrimiçi test edin!

açıklama

 Ê É © 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.

Özyineleme Japt için gerçekten geleneksel olmayan bir yaklaşımdır, ancak bir sonraki alternatiften 4 bayt daha kısa görünüyor ...


@Shaggy 16 baytlık sürümüme F.a()düzeltme geçmişinden erişmeye devam edebilirsiniz. Yine de 14 baytınızı görmek isterim!
ETHproductions

3

Brachylog , 12 bayt

;.{ḅlᵐ}ⁱ⁾l1∧

Çevrimiçi deneyin!

açıklama

;.{   }ⁱ⁾        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

2

C (gcc) , 108 bayt

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

Çevrimiçi deneyin!

açıklama

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

Çevrimiçi deneyin!


2

JavaScript (ES6), 67 65 63 bayt

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

Gariptir ki, JavaScript ve Japt bir kez aynı en kısa algoritmaya sahip gibi görünüyor ...


2

K (ok) , 20 19 bayt

Çözüm:

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

Çevrimiçi deneyin!

Örnekler:

#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

Açıklama:

Bu oldukça basit, yine de daha iyi bir yaklaşım olup olmadığını merak ediyorum ... Girdinin farklı olduğu indeksleri bulun, bu indekslere bölün ve sonra her alt listenin uzunluğunu sayın. Sonuçlar 1'e yaklaşana kadar tekrarlayın.

#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

Notlar:

Aşağıdaki 14 bayt çözümü , tek öğe listesi dışındaki herkes için çalışır :

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

Çevrimiçi deneyin!


2

J , 25 23 bayt

Streetster sayesinde 1 bayt kaydedildi

FrownyFrog sayesinde 1 bayt kaydedildi

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

Çevrimiçi deneyin!

İlk çözüm:

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

Çevrimiçi deneyin!

açıklama

      (               )^: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

1
_2+Bir bayt kaydetmek yerine 'iki' damla 'sonra' sayım 'yapabilir misiniz ?
streetster

1
Bence #;.1@(0,2=/\])1 byte tasarruf sağlıyor.
FrownyFrog

@ FrownyFrog Evet, var. Teşekkür ederim!
Galen Ivanov

@streetster Evet, Bayt tasarrufuna yardımcı olur. Teşekkür ederim!
Galen Ivanov

2

Stax , 9 bayt

ÆÑfá╒]`*Ä

Çevrimiçi çalıştırın ve hata ayıklayın

Aynı programın ascii temsili şudur.

{D}{|RMHgf%

Bu, a adında bir stax özelliği kullanır dönüştürme ve filtre bloklarına göre değer üreten jeneratör olarak .

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

2

Python 2 , 84 bayt

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

Çevrimiçi deneyin!

Nasıl?

fgirdisi a2 veya daha fazla uzunluğa ( len(a)>1) sahip olan yinelenen bir işlevdir; 1+f(x)burada xgrup uzunlukları a; Girdi uzunluğu 1 veya 0 ise False(Python'da 0'a eşittir) - bunun nedeni,and falsey olduğu zaman değerlendirilmemesidir.

* -~f(x)Olduğunu -(-1 - f(x))ancak dayanacak olabilir andaksine1+f(x) veyaf(x)+1 )

Grup uzunlukları daha sonra ile değerlendirilen kod oluşturularak hesaplanır eval(...). Oluşturulan kod şuna benzer1,1,1+1+1,1,1+1,1, gibi tuplea hangi değerlendirir(1,1,3,1,2,1) .

Kod üzerinden sıkıştırma yoluyla oluşturulur ave abaş (olmadan ...for x, y in zip(a,a[1:])yapma xve ykomşu çiftlerinin her biri abir çift eşit ise. x==yÜzere değerlendirir True(1) olarak False(= 0) -, bu sonuç dizesine dizin için kullanılan ,+ elde +ve ,sırasıyla her bir Elde edilen karakter öncesinde 1( '1'+...) - Her şey daha sonra, bir son mutlaka eğik 1,. ekteki Örneğin eğer aedildi [5,5,2,9,9,9], sonrax,y çiftleri olacaktır (5,5)(5,2)(2,9)(9,9)(9,9)eşitlikler yapmak 10011o zaman karakter olacaktır +,,++önceki ile olan 1olur ler 1+1,1,1+1+ve son arka 1,yapma1+1,1,1+1+1,bu (2,1,3)da gerektiği gibi değerlendirilir .

İzlemenin, ,tek bir gruba sahip bir girdinin bir tamsayı yerine bir demet olarak değerlendirilmesini sağladığına dikkat edin (yani [3,3]-> 1+1,-> (2)yerine [3,3]-> 1+1- -> 2)





1

Kabuk , 8 bayt

@Zgarb sayesinde -1 bayt!

←Vε¡(mLg

Çevrimiçi deneyin!

açıklama

←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

1
←Vεsingleton listesinin dizinini bulmak için daha kısa bir denetimdir.
Zgarb


1

05AB1E , 9 bayt

[Dg#γ€g]N

Çevrimiçi deneyin!

açıklama

[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



1

SmileBASIC, 110 108 bayt

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

Fonksiyonu şu şekilde çağır R list,0; çıktı konsola yazdırılır.



0

R , 51 45 bayt

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

Çevrimiçi deneyin!

Yinelenen çalışma uzunluğu kodlamasının uzunluğunu alın ve sayacı artırın.


0

Retina 0.8.2 , 31 bayt

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

Çevrimiçi deneyin! Bağlantı, test senaryolarını içerir. Açıklama:

,.*
$&_

Virgül varsa, başka bir yineleme yapacağız, bu yüzden bir sayı karakteri ekleyin.

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

Her çalışmayı azaltılmış uzunluğu ile değiştirin. Yukarıdaki aşamalar, virgül kalmayana kadar tekrarlanır.

_

Yineleme sayısını sayın.


0

Perl 6 , 52 bayt

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

Dene

Expanded:

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



0

Kotlin , 123 bayt

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

Daha okunabilir:

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

Çevrimiçi deneyin!


131 bayt, 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 bayt, TIO

İçin 39 içerir 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}

0

Kırmızı , 140 bayt

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]

Çevrimiçi deneyin!

Sadece Red's Parse lehçesine yeniden denemek istedim.

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