0xBEEF在哪里?


92

这项挑战的灵感来自1984年温迪的广告

牛肉在哪里?

TS Rogers的插图

您的任务是在二进制包中找到一个十六进制的0xBEEF。

“牛肉”由以下模式组成:

1 0 1 1  (0xB)
1 1 1 0  (0xE)
1 1 1 0  (0xE)
1 1 1 1  (0xF)

“小圆面包”由12x12二进制矩阵组成,例如:

1 1 1 0 0 1 1 1 1 1 1 0
1 1 0 1 0 0 1 0 0 0 0 0
0 1 0 0 0 1 1 1 1 1 0 1
1 0 0 1 0 0 1 0 0 1 0 0
1 0 0 1 0 1 1 0 0 1 1 1
1 1 1 1 1 1 0 0 0 0 1 0
1 1 0 1 1 1 0 0 0 0 0 1
1 0 0 1 1 1 1 0 0 0 0 1
1 0 0 1 1 1 0 1 1 1 1 1
1 1 1 1 1 0 0 1 1 1 1 1
1 0 0 0 0 1 0 1 0 1 1 1
1 1 0 0 1 1 0 0 0 0 1 1

输入值

您的程序或函数将采用二进制矩阵作为输入。矩阵格式非常灵活,但是必须在答案中明确说明。

例如:

  • 单个二进制字符串,行之间有或没有分隔符:

    "111001111110 110100100000..."

    要么:

    "111001111110110100100000..."

  • 二进制字符串数组:

    ["111001111110", "110100100000", ...]

  • 一个数字数组(每个数字描述的行一旦转换回二进制并用零补齐):

    [3710, 3360, ...]

输出量

(X, Y)“牛肉” 的坐标(0, 0),即面包的左上角。

或者,您可以使用基于1的坐标(但不能同时使用两种格式,例如X的基于0的坐标和Y的基于1的坐标)。

对于以上示例,预期答案为(3, 4)(从0开始)或(4, 5)(从1开始):

   00 01 02 03 04 05 06 07 08 09 10 11 
00  1  1  1  0  0  1  1  1  1  1  1  0
01  1  1  0  1  0  0  1  0  0  0  0  0
02  0  1  0  0  0  1  1  1  1  1  0  1
03  1  0  0  1  0  0  1  0  0  1  0  0
04  1  0  0 [1  0  1  1] 0  0  1  1  1
05  1  1  1 [1  1  1  0] 0  0  0  1  0
06  1  1  0 [1  1  1  0] 0  0  0  0  1
07  1  0  0 [1  1  1  1] 0  0  0  0  1
08  1  0  0  1  1  1  0  1  1  1  1  1
09  1  1  1  1  1  0  0  1  1  1  1  1
10  1  0  0  0  0  1  0  1  0  1  1  1
11  1  1  0  0  1  1  0  0  0  0  1  1

同样,只要您的答案中指定了任何合理的格式都可以。如果您使用的是从0开始或从1开始的座标,请也提及。

规则

  • 您可以放心地假设面包上总是只有一个“牛肉”。不需要支持多于一根牛肉或根本没有牛肉的案例的代码。
  • 牛肉图案将始终如所述出现。它绝不会以任何方式旋转或镜像。
  • 这是代码高尔夫球,因此最短的答案以字节为单位。禁止出现标准漏洞。

测试用例

在以下测试案例中,矩阵的每一行均以其十进制表示形式表示。

Input : [ 3710, 3360, 1149, 2340, 2407, 4034, 3521, 2529, 2527, 3999, 2135, 3267 ]
Output: [ 3, 4 ]

Input : [ 1222, 3107, 1508, 3997, 1906, 379, 2874, 2926, 1480, 1487, 3565, 633 ]
Output: [ 3, 7 ]

Input : [ 2796, 206, 148, 763, 429, 1274, 2170, 2495, 42, 1646, 363, 1145 ]
Output: [ 6, 4 ]

Input : [ 3486, 3502, 1882, 1886, 2003, 1442, 2383, 2808, 1416, 1923, 2613, 519 ]
Output: [ 1, 1 ]

Input : [ 3661, 2382, 2208, 1583, 1865, 3969, 2864, 3074, 475, 2382, 1838, 127 ]
Output: [ 8, 8 ]

Input : [ 361, 1275, 3304, 2878, 3733, 3833, 3971, 3405, 2886, 448, 3101, 22 ]
Output: [ 0, 3 ]

Input : [ 3674, 2852, 1571, 3582, 1402, 3331, 1741, 2678, 2076, 2685, 734, 261 ]
Output: [ 7, 7 ]

是否允许使用基于1的索引(左上角为(1,1))?
门把手

@Doorknob是的,如果X和Y的格式相同(问题已相应更新)。
Arnauld

35
如果我们还输出0xBEEF为0xDEAD,则有加分吗?:P
TuxCrafting,2016年

10
这个挑战真的是随机的,有点傻。但这实际上仍然是一个巨大的挑战。+1
DJMcMayhem

我可以输出yx(逆序)吗?
路易斯·门多

Answers:


30

果冻20 17 16 字节

ṡ€4ḄZw€“¿ÇÇБĖUṀ

输入为布尔矩阵形式,输出为基于1的索引对(Y,X)

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

这个怎么运作

ṡ€4ḄZw€“¿ÇÇБĖUṀ  Main link. Argument: M (2D array of Booleans)

ṡ€4               Split each row into 9 chunks of length 4.
   Ḅ              Convert these chunks from base 2 to integer.
    Z             Zip/transpose. This places the columns of generated integers
                  into the rows of the matrix to comb through them.
       “¿ÇÇБ     Push the array of code points (in Jelly's code page) of these
                  characters, i.e., 0xB, 0xE, 0xE, and 0xF.
     w€           Window-index each; in each row, find the index of the contiguous
                  subarray [0xB, 0xE, 0xE, 0xF] (0 if not found).
                  Since the matrix contains on one BEEF, this will yield an array
                  of zeroes, with a single non-zero Y at index X.
             Ė    Enumerate; prefix each integer with its index.
              U   Upend; reverse the pairs to brings the zeroes to the beginning.
               Ṁ  Take the maximum. This yields the only element with positive
                  first coordinate, i.e., the pair [Y, X].

14
我不明白...您该如何编码人类不可读的内容?
L3n

12
到目前为止,果冻比阅读容易。:P
丹尼斯

45
@ l3n您似乎暗示丹尼斯是人。虽然这是有可能的,但考虑到通常会冒出来的那种花样,我不会打折其他……比如说更多的网络朋克替代品;-)
Francesco

1
您可以使用ṡ4Z€Ḅw€“Ье‘ĖUṀ
Jonathan Allan

2
@乔纳森·艾伦尼斯。还有ṡ€4ḄZjw“¿ÇÇБ’d24基于0的索引,但是不幸的是,它长了一个字节。
丹尼斯

40

vim,126 80 77 76

/\v1011\_.{9}(1110\_.{9}){2}1111<cr>:exe'norm Go'.join(getpos('.'))<cr>xxdawhPXXd{

期望以以下形式输入

111001111110
110100100000
010001111101
100100100100
100101100111
111111000010
110111000001
100111100001
100111011111
111110011111
100001010111
110011000011

和输出(从1开始的索引)为

4 5
/                      regex search for...
\v                     enable "very magic" mode (less escaping)
1011\_.{9}             find the first line ("B"), followed by 8 chars + 1 \n
(1110\_.{9}){2}        find the second and third lines ("EE")
1111<cr>               find the fourth line ("F")
:exe'norm Go'.         insert at the beginning of the file...
join(getpos('.'))<cr>  the current position of the cursor
xxdawhPXX              do some finagling to put the numbers in the right order
d{                     delete the input

感谢JörgHülsermann通过使我意识到我的正则表达式非常笨拙而间接地节省了46个字节,并感谢DJMcMayhem多了3个字节。


1
有两个提示:1)Yp优于yyp(即使我知道您反对Y:P)2)exec 'norm Go'不需要空格。和3)kd{比短kdgg。(虽然尚未测试)
DJMcMayhem

1
@DJMcMayhem哦,我总是忘了,Y因为我在vimrc中反弹了它。:P实际上,kdgg等效于just d{,令人惊讶的是,它不会删除当前行。
门把手

真有趣 多么方便!
DJMcMayhem

当诸如{角色运动之类的事情出现时,我总是感到困惑。所以我做了一些类似的事情{d''来删除整行。
尼尔

1
您可以使用echo而不是打印到缓冲区中,我认为在挑战中没有什么可以阻止这种情况的发生。那将节省大约10个字节。
克里斯蒂安·隆多

22

JavaScript(ES6),63 60 56字节

s=>[(i=s.search(/1011.{9}(1110.{9}){2}1111/))%13,i/13|0]

将输入作为以155个字符分隔的12个12位二进制字符串的空格分隔的字符串,返回零索引值。编辑:感谢@JörgHülsermann,节省了3个字节。@ETHproductions节省了4个字节。


您可以s.search(r)代替使用r.exec(s).index吗?
ETHproductions 16-10-24

1
@ETHproductions当然可以。我昨天一定睡着了……
Neil

对我来说,使用nodejs执行,除非我更改s=>[(s,i)=>[,否则它不起作用,因为您需要在某处定义我:/
Mijago

@Mijago Odd,当我尝试它时它在Node 4中起作用(我通常使用Spidermonkey JS shell)。请注意,您在输入代码时打错了字,所以从中得到了一些好处!
尼尔

我认为这失败了,因为000010110010110011100011100011100011100011110011110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Taemyr

14

C,146个 177 173 163字节

感谢Numberknot修复了代码(将低三行移位)。

通过更换保存4个字节>>=1/=24位。通过让节省10多个字节x,并y是全球性的,并默认int感谢MD XF

#define T(i,n)(A[y+i]&15)==n
x,y;b(int A[12]){for(x=9;x--;){for(y=0;++y<9;A[y]/=2)if(T(0,11)&&T(1,14)&&T(2,14)&&T(3,15))return(x<<4)+y;A[9]/=2;A[10]/=2;A[11]/=2;}}

取消高尔夫:

int b(int A[12]) {
 for (int x=8; x>=0; --x) {
  for (int y=0; y<9; ++y) {
   if ((A[y]&15)==11 && (A[y+1]&15)==14 && (A[y+2]&15)==14 && (A[y+3]&15)==15) { 
    return (x<<4) + y; 
   }
   A[y]/=2;
  }
  A[9]/=2; A[10]/=2; A[11]/=2;
 }
}

以字节的高半字节和低半字节返回x,y(从0开始)。

用法:

int temp=b(array_to_solve);
int x=temp>>4;
int y=temp&15;
printf("%d %d\n",x,y);

1
您可以将define更改#define T(i,n)if((A[y+i]&15)==n)为if部分,T(0,11)T(1,14)T(2,14)T(3,15)return以节省6个字节。还要将功能签名更改为另外int b(int*A)保存4个字节。
Lince Assassino


9

MATL22 21字节

Eq[ODDH]B~EqZ+16=&fhq

输入是一个二进制矩阵,带有;行分隔符。输出以相反的顺序从1开始:Y X

在线尝试!或使用十进制输入格式验证所有测试用例

说明

使用2D卷积检测图案。为了这,

  • 矩阵和图案必须为双极性形式,1, -1而不是1, 0。由于模式的大小为4×4,因此通过16卷积输出中等于的条目来检测其出现。
  • 卷积内核需要定义为在两个维度上都反转的搜索模式。

而且,由于卷积在检测到的索引中引入了偏移,因此需要在输出中对此进行校正。

Eq      % Implicitly input binary matrix. Convert to bipolar form (0 becomes -1)
[ODDH]  % Push array [0 8 8 2]
B       % Convert to binary. Each number gives a row
~Eq     % Negate and convert to bipolar. Gives [1 1 1 1; 0 1 1 1; 0 1 1 1; 1 1 0 1]
        % This is the "BEEF" pattern reversed in the two dimensions. Reversal is
        % needed because a convolution will be used to detect that patter
Z+      % 2D convolution, keeping original size
16=&f   % Find row and column indices of 16 in the above matrix
h       % Concatenate horizontally
q       % Subtract 1. Implicitly display

8

Mathematica,62个字节

BlockMap[Fold[#+##&,Join@@#]==48879&,#,{4,4},1]~Position~True&

返回1索引的BEEF矩阵的所有位置。输入必须是二进制数字矩阵。但是,输出中的x和y会切换。


不用担心xy被切换。
Arnauld

7

单据,28字节

27个字节的代码,+ 1为p选项。

(?|1011)(\(?|1110)){2}\1111

需要输入为1和0的多行矩形,没有空格。在这里尝试(输入第三个测试用例)。

说明

滑动是2D模式匹配挑战中的一种语言。Sp3000可能比我说的要多得多,但是基本上它是regex的扩展形式,带有一些定向命令,可让您在二维上进行匹配。上面的代码使用了同义的“ slip”命令\,该命令不会更改匹配指针的方向,而是将其向一侧移动一个字符。它还使用“固定组” (?|...),该组与某些内容匹配,然后将指针重置为其先前的位置。

代码分解如下:

(?|1011)                     Match 1011; reset pointer to beginning of match
        (         ){2}       Do the following twice:
         \                     Slip (moves pointer down one row)
          (?|1110)             Match 1110; reset pointer to beginning of match
                      \1111  Slip and match 1111

这与0xBEEF正方形相符。该p选项输出匹配的坐标,索引为0。


1
尼斯:)奇怪的是,对于某些块状图案,有时高尔夫球手只是螺旋走动:1011>001>1(11>){3}1>1
Sp3000

@ Sp3000哈!螺旋是SnakeEx中最短的方法,但是我没有想到要在Slip中尝试。真的很棒1(11>){3}
DLosc

7

PHP,87字节

不带分隔符的二进制字符串作为输入,返回零索引值。

preg_match("#1011(.{8}1110){2}.{8}1111#",$argv[1],$c,256);echo($s=$c[0][1])%12,$s/12^0;

数字数组作为输入128字节

<?foreach($_GET[a]as$a)$b.=sprintf("%012b",$a);preg_match("#1011(.{8}1110){2}.{8}1111#",$b,$c,256);echo($s=$c[0][1])%12,$s/12^0;

@Titus保存了14个字节谢谢


使用,而不是.中的echo,您可以删除括号。(-4)
泰特斯

在注释中,Arnauld允许不带定界符的输出。(-4)
泰特斯

使用标志PREG_OFFSET_CAPTURE:附加,256preg_match参数中,^(.*)从正则表达式中删除,$c[0][1]而不是strlen($c[1])(-6)
Titus

@Titus不错,做
约尔格Hülsermann

5

Java 7182 177字节

我将Karl Napf C的答案移植到JAVA上,并感谢Karl Napf通过提醒我Bit Magic节省了5个字节(顺便说一句,我也想出了这个主意,但是@KarlNapf返回的主意是你的,不是我的)。

(从0开始)

int f(int[]a){int x=9,y,z=0;for(;x-->0;){for(y=0;y<9;a[y++]/=2) if((a[y]&15)==11&(a[y+1]&15)==14&(a[y+2]&15)==14&(a[y+3]&15)==15)z=(x<<4)+y;a[y]/=2;a[10]/=2;a[11]/=2;}return z;}

不打高尔夫球

class Beef {

    public static void main(String[] args) {
        int x = f(new int[] { 1222, 3107, 1508, 3997, 1906, 379, 2874, 2926, 1480, 1487, 3565, 633 });
        System.out.println(x >> 4);
        System.out.println(x & 15);
    }

    static int f(int[] a) {
        int x = 9,
            y,
            z = 0;

        for (; x-- > 0; ) {
            for (y = 0; y < 9; a[y++] /= 2)
                if ((a[y] & 15) == 11 
                  & (a[y + 1] & 15) == 14
                  & (a[y + 2] & 15) == 14 
                  & (a[y + 3] & 15) == 15)
                    z = (x << 4) + y;

            a[y] /= 2;
            a[10] /= 2;
            a[11] /= 2;
        }
        return z;
    }

}

2
什么是那些四个空格之间有a[y++]>>=1)if((a[y]&15)==。顺便说一句,我算的是182个字节而不是183个字节?:S
凯文·克鲁伊森

@KevinCruijssen固定。
Numberknot

1
一切都很好;-)
Karl Napf

1
您还可以删除之间的空间...a[y++]/=2)if((a[y]&15)==...
Kevin Cruijssen

5

视网膜,47字节

我想为此道歉。我认为这可能是可怕的,并且是如何使用该语言的一个不好的例子,但是由于我在Perl答案中使用了Regex,所以我想尝试Retina。我不是很好。:( 尽管github上的代码片段对我有很大帮助!

感谢@wullzx对我的Perl -3字节答案的评论,以及@ Taemyr指出了我的方法存在的问题!

期望输入以空格分隔的二进制字符串,而输出坐标以空格分隔。

(.{13})*(.)*1011(.{9}1110){2}.{9}1111.*
$#2 $#1

在线尝试!

一次验证所有测试。


1
()失败的'000010110010110011100011100011100011100011110011110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'你*必须{0,8}()
Taemyr

被这反驳You can safely assume that there is always exactly one 'beef' on the bun. Your code is not required to support cases with more than one beef or no beef at all.吗?如果需要的话,可以用不贪心的修饰符来解决(.{12})*?(.)*?
Dom Hastings

1
再看一遍,该输入中只有一根牛肉-并非在程序指示的时候。通过使用热切的修饰符无法解决该问题,因为我可以将假牛肉与真正的牛肉交换。问题是您的正则表达式与从矩阵行的末尾开始少于4位的“牛肉”匹配。
塔米尔(Taemyr),2016年

您也可以通过将{8}更改为{9}并要求输入中的行以空格分隔来解决,以节省零字节的成本。
塔米尔(Taemyr),2016年

@Taemyr Ahhh!我懂了!我误会了你的意思。我的Perl解决方案也可能与此犯规。尽快得到改变。感谢您的评论和建议!
唐·黑斯廷斯

4

Scala,90个字节

("1011.{8}(1110.{8}){2}1111".r.findAllMatchIn(_:String).next.start)andThen(i=>(i/12,i%12))

说明:

(
  "1011.{8}(1110.{8}){2}1111" //The regex we're using to find the beef
  .r                          //as a regex object
  .findAllMatchIn(_:String)   //find all the matches in the argument thats going to be passed here
  .next                       //get the first one
  .start                      //get its start index
)                             //this is a (String -> Int) function
andThen                       //
(i=>                          //with the found index
  (i/12,i%12)                 //convert it to 2d values
)                             

(a -> b) andThen (b -> c)产生一个(a -> c)函数,就像compose的相反,但是在scala中需要更少的类型注释。在这种情况下,它将一串二进制数字作为输入,并返回从零开始的索引的元组。


4

J,31 29字节

[:($#:I.@,)48879=4 4#.@,;._3]

输入格式为2d二进制值数组,输出为基于零的坐标数组[y, x]

我从丹尼斯的评论中学到了一些扁平化和基本转换以找到索引。

用法

   f =: [:($#:I.@,)48879=4 4#.@,;._3]
   ] m =: _12 ]\ 1 1 1 0 0 1 1 1 1 1 1 0 1 1 0 1 0 0 1 0 0 0 0 0 0 1 0 0 0 1 1 1 1 1 0 1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 1 1 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 1 0 1 1 0 1 1 1 0 0 0 0 0 1 1 0 0 1 1 1 1 0 0 0 0 1 1 0 0 1 1 1 0 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 0 0 0 0 1 0 1 0 1 1 1 1 1 0 0 1 1 0 0 0 0 1 1
1 1 1 0 0 1 1 1 1 1 1 0
1 1 0 1 0 0 1 0 0 0 0 0
0 1 0 0 0 1 1 1 1 1 0 1
1 0 0 1 0 0 1 0 0 1 0 0
1 0 0 1 0 1 1 0 0 1 1 1
1 1 1 1 1 1 0 0 0 0 1 0
1 1 0 1 1 1 0 0 0 0 0 1
1 0 0 1 1 1 1 0 0 0 0 1
1 0 0 1 1 1 0 1 1 1 1 1
1 1 1 1 1 0 0 1 1 1 1 1
1 0 0 0 0 1 0 1 0 1 1 1
1 1 0 0 1 1 0 0 0 0 1 1
   f m
4 3
   f (#:~2#~#) 3710 3360 1149 2340 2407 4034 3521 2529 2527 3999 2135 3267
4 3
   f (#:~2#~#) 1222 3107 1508 3997 1906 379 2874 2926 1480 1487 3565 633
7 3
   f (#:~2#~#) 2796 206 148 763 429 1274 2170 2495 42 1646 363 1145
4 6
   f (#:~2#~#) 3486 3502 1882 1886 2003 1442 2383 2808 1416 1923 2613 519
1 1
   f (#:~2#~#) 3661 2382 2208 1583 1865 3969 2864 3074 475 2382 1838 127
8 8
   f (#:~2#~#) 361 1275 3304 2878 3733 3833 3971 3405 2886 448 3101 22
3 0
   f (#:~2#~#) 3674 2852 1571 3582 1402 3331 1741 2678 2076 2685 734 261
7 7

说明

[:($#:I.@,)48879=4 4#.@,;._3]  Input: 2d array M
                            ]  Identity. Get M
                 4 4    ;._3   For each 4x4 subarray of M
                       ,         Flatten it
                    #.@          Convert it to decimal from binary
           48879=              Test if equal to 48879 (decimal value of beef)
[:(       )                    Operate on the resulting array
         ,                       Flatten it
      I.@                        Find the indices where true
    #:                           Convert from decimal to radix based on
   $                               The shape of that array
                               Returns the result as coordinates [y, x]

4

Python 2,98 95 92字节

lambda x:'%x'%(`[''.join('%x'%int(s[i:i+4],2)for s in x)for i in range(9)]`.find('beef')+15)

输入是字符串列表,输出是字符串XY(从1开始的索引)。

Ideone上进行测试


可能会错误地在连接两条线的边界上找到“牛肉”吗?
xnor

是的,我是这样认为的。我将回滚编辑,直到可以正确测试为止。
丹尼斯

2
这就是使用环形use头时发生的情况。
mbomb007 '16

4

Perl,54个字节

53字节代码+ 1 for -n。使用-E无需支付额外费用。

使用基于0的索引。期望输入为1s和0s 的字符串,并输出以空格分隔的坐标。

感谢@wullxz和@ GabrielBenamy帮助我节省了9个字节,并感谢@Taemyr对我的Retina答案的评论指出了一个问题!

/1011.{9}(1110.{9}){2}1111/;say$-[0]%13,$",$-[0]/13|0

用法

perl -nE '/1011.{9}(1110.{9}){2}1111/;say$-[0]%13,$",$-[0]/13|0' <<< '111001111110 110100100000 010001111101 100100100100 100101100111 111111000010 110111000001 100111100001 100111011111 111110011111 100001010111 110011000011
010011000110 110000100011 010111100100 111110011101 011101110010 000101111011 101100111010 101101101110 010111001000 010111001111 110111101101 001001111001
101011101100 000011001110 000010010100 001011111011 000110101101 010011111010 100001111010 100110111111 000000101010 011001101110 000101101011 010001111001
110110011110 110110101110 011101011010 011101011110 011111010011 010110100010 100101001111 101011111000 010110001000 011110000011 101000110101 001000000111
111001001101 100101001110 100010100000 011000101111 011101001001 111110000001 101100110000 110000000010 000111011011 100101001110 011100101110 000001111111
000101101001 010011111011 110011101000 101100111110 111010010101 111011111001 111110000011 110101001101 101101000110 000111000000 110000011101 000000010110
111001011010 101100100100 011000100011 110111111110 010101111010 110100000011 011011001101 101001110110 100000011100 101001111101 001011011110 000100000101'
3 4
3 7
6 4
1 1
8 8
0 3
7 7

1
您可以通过组合二进制EE的正则表达式来保存3个字符:(.{8}1110){2}代替.{8}1110.{8}1110
wullxz

1
您还可以通过length$`改成$-[0]
Gabriel Benamy,

@wullxz当然!我尝试过\1但没有运气,没想尝试{2}!谢谢!
Dom Hastings

@GabrielBenamy太好了,非常感谢!更新!
Dom Hastings

2
“ @ User112638726” $-[0]是上一次成功匹配$-[n]的开始的偏移量。是第n个子模式匹配的子字符串的开始偏移量,或者undef如果子模式不匹配。来自:perldoc.perl.org/perlvar.html(查找@-
Dom Hastings

1

Scala,318字节

该解决方案可以进一步改进...但是我保持其可读性,并允许输入为多行分隔的矩阵。

如果二进制字符串数组的实际解决方案

def has(s: String, t: String): Int = s.indexOf(t)
val beef = List("1011", "1110", "1110", "1111")
l.zipWithIndex.map{case(e,i)=>l.drop(i).take(4)}.map{_.zip(beef)}.map{_.collect{case e=>has(e._1,e._2)}}.zipWithIndex.filterNot{e => e._1.contains(-1) ||  e._1.distinct.length > 1}.map{e=>s"(${e._1.head},${e._2})"}.head

样品工作

val bun = 
"""1 1 1 0 0 1 1 1 1 1 1 0
1 1 0 1 0 0 1 0 0 0 0 0
0 1 0 0 0 1 1 1 1 1 0 1
1 0 0 1 0 0 1 0 0 1 0 0
1 0 0 1 0 1 1 0 0 1 1 1
1 1 1 1 1 1 0 0 0 0 1 0
1 1 0 1 1 1 0 0 0 0 0 1
1 0 0 1 1 1 1 0 0 0 0 1
1 0 0 1 1 1 0 1 1 1 1 1
1 1 1 1 1 0 0 1 1 1 1 1
1 0 0 0 0 1 0 1 0 1 1 1
1 1 0 0 1 1 0 0 0 0 1 1
""".replaceAll(" ","")
def has(s: String, t: String): Int = s.indexOf(t)
val beef = List("1011", "1110", "1110", "1111")
val l = bun.split("\n").toList
l.zipWithIndex.map{case(e,i)=>l.drop(i).take(4)}
.map{_.zip(beef)}
.map{_.collect{case e=>has(e._1,e._2)}}.zipWithIndex
.filterNot{e => e._1.contains(-1) ||  e._1.distinct.length > 1}
.map{e=>s"(${e._1.head},${e._2})"}.head

1

Python,137个字节(根据Linux(感谢ElPedro))

def f(s,q=0):import re
 i=s.index(re.findall('1011.{8}1110.{8}1110.{8}1111',s)[q])+1
 x=i%12
 y=(i-x)/12
 if x>8:x,y=f(s,q+1)
 return x,y

字节数并不完全具有竞争力,但是该算法有点有趣。将输入作为一串二进制值。


如果您使用单空格而不是4并在Linux上进行检查,
则为

1
我认为在导入之前需要一个换行符和空格(我在Python 2中没有IndentError),它需要2个字节,但是您可以将i = ...,x = ...和y = ...放在与...同行并与之分开; 失去1个字节以换136
ElPedro '16

@elpedro我正在使用Python 3,并且导入在同一行上也很好。
penalosa

完全理解的:)
ElPedro

哎呀,只要重新阅读我的评论,我今晚就会犯很多错字。好东西我不是想写任何代码...
ElPedro

1

红宝石,62字节

def f(a);a=~/1011(.{8}1110){2}.{8}1111/;$`.size.divmod(12);end 

它需要一个字符串0and,1并返回一个从零开始的Y和X数组。

尝试ideone


1

F#-260字节

完整的程序,包括必需的EntryPoint指示符(如果您希望,我可以减少计数)。

输入:每行作为单独的字符串:“ 111001111110”“ 110100100000”“ 010001111101”“ 100100100100”“ 100101100111”“ 111111000010”“ 110111000001”“ 100111100001”“ 100111011111”“ 111110011111”“ 100001010111”“ 110011000011”

码:

[<EntryPoint>]
let main a=
 let rec f r:int=
  let b=a.[r].IndexOf"1011"
  if(b>0)then if(a.[r+1].[b..b+3].Equals"1110"&&a.[r+2].[b..b+3].Equals"1110"&&a.[r+3].[b..b+3].Equals"1111")then r else f(r+1)
  else f(r+1)
 printfn"%d%d"(a.[f 0].IndexOf"1011")(f 0);0

这不是最优雅的解决方案,但我想保留字符串,所以这就是我的做法。我几乎把它变成了单行,使用管道更小,但是double if块却让我无法解决。好吧!

我也考虑过将Karl的答案移植到F#中,因为它是一个很好的方法,并且可能仍然很有趣地将其用作另一种方法,但是我想坚持用这个方法来与众不同。


1

Dyalog APL,29 27字节

以12x12二进制数组作为用户输入,并以相反的顺序返回坐标,索引从1开始。

感谢@Adám节省了很多字节。-2字节,因为我很笨,无缘无故地将所有内容留在了函数中。

0~⍨∊{⍵×⍳⍴⍵}⎕⍷⍨~0 8 0 6⊤⍨4/2

替换~2 8 12∊⍨4 4⍴⍳16为保存2 15 7 15 9⊤⍨4/2。请注意,0~⍨∊{⍵×⍳⍴⍵}可以从16.0版开始替换(您的代码仅在Dyalog APL中有效)。
阿达姆,2013年

是的,Dyalog具有与GNU不同的字符。或者是别的什么?
扎卡里

好吧,从v16版本开始,我一直无法找到GNUAPL原语的列表。
2013年

我已经运行了GNU APL,主要只是代码点差异。
扎卡里

从我所注意到的。
扎卡里

0

元素,130字节

_144'{)"1-+2:';}144'["1-+19:~?1+~?!2+~?3+~?12+~?13+~?14+~?15+~?!24+~?25+~?26+~?27+~?!36+~?37+~?38+~?39+~?16'[&][12%2:`\ `-+12/`]']

在线尝试!

将输入作为1和0的一长串,没有任何定界符。输出3 4((从0开始的索引)。

通过将输入数据放入“数组”(基本上是带有整数键的字典)中,然后针对每个可能的起始值,对特定偏移量的位进行测试(在非常费力的过程中对所有16位进行测试),即可实现这一点。

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.