9
\$\begingroup\$

Take two inputs, a non-empty vector/list containing digits 1 and 2 and a string (no, you may not take 0/1 instead). The string will be one of the following (in lowercase, exactly as written below:

increasing
decreasing
ones
twos
all
none

If the string is ____ then you shall return the indices ___:

  • increasing ... where the list changes from 1 to 2 (every 2 that follows directly after a 1)
  • decreasing ... where the list changes from 2 to 1 (every 1 that follows directly after a 2)
  • ones ... of all digits that are 1
  • twos ... of all digits that are 2
  • all ... all the digits
  • none ... none of the digits. 0 is fine if the list is 1-indexed. A negative number is fine if the list is 0-indexed. You may also output an empty list or string.

Test cases:

These are 1-indexed. You may choose if you want 1-indexed or 0-indexed. The same vectors are used for different strings in the test cases.

--------------------------------
Vector:
1 1 2 2 2 1 2 2 1 1 2

String       - Output
increasing   - 3, 7, 11
decreasing   - 6, 9
ones         - 1, 2, 6, 9, 10 
twos         - 3, 4, 5, 7, 8, 11
all          - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
none         - 0 / []

------------------------------------
Vector:
1

String:
ones         - 1
all          - 1
decreasing / increasing / twos / none  - 0 / []

Scoring

As this is , the answer with the least bytes wins.

Explanations are encouraged!

\$\endgroup\$
  • \$\begingroup\$ @RobertoGraham yes. \$\endgroup\$ – Stewie Griffin Sep 29 '17 at 11:11
  • \$\begingroup\$ @KevinCruijssen You are a good guesser :) \$\endgroup\$ – Stewie Griffin Sep 29 '17 at 11:11
  • \$\begingroup\$ So far none of the answers seem to output a list as shown in the example. (ie, joined by ", " with no trailing delimiter). As the challenge text doesn't say how flexible the list can be, what's normally accepted for challenges like this? \$\endgroup\$ – Tahg Sep 29 '17 at 15:03
  • \$\begingroup\$ It's normally very flexible. As long as it's a list of numbers you're fine. \$\endgroup\$ – Stewie Griffin Sep 29 '17 at 15:59

14 Answers 14

7
\$\begingroup\$

JavaScript (Firefox 30-57), 74 73 bytes

(a,[s],i=0,p)=>[for(e of a)if({i:e>p,d:e<p,o:e<2,t:e>1,a:1}[p=e,i++,s])i]

Array comprehensions are a neat way of combining map and filter in one go. Edit: Saved 1 byte thanks to @edc65.

\$\endgroup\$
3
\$\begingroup\$

Python 2, 136 131 119 108 97 bytes

  • Saved five bytes; using a lambda function.
  • Saved twelve bytes thanks to TFeld; golfing two conditions.
  • Saved eleven bytes thanks to Mr. Xcoder; using enumerate() instead of range(len()).
  • Saved eleven bytes by using a list instead of a dictionary and using 0-indexing (as in TFeld's answer) and golfing "adinot".find(m[0]) to ord(m[0])/3-32.
lambda l,m:[j for j,k in enumerate(l)if[1,j*k<j*l[~-j],0,j*k>j*l[~-j],0,k<2,k>1][ord(m[0])/3-32]]

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Since the input is always 1or 2, you can change (l[j]>1)*(l[~-j]<2) to (l[j]>l[~-j]) for 119 bytes \$\endgroup\$ – TFeld Sep 29 '17 at 7:03
  • \$\begingroup\$ Also, you can save a byte by switching to 0-indexed \$\endgroup\$ – TFeld Sep 29 '17 at 7:06
  • \$\begingroup\$ @TFeld Thanks; though I think I will stick with 1-indexed. \$\endgroup\$ – Jonathan Frech Sep 29 '17 at 7:11
  • \$\begingroup\$ 108 bytes, using enumerate() \$\endgroup\$ – Mr. Xcoder Sep 29 '17 at 8:55
3
\$\begingroup\$

Python 2, 117 111 110 99 97 92 bytes

lambda l,t:[i for i,v in enumerate(l)if[l[i+i/~i]<v,0,v<2,v>1,1,l[i+i/~i]>v][ord(t[0])/3%7]]

Try it online!

0-indexed

Switched to using Jonathan's indexing, and golfed ord(m[0])/3-32 to ord(t[0])/3%7

\$\endgroup\$
  • \$\begingroup\$ You can golf l[i]==2 to l[i]>1. \$\endgroup\$ – Jonathan Frech Sep 29 '17 at 6:57
3
\$\begingroup\$

Haskell, 112 83 81 bytes

s%l=[i|(i,p,q)<-zip3[1..]l$l!!0:l,elem(s!!0,1<2)$zip"idota"[q<p,p<q,p<2,1<p,1<2]]

Try it online! Example usage: "increasing"%[1,1,2,1,2]. Results are 1-indexed.

Partly inspired by Lynn's Haskell answer.

\$\endgroup\$
2
\$\begingroup\$

MATL, 32 31 30 29 bytes

dQ~fQGqfOOGofGd1=fQGfO[]Xhjs)

Output is 1-based, or empty.

Try it online!

Explanation

The code computes the six possible outputs for the array input, and then selects the appropriate output depending on the string input.

To select the output, the ASCII code points of all characters of the string input are added. The result modulo 9 gives 6, 1, 5, 2, 7, 0 respectively for 'increasing', 'decreasing', 'ones', 'twos', 'all', 'none'. Since all the resulting numbers are distinct this can be used as a selection criterion.

Instead of actually performing a modulo 9 operation on the sum, the list of possible inputs is extended to 9 entries (some of which are dummy), and so indexing into that list is automatically done modulo 9.

d     % Implicit input: numeric vector. Push vector of consecutive differences.
      % Contains -1, 0 or 1
Q~    % For each entry: add 1, negate. This turns -1 into 1, other values into 0
f     % Push indices of nonzeros
Q     % Add 1 to each entry (compensates the fact that computing consecutive
      % differences removes one entry). This the output for 'decreasing'
Gq    % Push input again. Subtract 1 from the code points
f     % Push indices of nonzeros. This is the output for 'twos'
OO    % Push two zeros. These are used as placeholders
Go    % Push input and compute parity of each entry
f     % Push indices of nonzeros. This is the output for 'ones'
Gd    % Push input and compute consecutive differences
1=    % Test each entry for equality with 1
f     % Push indices of nonzeros 
Q     % Add 1. This is the output for 'increasing'
Gf    % Push indices for all input (nonzero) entries. This is the output for 'all'
O     % Push zeros. Used as placeholder
[]    % Push empty array. This is the output for 'none'
Xh    % Concatenate stack into a cell array
j     % Input a string
s     % Sum of code points
)     % Use as an index into the cell aray. Implicitly display
\$\endgroup\$
1
\$\begingroup\$

Python 2, 92 bytes

lambda a,s:[i for i,(x,y)in enumerate(zip([0]+a,a))if[0<x<y,0,y<2,y>1,1,x>y][ord(s[0])/3%7]]

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Jelly, 27 bytes

>2\0;
NÇ
Ị
=2

ḟ
⁹Ḣ“hɠ»iµĿT

Try it online!

-3 thanks to Jonathan Allan.

\$\endgroup\$
  • \$\begingroup\$ Save three bytes by using the dictionary word "diota" - note that link 0 gets it right, but you could reorder again and use "antidote" or other such word and allow your test harness to work again. \$\endgroup\$ – Jonathan Allan Sep 29 '17 at 20:12
  • \$\begingroup\$ @JonathanAllan I thought link 0 was the bottom-most link, but apparently it's like Ç but weirder, thanks! (also I just learned a new word :p) \$\endgroup\$ – Erik the Outgolfer Sep 30 '17 at 7:27
1
\$\begingroup\$

Husk, 27 bytes

`fN!+mmëI=2ε¬moΘẊe><€¨Ÿȧö¨←

Try it online!

-9 thanks to H.PWiz.

I'm quite proud of this answer.

\$\endgroup\$
  • \$\begingroup\$ Golfed mostly by using ΘẊ> and ΘẊ< and `fN \$\endgroup\$ – H.PWiz Sep 30 '17 at 13:16
  • \$\begingroup\$ @H.PWiz how didn't I see those honestly \$\endgroup\$ – Erik the Outgolfer Sep 30 '17 at 13:16
  • \$\begingroup\$ -1 byte A list indexed at 0 is the last element. \$\endgroup\$ – H.PWiz Sep 30 '17 at 13:37
  • \$\begingroup\$ @H.PWiz Ooh I thought that the compressed string would be ¨₆Żσa¨ instead that's why I didn't use that feature, thanks. And now I can say it ties Jelly. \$\endgroup\$ – Erik the Outgolfer Sep 30 '17 at 13:39
1
\$\begingroup\$

Java (OpenJDK 8), 266 217 213 205 172 171 155 131 bytes

s->a->{int i=0,l=0,c=s.charAt(0)-97;for(int e:a){if(++i>1&(c==8&e>l|c==3&e<l)|c==14&(l=e)<2|c>18&l>1|c<1)System.out.print(i+",");}}

Try it online!

\$\endgroup\$
  • \$\begingroup\$ If you define y as a char, you can golf equality tests like y.equals("a") to y=='a', y==97 or even y<98. \$\endgroup\$ – Jonathan Frech Sep 29 '17 at 10:26
  • \$\begingroup\$ @JonathanFrech Was just changing it :) \$\endgroup\$ – Roberto Graham Sep 29 '17 at 10:28
  • \$\begingroup\$ The TIO at least is not the output I would expect. While only given by example, the list requires a space between elements and no trailing comma. \$\endgroup\$ – Tahg Sep 29 '17 at 11:28
  • \$\begingroup\$ Since 19 is c's highest value, c==19 is equal to c>18. \$\endgroup\$ – Jonathan Frech Sep 29 '17 at 11:37
  • 2
    \$\begingroup\$ 131 bytes: s->a->{int i=0,l=0,c=s.charAt(0)-97;for(int e:a){if(++i>1&(c==8&e>l|c==3&e<l)|c==14&(l=e)<2|c>18&l>1|c<1)System.out.print(i+",");}} \$\endgroup\$ – Nevay Sep 29 '17 at 18:12
1
\$\begingroup\$

Jq 1.5, 131 bytes

Based on xcali's approach since string matching is shorter then my array version.

def D(s):[.[1]|gsub(" ";"")|match(s;"g").offset+(s|length)];./"
"|{i:D("12"),d:D("21"),o:D("1"),t:D("12"),a:D("."),n:[]}[.[0][0:1]]

Assumes jq is invoked with -Rs options and input appears on two lines e.g.

decreasing
1 1 2 2 2 1 2 2 1 1 2

Expanded:

def D(s): [
      .[1]                              # find where s appears
    | gsub(" ";"")                      # in the input and add
    | match(s;"g").offset + (s|length)  # length to get ending index
  ]
;

  ./"\n"                                # split on newline
| {i:D("12"),                           # increasing
   d:D("21"),                           # decreasing
   o:D("1"),                            # ones
   t:D("2"),                            # twos
   a:D("."),                            # all
   n:[]                                 # none
  }[.[0][0:1]]

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Haskell, 91 bytes

(c:_)!l=[i|(i,y,x)<-zip3[1..]l$l!!0:l,c/='i'||x<y,c>'d'||x>y,c/='o'||y<2,c<'t'||y>1,c/='n']

Try it online!

Laikoni saved a byte.

\$\endgroup\$
  • 1
    \$\begingroup\$ You can save a byte with (i,y,x)<-zip3[1..]l$l!!0:l. \$\endgroup\$ – Laikoni Sep 30 '17 at 15:24
  • \$\begingroup\$ Some competition \$\endgroup\$ – Laikoni Oct 1 '17 at 4:54
1
\$\begingroup\$

J, 73 bytes

g=.[:I.[=0,2-/\]
(_1 g])`(1 g])`(1=])`(2=])`(i.@#@])`_1:@.('idotan'i.{.@[)

Would be curious to see how this can be significantly condensed -- I believe it can (10 chars just for all those agenda parens!)

  • g - helper verb for increasing and decreasing, which just amount to comparing the values of infix \ runs of size 2
  • The rest just grabs the first character from the "command" and executes the corresponding case using Agenda @.

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Do 1=] and 2=] not work? Also, what if g took a number as its left argument and a list as its right argument and returned the indices where 2-/\ applied to the list equaled the left argument. That way you could pass it _1 or 1 to find decreasing and increasing instead of using an adverb. \$\endgroup\$ – cole Sep 30 '17 at 7:45
  • \$\begingroup\$ @cole Good comments. I made the changes, and the result is much cleaner, though 73 still seems like a high byte count. I mean, J is tying the JS here.... the shame! \$\endgroup\$ – Jonah Sep 30 '17 at 18:22
0
\$\begingroup\$

Java 8, 233 229 216 bytes

l->s->{int i=s.charAt(0)-97,k=0,j=1;for(s=(l+"").replaceAll("[^12]","");s.length()*j>0;System.out.print(j++<0?"":(k+=j)+","),s=s.substring(j))j=i<1?0:s.indexOf(i<4?"21":i<9?"12":i<14?" ":i<15?"1":"2")+(i>2&i<9?1:0);}

This String approach ended up longer than I was expecting.. But even thought I'm hugely out-golfed by the other Java 8 answer, I decided to post it anyway.
It can definitely be golfed, even with this approach.. The "none" and "increase/decreasing" mainly caused some workaround that cost some bytes..

The result is 1-indexed.

Explanation:

Try it here.

l->s->{                          // Method with List and String parameters
  int i=s.charAt(0)-97,          //  First character of the String - 97
                                 //   (i=8; d=3; o=14; t=19; a=0; n=13)
      k=0,                       //  Total counter
      j=1;                       //  Index integer
  for(s=(l+"")                   //  toString of the List,
         .replaceAll("[^12]","");//   and leave only the 1s and 2s 
      s.length()*j>0             //  Loop as long as `j` and the size of the String
                                 //  are both larger than 0
      ;                          //   After every iteration:
      System.out.print(          //    Print:
       j++<0?                    //     If `j` is -1:
        ""                       //      Print nothing
       :                         //     Else:
        (k+=j)+",")              //      Print the current index
      ,s=s.substring(j))         //    And then remove the part of the String we've checked
    j=i<1?                       //   If "all":
                                 //    Change `j` to 0
      :                          //   Else:
       s.indexOf(                //    Replace `j` with the next index of:
        i<1?                     //     If "all":
         s.charAt(0)+""          //      The next character
        :i<4?                    //     Else-if "decreasing":
         "21"                    //      Literal "21"
        :i<9?                    //     Else-if "increasing":
         "12"                    //      Literal "12"
        :i<14?                   //     Else-if "none":
         " "                     //      Literal space (any char that isn't present)
        :i<15?                   //     Else-if "one":
         "1"                     //      Literal "1"
        :                        //     Else(-if "two"):
         "2")                    //      Literal "2"
       +(i>2&i<9?1:0);           //     +1 if it's "increasing"/"decreasing"
                                 //  End of loop (implicit / single-line body)
}                                // End of method
\$\endgroup\$
0
\$\begingroup\$

Perl 5, 71 + 2 (-nl) = 73 bytes

$p=/l/?'.':/t/?2:/^o/?1:/d/?21:/i/?12:0;$_=<>;s/ //g;say pos while/$p/g

Try it online!

Revised logic is effectively the same as the below explanation, but the pattern matches have been shortened.

Previously:

$p=/all/?'.':/^o/?1:/^t/?2:/^d/?21:/^i/?12:0;$_=<>;s/ //g;say pos while/$p/g

Try it online!

Outputs nothing if the criteria is not matched.

Explained:

$p=          # set the pattern to seach based on the input string
  /all/?'.'  # any character
 :/^o/?1     # starts with 'o', find ones
 :/^t/?2     # starts with 't', find twos
 :/^d/?21    # starts with 'd', find decreasing
 :/^i/?12    # starts with 'i', find increasing
 :0;         # anything else: create pattern that won't match
$_=<>;s/ //g;# read the digits and remove spaces
say pos while/$p/g # output position(s) of all matches
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.