块重排


14

因此,您的任务是采用一个3x3的块,其中-的平均空格和*的平均填充空格,例如:

-**
-*-
*-*

并重新排列该块,以使*形成一个X,如下所示:

*-*
-*-
*-*

输入: 3x3个正方形,如上面,它们可以是3条线,一个数组,也可以是您想要的。

输出:重新排列成X的最短动作量。每个动作都翻转了两个相互接触的字符,这些字符彼此水平,彼此垂直或彼此对角线。如果不可能,则返回任何不可能的输出,例如999-42425是最小的此类数字。

测试用例:

1)输出:1

-**
-*-
*-*

2)输出:-1

-*-
-*-
*-*

3)输出:3

---
-**
***

4)输出:0

*-*
-*-
*-*

您可以替换空白和非空白字符,但请确保在帖子中包括哪个字符

高尔夫代码

请记住,这是最短代码胜利的代码高尔夫球!


1
翻转2个字符,您是说要从太空翻转到*相反,还是要交换吗?
user202729 '18

如果有五个以上*怎么办?您可以添加更多测试用例吗?
Stewie Griffin

如果翻转了最后2个字符,则@ user202729例如abc将为acb。
诺亚·克里斯蒂诺

@StewieGriffin“如果不可能返回-1”,如果大于5 *或小于5,则不可能。
诺亚·克里斯蒂诺

6
我们可以使用其他东西-1吗?例如5(否则不可能),或者抛出错误?
乔纳森·艾伦

Answers:


12

Python 3中104个 78字节

lambda n:-(sum(n)!=5)or sum(n[1::2])+n[4]*(max(n,n[6:],n[::3],n[2::3])>=[1]*3)

在线尝试!

编辑:应用了@Jonathan Allan和@xnor的建议,以大大减少字节数。

输入是长度为9 的字符串列表,其中包含零和一,一个为*s。

以下是一些观察结果:

  • 我们永远不需要移动已经在正确细胞上的恒星。任何放错位置的恒星都有5个周围的细胞,这些细胞不能立即被阻止(否则答案已经是-1)。
  • 每颗错位的恒星的成本为1或2,只有三颗正确放置的恒星将其包围时,成本为2。
  • 每颗错位的恒星的成本彼此独立。

因此,我们首先测试字符串是否有五个,然后计算这些事情:

  • 错位的恒星数(=处于奇数索引的恒星)
  • 成本2的放错位置的星的数量(=在细胞0124034624584678为全1的)
    • n[4]作为一个因子,然后测试每个范围的提取'111'
    • 由于这种恒星最多为一颗,因此我们可以放心使用max代替sum

保存17个字节,接受一个列表,而不是字符串(更换count与S sumS和'111'[1]*3TIO(我一直巧言令色与n[i::j]>=[1]*3循环,但还没有找到更短)。
乔纳森·艾伦

由于只能有一颗成本2星,因此看起来您可以做到max(n,n[6:],n[::3],n[2::3])>='1'*3
xnor

还有其他安排具有成本2星。我认为[0,1,1,1,1,0,1,0,0]应该返回3而不是2
RootTwo

此外,[1,1,1,1,0,0,1,0,0]应该是3而不是2
RootTwo

此外,[1,1,1,1,0,0,1,0,0]应该是3而不是2
RootTwo

4

果冻,26个字节

5ḶḤd3ạŒ!Ṁ€€ḅ1Ṃ
T’d3Ç-L=5Ɗ?

在线尝试!


以平面清单作为输入。

太可惜了,果冻没有“多维真实索引” ... T€ṭ€"JẎ也可以工作,但又需要1个字节。


算法:当前有5个块位置和5个目标(目的地),该算法尝试5个!匹配,并输出[源,目标] Chebyshev距离的最小和。


您可以采用固定列表(“无论如何”)...甚至可以采用基于0的索引并有24个索引?
乔纳森·艾伦

4

Haskell中176个 132 126 104字节

w=0:1:w
m a|sum a/=5=5|1>0=sum$[a!!4|3<-sum.map(a!!)<$>[[0,1,2],[0,3,6],[2,5,8],[6,7,8]]]++zipWith(*)a w

在线尝试!


接受一个以1作为非空白字符的整数列表。对非零偶数索引的平方进行求和,如果找到任何两次移动模式(中心平方和边列/行完全填充),则加1。我认为最后一部分有点浪费,可能可以通过这种蛮力方法加以改进。在不可能的输入上返回5(不可能的输出)。


2
一些提示:length测试可以缩短为sum[1|1<-a]。功能s到:(1-e,n+sum[1|b>e])您可以内联保存另一个字节。您可以使用otherwise守卫m萨韦对()。最后,&&在守卫的最上层可以替换为,。...
nimi

2
您可以通过使用sum对列表的理解将布尔值转换为int 来保存另一个字节。在线尝试!
发布Rock Garf Hunter '18 -4-9

2
实际上,您可以节省很多字节,因为一旦模式保护消失了,您就可以将整个内容移入m在线尝试!
发布Rock Garf Hunter '18 -4-9

2
此外,由于每一个非1元a必须是0不能使用sum a的,而不是sum[1|1<-a]在线尝试!
发布Rock Garf Hunter,

1
我只是意识到,因为1除非中心是中心0,否则所有的边不能超过1个,您可以3<-代替elem 3$。您也可以使用sum.map(a!!)代替sum<$>map(a!!)
发布Rock Garf Hunter'Apr

3

Python 2中194个 192字节

from itertools import*
f=lambda l,k=0:-(sum(l)!=5)or[1,0]*4!=l[:-1]and k<4and-~min(f(l[:a]+[l[b]]+l[a+1:b]+[l[a]]+l[b+1:],k+1)for a,b in combinations(range(9),2)if max(b/3-a/3,abs(a%3-b%3))<2)

在线尝试!


1
不适用于[0,1,0,1,0,1,1,1,0](预期:4,实际:13)。
Bubbler

@Bubbler修复了它
ovs '18

3

JavaScript(ES6),123字节

将输入作为9位整数。天真地应用规则可以解决难题,事实证明这不是最短的方法。

f=(n,k=b=-1)=>n^341?k>2?b:[3,6,9,10,17,18,20,34,36].map(m=>[1,8,8].map(M=>(x=n&(m*=M))&-x^x||f(n^m,k+1)))|b:!~b|k<b?b=k+1:b

在线尝试!

已评论

f = (                           // f = recursive function taking:
  n,                            //   n = input
  k =                           //   k = number of moves, initialized to -1
  b = -1                        //   b = best result so far, initialized to -1
) =>                            //
  n ^ 341 ?                     // if n does not match the target pattern:
    k > 2 ?                     //   if we've already done more than 3 moves:
      b                         //     we're not going to find a solution -> abort
    :                           //   else:
      [3,6,9,10,17,18,20,34,36] //     for each swap bitmask m
      .map(m =>                 //     and
      [1,8,8]                   //     for each multiplier M:
      .map(M =>                 //       apply the multiplier to m and
        (x = n & (m *= M))      //       apply the final bitmask to n -> this gives x
        & -x                    //       isolate the least significant bit of x
        ^ x ||                  //       if it's the only bit set,
        f(n ^ m, k + 1)         //       then swap the bits and make a recursive call
      )) | b                    //     end of both map() loops; return b
  :                             // else:
    !~b | k < b ? b = k + 1 : b //   this is a solution in k+1 moves: update b

注意:当m乘以64 时,此代码会执行一些非法移动,超出了面板顶部。但是它们被简单地忽略了,因为它们不可能导致比最佳法律解决方案更短的解决方案。

以下是9个基本交换位掩码和目标模式。左上角是最高有效位。

000  000  001  001  010  010  010  100  100     101
011  110  001  010  001  010  100  010  100     010 (341)
(3)  (6)  (9)  (10) (17) (18) (20) (34) (36)    101

您可以链接一个十六进制转储进行测试吗?另外,我不知道JS中可能有9位整数
Stan Strum,

@StanStrum已更新为具有更直接编码的较短版本。(是的:JS支持最多32位的按位运算。)
Arnauld '18

2

果冻,26 个字节

“ċȤ‘ḤB;U$=a¥;Ḋm2ƊẠ€SɓSn5Nȯ

在线尝试!

单子链接。

怎么样?

Bubbler的Python答案启发;打高尔夫球以适合果冻...

“ċȤ‘ḤB;U$=a¥;Ḋm2ƊẠ€SɓSn5Nȯ - Link: length 9 list of ones & zeros, X
“ċȤ‘                       - list of code-page indices     = [232,154]
    Ḥ                      - double                        = [464,308]
     B                     - to binary     = [[1,1,1,0,1,0,0,0,0],[1,0,0,1,1,0,1,0,0]]
        $                  - last two links as a monad:
       U                   -   upend       = [[0,0,0,0,1,0,1,1,1],[0,0,1,0,1,1,0,0,1]]
      ;                    -   concatenate = [[1,1,1,0,1,0,0,0,0],[1,0,0,1,1,0,1,0,0],[0,0,0,0,1,0,1,1,1],[0,0,1,0,1,1,0,0,1]]
           ¥               - last two links as a dyad:
          a                -   logical AND (vectorises)
         =                 -   equal? (vectorises)
                Ɗ          - last three links as a monad:
             Ḋ             -   dequeue X (remove leftmost element)
               2           -   literal two
              m            -   modulo slice (keeps the "edge-elements") 
            ;              - concatenate
                 Ạ€        - all? for €ach (edge-elements: no-op
                           -                else: 1 for any cost-2 element 0 otherwise)
                   S       - sum
                    ɓ      - new dyadic chain ^that on the right; X on the left
                     S     - sum X
                       5   - literal five
                      n    - not equal?
                        N  - negate (-1 if not exactly 5 1s, 0 otherwise)
                         ȯ - logical OR with right

2

JavaScript,85个字节

s=>/^0*(10*){5}$/.test(s)*s.match(/(?=1.(..)*$|^1(..)?11.1|1.11(..)?1$)|$/g).length-1

这是Bubbler答案的正则表达式端口。

输入为0/1的字符串。


2

Stax23 22 字节

Ç╙╤Ü┤└åVτ┐├Y-²▼░█∩¡3ëâ

运行并调试

该程序将一个数组[0, 1]作为输入,并返回整数的步数,如果无法解决,则返回一个空字符串。

考虑网格的此索引

0 1 2
3 4 5
6 7 8
  • 如果1输入中不完全是5 s,则没有解,因此我们不产生输出。
  • 两侧的中心位置不正确。它们分别是索引1、3、5和7。1将这些位置中每个位置的距离相加将得出最终结果。
  • 对于每个1位置不正确的对象,其距离均为1或2。如果被其他1s 包围,则距离为2 。例如,如果1在索引[0,1,2,4]处有s,则错误的距离1 2。
  • 考虑到这一点,请考虑使用此伪代码来获取索引1为结果贡献的距离。

    1. 从索引[1、0、2、4]读取4位。这会将错误的位置放在最重要的位置。
    2. 将这些位转换b为0到15之间的数字。
    3. 0 <= b <= 7距离为0时8 <= b <= 14。当距离为1时。当b == 15距离为2时。可以使用整数除以计算b * 2 / 15

因此,可以通过重复此过程4次并在两者之间旋转网格来计算总距离。

1#5=4*  if the number of 1s is 5, then 4, else 0
D       repeat the rest of the program that many times
  x     push the value in the x register, which is initially the input
  3/    split into 3 rows
  rM    rotate 90 degrees
  $X    flatten back into single array, and save the "rotated" array in the X register
  A|2E  get the digits of 2^10 i.e. [1,0,2,4]
  @     read the bits from the current rotation at indices [1,0,2,4]
  :b    convert bits to integer
  H15/  double, then divide by 2
  +     add to running total

运行这个


检查编辑,接受所有不可能的值,如果可以帮助,则不只是-1
Noah Cristino 18-4-9

是。节省了2个字节。
递归

1

Excel,86 81字节

=SUM(B1,A2,B3,C2)+B2*(AND(A1:A3)+AND(A1:C1)+AND(C1:C3)+AND(A3:C3))/(SUM(A1:C3)=5)

旧: 当“不可能”的输出是-1

=IF(SUM(A1:C3)=5,SUM(B1,A2,B3,C2)+B2*(AND(A1:A3)+AND(A1:C1)+AND(C1:C3)+AND(A3:C3)),-1)

用途1用于填充0空,输入范围A1:C3如果我们可以返回-1“不可能” 以外的值,则可以进一步打高尔夫球。#DIV/0!在不可能的网格上 返回错误

以与Bubbler的Python answer相同的逻辑进行操作。


检查编辑,接受所有不可能的值,而不仅仅是-1
Noah Cristino '18
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.