목록을 빠르게 재 그룹화


17

그룹화는 목록을 가져 와서 동일한 인접 요소의 새로운 목록으로 나눕니다. 예를 들어

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

그런 다음이 그룹의 길이를 사용하면 새로운 정수 목록을 얻습니다.

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

당신의 임무는 양의 정수 목록을 취하는 프로그램을 작성하고 결과 목록이 단일 요소를 갖기 전에 그룹화하고 길이를 지정할 수있는 횟수를 찾는 것입니다. 예를 들어 목록 [1,2,3,3,2,1]을 4 번 다시 그룹화 할 수 있습니다.

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

이것은 이므로 바이트 수가 적을수록 답이 바이트로 표시됩니다.

테스트 사례

[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
이것은 기본적으로 값을 저장하지 않고 실행 길이 인코딩입니다.
12Me21

[1]올바른 입력이며 0, 맞습니까?
ETHproductions

@ETHproductions 예, 약간 까다로운 경우이므로 추가하겠습니다.
Post Rock Garf Hunter

답변:




3

Japt , 12 바이트

ÊÉ©1+ßUò¦ ml

온라인으로 테스트하십시오!

설명

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

재귀는 Japt에 대한 비 전통적인 접근 방식이지만 다음 대안보다 4 바이트 더 짧은 것 같습니다 ...


@Shaggy 내 16 바이트 버전의 버전 F.a()은 여전히 ​​개정 내역을 통해 액세스 할 수 있습니다. 나는 당신의 14 바이 터를보고 싶습니다!
ETHproductions


2

C (gcc) , 108 바이트

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

온라인으로 사용해보십시오!

설명

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

온라인으로 사용해보십시오!


2

자바 스크립트 (ES6), 67 65 63 바이트

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

이상하게도 JavaScript와 Japt는 한 번만 같은 가장 짧은 알고리즘을 가지고있는 것 같습니다 ...


2

K (oK) , 20 19 바이트

해결책:

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

온라인으로 사용해보십시오!

예 :

#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

설명:

이것은 매우 간단하지만 더 나은 접근 방법이 있는지 궁금합니다 ... 입력이 다른 인덱스를 찾아 해당 인덱스로 분할 한 다음 각 하위 목록의 길이를 계산하십시오. 결과가 1로 수렴 될 때까지 반복하십시오.

#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

노트:

다음 14 바이트 솔루션은 단일 항목 목록을 제외한 모든 항목에 적용됩니다.

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

온라인으로 사용해보십시오!


2

J , 25 23 바이트

streetster 덕분에 1 바이트 절약

FrownyFrog 덕분에 1 바이트 절약

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

온라인으로 사용해보십시오!

초기 해결책 :

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

온라인으로 사용해보십시오!

설명

      (               )^: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+바이트를 저장하는 대신 '2를 떨어 뜨린 다음'카운트를 수행 할 수 있습니까 ?
streetster February

1
#;.1@(0,2=/\])1 바이트를 절약 한다고 생각 합니다.
FrownyFrog

@ FrownyFrog 그렇습니다. 감사합니다!
Galen Ivanov 12

@streetster 예, 바이트를 저장하는 데 도움이됩니다. 감사합니다!
Galen Ivanov

2

Stax , 9 바이트

ÆÑfá╒]`*Ä

온라인으로 실행 및 디버깅

동일한 프로그램의 ASCII 표현은 이렇습니다.

{D}{|RMHgf%

변환 및 필터 블록에 따라 값을 생성 하는 생성기 라고하는 stax 기능을 사용합니다 .

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

파이썬 2 , 84 바이트

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

온라인으로 사용해보십시오!

어떻게?

f그 입력하면 재귀 함수이며 a, 길이가 2 개 이상 (보유 len(a)>1) 복귀 1+f(x)* x의 그룹 길이되고a ; 입력이 길이 1 또는 0이면 False파이썬에서 0과 같습니다-이것은 and왼쪽이 거짓 일 때 오른쪽이 평가되지 않기 때문입니다.

* -~f(x)이다 -(-1 - f(x))하지만을 접촉 할and 달리 1+f(x)이상 f(x)+1)

그룹 길이는 코드를 작성하여 계산 한 다음로 평가됩니다 eval(...). 생성 된 코드는1,1,1+1+1,1,1+1,1, 는와 같은 튜플로 평가되는 것과 같습니다 (1,1,3,1,2,1).

이 코드를 통해 압축에 의해 생성 a하고 a그 헤드 (않고 ...for x, y in zip(a,a[1:])제작 xy의 인접 쌍 각각 a한 쌍의 동일한 경우. x==y평가 True(1), 그렇지 않으면 False(0) -이 결과는 문자열에 인덱스에 사용되는 ,+ 항복 +,각각과 각 결과 문자는 앞에있다 1( '1'+...) - 모든 일이 후, 최종 후행하고있다 1,. 추가 예를 들어 a[5,5,2,9,9,9]다음 x,y쌍 될 (5,5)(5,2)(2,9)(9,9)(9,9)등식을 10011다음 문자가 될 것 +,,++이전에, 이는 1하게의 1+1,1,1+1+최종 후행 1,결정1+1,1,1+1+1,(2,1,3)필요 에 따라 평가됩니다 .

후행 ,은 단일 그룹의 입력이 정수가 아닌 튜플로 평가되도록합니다 (예 : [3,3]-> 1+1,-> (2)대신 [3,3]-> 1+1-> 2).





1

껍질 , 8 바이트

@Zgarb 덕분에 -1 바이트!

←Vε¡(mLg

온라인으로 사용해보십시오!

설명

←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ε싱글 톤리스트의 인덱스를 찾기위한 짧은 점검입니다.
Zgarb





1

SmileBASIC, 110 108 바이트

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

다음과 같이 함수를 호출하십시오 R list,0. 출력이 콘솔에 인쇄됩니다.




0

레티 나 0.8.2 , 31 바이트

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

온라인으로 사용해보십시오! 링크에는 테스트 사례가 포함됩니다. 설명:

,.*
$&_

쉼표가 있으면 다른 반복을 수행하므로 카운트 문자를 추가하십시오.

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

각 런을 감소 된 길이로 교체하십시오. 위의 단계는 쉼표가 남지 않을 때까지 반복됩니다.

_

반복 횟수를 계산하십시오.


0

펄 6 , 52 바이트

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

그것을 테스트

넓히는:

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

코 틀린 , 123 바이트

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

더 읽기 쉬운 :

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

온라인으로 사용해보십시오!


131 바이트, 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 바이트, TIO

에 39을 포함합니다 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

빨강 , 140 바이트

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]

온라인으로 사용해보십시오!

Red 's Parse 방언에 다른 시도를하고 싶었습니다.

언 골프

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
]
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.