我可以安顿下来吗?


23

“卡坦殖民者”棋盘游戏中,有五种资源类型:砖块,原木,矿石,小麦和绵羊。建立定居点需要花费砖块,原木,小麦和绵羊。但是,您也可以交换四个相同的资源来获取不同类型的资源。例如,如果您手中有四个矿石,则可以将所有矿石换成一只羊。

您的工作是确定我是否可以建立解决方案。

你的任务

输入将是字母的顺序BLOW,和S,采取任何合理的格式。这些字母对应于上面给出的五种资源类型。考虑到进行四种交易的可能性,您应该输出我是否拥有建立和解所需的资源。

这是,因此以字节为单位的最短代码获胜。

笔记

  • 您不必输出我需要执行的交易或可以建立的结算数量。简单的“是”或“否”即可。
  • 您可能假定输入是按任何特定顺序进行的。特别是,您可能不会假定相同类型的资源被分组在一起,因此OBLSO,有效输入也不是。
  • 这是,因此,只要选择的两个值是不同且一致的,就可以使用要表示“是”和“否”的任何值。
  • 我们在这里关心的唯一规则是上面列出的规则。与其他玩家交易或在港口交易等更为复杂的卡坦定居者规则在这里无关紧要。
  • 输入的字符(BLOWS)可以与其他的值取代,只要它是你所选择的特定的语言更容易,所以只要有五个不同的输入。如果您使用其他输入值,请在答案中指定它们。

例子

BLWS -> Yes
OOOOWLB -> Yes (trade four O for a S)
OOW -> No
BBBO -> No
(empty input) -> No
BBBBLW -> No
BBBBBLW -> Yes (trade four B for a S)
OOOOOOOOOOOOOOOO -> Yes (sixteen O; trade for B, L, W, S)
BLBLBLBLBL -> Yes (trade L for W and B for S)
BLSWBLSWBLSW -> Yes (extra, unused resources are ignored)

13
“建立一个定居点要花一块砖,一根原木,一块小麦和一只绵羊”。是的,要执行建造定居点的仪式,您需要一只羊。想知道为什么没有素食主义者?
Okx

5
@Okx,绵羊从小麦中拿出牛奶和面包一起喂给建设者(他们最后把绵羊带走作为付款)。在定居点​​的建筑中没有任何动物受到伤害
Aganju

程序要求对输入进行排序是否可以?
NieDzejkob

@NieDzejkob不,明确禁止要求订购。您的程序必须准备好处理这五个资源的任何顺序。
Silvio Mayolo

@SilvioMayolo对不起,我不知道我怎么想念
NieDzejkob

Answers:


16

Python 2,54个字节

lambda s:sum((s+"BLSW"*3).count(n)/4for n in"BLSWO")>3

在线尝试!

对于每一个我们的资源,我们计算的数量“自由”具有给定 n种资源所。考虑到我们可以转换我们的资源这一事实,自由表示有机会填补我们需要填补的原木,小麦,羊茅插槽之一。

对于所有BLSW,拥有一个资源给我们一个这样的自由,而每增加4个额外资源给我们另一个。自由计数规则是这样的:

* Having 1 brick/log/wheat/sheep gives 1 freedom.
* Having 5 bricks/logs/wheat/sheep gives 2 freedoms.
* Having 9 bricks/logs/wheat/sheep gives 3 freedoms.
* 

所以 n个积木/原木/小麦/绵羊给了⌊(n + 3)/4⌋自由度。

对于矿石,只有多余的四人一组才算在内。自由计数规则是这样的:

* Having 4 ores gives 1 freedom.
* Having 8 ores gives 2 freedoms.
* Having 12 ores gives 3 freedoms.
* 

所以 n矿石赋予⌊n/4⌋自由。

定理:只有当我们有≥4个这样的“自由”时,我们才能解决。

因此,我们计算自由度,并检查是否有≥4个自由度。为了将计数矿石计算为⌊n/4⌋,而将其他资源计算为⌊(n + 3)/4⌋,我们人为地将其他资源的计数乘以3,然后对所有其他资源计数⌊n/4⌋。我们通过映射(s+"BLSW"*3).count而不是来实现s.count

证明

  • 假设我们可以解决。然后,对于[B,L,S,W]中的每一个,我们要么(a)使用我们已经拥有的一种资源,要么(b)牺牲了其他一些资源(包括矿石)中的4种来创建它。无论哪种情况,我们都必须按照上述规则计算至少1种自由。因此,我们有≥4个自由度。

  • 假设我们有4个自由,K这都是由于“过火”(从矿石中每一个自由度是多余的,和其他资源的每一个自由过去的第一个也是)和4-K,其中至少有一个拥有的见证砖/原木/小麦/绵羊(给予“第一自由”的人)。然后,我们使用赋予我们第一个自由的积木/原木/小麦/绵羊填充4–k个插槽,并通过转换多余的空间来填充其余的k个插槽。所有4个位置均已满,我们可以安顿下来。我们可以很明显仍然这样做,如果我们有更多比4点的自由。

这个证据很烂,但我很困。我敢肯定有更好的解释。


2
所以说sOOOOBLW,你最终得到sum(n/4for n in map(("OOOOBLWBBBLLLSSSWWW").count,"BLSWO"))>3...所以对于每个BLOWS算你有多少次出现在起动机的字符串"BLWS"*3,然后总结一下。
Pureferret

2
恰好!("OOOOBLWBLSWBLSWBLSW"实际上,字符串是,但计数相同。)
Lynn

Python映射“向后”总是使我感到困惑!
Pureferret

两者之间的空间in"BLSWO"在Python中是不必要的,不是吗?似乎在TIO工作至少..
凯文Cruijssen

8

Python 2中 52  51个字节的

-1字节由于卢克(替换>=0<0,反相False/ True结果)

lambda h:sum(~-(h+"O").count(c)/4for c in"BOWLS")<0

包含字符串BOWLS的未命名函数(如在OP中),然后返回False是否可以沉降True

在线尝试!(将输出强制为yes/noOP的)。

怎么样?

这是我的果冻答案的一部分。在使用剩余的BWLS中的每一个之后,我们需要对其进行补偿。这样,我们可以在手上加一个额外的O,然后将所有计数减一,然后将所有计数除以四,然后求和-如果结果为零或更多,我们可以解决(要么是因为没有缺少所需的资源或因为我们可以交易以获取失踪的人)。

lambda h:sum(~-(h+"O").count(c)/4for c in"BOWLS")<0
lambda h:                                           - a function that takes h (a string)
                                 for c in"BOWLS"    - for each letter, c, in "BOWLS":
                h+"O"                               -   append "O" to h
               (     ).count(c)                     -   count c instances
              -                                     -   negate
             ~                                      -   bitwise not (this is -x-1)
                               /4                   -   integer divide by 4
                                                    -    (NB: -1 and 0 are not affected)
         sum(                                   )   - sum the five values
                                                 <0 - less than zero? (inverted result)

如何使用Falsefor 'yes'Truefor 'no'?然后,您可以更改>=<,节省1个字节。
路加福音

与问题相比,我更喜欢您选择的资源订购方式!
尼尔

7

Pyth,14个字节

gsm/t/+Q4d4U5Z

在这里尝试!验证所有测试用例。

Pyth 31 27 17  16字节

<3s/R4/L+Q*3U4U5

验证测试用例。

这些如何运作?

说明#1

gsm/t/+Q4d4U5Z   - Full program.

  m        U5    - Map over the range [0, 5) with a variable d.
      +Q4        - The input, with a 4 appended (this corresponds to O)
     /   d       - Count the occurrences of the current value in ^.
    t            - Decrement.
   /      4      - Integer division by 4.
 s               - Sum
g            Z   - Is non-negative (is the sum ≥ 0)?  
                 - Output implicitly.

说明#2

<3s/R4/L+Q*3U4U5   - Full program.

          *3U4     - The range [0, 4) repeated 3 times.
        +Q         - The input with ^ appended.
      /L      U5   - Count the occurrences of each element in [0, 5) in ^.
   /R4             - Integer division of each by 4.
  s                - Sum.
<3                 - Is higher than 3?
                   - Output implicitly.

这些是我的程序使用的代码:

B -> 0
L -> 1
S -> 2
W -> 3
O -> 4


哦,那好吧。
Erik the Outgolfer

我相信//Q4 4可以,/Q16但我不太确定...
Egg the Outgolfer

@EriktheOutgolfer无效... BBBO例如,失败
Xcoder先生17年

@EriktheOutgolfer不,它计算的出现次数4并除以4
Xcoder先生17年

6

果冻 13  12 字节

;5ċЀ5’:4S>-

一个单子链接,它接受代表您拥有的资源的数字列表,1如果您可以安定下来,0则返回该列表。

资源在1, 2, 3, 4, 5哪里5代表矿石

在线尝试!或查看测试套件(使用OP IO)。

怎么样?

想法是首先按类型对资源进行计数,然后将BLWS的所有计数都减一-如果我们对这四个中的任何一个都不计数,那么它们现在将具有-1项-我们需要获取从我们剩余的资源中删除它们(这实际上是通过添加一个额外的O5)并将所有五个计数都减少1来实现的)。接下来,我们将所有这些值整数除以四,以查看我们可以根据资源类型用剩余计数中的每一个交易多少个单位,同时不影响-10计数(请注意-1整数除以4是-1,而不是0)。最后,我们将这些值相加并检查结果是否大于或等于零(此处可以使用大于-1,因为我们总是有整数)。

;5ċЀ5’:4S>- - Link: list of numbers (BLWSO:12345) e.g. [3,2,2,2,2,2,5,5,5,5] (WLLLLLOOOO)
;5           - concatenate a five                       [3,2,2,2,2,2,5,5,5,5,5]
     5       - literal 5
   Ѐ        - map across implicit range(5) = [1,2,3,4,5]:
  ċ          -   count                                  [ 0, 5, 1, 0, 5]
      ’      - decrement (vectorises)                   [-1, 4, 0,-1, 4]
       :4    - integer divide by four                   [-1, 1, 0,-1, 1]
         S   - sum                                      0
           - - literal -1                              -1
          >  - greater than?                            1

5

Java 8,101字节

Lambda从int[]boolean。分配给Function<int[], Boolean>

a->{int h,f[]=new int[5],i=0;for(int x:a)f[x]++;for(h=f[4]/4;i<4;)h+=--f[i]>>-1|f[i++]/4;return~h<0;}

在线试用

输入输出

输入是一个从0到4(含)的整数数组。4代表矿石,其他映射无关紧要。我的测试用例是该问题的直接翻译,0代表Brick,1代表Log,2代表Wheat,3代表Sheep。

输出是是否可以建立结算。

不打高尔夫球

a -> {
    int
        h,
        f[] = new int[5],
        i = 0
    ;
    for (int x : a)
        f[x]++;
    for (h = f[4] / 4; i < 4; )
        h += --f[i] >> 31 | f[i++] / 4;
    return ~h < 0;
}

说明

h是可交易的资源四倍数量。我们遍历每种资源类型(矿石除外),h对我们拥有的每四倍的额外资源进行递增,并在不存在任何资源的情况下递减。那么我们的结果就是是否h为负数。

线

h += --f[i] >> 31 | f[i++] / 4;

h无论没有资源(短缺)还是至少有一种资源(盈余),都可以适当地进行调整。f[i]减少以在剩余情况下考虑所需的资源,在短缺情况下产生-1。带符号的右移将表达式减小为0(多余的情况)或-1(短缺的情况),以便与数字按位或f[i++] / 4四倍的剩余部分(在剩余情况下)在短缺情况下不起作用,但结果为本身在剩余情况下。

致谢

  • -9字节归功于Nevay,位大师

-3个字节:...for(h=f[4]/4;i<4;h+=f[i++]/4)n+=--f[i]>>-1;return~h<n;
Nevay

103字节:a->{int h,f[]=new int[5],i=0;for(int x:a)f[x]++;for(h=f[4]/4;i<4;h+=f[i++]/4)h+=--f[i]>>-1;return~h<0;}
Nevay

2
101字节:a->{int h,f[]=new int[5],i=0;for(int x:a)f[x]++;for(h=f[4]/4;i<4;)h+=--f[i]>>-1|f[i++]/4;return~h<0;}
Nevay

现在,这是一些多汁的黑客活动!
雅各布

4

视网膜,34字节

^
BBBLLLWWWSSS
O`.
((.)\2{3}.*){4}

在线尝试!说明:建立解决方案需要4个资源,它们是您的第一个B,L,W或S,或任何其他4个相同类型的资源。这等效于将这四种资源中的每种资源相加三个,然后进行计数以查看是否有四个四个资源。




2

Python 3中79 78个字节

编辑: -1字节感谢@ Mr.Xcoder

lambda x:3<sum((a>0)+~-a*(a>1)//4for a in map(x.count,"BLSW"))+x.count("O")//4

在线尝试!


如果您愿意切换到Python 2,则可以使用77个字节来完成操作
Xcoder先生,17年


@先生。Xcoder为什么不制作Python 2解决方案?
雅各布

@Jakob因为它与Halvard的太相似了。
Xcoder先生17年

@ Mr.Xcoder会将其保留为Python 3
Halvard Hummel

2

MATL,19字节

Oh!5:=s4&\w4:)ghs3>

输入是一个数字行向量,其中字母表示为数字,如下所示:

B: 1
L: 2
W: 3
S: 4
O: 5

输出是1真实的,0是虚假的。

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

怎么运行的

  1. 计算每种资源的出现次数。
  2. 将它们除以4。
  3. 计算前四个资源(字母BLWS)的余数为非零。这给出一个数字c
  4. 对商求和。这给出一个数字s
  5. 输出是否Ç + 小号 ≥4。

注释代码

Oh     % Append 0 to implicit input. This is just in case inpout is empty
!      % Convert into column vector
5:     % Push row vector [1 2 3 4 5]
=      % Compare for equality, element-wise with broadcast
s      % Sum of each column. Gives number of times that each entry of
       % [1 2 3 4 5] appears in the input
4&\    % Mod-div 4, element-wise. Pushes vector of remainders and then vector
       % of quotients of division by 4
w      % Swap. Brings remainders to top
4:)    % Get the first four entries
g      % Convert to logical. This transforms non-zero values into 1
h      % Concatenate with vector of quotients
s      % Sum
3>     % Does the result exceed 3? Implicitly display

2

> <>,61字节

510ap\~1(n;
1+$ap> i:0(?v8%:ag
0:ga:v?=5:+1<$-}$,4-%4:-}-${:)

在线尝试!

使用以下资源映射:

O -> 0
B -> 1
L -> 2
W -> 3
S -> 4

只要它们在range 0-4中并且0用于O,使用什么映射就没有关系。利用这样的事实:查找组合BLWS与查找组合与OBLWS在已经有Oin的情况下查找组合相同手。


1

05AB1E,19个字节

0->矿石
1->砖
2->原木
3->小麦
4->绵羊

如果为false,则返回0,否则返回1。

{γvyDĀi¼¨}g4÷}¾)O3›

在线尝试!

说明:

{γvyDĀi¼¨}g4÷}¾)O3› Implicit input, e.g. 0030201
{                   Sort -> 0000123
 γ                  Split into chunks of consecutive elements: [0000, 1, 2, 3]
  vy                For each chunk...
    DĀ                 ...is different than 0?
      i¼¨}                ...if true: increment the counter by 1, and 
                              remove 1 element from the chunk
          g4÷         ...divide the number of elements by 4
             }      End For
              ¾     Push the counter
               )    Wrap the entire stack in a list
                O   Sum of that list
                 3> True if > 3
                    Implicit output

非竞争性解决方案:17个字节

当我首次提交该解决方案时,05AB1E中存在一个错误,其中一些操作员严重地处理了空输入。这导致该解决方案的回答1在输入为空时进行。现在,此问题已得到解决,因此此解决方案可以正常工作。

此处的区别在于,我们在删除每种资源之一之前先添加矿石,然后不加选择地计算以这种方式删除的资源数量。然后,我们将计数器减1,以获得正确的B,L,W和S数。

0«{γε¨g4÷¼}O¾<+3›

在线尝试!


0

JavaScript(SpiderMonkey),116字节

s=>Array.from("BLOWS").reduce((m,c)=>Math.floor(((s+"BLSW".repeat(3)).match(new RegExp(c,'g'))||"").length/4)+m,0)>3

在线尝试!

超级笨拙的错误答案。我敢肯定它可以被清理更多。该方法受Lynn的回答启发。


0

科特林131个 129字节

投稿

fun r(i:String):Any=i.split("").groupingBy{it}.eachCount().map{when(it.key){
""->0
"O"->it.value/4
else->(it.value+3)/4}}.sum()>3

测试

fun r(i:String):Any=i.split("").groupingBy{it}.eachCount().map{when(it.key){
""->0
"O"->it.value/4
else->(it.value+3)/4}}.sum()>3

data class TestData(val input:String, val output:Boolean) {
    fun run() {
        val out = r(input)
        if (out != output) {
            throw AssertionError("Failed test: ${this} -> $out")
        }
    }
}
fun main(args: Array<String>) {
    listOf(

            TestData("BLWS", true),
            TestData("OOOOWLB", true),
            TestData("OOW", false),
            TestData("BBBO", false),
            TestData("", false),
            TestData("BBBBLW", false),
            TestData("BBBBBLW", true),
            TestData("OOOOOOOOOOOOOOOO", true),
            TestData("BLBLBLBLBL", true),
            TestData("BLSWBLSWBLSW", true)
    ).forEach(TestData::run)
    println("Test passed")
}

无法在TryItOnline上工作,但在 try.kotlinlang.org 工作

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.