61
\$\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\$
17
  • 36
    \$\begingroup\$ Hmmm... Now I'm really tempted to create MyOwnLanguage and add the x command... :P \$\endgroup\$
    – DJMcMayhem
    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
  • 11
    \$\begingroup\$ If I call the builtin p, can I use it? \$\endgroup\$
    – Mindwin
    May 9 '17 at 16:02

44 Answers 44

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
\$\endgroup\$
5
  • \$\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\$ 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\$ 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~ \
\$\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}.

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

Awk, 27 bytes

{a[b=NR%3]=$0}!b&&a[2]<a[1]
\$\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]);}
\$\endgroup\$
2
  • \$\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
                                 }} 
\$\endgroup\$
2
  • \$\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
\$\endgroup\$
2
  • \$\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
\$\endgroup\$
1
\$\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
\$\endgroup\$
1
\$\begingroup\$

Ly, 17 bytes

0&n[spG[rlr!]pp]p

Try it online!

This is a pretty much a direct mapping of the rules to code... After reading all the numbers onto the stack, each iteration of the loop processes the top three numbers on the stack. If the 2nd is less than the 1st, the third is appended to the end of the stack.

Once the 0 delimiter is hit on the stack, the program exits and the default action to print everything on the stack as numeric takes care of the output.

0                  - add a "0" delimiter to stop the loop
 &n                - read all the numbers into the stack (expects one per line)
   [         pp]   - loop to process three nums ("pp" pops a work var and the 1at num)
    sp             - save the 3rd number and pop it from the stack
      G            - compare the 1st and 2nd
       [   !]      - true if 2nd is less than 1st
        rlr        - reverse the stack, load 3rd char, reverse again
                p  - pop the "0" delimiter, leaving just the answers
\$\endgroup\$
1
\$\begingroup\$

Python 3, 50 bytes

lambda l:[c for a,b,c in zip(*(iter(l),)*3)if b<a]

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ You can save a few bytes by using s[2]for s in ... and getting rid of the outer list comprehension. Then for a,b,c in zip... saves a couple more: Try it online! \$\endgroup\$
    – ovs
    Jan 15 at 8:53
0
\$\begingroup\$

Mathematica 65 bytes

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

Factor, 44 bytes

[ 3 group [ first2 > ] [ last ] filter-map ]

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Pip -xp, 14 bytes

_@2M$>H_FIa<>3

Takes the list as a command-line argument. Attempt This Online!

Explanation

          a     ; First command-line argument
           <>3  ; Grouped into sublists of length 3
        FI      ; Filtered on this function:
      H_        ;   Prefix (all but the last item)
    $>          ;   Folded on > (in this case, truthy iff the first item > the second)
   M            ; Map this function to each remaining sublist:
_@2             ;   Get the item at index 2

No flags, 14 bytes

Here's a recursive solution without flags:

Ib<aPcIgfVg@>3

Takes the numbers as separate command-line arguments. Attempt This Online!

Explanation

Ib<a            ; If the second argument is less than the first:
    Pc          ;   Print the third argument
      Ig        ; If the arglist is truthy (not empty):
        fV      ;   Call the current function again with arglist...
          g@>3  ;   ... current arglist without the first three elements

When g is empty, all of a, b, and c are set to nil. Since nil is not less than nil, b<a is false and the first if statement is not executed.

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