我可以重新堆放水桶吗?


30

我的小孩有这样的玩具:

Stacked

这个玩具包含10个可叠放的小桶,我们将把它从1个(最小的一个)编号为10个(最大的一个)。有时他会堆成小堆,玩具最终变成这样:

Scattered

我们可以像这样示意地表示堆:

      1  6
4  9  2  7
5  10 3  8
----------  <-- Floor
1  2  3  4  <-- Pile #

或者,换一种说法:

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

通过将较小的水桶堆连续放置在较大的水桶堆中,可以轻松地重新堆叠这组水桶堆以重建原始集(第一个图像):

                             1                            1  6
                             2                            2  7
      1  6                   3        6                   3  8
4  9  2  7                   4  9     7                   4  9
5  10 3  8                   5  10    8                   5  10
---------- > [Pile 3 to 1] > ---------- > [Pile 4 to 2] > ---------- > [Pile 1 to 2] > Done!
1  2  3  4                   1  2  3  4                   1  2  3  4

尽管如此,有时我的孩子还是试图建造塔楼或扔掉水桶,结果导致桩头不一致,仅将一堆桩放入另一桩堆就无法重建原始桩堆。这样的例子:

[[1,3,2],[4]] (the kid tried to build a tower by placing a bigger bucket
               over a smaller one, we would need to reorder the buckets
               first)
[[1,3,4],[2]] (the kid left aside an unordered bucket, we would need to remove
               bucket #1 from pile #1 before restacking)
[[1,2,3],[5]] (the kid lost a bucket, we need to find it first)

挑战

给定代表一组桶形桩的整数列表,如果列表表示一组易于重堆的桩,则返回真值,否则返回假值。

  • 输入将以整数列表的形式给出,表示每个堆栈从上到下的存储桶。
  • 不会有空的起始桩(您不会得到[[1,2,3],[],[4,5]]输入)。
  • 桶的总数可以在合理的整数范围内。
  • 我的孩子只有一组水桶,因此不会有重复的元素。
  • 您可以为真或假选择任意两个一致(和一致)的值。
  • 这些存储桶将被标记为从#1到#N,这是N整数列表中的最大整数。我的孩子仍然不知道零的概念。
  • 您可以以任何合理的格式接收输入,只要它代表一堆桶即可。如果您更改接收输入的方式,只需在答案中指定即可。
  • 这是,因此每种语言中最短的程序/功能可能会获胜!

例子

Input:  [[4,5],[9,10],[1,2,3],[6,7,8]]
Output: Truthy

Input:  [[6,7,8,9,10],[1],[2],[3,4,5],[11,12,13]]
Output: Truthy

Input:  [[2,3,4],[1],[5,6,7]]
Output: Truthy

Input:  [[1,2],[5,6],[7,8,9]]
Output: Falsey (buckets #3 and #4 are missing)

Input:  [[2,3,4],[5,6,7]]
Output: Falsey (bucket #1 is missing)

Input:  [[1,3,4],[5,7],[2,6]]
Output: Falsey (non-restackable piles)

Input:  [[1,4,3],[2],[5,6]]
Output: Falsey (one of the piles is a tower)

这来自沙盒
查理

2
@ Mr.Xcoder不,不会有重复的元素(我的孩子只有一组存储桶,而且它们都是不同的。–
Charlie

1
我们是否可以假设存储桶1永不丢失?
PurkkaKoodari

2
@ Pietu1998存储桶#1可能会丢失,我只是添加了一个测试用例(实际上,最小的存储桶最容易丢失)。
查理

1
河内塔的各种挑战与此有关(而不是重复)。
AdmBorkBork

Answers:


12

果冻6 5字节

感谢@Lynn节省了1个字节。

ṢFµJ⁼

在线尝试!(带有测试套件页脚)

说明

ṢFµJ⁼    Main link. Argument: piles
Ṣ          Sort the piles by the size of the top bucket.
 F         Stack the piles, putting the left one to the top.
   J       See what a full pile with this many buckets would look like.
    ⁼      See if that looks like the pile you built.

我认为ṢFµJ⁼可以,但是我还没有考虑所有的极端情况。
林恩

@Lynn假设1不遗漏存储桶,该方法有效。我不确定OP是否能保证这一点。
PurkkaKoodari

@Lynn bucket#1可能会丢失,是的。我刚刚添加了一个新的测试用例。
查理

如果缺少存储桶,则排序后的列表将始终包含大于J返回值的数字,从而确保输出错误。我错过了什么吗?
林恩

我认为您仍可以使用缺少第1个存储桶的5字节版本?
暴民埃里克(Erik the Outgolfer)'17年


5

JavaScript(ES6),59 58字节

a=>!(a.sort((a,[b])=>a[i=0]-b)+'').split`,`.some(v=>v-++i)

说明

a=>                                                        // given a 2D-array 'a'
     a.sort((a,[b])=>a[i=0]-b)                             // sort by first item
                              +''                          // flatten
    (                            ).split`,`                // split again
                                           .some(v=>v-++i) // i such that a[i] != i+1?
   !                                                       // true if none was found

测试用例




5

Haskell,37个字节

import Data.List
(<[1..]).concat.sort

在线尝试!

检查级联排序列表是否在字典上小于无限列表[1,2,3,...]。由于没有重复的,缺少任何桶或乱序桶将导致一个值大于kk“次到位,使得结果列表更大..


4

Pyth,6个字节

UItMsS

在这里尝试。

说明:

UItMsSQ
UI      Invariant from U (range(len(A)) for our purpose)
  tM     Map t (A - 1 for our purpose)
    s     s (flatten 1-deep for our purpose)
     S     S (sort for our purpose)
      Q     Q (autoinitialized to input) (implicit)

?!说明加入的UI一部分,请
Xcoder先生

@ Mr.Xcoder U <col>range(len(A))I <pfn> <any> <n-1:any>A(B, ...) == B
暴民埃里克(Erik the Outgolfer)

然后我就出乎意料地>。<。我可能会打高尔夫。天才,出色的解决方案,现在我知道它是如何工作的...恭喜!
Xcoder先生17年

@ Mr.Xcoder实际上只是在文档中搜索内容……
Erik the Outgolfer

不,这不对。我知道U <col>range(len(A)),但是我没有意识到移植Python解决方案会更短……
Xcoder先生17年

4

PROLOG(SWI),54个字节

s(L):-sort(L,M),flatten(M,N),last(N,O),numlist(1,O,N).

现在,这是更好的。仍然很冗长,a。

在线尝试!

s/1谓词将列表作为参数,如果该列表是易于堆叠的存储桶的列表,则该谓词为true。

算法方面的改进:如果在对列表进行展平之前对其进行了排序,这将强制对所有子列表进行排序,以使谓词为真。从Pietu1998的Jelly答案中略微“借用” 。因此,我可以转储forall超过程序一半的内容(请参阅下面的原始答案)。

它是如何工作的?

如果谓词的所有子句都为true,则该谓词为true:

s(L) :-
    sort(L,M),                % M is L sorted in ascending order
    flatten(M,N),             % N is the 1-dimention version of M
    last(N,O),                % O is the last elemnt of N
    numlist(1,O,N).           % N is the list of all integers from 1 to O

上一个答案,PROLOG(SWI),109个字节

s(L):-flatten(L,M),sort(M,N),last(N,O),numlist(1,O,N),forall(member(A,L),(A=[B|_],last(A,C),numlist(B,C,A))).

在线尝试!


3

Pyth 9 16 11字节(固定)

使用与其他答案完全不同的方法。可以在下面找到一种较短的7字节方法。

!.EtM.++0sS

测试套件。


说明

!.EtM。++ 0sSQ->完整程序,在末尾有隐式输入。

          SQ->按每个子列表中的最高元素对输入进行排序。
         s->展平。
       +0->加上0。
     。+->获取列表的增量(即连续元素之间的差异)
   tM->减少每个元素。
 .E->任何真实元素(1为真实,0为虚假)
!->取反(具有连贯的真实/虚假值)

这是如何运作的?

让我们举几个例子,这些例子更易于理解。假设输入为[[1,3,4],[5,7],[2,6]]。该算法的核心是未展平列表中的每个增量都必须为1,以使存储桶可堆叠。

  • 首先,S将其转换为[[1, 3, 4], [2, 6], [5, 7]]

  • 然后,s变平的:[1, 3, 4, 2, 6, 5, 7]

  • 前置一个0在前面:[0, 1, 3, 4, 2, 6, 5, 7]

  • .+获取列表的增量,[1, 2, 1, -2, 4, -1, 2]

  • tM递减每个元素[0, 1, 0, -3, 3, -2, 1]

  • 0在Pyth中,任何非整数都是真值,因此我们检查是否有任何真值元素.E(这意味着不能正确形成堆栈)。我们得到True

  • !否定结果,这匝TrueFalse

例如,如果输入是,[[6,7,8,9,10],[1],[2],[3,4,5],[11,12,13]]则算法将以这种方式工作:

  • 按最高元素:排序[[1], [2], [3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13]],并以0前置:展平[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]

  • Deltas :[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]。全部递减:[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

  • 没有诚实的元素,所以我们得到了False。通过逻辑否定,结果为True


Pyth,7个字节

qSlsQsS

测试套件。

Python答案的端口和@Erik解决方案的变


非常感谢您抽出宝贵的时间来解释其工作原理!
查理


@ Mr.Xcoder tM递减每个元素是什么意思?我认为减少每个元素[1, 2, 1, -2, 4, -1, 2]都会产生收益[0, 1, 0, -3, 3, -2, 1]。但这无助于解决问题,因此我一定会误解每个元素递减意味着什么。
布赖恩J

@BrianJ tM将列表中的每个元素减少1。我的解释有误。将修复。
Xcoder先生17年

@BrianJ固定。感谢察觉这
Xcoder先生

3

Brachylog,5个字节

oc~⟦₁

在线尝试!

解释的统一:

?o₀c₀~⟦₁.
?         The input (implicit)
 o₀       Sorted (subscript default = 0 => ascending)
   c₀     Concatenated (subscript default = 0 => no length check)
     ~    Inverse (find the input)
      ⟦₁   Range (subscript = 1 => [1..input])
        . The output (implicit)

分析说明:

首先,我们对列表列表进行排序,然后连接(即,将1-deep展平)(oc),以便在可能的情况下将存储桶从右到左堆叠。然后,要检查桶是否已正确堆叠(即没有丢失的桶或塔),我们检查结果列表是否为从1到其长度的包含范围。现在,与其{l⟦₁?}尝试用长度()的[1..n]范围对列表进行相等检查,不如寻找一个生成该范围(~⟦₁)的函数的输入。如果找到输入,则程序以没有问题结束,因此触发true.状态。如果未找到任何输入,则程序失败,并触发false.状态。


3

Python 2 2,43个字节

lambda l:sum(sorted(l),[0])<range(len(`l`))

在线尝试!

检查级联排序列表是否在字典上小于[1,2,3,...N]大列表N。由于没有重复的,缺少任何桶或乱序桶将导致一个值大于kk“次到位,使得结果列表更大。输入的字符串长度足以作为上限,因为每个数字都需要超过1个字符。


很好,我认为应该有一种方法可以大大改善我的解决方案,而且做到了!
Chris_Rands

3

MATL,5个字节

Sgtf=

在线尝试!

(例如,隐式输入{[4,5],[9,10],[1,2,3],[6,7,8]}

S-按字典顺序({[1,2,3],[4,5],[6,7,8],[9,10]})对输入数组进行排序

g -转换为单个数组(cell2mat

t -复制

f-查找非零值的索引。由于此处的输入均为非零,因此返回从1到length(array)([1,2,3,4,5,6,7,8,9,10],[1,2,3,4,5,6,7,8,9,10])的索引列表

= -检查数组是否等于1到length(array)的范围


3

Japt13 12 11字节

这可能会更短。

ñÎc äaT e¥1
  • ETH节省了1个字节

尝试运行所有测试用例


说明

                :Implicit input of 2D array `U`
ñÎ              :Sort sub-arrays by their first element
  c             :Flatten
      T         :Prepend 0
    äa          :Consecutive absolute differences
        e¥1     :Does every element equal 1?

Yeah, you're right I think. It was worth a shot though
ETHproductions

I think you can save a byte on the last line with either ä-0 e¥J or än0 e¥1
ETHproductions

Another similar 13-byte solution: ethproductions.github.io/japt/…
Oliver

@ETHproductions, I have no idea what's happening there! :D Don't think I've had occasion to touch ä for arrays yet. Thanks for the saving.
Shaggy

1
@LuisfelipeDejesusMunoz It works when you use the first line of this solution and the second line of the linked solution, just as I said, nine bytes: codegolf.stackexchange.com/a/168967/16484
Nit

2

Scala, 49 Bytes

p=>{val s=p.sortBy(_(0)).flatten
s==(1 to s.max)}

Ungolfed:

piles: List[List[Int]] =>
{
  val sorted = piles.sortBy(pile=>pile(0)).flatten //Since piles are sequential, we can sort them by their first element
  sorted == (1 to sorted.max) //If all the buckets are present and in order, after sorting them it should be equivalent to counting up from 1 to the max bucket
}


2

R, 58 bytes

function(v,a=unlist(v[order(sapply(v,min))]))any(a-seq(a))

Try it online!

N.B. : FALSE is the truthy outcome, TRUE is the falsy one

  • -3 bytes thanks to @JayCe

Explanation :

a=unlist(v[order(sapply(v,min))])  # order the list of vector by the min value and flatten
all(a==seq(a=a))                   # if the flattened list is equal to 1:length then it's ok

1
Simply seq(a) for 2 byte?. Also, it's allowed to use TRUE as a falsy value and vice versa (just specify in your answer), so you can do any(a-seq(a)) for another byte.
JayCe

@JayCe: I'm a fool... I was so concerned about seq(a) behaving differently when a is of length 1 and I missed that in this case we'll get the same results :D THanks !
digEmAll

1

C# (.NET Core), 157 145 132 bytes

-13 bytes thanks to TheLethalCoder

l=>{var k=l.OrderBy(x=>x[0]).SelectMany(x=>x);return!Enumerable.Range(1,k.Count()).Zip(k,(x,y)=>x==y).Any(x=>!x);}

Byte count also includes

using System.Linq;

Try it online!

Ungolfed:

l => {
        var k = l.OrderBy(x=>x[0])              // First, sort stacks by first bucket
                 .SelectMany(x => x);           // Concatenate stacks into one
        return !Enumerable.Range(1, k.Count())  // Create a sequence [1...n]
               .Zip(k, (x, y) => x == y)        // Check if our big stack corresponds the sequence
               .Any(x => !x);                   // Return if there were any differences
     };

1
x.First() -> x[0]? Enumerable.Range -> new int[] and Zip with index if possible..? Remove Where and place the condition into Any.
TheLethalCoder

@TheLethalCoder Thank you for the tips! And the new int[] approach would require adding a Select() to get the index, and ultimately make the byte count bigger.
Grzegorz Puławski


1

Charcoal, 19 bytes (non-competing?)

A▷m⟦▷s▷vθυ⟧θ⁼θ…·¹Lθ

Try it online!

-10 bytes thanks to ASCII-only.

-3 bytes thanks to ASCII-only for a subsequent implementation (see revision history for possibly competing version).

- for truthy, for falsy.

Input is a singleton list of a list of lists, because of how Charcoal takes input.


It's the first answer in Charcoal I see that uses UP.
Charlie

@CarlosAlejo I had to find a way to sort, and the easiest way was just UPsorted.
Erik the Outgolfer


the used there makes scope things the priority though so that;s why UP is still there but i guess you can just avoid using python function names as varnames?
ASCII-only

yay added eval as v, also O_O this isn't even an ascii art challenge (no wonder it's so ungolfy :P
ASCII-only

0

Java 10, 213 bytes

import java.util.*;m->{Arrays.sort(m,(a,b)->Long.compare(a[0],b[0]));var r=Arrays.stream(m).flatMapToInt(Arrays::stream).toArray();return Arrays.equals(r,java.util.stream.IntStream.range(1,r.length+1).toArray());}

Try it online.

It seemed like a good idea when I started, but these builtins only make it longer.. Can definitely be golfed by using a more manual approach..

Inspired by @EriktheOutgolfer's 4-byte 05AB1E answer. 4 vs 213 bytes, rofl.. >.>

Explanation:

import java.util.*;      // Required import for Arrays
m->{                     // Method with 2D integer-array parameter and boolean return-type
  Arrays.sort(m,         //  Sort the 2D input-array on:
    (a,b)->Long.compare(a[0],b[0])); 
                         //  The first values of the inner arrays
var r=Arrays.stream(m).flatMapToInt(Arrays::stream).toArray();
                         //  Flatten the 2D array to a single integer-array
return Arrays.equals(r,  //  Check if this integer-array is equal to:
  java.util.stream.IntStream.range(1,r.length+1).toArray());} 
                         //  An integer-array of the range [1, length+1]
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.