53
\$\begingroup\$

In the standard loopholes, the following is forbidden:

Claiming that your answer is written in "MyOwnLanguage", where the command x means "read a sequence of numbers, split them into groups of three, and print the last numbers of those groups where the second number is less than the first"

Here, we are going to do the exact same thing.

Task

Given a sequence of positive integers, whose length is divisible by 3, split them into groups of three, and print the last numbers of those groups where the second number is less than the first.

Testcases

Input               Output
[]                  []
[1,2,3,4,5,6,7,8,9] []
[2,1,3,5,4,6,8,7,9] [3,6,9]
[3,1,4,1,5,9,2,6,5] [4]
[100,99,123]        [123]
[123,123,456]       []
[456,123,789]       [789]

Scoring

This is . Shortest answer in bytes wins.

Standard loopholes apply, so remember not to have a built-in command x that does this task.

\$\endgroup\$
  • 33
    \$\begingroup\$ Hmmm... Now I'm really tempted to create MyOwnLanguage and add the x command... :P \$\endgroup\$ – James May 9 '17 at 5:55
  • 6
    \$\begingroup\$ *remember not to have a built-in*‽ Well, if we already have it, we can use it, no? \$\endgroup\$ – Adám May 9 '17 at 6:28
  • 3
    \$\begingroup\$ @Adám According to the standard loopholes, you cannot have a language containing the built-in x specifically performing that function. \$\endgroup\$ – Leaky Nun May 9 '17 at 6:34
  • 35
    \$\begingroup\$ @LeakyNun Yes you can, you just cannot make such a language because of the challenge. If your language predates the challenge, it is acceptable. \$\endgroup\$ – Adám May 9 '17 at 6:38
  • 9
    \$\begingroup\$ If I call the builtin p, can I use it? \$\endgroup\$ – Mindwin May 9 '17 at 16:02

40 Answers 40

1
2
1
\$\begingroup\$

Retina, 42 36 bytes

\d+
$*
M!`1+ 1+ 1+
A`^(1+) \1
%r`1\G

Try it online! Takes input as a space-separated list of numbers and outputs a newline-separated list of numbers. Edit: Saved 6 bytes thanks to @MartinEnder. Explanation:

\d+             Match input numbers
$*              Convert to unary
M!`1+ 1+ 1+     Capture groups of three numbers
A`^(1+) \1      Filter out if the first is less than or equal to the second
%r`1\G          Convert the third to decimal
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ M! saves a byte over S...(...). The second stage needs a ^ otherwise it can yield false positives where the third is less than the second, but then it's shorter to negate the logic with A`^(1+) \1. And the last stage can be shortened to r`1\G (count consecutive ones from the end of the string). Link: tio.run/nexus/… \$\endgroup\$ – Martin Ender May 9 '17 at 13:47
  • \$\begingroup\$ @MartinEnder My second stage doesn't need a ^ because there's no space after the third value, but A is a better idea anyway, thanks. \$\endgroup\$ – Neil May 9 '17 at 14:06
  • \$\begingroup\$ oh, I didn't see that the space was part of the capturing group, that works as well then \$\endgroup\$ – Martin Ender May 9 '17 at 14:07
  • \$\begingroup\$ I think the last stage needs a % modifier, otherwise this will return only the last value. TIO \$\endgroup\$ – Leo May 9 '17 at 21:46
  • \$\begingroup\$ @Leo Thanks, I see what you mean. \$\endgroup\$ – Neil May 9 '17 at 22:03
1
\$\begingroup\$

><>, 19 + 3 for -v = 22 bytes

rl?!;(?\~r
naaao~ \
| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Mathematica, 42 39 bytes

Edit: Saved 3 bytes thanks to Greg Martin

BlockMap[Apply[If[#>#2,#3,Nothing]&],#,3]&

BlockMap[If[#>#2,#3,Nothing]&@@#&,#,3]&

Not shorter than Greg Martin's answer, but I couldn't resist the opportunity to finally use BlockMap. Partitions the input list # into sublists of size 3 and Applys the functions If[#>#2,#3,Nothing]& to each sublist.

Questionable solution, 38 bytes

BlockMap[If[#>#2,Print@#3]&@@#&,#,3]&

Same as above, except it prints the desired elements and returns {Null,...Null}.

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

C, 65 bytes

Try Online

i;f(s,l)int*l;{for(;i+2<s;i++)l[i]>l[i+1]&&printf(" %d",l[i+2]);}
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ This code doesn't work. s is supposed to be the number of groups of 3, right? Doesn't work when s is number of numbers either. \$\endgroup\$ – simon May 10 '17 at 19:39
  • \$\begingroup\$ @gurka s is the size of array l, I've fixed the code, check here Try Online \$\endgroup\$ – Khaled.K May 11 '17 at 6:38
1
\$\begingroup\$

Ruby, 37 35 bytes

->a{a.map{x,y,z,*a=a;z&&x>y&&p(z)}}

Try it online!

How it works:

->a{
    a.map{                          -> Loop [a.size] times
          x,y,z,*a=a;               -> get and remove 3 elements from a
                     z&&x>y&&p(z)   -> print z if not null and x>y
                                 }} 
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ I think you need each_slice, not each_cons. each_cons yields overlapping groups. \$\endgroup\$ – histocrat May 10 '17 at 14:17
  • \$\begingroup\$ You are right, I'm fixing it \$\endgroup\$ – G B May 11 '17 at 6:21
1
\$\begingroup\$

Scala, 74 66 bytes

Edit: Lost 8 bytes thanks to @AlecZorab

The suggestion was to use collect() instead of the equivalent filter() followed by map() (which my for comprehension is equivalent to) and a pattern match, kind of like:

(_:Seq[Int]).grouped(3).collect{case(Seq(a,b,c))if(a>b)=>c}.toList

Another suggestion was to drop the parameter name as it was only used once.

The character/byte count can be dropped to 59 bytes if an iterator is an acceptable output. Usage is similar to the old version.

Old version:

(s:Seq[Int])=>(for(l<-s.grouped(3)if l.size>2&l(0)>l(1))yield l(2)).toList

Straightforward. The toList at the end is to consume the iterator produced - toSeq produces a Stream in my tests, which shows only the first element. If the iterator itself is legal as output, this version comes in at 64 bytes:

(s:Seq[Int])=>for(l<-s.grouped(3)if l.size>2&l(0)>l(1))yield l(2)

Scala allows Unicode operators, so I could lower the character count to 62 at the cost of increasing the byte count to 66:

(s:Seq[Int])⇒for(l←s.grouped(3)if l.size>2&l(0)>l(1))yield l(2)

Lambda, the parameter type is required in the REPL. Enter into the REPL and call the res0 or whatever function object it shows with the Seq[Int] to test with. For ease of testing, you can consider the following function which converts a test case String into a proper Seq[Int]:

def testCaseAsSeq(input: String): Seq[Int] =
    input.drop(1).dropRight(1)
         .split(",")
         .filter(! _.isEmpty)
         .map(_.toInt).toSeq

Prettified version with some obfuscations removed to make it more standard Scala:

(sequence: Seq[Int]): List[Int] => 
                    (for(group <- s.grouped(3) 
                    if group.size == 3 && group(0) > group(1))
                        yield group.last)
                    .toList
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ couple of things you can do to tighten that up a little First up, if you write it without the for comprehension you get (s:Seq[Int]) => s.grouped(3).filter(g => g.size==3 && g(0) > g(1)).map(g => g(2)) since s is only used once, you can replace the start with (_: Seq[Int]).grouped, saving a couple of characters. Then we notice that a filter and a map in scala is called collect, so you can merge them into \$\endgroup\$ – AlecZorab May 11 '17 at 9:08
  • \$\begingroup\$ ... collect{ case g if g.size == 3 && g(0) > g(1) => g(2)}. Then we can replace that with a pattern match, giving (_:Seq[Int]).grouped(3).collect{case(Seq(a,b,c))if(a>b)=>c}.toList (66 bytes) \$\endgroup\$ – AlecZorab May 11 '17 at 9:14
1
\$\begingroup\$

Japt, 18 12 bytes

ò3 f_v >ZvÃc

Try it online

Or 10 bytes if returning a nested array is permitted, e.g. [[3],[6],[9]]

ò3 f_v >Zv
| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

Mathematica 65 bytes

{K={};Cases[Partition[#,3],{a_,b_,c_}->If[b<a,AppendTo[K,c]]];K}&
| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

Awk, 27 bytes

{a[b=NR%3]=$0}!b&&a[2]<a[1]
| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

GolfScript, 17 bytes

~3/{~@@>{}{;}if}%

Try it online!

Explanation

~                 # Evaluate the input
 3/               # Split the input into chunks of 3
   {           }% # Map every item in the input
    ~@@>          # Is the 1st item < second item?
        {}{;}if   # If false, discard the current item
| improve this answer | |
\$\endgroup\$
1
2

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.