干し草の山で針を見つける


38

すべて同じ印刷可能なASCII文字で構成される少なくとも2x2のサイズの長方形の干し草が与えられた場合、異なる文字である針の位置(左上から数えて)を出力します。

たとえば、次のhaystackが入力された場合:

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

出力は、3,1インデックスがゼロの場合(このチャレンジで使用するもの)または4,2インデックスが1の場合です。

haystackは、印刷可能な任意のASCII文字で構成できます。

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

出力: 1,2

針は他の印刷可能なASCII文字になります。

jjjjjj
j@jjjj
jjjjjj

出力 1,1

コーナーに針を置くことも可能です:

Z8
88

出力 0,0

88
8Z

出力 1,1

または、針を端に置くには:

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

出力 9,1

規則と説明

  • 入力と出力は、任意の便利な方法で指定できます。これは、文字のリストのリスト、単一の文字列などとして入力を取得できることを意味します。
  • 結果をSTDOUTに出力するか、関数結果として返すことができます。提出物の中で、出力の順序を指定してください(つまり、チャレンジで使用される水平方向と垂直方向、またはその逆)。
  • 完全なプログラムまたは機能のいずれかが受け入れられます。
  • あなたはしない使用する文字を選択。それが課題です。
  • 干し草の山のサイズは少なくとも2x2であることが保証されているため、どちらが針であり、どちらが干し草であるかは明確です。
  • 入力に含まれる針は1つだけで、サイズは1文字だけです。
  • 標準的な抜け穴は禁止されています。
  • これはので、通常のゴルフルールがすべて適用され、最短のコード(バイト単位)が勝ちます。

推奨されるテストケース:(88\n8Zもちろん任意の2文字を使用)。
ケビンクルーッセン

入力を多次元配列として取得できますか?すなわち[['#'、 '#'、 '#'、 '#'、 '#']、['#'、 '#'、 '#'、 'N'、 '#']、['#' 、 '#'、 '#'、 '#'、 '#']、['#'、 '#'、 '#'、 '#'、 '#']];
640KB

2
@gwaugh文字のリストのリストが好きですか?はい、それで問題ありません(また、明示的にOKと呼ばれます)。
AdmBorkBork

3
入力を、改行と干し草の山の幅(または高さ)のない文字列のペアとして取得できますか?すなわち("########N###########", 5)
私の代名詞はmonicareinstate

3
@someoneはい、実際の定足数はありませんが、許可されるべきだと思います。
AdmBorkBork

回答:



9

Perl 641 38 37バイト

@nwellnhofのおかげで3バイト節約されました。

Jo Kingのおかげで1バイト節約されました。

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

オンラインでお試しください!

説明

入力を文字のリストのリストとして受け取り、針のゼロベースのXおよびY座標を含む長さ2のリストを返します。

{[+] ^∞ Z* !<<.&[Z~~]}入力と転置にブロックを適用することで機能します。.&[Z~~]引数のすべての列をTrue調べ、すべての要素が同じ場合に戻りますFalse。それ以外の場合に戻ります。次に、すべての値を否定します(したがって、列ごとに1つのブールを持つリストがあり、ブールは「その列に針はありますか?」という質問に答えます)、要素ごとにシーケンス0,1,2、を掛けます。 ..(True = 1およびFalse = 0)およびリストを合計するため、ブロック全体の結果は、針が見つかった列の0から始まる番号になります。

Nwellnhofのより良いアプローチ、Perl 6、34 バイト

{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]は、ダブルマップよりも2バイト短くなりました。これは、次のようなリストにキャストする必要があるためです。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入力として、改行と幅(または高さ)なしの文字列を使用します。

  • -5バイト、chr()呼び出しの削除、@ Titusの小道具
  • 入力を2つの関数引数として-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の2番目のパラメーターが整数の場合、ASCIIコードとして解釈されます。-> -5バイト。2)2つの関数パラメーター$s,$wにより、さらに9バイトを節約できます。
タイタス

@Titus、素晴らしいchr()を削除します。THX!func paramsは私にも発生しました。入力要求のafowlを実行したくありませんでした。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..を完全に忘れてしまった
Kevin Cruijssen

@KevinCruijssen:ええ。私はこれまで使ったことはないと思います .mが、どこかで見たことがあると確信していました:)
Emigna

5

Python 3 + NumPy75 66バイト

@ASCII のみのおかげで-9バイト

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

オンラインでお試しください!

これは、入力がNumPy配列であることを前提としています。出力はインデックスがゼロで、最初は垂直、次に水平です。

それはからの入力に変換charするint、その後は、干し草の山の文字となり、配列の中央値を計算します。配列からそれを差し引くと、針が唯一の非ゼロ要素になります。最後に、その要素のインデックスを返しnumpy.where()ます。


1
入力はASCII(つまり、1バイトに収まる)になることがわかっているのでuint8、1バイト少なくしてみませんか?
ドラコニス

1
numpyは通常のPythonディストリビューションに含まれていないため、言語はここで「Python 3 + numpy」である必要があります
ASCIIのみ

@Draconisは実際には私の計画でしたが、正しいuint8ASCIIコードの間にゼロが導入されました。これは、Python3が文字列の標準入力形式としてUnicodeを使用しているためだと思います。
hbaderts


1
結局のところ、ソリューションに基づいているだけでなく、通常はnumpyを使用しません。プラス、それは解決策は、すべてのソリューションは、公開されていることを考えると、とにかく非常に似ているかもしれないとちょっとやむを得ないだ、これは比較的容易な課題である
ASCIIのみ


4

ゼリー、4 バイト

Maybe this could've just been a comment for Mr. Xcoder it is pretty similar...

ŒĠEƇ

A monadic link accepting the matrix of characters which yields a list of one item, the 1-indexed (row, column) co-ordinate from top-left.
(...As a full program given an argument formatted such that parsing results in a list of lists of characters -- that is a list of strings in Python format -- the single coordinate is printed.)

Try it online!

How?

ŒĠ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
Well... this seems borderline, since the is clever.
Erik the Outgolfer

4

JavaScript (ES6), 55 bytes

Takes input as (s)(w), where s is a string and w is the width of the matrix. Returns [x,y].

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

Try it online!


JavaScript (ES6),  65  64 bytes

Saved 1 byte thanks to @Neil

Takes input as a matrix of characters. Returns [x,y].

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

Try it online!

How?

We look for the first character c located at (x,y) which does not appear anywhere in another row r[Y]. We can perform this test on any row, as long as Yy. Because the input matrix is guaranteed to be at least 2×2, we can simply use Y=0 if y is odd or Y=1 if y is even.


1
~y&1 saves a byte over y&1^1.
Neil

4

Java 8, 132 111 bytes

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 bytes (and -13 more implicitly) thanks to @dana.

Input as character-matrix.

Try it online.

Explanation:

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 - the final return statement should never get hit. There might be a better way to keep the outer loop going?
dana

@dana Thanks! As for: "There might be a better way to keep the outer loop going?", there certainly is; just removing it so it becomes an infinite loop. And then the return""; is unreachable and can be removed as well. :D So -21 bytes thanks to you.
Kevin Cruijssen

Interesting... I had tried removing the outer loop condition and was getting an unreachable code error. Didn't know that removing the final return was the fix.
dana

What exactly does the --> operator do in the inner loop? I was trying to find the java docs for that syntax but couldnt find anything
KBusc

1
@KBusc It's two operators: i-- and >. :) See this SO answer for more info. So the i > 0 is executed first, checking if i is larger than 0. And then i is decreased by 1 with i--, before it enters the body of the loop.
Kevin Cruijssen

3

MATL, 12 8 bytes

tX:XM-&f

Try it online!

Using the mode function as the majority-detector. Returns 1-based indices.

 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 characters thanks to @LuisMendo


1
@LuisMendo Thanks. I don't think I knew about the 2 output version of find, even in MATLAB. (Hi, btw!)
sundar - Reinstate Monica

3

Wolfram Language 37 58 bytes

My earlier entry did not correctly handle the case where the "odd character out" was at the upper left corner of the matrix. This does.

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

Counts@Flatten@# lists how many of each character are in the array, #.

TakeSmallest[...,1] returns the least frequent count, in the form of an association rule such as <| "Z"->1|>

Keys...[[1]] returns the "key" to the only item in the association, that of the least used character. ("Z" in the present case)

#~Position~... returns then position of the key in the original matrix, #.


3

Perl 5 -p00, 52 45 bytes

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

45 bytes

52 bytes

How

  • -p00 : like -n but also print, paragraph mode
  • /^(.)(\1* )*(\1*)|^/ : matches either
    • from start $1: first character, $2: repetition (not used), $3: characters before the "needle" in the line, $& whole match
    • or null string (position 0) no capture.
  • $_= : to assign the default input/argument variable
  • so $&=~y/ // the number of newlines of $&
  • .$". : concatenate with $" (space character by default) and concatenate
  • length$3 : the length of $3

3

R 42 bytes

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

Try it online!

Input: a haystack matrix m

Output: (row,col) vector - index starting at 1


1
Nice job, and welcome to PPCG! I believe this is 42 bytes, since the f= can be omitted from the byte count, but not the function(m)=.
BLT

@BLT I wasn't sure about that but thanks for the heads up :)
niko




2

PowerShell, 107 98 82 77 bytes

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

Try it online!

Takes a splatted string with LFs. Returns zero-indexed location x,y. Unrolled:

$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

Retina 0.8.2, 41 bytes

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

Try it online! 0-indexed. Explanation:

s`

Allow . to match newlines. This costs 3 bytes (3rd byte is the ? before the ) but saves 6 bytes.

(?=(.)+\1)

Look ahead for two identical characters. \1 then becomes the hay.

(.*?¶)*

Count the number of newlines before the needle.

(.*)

Capture the hay to the left of the needle.

(?!\1|¶)

Ensure that the needle isn't hay or a newline.

.+

Match the rest of the hay so that the result replaces it.

$.3,$#2

Output the width of the left hay and the number of newlines.


1

C# (Visual C# Interactive Compiler), 82 bytes

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

Thanks to dana for shaving off 6 bytes!

Try it online!

Old solution, 106 bytes

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);}

Both take input as a string and an integer specifying the amount of columns.

Try it online!


@dana never knew that Enumerable.Last() accepted a delegate, thanks
Embodiment of Ignorance

1

Java 8, 104 Bytes

(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;}

Input is array of char, and integer indicating row width.

Output is zero-based, vertical then horizontal (i.e., row number then column number)

Explanation:

(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 bytes

Complete rewrite taking input as concatenated string, width:

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

Try it online!


Original answer:

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

EDIT: Saved 4 bytes by swapping linebreak/indent for semicolons. Saved another 4 bytes by using divmod(thanks @JonathanFrech).

Try it online!

I know this could be a lot shorter, but I just wanted to try an approach around this dict comprehension.


1
Using divmod would save five bytes.
Jonathan Frech

0

MATL, 11 bytes

tX:YmyYk-&f

Output is row, then column; 1-based.

Try it online!

Explanation

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 bytes

.Dxz-zh.-z{z

Takes input as the length of the row and the input without lines and outputs as [row, column].
Try it here

Explanation

.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.

Old approach

mxJmt{kdeSJ.TB

Try it here

Explanation

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

Charcoal, 40 bytes

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

Try it online! Link is to verbose version of code. I must be doing something wrong because this is almost as long as the Retina answer. Explanation:

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

Check whether the second character in the first string is also the first character, and take the first character of the first string if so otherwise the first character of the second string if not. This is then the hay.

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

Keep reading strings until a string whose hay is less than its length is found.

I⌕Eθ⁼ιζ⁰,ILυ

Output the position of the mismatching element and then the number of strings previously read.


0

MATLAB, 68 22 bytes

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

If I could exclude any one case, such as [1,1] in this solution, I could have saved several bytes.

Updated solution:

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

Thanks to @sundar for helping me with the special case problem and saving 42 bytes! Also, thanks to @Luis_Mendo for the suggestions and saving me another 2 bytes!


I think you can get rid of the check for [1,1] case by using mode(v(:)) instead of v(1).
sundar - Reinstate Monica

You need to wrap your code so that it is a full program or a function; you cannot assume that the input is in a variable v. Also, you can probably replace ~= by -, and remove the final ;
Luis Mendo

0

Röda, 81 bytes

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

Try it online!

Takes input as a string containing newline-terminated lines. Returns a stream containing 0-indexed horizontal and vertical indexes.

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.