可堆叠序列


29

您一次从一副牌中发出标记为0到9的纸牌,形成从0开始并以1递增的堆叠。

  • 分配0时,将其放在桌子上以开始新的堆栈。
  • 当您处理其他任何卡时,您会将其堆叠在一张价值稍低的卡上,并将其覆盖。如果没有这样的卡,则卡座无法堆叠。

给定一个甲板,确定在按给定顺序处理时是否可以堆叠。等效地,给定一个数字列表,决定是否可以将其划分为每种形式的不相交的子序列0,1,..,k

走上甲板0012312425。前两张牌是0,因此他们在桌上:

Stacks: 00

  Deck: 12312425

接下来,我们处理1,继续在上0,无论哪个:

        1
Stacks: 00

  Deck: 2312425

然后,我们2在刚放置13顶部和顶部放置一个。

        3
        2
        1
Stacks: 00

  Deck: 12425

接着,对12并置于所述第一堆叠的顶上和4顶上的第二个。

        4
        3
        22
        11
Stacks: 00

  Deck: 25

现在,我们需要放置一个2,但1两个堆栈都没有顶部。因此,此甲板不可堆叠。

输入:一个非空的数字列表0-9,或一个字符串。您不能假设输入中始终为0。

输出:两个不同的一致值之一,一个用于可堆叠序列,一个用于不可堆叠序列

测试用例:

可堆叠:

0
01
01234
00011122234567890
012031
0120304511627328390

不可堆叠:

1
021
0001111
0012312425
012301210
000112223

为方便起见,如下所示:

[0]
[0, 1]
[0, 1, 2, 3, 4]
[0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 4, 5, 6, 7, 8, 9, 0]
[0, 1, 2, 0, 3, 1]
[0, 1, 2, 0, 3, 0, 4, 5, 1, 1, 6, 2, 7, 3, 2, 8, 3, 9, 0]

[1]
[0, 2, 1]
[0, 0, 0, 1, 1, 1, 1]
[0, 0, 1, 2, 3, 1, 2, 4, 2, 5]
[0, 1, 2, 3, 0, 1, 2, 1, 0]
[0, 0, 0, 1, 1, 2, 2, 2, 3]

分组:

[[0], [0, 1], [0, 1, 2, 3, 4], [0, 0, 0, 1, 1, 1, 2, 2, 2, 3], [0, 1, 2, 0, 3, 1], [0, 1, 2, 0, 3, 0, 4, 5, 1, 1, 6, 2, 7, 3, 2, 8, 3, 9, 0]]
[[1], [0, 2, 1], [0, 0, 0, 1, 1, 1, 1], [0, 0, 1, 2, 3, 1, 2, 4, 2, 5]]

排行榜:


我们可以假设列表长度有限制吗?
orlp

@orlp没有明确限制。
xnor

@xnor他可能正在要求证明int a[99]用C 进行写作的理由
Leaky Nun

@LuisMendo您可能会说“非空”。
xnor

@xnor啊,对不起,我没有看到。数组可以基于1吗?也就是说,号码从110
Luis Mendo

Answers:



6

Haskell,55个字节

一个匿名函数,接受整数列表并返回Bool

用法:(all(<1).foldr(?)[]) [0,1,2,3,4]

all(<1).foldr(?)[]
m?l|(p,r)<-span(/=m+1)l=m:p++drop 1r

在线尝试!

怎么运行的

  • foldr(?)[]使用?,从一个空列表开始,从右到左折叠其list参数。结果是列表中的数字列表不适合先前的数字。
  • all(<1) 测试在前一个数字之上不适合的唯一数字是否为零。
  • m?l在不适合的数字m列表l前添加数字。如果m+1已在列表中,则可以将其删除,因为它位于的顶部m
    • (p,r)<-span(/=m+1)l将列表l分为两部分pr在数字的第一个实例处m+1。如果没有,则右侧r为空。
    • m:p++drop 1r预先考虑m到拆分的部件。如果r为非空,则它必须以开头m+1,并由删除drop 1

反向堆叠的好主意!我尝试?递归扩展您的长度,但长度相同
xnor

54个字节,Data.List.delete
H.PWiz

5

外壳,9个字节

Λ¬ḞS:o-→ø

在线尝试!

返回1可堆叠甲板和0不可堆叠甲板。

ØrjanJohansen在他的Haskell答案中似乎已经想出了相同的算法,但是在Husk中,这显然更加简洁。

说明

我们从另一个角度解决问题:翻转甲板并堆放下降的桩。如果经过所有甲板之后,所有桩的顶部都为0,则该甲板是可堆叠的。

Λ¬ḞS:(-→)ø
         ø    Starting with the empty list (each element of this list will be the top card
              of a stack)
  ḞS          Traverse the input from right to left. For each card:
      -→        Remove the successor of this card from our list (if present)
    :           Add this card to our list
Λ¬            At the end, check if all the cards in our list are zeroes (falsy)


4

C(gcc),74 73字节

f(int*l){int s[10]={},r=1;for(;~*l;s[*l++]++)r*=!*l||s[*l-1]--;return r;}

需要输入数组以-1标记结尾。用法示例:

int main(int argc, char** argv) {
    int a[] = {0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 4, 5, 6, 7, 8, 9, 0, -1};
    printf("%d\n",  f(a));
    return 0;
}

Plain有什么问题return r
Leaky Nun

4

视网膜,42字节

O$#`(.)(?<=(\1.*?)*)
$#2
.
$*1,
^(,|1\1)+$

在线尝试!

说明

O$#`(.)(?<=(\1.*?)*)
$#2

这将根据以前发生过相同数字的频率稳定地对这些数字进行排序。实际上,这会将各种候选子序列整理在一起。结果字符串将首先出现每个数字的第一个出现,然后出现每个数字的第二个出现,依此类推。在可堆栈输入中,结果将类似于0123...0123...0123...,其中这些子字符串中的每一个都可以在任何点终止。

最容易确定输入是否具有这种一元模式。

.
$*1,

我们更换每一个数字ññ 1秒,然后用逗号个人数字分开。

^(,|1\1)+$

最后,我们使用前向引用来匹配连续增加的数字游程。我们尝试通过匹配单个逗号(代表0,开始新的运行)来匹配整个字符串,或者通过匹配前面的东西加上一个额外的来匹配整个字符串1,这仅在当前数字是前一个数字的后继者时才有效。


3

TI-Basic(83系列),25个字节(49个字符)

:min(seq(min(cumSum(Ans=I)≤cumSum(Ans=I-1)),I,1,9

怎么运行的

在中将输入作为列表Ans1可堆叠输入的输出,0否则。

对于每个IcumSum(Ans=I)计算I每个初始段中发生的次数的列表,min(cumSum(Ans=I)≤cumSum(Ans=I-1))如果在每个位置上看到的I-1次数至少等于,则为1 I。整体表达是1每一个都成立的时候I


3

JavaScript(ES6),61 45 40字节

将输入作为列表。

a=>a.every(k=>a[~k]=!k|a[-k]--&&-~a[~k])

测试用例

怎么样?

对于每个值0 ... 9,我们跟踪前面的卡位于顶部的可用堆栈数。这些计数器存储在a [-9]a [0]中,其中a []是原始输入数组。唯一与输入数据冲突的计数器是a [0],但我们并不在乎这一点,因为1)始终允许标记为0的卡并且无论如何都必须分别对其进行处理,以及2)输入值a [0 ]在有机会被更新之前被处理。

a => a.every(k =>  // given the input array a, for each card k in a:
  a[~k] =          // the card is valid if:
    !k |           //   - it's a 0 or
    a[-k]-- &&     //   - there's at least one stack with the card k-1 atop
    -~a[~k]        // in which case we allow a new card k+1 and go on with the next card
)                  // otherwise, every() fails immediately

你比我快:o
Leaky Nun

@LeakyNun您必须已经离开20分钟...;)
Arnauld

2

MATL,16字节

0*GQ"@yQy=f1)(]a

输入是一个数字数组。

1如果输入是可堆叠的,则代码在STDOUT中输出;如果输入不可堆叠,则以错误退出并在STDOUT中输出为空。

在线尝试!


2

视网膜,110字节

+`0((.*?)1((.*?)2((.*?)3((.*?)4((.*?)5((.*?)6((.*?)7((.*?)8((.*?)9)?)?)?)?)?)?)?)?)?
$2$4$6$8$10$12$14$16$+
^$

在线尝试!链接包括测试用例。我不经常使用$16...


2

Mathematica,80个字节

Catch[Fold[#~Join~{-1}/.{{p___,#2-1,q___}:>{p,#2,q},-1:>Throw[1<0]}&,{},#];1>0]&


2

R,88字节

function(d){s={}
for(e in d)if(!e)s=c(s,0)else{k=match(e,s+1)
if(is.na(k))T=F
s[k]=e}
T}

在线尝试!

带有R向量的函数;返回TRUE可堆叠和FALSE不可堆叠。

说明:

function(d){
 s <- {}              # initialize the stacks as empty
 for(e in d){         # iterate over the deck
  if(!e)              # if e is zero
   s <- c(s,0)        # start a new stack
  else {              # otherwise
   k <- match(e,s+1)  # find where e should go in s, NA if not there
   if(is.na(k))       # if no match (unstackable)
    T <- F            # set T to F (False)
   s[k] <- e          # set s[k] to e
  }
 T                    # return the value of T, which is TRUE by default and only gets changed in the loop to F.
}

2

Nim,133个字节

proc s(d:seq[int]):int=
 var
  t= @[0]
  r=1
 for c in d:(t.add(0);var f=0;for i,s in t.pairs:(if s==c:(t[i]=c+1;f=1;break));r*=f)
 r

1如果可行;0如果没有。

必须拉一些时髦的生意来处理for循环中变量的可变性,哦,好。


1

Haskell77 75字节

import Data.List
g[]=1<3
g(x:r)|s<-r\\[x-1]=g r&&(x<1||s/=r&&g s)
g.reverse

在线尝试!用法:g.reverse $ [0,1,2]。返回True可堆叠输入,False否则返回。

这是一种递归解决方案,它从后到前遍历给定列表。它实现了观察

  • 空列表是可堆叠的。
  • 前缀一个非空列表r和最后一个元素x是可堆叠的,如果r是可堆叠的,要么x是零或两者x-1出现在rrx-1去除也可堆叠。

1

爪哇8,168个 150 142字节

a->{int x[]=new int[a.length],s=0,i;a:for(int n:a){if(n<1){s++;continue;}for(i=0;i<s;i++)if(x[i]==n-1){x[i]=n;continue a;}return 0;}return 1;}

返回0/ 1是否可正确堆叠。

说明:

在这里尝试。

a->{                         // Method with integer-array parameter and integer return-type
  int x[]=new int[a.length], //  Array for the stacks, (max) size equal to input-size
      s=0,                   //  Amount of stacks, starting at 0
      i;                     //  Index integer
  a:for(int n:a){            //  Loop (1) over the input
    if(n<1){                 //   If the current item is a zero:
      s++;                   //    Increase amount of stacks `s` by 1
      continue;}             //    And go to the next iteration
    for(i=0;i<s;i++)         //   Inner loop (2) over the stacks
      if(x[i]==n-1){         //    If a top item of a stack equals the current item - 1:
        x[i]=n;              //     Set this item in the stacks-array
        continue a;}         //     And go to the next iteration of loop (1)
    return 0;                //   If we haven't encountered a `continue`, return 0
  }                          //  End of loop (1)
  return 1;                  //  Return 1 if we were able to correctly stack everything
}                            // End of method

1

C,248字节

注意:要打印返回状态,请在终端中键入“ echo $ status”

返回状态0:不可堆叠

返回状态1:可堆叠

说明:递增数组元素,使其索引等于堆栈中的当前最新数字。然后,程序检查此刚增加的数组元素是否大于其前面的元素。如果是,则返回0。否则,如果程序使它到达数组的末尾,则返回1。

 main(int argc, char ** argv)
{
    static int stack[10];

    while ( *++argv != 0x0 )
    {
        stack[**argv - 0x30]++;

        if ( **argv - 0x30 > 0 )
        {
            if ( stack[**argv - 0x30] > stack[**argv - 0x30 - 1] )
            {
                return 0;
            }

        }

    }   

    return 1;
}

3
欢迎来到Code Golf!您的代码和字节数应该匹配,因此请确保提供完整的代码版本。非高尔夫版本是可选的。
斯蒂芬

0

果冻,15 字节

œp@ŒQẎµ0rṀ⁼Qµ¿Ẹ

单链链接,该列表包含非负整数列表,0如果可堆叠或1不可堆叠,则返回。

在线尝试!

怎么样?

œp@ŒQẎµ0rṀ⁼Qµ¿Ẹ - Link: list
             ¿  - while loop:
      µ     µ   - ...condition chain:
       0        -      literal zero
         Ṁ      -      maximum of current list
        r       -      inclusive range = [0,1,2,...,max(list)]
           Q    -      de-duplicate list (unique values in order of appearance)
          ⁼     -      equal?
                - ...do:
   ŒQ           -      distinct sieve (1s at first occurrences 0s elsewhere)
  @             -      use swapped arguments:
œp              -        partition (the list) at truthy values (of the distinct sieve)
     Ẏ          -      tighten (makes the list flat again ready for the next loop)
              Ẹ - any truthy? 1 if the resulting list has any non-zero integers remaining
                -           - effectively isNotEmpty for our purposes since a list of only
                -             zeros gets reduced to an empty list via the loop.

您的举动:P:P
Leaky Nun

呵呵,好吧,我怀疑我会战胜11分(或10分!!)并且必须入睡:D
Jonathan Allan

0

Japt,16字节

£=k_¥T©°T}T=0ÃUd

在线测试!false可堆叠的输出,true不可堆叠的输出。

说明

 £   = k_  ¥ T© ° T}T=0Ã Ud
UmX{U=UkZ{Z==T&&++T}T=0} Ud    Ungolfed
                               Implicit: U = input array
UmX{                   }       For each item X in the array:
                    T=0          Set T to 0.
      UkZ{         }             Remove the items Z where
          Z==T&&++T              Z == T (and if so, increment T).
                                 This has the effect of removing the largest stack.
    U=                           Reset U to the result.
                               This process is repeated U.length times, which is
                               evidently enough to handle any U.
                         Ud    Return whether there are any truthy items in U.
                               Any items not part of a stack are non-zero/truthy,
                               so this works for every possible case.

0

05AB1E,25 个字节

ηε[DõQ#ZƒDNåiNõ.;Dëˆ#]¯OĀ

挑战看起来并不那么困难,但在05AB1E中却相当困难(至少对我来说是。)

0如果是可堆叠的,1则为不可堆叠的输出。

在线尝试验证所有测试用例

说明:

η             # Prefixes of the (implicit) input
              #  i.e. '012031' → ['0','01','012','0120','01203','012031']
              #  i.e. `021` → ['0','02','021']
 ε            # Map each to:
  [           # Start an infinite inner loop
   D          # Duplicate the current value
    õQ#       # If it's an empty String, stop the infinite loop
   Z          # Get the maximum (without popping)
              #  i.e. '01203' → 3
              #  i.e. '02' → 2
    ƒ         # Inner loop `N` in the range [0,max]
     D        # Duplicate the current value
      Nåi     # If it contains the current digit `N`
              #  i.e. '01203' and 1 → 1 (truthy)
              #  i.e. '02' and 1 → 0 (falsey)
         Nõ.; # Remove the first one (by replacing the first `N` with an empty string)
              #  i.e. '1203' and 1 → '203'
         D    # And duplicate it again for the next iteration of the inner loop
      ë       # Else (does not contain the digit `N`):
       ˆ      # Push `N` to the global stack
        #     # And break the infinite loop
 ]            # Close the if-else, inner loop, infinite loop, and mapping (short for `}}}}`)
  ¯           # Push the global stack
   O          # Take the sum
              #  i.e. [] → 0
              #  i.e. ['2'] → 2
    Ā         # And get the trutified value of that (which we implicitly output as result)
              #  i.e. 0 → 0
              #  i.e. 2 → 1

0

Java 8,87字节

我不会构建堆栈,而只是计算元素在先前的元素上是否不可堆叠,并在遇到不可堆叠的元素时返回0。如果到达末尾,则整个字符串都是可堆叠的,并返回1:

s->{int l[]=new int[10];for(int n:s)if(n!=0&&l[n]>=l[n-1]||l[n]++<0)return 0;return 1;}

在线尝试!

说明:

s->{
  int l[]=new int[10];                # initialise the counts of each digit encountered prefix of element, all initialised to 0
  for(int n:s)                        # Iterate over all entries in input
    if(n!=0&&l[n]>=l[n-1]||++l[n]<0)  # Check if the element is stackable on the previous elements. Last check is always evaluated and false, but the sideeffect is to add the element to the handled, prefixed element og the next element.  
      return 0;                       # Unstackable
  return 1;                           # No unstackable elements, so the result is stackable
}
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.