Match coordinates with their values

10

1

Given 3 input items, a list of coordinate pairs, a 2D string, and a single-character string, output whether the character at each coordinate of the 2D string is equal to the single character. You can take the input in any order and the coordinates may be 1-indexed.

You may take the 2D string as a 2D list, a list of lines, or a 2D string.

Example: (0,0), "#_\n__", "#" -> True

The string is

#_
__

The char at the coordinate (0,0) (from the top left) is #. This is equal to the third input item, #, so you output True (or any truthy value)

Example: [(0,0), (1,1)], "#_\n_#", "#" -> True

The string is

#_
_#

The characters at the coordinates of (0,0) and (1,1) are both #, so the output is true.

The output is only true iff every coordinate matches a hash. Not every hash has to have a matching coordinate though. If there are no occurrences of the single char (# in some of the test cases) in the 2D string, the output is still just falsy.

You can assume the coordinates will always be within the bounds of the 2D string.

More test cases: (I put the single char second for ease of readability)

[(0,0), (2,1), (3,0)], #

#_##
#_##

True


[(0,0), (1,1), (3,0)], #

#_##
#_##

False (1,1 is not a hash)



[(1,1)], a

#a##
#a##

True


[(4, 0), (3, 0), (2, 0), (1, 0), (0, 0), (0, 1), (0, 2), (0, 3), (1, 3), (2, 3), (2, 2), (3, 2), (4, 2), (4, 3)], ' '


 ####
 #   
   # 

True

Note the last test case uses spaces as the single char string, and hashes around the spaces.

Related. (inverse of this challenge)

Rɪᴋᴇʀ

Posted 2017-01-14T15:44:58.923

Reputation: 7 410

Can we assume that input is a 2d array instead of using "\n"? – rahnema1 – 2017-01-14T15:54:29.063

@rahnema1 not a 2D array, but an array/list of lines yes. – Rɪᴋᴇʀ – 2017-01-14T15:54:56.253

@EasterlyIrk I believe this falls into the category Cumbersome I/O formats

– JungHwan Min – 2017-01-14T16:06:44.037

In your first example coordinates are in the format (row, column) but in the last example coordinates are in the format (column, row) . – rahnema1 – 2017-01-14T16:07:47.857

@JungHwanMin no, because it trivializes the challenge a bit more. – Rɪᴋᴇʀ – 2017-01-14T16:09:01.447

@rahnema1 ah, thanks for catching that. For reference, you may use either coordinate input method. – Rɪᴋᴇʀ – 2017-01-14T16:09:29.613

@EasterlyIrk Some languages treat strings like an array of chars. Wouldn't that make this challenge trivial already? – JungHwan Min – 2017-01-14T16:10:30.270

1Can the coordinates be 1-indexed? – user41805 – 2017-01-14T16:14:01.317

@KritixiLithos yes, they can. – Rɪᴋᴇʀ – 2017-01-14T16:18:55.523

@JungHwanMin yeah, it would. I don't want to trivialize it any more though. – Rɪᴋᴇʀ – 2017-01-14T16:19:13.003

@EasterlyIrk my point is that there is no difference between allowing 2D arrays and not allowing it because there is no distinction in some languages. – JungHwan Min – 2017-01-14T16:20:54.210

@JungHwanMin eh, I guess I'll allow it. – Rɪᴋᴇʀ – 2017-01-14T16:21:44.040

I'm assuming that the "list of coordinate pairs" can be understood as a 2×N matrix, where N is the number of coordinates. Can you confirm? – Luis Mendo – 2017-01-15T03:09:45.367

@Luis yes that's correct – Rɪᴋᴇʀ – 2017-01-15T03:10:23.307

@EasterlyIrk Thanks for clarifying. Also, can we assume the list / matrix will not be empty? – Luis Mendo – 2017-01-15T03:13:17.957

@Luis yeah, sure – Rɪᴋᴇʀ – 2017-01-15T03:13:53.727

Answers

1

Dyalog APL, 8 bytes

Prompts for list of coordinate pairs (row,column), then 2D array, then character.

∧/⎕=⎕[⎕]

[⎕] prompt for coordinates and use them to scatter pick from

prompted input (2D array)

= compare the selected elements to

input (the character)

∧/ check if all are true (AND-reduction)

Test cases (⎕IO←0 to match examples, but this is not necessary):

First example

Second example

Third example

Fourth example

Fifth example

Adám

Posted 2017-01-14T15:44:58.923

Reputation: 37 779

6

Python, 39 bytes

Takes the inputs:

  1. a list of (x, y) integer coordinates
  2. b list of strings
  3. c single character string

lambda a,b,c:{b[y][x]for x,y in a}=={c}

ovs

Posted 2017-01-14T15:44:58.923

Reputation: 21 408

2On this site, you don't need to name your functions. You can remove the f=. Welcome to PPCG! – Rɪᴋᴇʀ – 2017-01-14T20:48:06.717

Welcome to PPCG, nice first answer! – FlipTack – 2017-01-15T11:12:23.533

4

Octave, 45 38 29 bytes

@(A,B,C)A(1+B*[rows(A);1])==C

A function that takes a 2D array of chars as A and coordinates(0 based) B as a two column matrix of [col row] and the matching character as C. The two element coordinates(using matrix multiplication) converted to linear index.

Note: Previous answer that made use of sparse matrix was wrong.

Other Contributors:

Stewie Griffin for saving 5 bytes noting that [0 1 0] can be regarded as false value!!

Luis Mendo for saving 2 bytes that ~0 == true and notification about sparse matrix.

Try it Online

rahnema1

Posted 2017-01-14T15:44:58.923

Reputation: 5 435

2Nice :) You can skip all and save three bytes. 1 1 1 is true, and 1 0 1 is false in Octave, so it should be OK. :) – Stewie Griffin – 2017-01-14T21:22:35.813

1

Great approach! I like how this exploits the fact that logical indices need not have the same size as the indexed array

– Luis Mendo – 2017-01-15T02:52:59.817

1In addition to Stewie's suggestion, you can replace true by ~0 to save 2 bytes – Luis Mendo – 2017-01-15T03:00:58.823

@StewieGriffin Thanks it is really OK:) – rahnema1 – 2017-01-15T03:31:10.007

@LuisMendo Good point – rahnema1 – 2017-01-15T03:31:44.913

@LuisMendo It was my mistake for assuming that input format is [row col], so I flipped B in tio to work correctly, Thanks for notification – rahnema1 – 2017-01-15T04:00:13.457

@LuisMendo my answer based on sparse matrix was wrong (since it is not always correct to index a matrix with logical matrix of smaller dimensions! ) and consumed more bytes so I changed it – rahnema1 – 2017-01-15T11:01:39.480

Oh now I see the problem with the smaller logical mask. It linearizes – Luis Mendo – 2017-01-15T11:26:43.203

4

JavaScript (ES6), 37 bytes

Takes the inputs:

  1. a array of [x, y] integer coordinates
  2. s array of strings
  3. c single character string

(a,s,c)=>a.every(([x,y])=>s[y][x]==c)

George Reith

Posted 2017-01-14T15:44:58.923

Reputation: 2 424

3

Mathematica, 28 bytes

#3~Extract~#~MatchQ~{#2...}&

1-indexed. Due to how arrays are structured in Mathematica, the input coordinates must be reversed (i.e. (row, column))

Usage

#3~Extract~#~MatchQ~{#2...}&[{{1, 1}, {2, 3}, {1, 4}}, "#", {{"#", "_", "#", "#"}, {"#", "_", "#", "#"}}]

True

JungHwan Min

Posted 2017-01-14T15:44:58.923

Reputation: 13 290

2

Perl 6, 41 40 bytes

->\c,\h,\n{all map {n eq h[.[0];.[1]]},c}

->$_,\h,\n{all .map:{n eq h[.[0];.[1]]}}

Expects the 2D string as a 2D list.

Thanks to b2gills for -1 byte.

smls

Posted 2017-01-14T15:44:58.923

Reputation: 4 352

If you used $_ instead of \c you could use .map:{…} saving one byte – Brad Gilbert b2gills – 2017-01-14T21:10:39.877

@BradGilbertb2gills: Oh, I didn't realize the space was optional in .map: {…}. That's useful to know. Also, it's a shame that prefix || isn't implemented yet, it could make the inner lambda simply n eq h[||$_]... – smls – 2017-01-15T07:58:50.360

2

Haskell, 27 bytes

s!c=all(\(x,y)->s!!y!!x==c)

Usage example: ( ["#_##","#_##"] ! '#' ) [(0,0), (2,1), (3,0)] -> True.

nimi

Posted 2017-01-14T15:44:58.923

Reputation: 34 639

2

C#, 80 77 bytes

Saved 3 bytes, thanks to pinkfloydx33

a=>b=>c=>{foreach(var i in a){if(b[i[0]][i[1]]!=c){return 1<0;}}return 1>0;};

a is the pairs of coordinate, b is the list of lines, and c is the single-character string.

Horváth Dávid

Posted 2017-01-14T15:44:58.923

Reputation: 679

You can replace false with 1<0 and true with 1>0 and save 3 bytes. – pinkfloydx33 – 2017-01-15T09:16:04.920

2

Jelly, 10 bytes

ịṪ⁸ịḢð€Q⁼⁵

This only works as a full program. Input order is indices, string array, singleton string.

Try it online!

How it works

ịṪ⁸ịḢð€Q⁼⁵  Main link.
            Left argument:  P (array of coordinate pairs)
            Right argument: S (array of strings)
            Third argument: C (singleton string)

     ð€     Combine the links to the left into a dyadic chain and call it with each
            p = (x, y) in P as left argument and S as the right one.
ị             Unindex; retrieve the strings of S at indices x and y.
 Ṫ            Tail; yield s, the string of S at index y.
  ⁸ị          Unindex; retrieve the characters of s at indices x and y.
    Ḣ         Head; yield the character of s at index x.
       Q    Unique; deduplicate the resulting string/array of characters.
        ⁼⁵  Compare the result with the third argument.

Dennis

Posted 2017-01-14T15:44:58.923

Reputation: 196 637

1

Haskell, 72 63 bytes

c [] _ _ =1<2;c ((f,s):t) m n |n/=lines m!!s!!f=1>2|1>0=c t m n

Input of c [(0,0), (1,0), (3,0)] "#_##\n#_##" '#' Outputs False

Input c [(4, 0), (3, 0), (2, 0), (1, 0), (0, 0), (0, 1), (0, 2), (0, 3), (1, 3), (2, 3), (2, 2), (3, 2), (4, 2), (4, 3)] " \n ####\n # \n # " ' '

Output True

UnGolfed

checkfunc :: [(Int,Int)] -> String -> Char -> Bool
checkfunc [] _ _ = True
checkfunc (x:xs) string char | char /= ((lines string)!!(snd x))!!(fst x)= False  -- Checks first coordinates and returns False if no match
                             | otherwise = checkfunc xs string char --Otherwise iterate over remaining coordinate pairs

brander

Posted 2017-01-14T15:44:58.923

Reputation: 111

There is still unnecessary whitespace left: c[]_ _=1<2;c((f,s):t)m n|n/=lines m!!s!!f=1>2|1>0=c t m n – Laikoni – 2017-01-15T14:09:01.127

Also as you are doing boolean logic, the implicit conditional if n/=lines m!!s!!f then False else c t m n can be replaced by n/=lines m!!s!!f&&c t m n. – Laikoni – 2017-01-15T14:13:15.967

Finally, as the OP says You may take the 2D string as a 2D list, a list of lines, or a 2D string. you can drop the lines and directly take a list of lines as input. – Laikoni – 2017-01-15T14:19:19.917

1

Scala, 68 bytes

def f(l:(Int,Int)*)(s:String*)(c:Char)=l forall{x=>s(x._2)(x._1)==c}

jaxad0127

Posted 2017-01-14T15:44:58.923

Reputation: 281

1

Clojure, 39 bytes

#(apply = %3(map(fn[[x y]]((%2 y)x))%))

Example (string input is a vec of vec of characters):

(def f #(apply = %3(map(fn[[x y]]((%2 y)x))%)))
(f [[0 0] [1 1] [3 0]] (mapv vec ["#_##" "#_##"]) \#)

NikoNyrh

Posted 2017-01-14T15:44:58.923

Reputation: 2 361