快速重新整理清单


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
这基本上是游程长度编码,不存储值。
18Me21 '23

[1]是有效的输入,应该给0正确吗?
ETHproductions

@ETHproductions是的,我要补充一点,因为这有点棘手。
发布Rock Garf Hunter '18

Answers:




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

3

Brachylog,12个字节

;.{ḅlᵐ}ⁱ⁾l1∧

在线尝试!

说明

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

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

JavaScript(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

Ĵ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+保存一个字节吗?
streetster

1
我认为#;.1@(0,2=/\])可以节省1个字节。
FrownyFrog

@ FrownyFrog是的,确实如此。谢谢!
Galen Ivanov

@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

Python 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(在Python中等于0)-这是因为and当左侧为false时,不会评估的右侧。

* -~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)

该代码是通过压缩和解创建aa没有其头部(...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那么字符将是+,,++,这与前面的1S成为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字节

-1个字节感谢@Zgarb!

←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

05AB1E,9个字节

[Dg#γ€g]N

在线尝试!

说明

[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个字节

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

R51 45字节

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

在线尝试!

递归获取游程长度编码的长度,并增加计数器。


0

视网膜0.8.2,31字节

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

在线尝试!链接包括测试用例。说明:

,.*
$&_

如果有逗号,我们将进行另一次迭代,因此请添加一个计数字符。

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

用减少的长度替换每个运行。重复上述步骤,直到没有逗号为止。

_

计算迭代次数。


0

Perl 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
]
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.