在大海捞针中找针


38

给定一个矩形干草堆,该干草堆的大小至少为2x2,由所有相同的可打印ASCII字符组成,请输出针的位置(从左上数起),该针为不同的字符。

例如,如果输入以下干草堆:

#####
###N#
#####
#####

输出应该是3,1零索引时(我将在此挑战中使用的东西)或4,2单索引时。

干草堆可以由任何可打印的ASCII字符组成:

^^^
^^^
^N^
^^^
^^^
^^^

输出: 1,2

针将是任何其他可打印的ASCII字符:

jjjjjj
j@jjjj
jjjjjj

输出 1,1

也可以在拐角处插入针头:

Z8
88

输出 0,0

88
8Z

输出 1,1

或将针头放在边缘:

>>>>>>>>>>
>>>>>>>>>:
>>>>>>>>>>

输出 9,1

规则和说明

  • 输入和输出可以通过任何方便的方法给出。这意味着您可以将输入作为字符列表,单个字符串等。
  • 您可以将结果打印到STDOUT或将其作为函数结果返回。请在您的提交中说明输出的顺序(即在挑战中使用的是水平然后是垂直,反之亦然)。
  • 完整的程序或功能都是可以接受的。
  • 不会选择要使用的字符。那就是挑战。
  • 干草堆的大小至少要保证为2x2,因此毫无疑问,哪个是针,哪个是干草。
  • 输入中只有一根针,而且只有一个字符。
  • 禁止出现标准漏洞
  • 这是因此所有常见的高​​尔夫规则都适用,并且最短的代码(以字节为单位)获胜。

建议的测试用例:(88\n8Z当然有两个字符)。
Kevin Cruijssen

我们可以将输入作为多维数组吗?即[['#','#','#','#','#'],['#','#','#','N','#'],['#' ,'#','#','#','#'],['#','#','#','#','#']]];
640KB

2
@gwaugh像字符列表一样?是的,这很好(并且明确称为OK)。
AdmBorkBork

3
我们可以将输入作为一对没有换行符和干草堆的宽度(或高度)的字符串吗?即("########N###########", 5)
某人

3
@someone是的,尽管它没有真正的法定人数,但我认为应该允许这样做。
AdmBorkBork

Answers:



9

Perl 641 38 37字节

@nwellnhof节省了3个字节。

感谢Jo King,节省了1个字节。

{map {[+] ^∞Z*!<<.&[Z~~]},$_,.&[Z]}

在线尝试!

说明

它将输入作为字符列表,并返回长度2的列表,其中包含针的从零开始的X和Y坐标。

它通过将块{[+] ^∞ Z* !<<.&[Z~~]}应用于输入及其转置来工作。.&[Z~~]遍历参数的所有列,True如果所有元素都相同,False则返回,否则返回。然后,我们取反所有值(因此,我们有一个列表,其中每列有一个布尔值,布尔值回答了问题“该列中的针头是?”),将它们逐个元素地乘以序列0,1,2,。 ..(True = 1False = 0)并对列表求和,因此整个块的结果是从零开始的针所在列的编号。

Nwellnhof的更好方法, Perl个字节

{map *.first(:k,*.Set>1),.&[Z],$_}

在线尝试!

说明

通常使用相同的方法,只是更有效。它仍然在数组及其转置上使用一个块,但是现在该块将所有转换为Sets并检查元素数。first然后,该函数将给出:k包含多个元素的第一行的索引(由于)。因此,需要交换$_和的顺序.&[Z]


不错的方法!34字节first(:k)Set.&[Z]
nwellnhof

@nwellnhof,做得很好。您基本上找到了我想找到的东西,但没有做到:-)。(我也不知道你会写.&[Z]。)
Ramillies

通常,.&[op]它看起来并不等效,[op] $_但是Z出于某种原因它可以使用。
nwellnhof

@JoKing,谢谢!
拉米利斯

9

Python 2,57字节

lambda m:[map(len,map(set,a)).index(2)for a in zip(*m),m]

在线尝试!


Python 3的端口可以是62个字节

lambda m:[[len(set(v))for v in a].index(2)for a in(zip(*m),m)]

列表理解 [len(set(v))for v in a]现在比double映射短两个字节,因为它需要转换为类似的列表list(map(len,map(set,a)))

在线尝试!


6

Brachylog,20个字节

c≡ᵍ∋Ȯ&;I∋₎;J∋₎gȮ∧I;J

在线尝试!

输出[I,J],其中I行索引和J列索引均为0索引。

太长了,但是在Brachylog中获取索引通常非常冗长。

说明

c                       Concatenate the Input into a single string
 ≡ᵍ                     Group identical characters together
   ∋Ȯ                   Ȯ is a list of One element, which is the needle character
     &;I∋₎              Take the Ith row of the Input
          ;J∋₎          Take the Jth character of the Ith row
              gȮ        That character, when wrapped in a list, is Ȯ
                ∧I;J    The output is the list [I,J]

6

的PHP99 85字节

使用不带换行符的字符串和宽度(或高度)('########N###########', 5)作为输入。

  • 通过删除chr()调用-@ Titus的支持,减少-5个字节
  • 通过将输入作为两个函数args来获得-9个字节,也支持@Titus
function($a,$l){return[($p=strpos($a,array_flip(count_chars($a,1))[1]))%$l,$p/$l|0];}

在线尝试!

取消高尔夫:

function need_hay( $a, $l ) {

    // identify the "needle" by counting the chars and 
    // looking for the char with exactly 1 occurrence
    // note: this is 1 byte shorter than using array_search()
    $n = array_flip( count_chars( $a, 1 ) )[1];

    // find the location in the input string
    $p = strpos( $a, $n );

    // row is location divided by row length, rounded down
    $r = floor( $p / $l );

    // column is remainder of location divided by row length
    $c = $p % $l;

    return array( $c, $r );

}

输出:

#####
###N#
#####
#####
[3,1]

^^^
^^^
^N^
^^^
^^^
^^^
[1,2]

jjjjjj
j@jjjj
jjjjjj
[1,1]

1
1)不需要chr:如果strpos的第二个参数是整数,它将被解释为ASCII码。-> -5个字节。2)两个功能参数$s,$w可以节省另外9个字节。
泰特斯

@Titus,删除出色的chr()。谢谢!func参数也确实发生在我身上,我只是不想运行大量的输入请求。我会澄清w / OP。
640KB

5

05AB1E9 6字节

保存了3个字节的切换输入格式。

输入被视为字符串和行长。
输出是表单的从零开始的列表[y, x]

D.mks‰

在线尝试! 或作为测试套件

说明

D           # duplicate the input string
 .m         # get the least frequent character
   k        # get its index in the string
    s       # swap the row length to the top of the stack
     ‰      # divmod the index of the least frequent char with the row length

亲爱的你打败我了 正在寻找答案。刚刚完成了一个13轮游戏。但是您的方法更好,因此改为+1。:)完全忘了.m..
凯文·克鲁伊森

@KevinCruijssen:是的。我认为我以前从未用过 .m,但是我可以肯定地在某个时候看过它:)
Emigna

5

Python 3 + NumPy75 66字节

-9个字节(仅使用@ASCII)

lambda x:where(x.view('i')-median(x.view('i')))
from numpy import*

在线尝试!

假设输入是NumPy数组。输出为零索引,首先是垂直,然后是水平。

它将输入从转换为charint然后计算数组的中位数,这将是干草堆字符。我们从数组中减去该值,这使指针成为唯一的非零元素。最后,使用返回该元素的索引numpy.where()


1
既然您知道输入将是ASCII(即适合一个字节),为什么uint8不少使用一个字节呢?
Draconis

1
这里的语言必须是“ Python 3 + numpy”,因为正常的Python发行版不包含numpy
仅使用ASCII

@Draconis实际上是我的计划,但是在正确的uint8ASCII码之间引入了零。我认为这是因为Python3使用Unicode作为字符串的标准输入格式。
hbaderts


1
很好,毕竟这不仅基于您的解决方案,而且我通常也不会使用numpy。另外,考虑到所有解决方案都是公开的这是不可避免的,无论如何解决方案都非常相似这是一个相对容易的挑战
(仅ASCII)

4

果冻,5个字节

输出[高度,宽度](1索引)。

ŒĠLÐṂ

在线尝试!

ŒĠLÐṂ – Monadic link / Full program. Takes a list of strings M as input.
ŒĠ    – Group the multidimensional indices by their values (treating M as a matrix).
  LÐṂ – And retrieve the shortest group of indices (those of the unique character).

果冻,5个字节

ŒĠḊÐḟ

在线尝试!


4

果冻,4 字节

也许这只是对Xcoder的评论,它非常相似...

ŒĠEƇ

一个接受字符矩阵的单子链接,它产生一个项目列表,该列表由左上角的1​​索引(行,列)坐标组成。
(...作为一个完整的程序,给定一个参数,该参数的格式设置为使得解析产生一个字符列表列表-即Python格式的字符串列表-将打印出单个坐标。)

在线尝试!

怎么样?

ŒĠEƇ - Link: matrix, M
ŒĠ   - multi-dimensional indices grouped by Value
     -  ...due to the 2*2 minimum size and one needle this will be a list of two lists one
     -     of which will have length one (the needle coordinates as a pair) and the other
     -     containing all other coordinates as pairs
   Ƈ - filter keeping those for which this is truthy:
  E  -   all equal?
     -   ... 1 for the list of length 1, 0 for the list of at least 3 non-equal coordinates

1
好吧...这似乎是临界点,因为它很聪明。
Outgolfer的埃里克(Erik)

4

JavaScript(ES6),55个字节

swsw[Xÿ]

s=>w=>[(i=s.indexOf(/(.)\1+(.)/.exec(s+s)[2]))%w,i/w|0]

在线尝试!


JavaScript(ES6), 65  64字节

@Neil节省了1个字节

[Xÿ]

m=>m.some((r,y)=>r.some((c,x)=>!m[p=[x,y],~y&1].includes(c)))&&p

在线尝试!

怎么样?

CXÿ[R[ÿ]ÿÿ2×2ÿ=0ÿÿ=1个ÿ


1
~y&1保存一个字节y&1^1
尼尔

4

爪哇8,132个 111字节

m->{int c=m[0][0],i=0,j;for(c=m[1][0]!=c?m[1][1]:c;;i++)for(j=m[i].length;j-->0;)if(m[i][j]!=c)return i+","+j;}

-8个字节(暗含-13个字节)@dana

输入为字符矩阵。

在线尝试。

说明:

m->{                    // Method with char-matrix parameter and String return-type
  int c=m[0][0],        //  Character to check, starting at the one at position 0,0
      i=0,j;            //  Index integers
  for(c=m[1][0]!=c?     //  If the second character does not equal the first:
         m[1][1]        //   Use the character at position 1,1 instead
        :c;             //  Else: keep the character the same
      ;i++)             //  Loop `i` from 0 indefinitely upwards:
    for(j=m[i].length;j-->0;)
                        //   Inner loop `j` in the range (amount_of_columns, 0]:
      if(m[i][j]!=c)    //    If the `i,j`'th character doesn't equal our character to check:
        return i+","+j;}//     Return `i,j` as result

1
124-最终return声明永远都不会受到打击。可能有更好的方法来保持外循环运行?
dana

@dana谢谢!至于:“ 有没有更好的办法让外循环继续下去? ”,当然有;只是删除它,使其成为无限循环。然后return"";无法访问,也可以将其删除。:D所以-21个字节感谢您。
Kevin Cruijssen

有趣的...我曾尝试删除外循环条件,但出现unreachable code错误。不知道删除决赛return是解决办法。
dana

->运算符在内部循环中到底做什么?我试图为该语法找到Java文档,但找不到任何内容
KBusc

1
@KBusc这是两个运算符:i-->。:) 有关更多信息,请参见此SO答案。因此,i > 0首先执行,检查是否i大于0。然后在进入循环主体之前,使用将该i值减1 i--
凯文·克鲁伊森

3

MATL12 8字节

tX:XM-&f

在线尝试!

使用该mode功能作为多数检测器。返回从1开始的索引。

 t           % duplicate the input
  X:         % turn the copy into a linear array
    XM       % find the arithmetic mode of that (the 'haystack' character)
      -      % Subtract that from the original input
       &f    % find the position of the non-zero value in that result

-4个字符,感谢@LuisMendo


1
@LuisMendo谢谢。我不知道find即使在MATLAB中也知道2的输出版本。(嗨,顺便说一句!)
sundar-恢复莫妮卡

3

Wolfram语言37 58字节

我之前的文章没有正确处理“奇数字符输出”在矩阵的左上角的情况。确实如此。

#~Position~Keys[TakeSmallest[Counts@Flatten@#,1]][[1]]&

Counts@Flatten@#列出数组中每个字符的数量#

TakeSmallest[...,1] 以关联规则的形式返回最不频繁的计数,例如 <| "Z"->1|>

Keys...[[1]]将“键”返回到关联中的唯一项,即最少使用的字符。(在当前情况下为“ Z”)

#~Position~...然后返回键在原始矩阵中的位置#


3

Perl的5 -p0052 45字节

/^(.)(\1*
)*(\1*)|^/;$_=$&=~y/
//.$".length$3

45字节

52个字节

怎么样

  • -p00 : 喜欢 -n但也可以打印,段落模式
  • /^(.)(\1* )*(\1*)|^/ :匹配
    • 从头开始$1:第一个字符,$2:重复(未使用)$3,:该行中“针”之前的字符,$&完整匹配
    • 或null字符串(位置0)没有捕获。
  • $_= :分配默认输入/参数变量
  • 所以$&=~y/ //换行的数量$&
  • .$".:与$"(默认情况下为空格字符)连接并连接
  • length$3 :的长度 $3

3

R 42字节

function(m)which(ave(m,m,FUN=length)==1,T)

在线尝试!

输入:干草堆矩阵m

输出: (row,col)向量-索引始于1


1
干得好,欢迎来到PPCG!我相信这是42个字节,因为f=可以从字节数中省略,但不能从中删除function(m)=
BLT

@BLT我不确定,但是感谢大家的注意:)
Niko




2

PowerShell107 98 82 77字节

$l=@{}
$args|%{if($_-10){$l.$_+=$x++,+$y}else{$x=0;++$y}}
$l|% v*|? c*t -eq 2

在线尝试!

带有LF的splatted字符串。返回零索引位置x,y。展开:

$locations=@{}                      # make a hashtable. key=char, value=location array
$args|%{
    if($_-10){                      # if current char is not LF
        $locations.$_+=$x++,+$y     # add $x,$y to hashtable value and move $x to next pos
    }else{
        $x=0;++$y                   # move $x,$y to next line
    }
}
$locations|% Values|? Count -eq 2   # find and output location array with 2 elements (x,y)

1

Python 3,93字节

def f(s):x=s.find("\n")+1;return[(i%x,i//x)for i,c in enumerate(s)if s.count(c)<2and" "<c][0]

在线尝试!

输入被视为多行字符串。输出为0索引



1

视网膜0.8.2,41字节

s`(?=(.)+\1)(.*?¶)*(.*)(?!\1|¶).+
$.3,$#2

在线尝试!0索引。说明:

s`

允许.匹配换行符。这将花费3个字节(第3个字节是?之前的),但节省6个字节。

(?=(.)+\1)

向前看两个相同的字符。\1然后变成干草。

(.*?¶)*

在换针前计算换行符的数量。

(.*)

捕获针头左侧的干草。

(?!\1|¶)

确保针头不是干草或换行符。

.+

匹配其余的干草,以便结果代替它。

$.3,$#2

输出左干草的宽度和换行符的数量。


1

C#(Visual C#交互式编译器),82字节

x=>w=>{int y=x.IndexOf(x.GroupBy(c=>c).Last(g=>g.Count()<2).Key);return(y%w,y/w);}

感谢dana削减了6个字节!

在线尝试!

旧解决方案,106字节

n=>m=>{var z=n.Distinct();int d=n.IndexOf(n.Count(c=>c==z.First())>1?z.Last():z.First());return(d%m,d/m);}

两者都将输入作为字符串和整数来指定列数。

在线尝试!


@dana从不知道Enumerable.Last()接受了一位代表,谢谢
无知的体现

1

Java 8,104字节

(x,w)->{int i=0,p=x.length;for(;i<p;i++)if(x[i]!=x[(i+1)%p]&&x[i]!=x[(i+2)%p])break;return i/w+","+i%w;}

输入是char数组,整数表示行宽。

输出是从零开始的,垂直然后是水平(即行号然后列号)

说明:

(x,w)->{
    int i=0, p=x.length;
    for (;i<p;i++)          //iterate through characters in x
      if (x[i]!=x[(i+1)%p] && x[i]!=x[(i+2)%p])    //compare x[i] with the two subsequent characters in array, wrapping around if necessary
        break;
    return i/w+","+i%w;}  //return row number then column number, zero-based

1

Python 3中93个 89 85 58字节

完成重写,输入为concatenated string, width

lambda g,w:divmod(g.index({g.count(c):c for c in g}[1]),w)

在线尝试!


原始答案:

def k(g):t=''.join(g);return divmod(t.index({t.count(c):c for c in t}[1]),len(g[0]))

编辑:通过换行符/缩进为分号节省了4个字节。使用divmod(感谢@JonathanFrech)保存了另外4个字节。

在线尝试!

我知道这可能会短很多,但是我只是想尝试一种围绕这种dict理解的方法。


1
使用divmod将节省五个字节。
Jonathan Frech

0

MATL,11个字节

tX:YmyYk-&f

输出是行,然后是列;基于1。

在线尝试!

说明

t    % Implicit input. Duplicate
X:   % Linearize into a column
Ym   % Compute mean (characters are converted to ASCII codes)
y    % Duplicate from below: pushes input again
Yk   % Closest value: gives the input value that is closest to the mean
-    % Subtract, element-wise. Gives non-zero for the value farthest from the mean
&f   % Two-output find: gives row and column indices of nonzeros. Implicit display

0

Pyth,15 14 12字节

.Dxz-zh.-z{z

将输入作为行的长度,将没有行的输入作为输出,将输出作为[行,列]。
在这里尝试

说明

.Dxz-zh.-z{z
       .-z{z    Subtract one of each character from the input.
      h         Take the first.
    -z          Remove all instances from the input.
  xz            Find the remaining character in the input.
.D          Q   Take the result divmod the (implicit) length of the row.

旧方法

mxJmt{kdeSJ.TB

在这里尝试

说明

mxJmt{kdeSJ.TB
           .TBQ   Take the (implicit) input and its transpose...
m      d          ... and for each...
   mt{k           ... deduplicate each row...
 xJ     eSJ       ... and find the index of the largest.     

0

木炭,40字节

≔§⎇⌕θ§θ¹ηθ⁰ζSθW⁼№θζLθ«⊞υωSθ»I⌕Eθ⁼ιζ⁰,ILυ

在线尝试!链接是详细版本的代码。我一定做错了,因为这几乎和视网膜的答案一样长。说明:

≔§⎇⌕θ§θ¹ηθ⁰ζ

检查第一个字符串中的第二个字符是否也是第一个字符,如果是,则取第一个字符串的第一个字符;否则,取第二个字符串的第一个字符。这就是干草。

SθW⁼№θζLθ«⊞υωSθ»

继续阅读字符串,直到找到干草长度小于其长度的字符串。

I⌕Eθ⁼ιζ⁰,ILυ

输出不匹配元素的位置,然后输出先前读取的字符串数。


0

MATLAB, 68 22字节

[r,c]=find(v~=v(1));if size(r,1)>1 disp([1,1]);else disp([r,c]);end;

如果我可以排除任何一种情况(例如[1,1]在此解决方案中),则可以节省几个字节。

更新的解决方案

@(v)find(v-mode(v(:)))

感谢@sundar为我解决特殊情况问题并节省了42个字节!另外,感谢@Luis_Mendo的建议,还为我节省了2个字节!


我认为您可以[1,1]使用mode(v(:))代替来摆脱对情况的检查v(1)
sundar-恢复莫妮卡

您需要包装代码,使其成为完整的程序或函数;您不能假定输入在变量中v。此外,你也许可以取代~=通过-,并删除最后;
路易斯Mendo

0

Röda,81个字节

f a{i=indexOf;l=i("
",a)+1;chars a|sort|count|[[_2,_1]]|min|i _[1],a|[_%l,_1//l]}

在线尝试!

将输入作为包含换行符结束的行的字符串。返回包含0索引的水平和垂直索引的流。

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.