arrayscode-golfsearchrosetta-stone

Array Searching code challenge


Here's my (code golf) challenge: Take two arrays of bytes and determine if the second array is a substring of the first. If it is, output the index at which the contents of the second array appear in the first. If you do not find the second array in the first, then output -1.

Example Input: { 63, 101, 245, 215, 0 } { 245, 215 }

Expected Output: 2

Example Input 2: { 24, 55, 74, 3, 1 } { 24, 56, 74 }

Expected Output 2: -1

Edit: Someone has pointed out that the bool is redundant, so all your function has to do is return an int representing the index of the value or -1 if not found.


Solution

  • J

    37 characters for even more functionality than requested: it returns a list of all matching indices.

    I.@(([-:#@[{.>@])"_ 0(<@}."0 _~i.@#))
    

    Usage:

       NB. Give this function a name
       i =: I.@(([-:#@[{.>@])"_ 0(<@}."0 _~i.@#))
       NB. Test #1
       245 215 i 63 101 245 215 0
    2
       NB. Test #2 - no results
       24 56 74 i 24 55 74 3 1
    
       NB. Test #3: matches in multiple locations
       1 1 i 1 1 1 2 1 1 3
    0 1 4
       NB. Test #4: only exact substring matches
       1 2 i 0 1 2 3 1 0 2 1 2 0
    1 7
    

    NB. list[0 to end], list[1 to end], list[2 to end], ...
    <@}."0 _~i.@#
    
    NB. Does the LHS completely match the RHS (truncated to match LHS)?
    [-:#@[{.>@]
    
    NB. boolean list of match/no match
    ([-:#@[{.>@])"_ 0(<@}."0 _~i.@#)
    
    NB. indices of *true* elements
    I.@(([-:#@[{.>@])"_ 0(<@}."0 _~i.@#))