15
\$\begingroup\$

Details

Write a function or program that, given an array (or list), containing only integers, returns or output an array with all sub-elements reversed. That is, reverse all elements of the deepest array, then the second deepest, etc. The dimensions need not be specified, but the function or program must work for jagged arrays in your programming language's native format.


Examples

This:

[[1,2], [3,4]]

Would become this:

[[4,3], [2,1]]

This:

[[[ 1, 2, 3], [ 4, 5, 6], [ 7, 8, 9]],
 [[10,11,12], [13,14,15], [16,17,18]],
 [[19,20,21], [22,23,24], [25,26,27]],
 [[28,29,30], [31,32,33], [34,35,36]],
 [[37,38,39], [40,41,42], [43,44,45]],
 [[46,47,48], [49,50,51], [52,53,54]]]

Would become this:

[[[54,53,52], [51,50,49], [48,47,46]],
 [[45,44,43], [42,41,40], [39,38,37]],
 [[36,35,34], [33,32,31], [30,29,28]],
 [[27,26,25], [24,23,22], [21,20,19]],
 [[18,17,16], [15,14,13], [12,11,10]],
 [[ 9, 8, 7], [ 6, 5, 4], [ 3, 2, 1]]]

This:

[[[1,2]],
 [[3,4], [5]],
 [[6,7,8], [9], [10,11]],
 [[[12,13], [14,15]], [16], [17,18,19,20]],
 [21]]

Would become this:

[[21],
 [[20,19,18,17], [16], [[15,14], [13,12]]],
 [[11,10], [9], [8,7,6]],
 [[5], [4,3]],
 [[2,1]]]

Bonus

This will hopefully encourage answers in some object-oriented programming languages...

-50% Bytecount If your program can take as input an array (or list) with its member's of various types (these can be in the form of objects) and successfully reverse all arrays.

This:

[["Foo",["Bar",1]],
  2,
 ["Baz"],
 [[["Qux"],3],3.14]]

Would become this:

[[3.14,[3,["Qux"]]],
 ["Baz"],
  2,
 [[1,"Bar"],"Foo"]]
\$\endgroup\$
8
  • 1
    \$\begingroup\$ In your bonus example, you treat strings as atoms. I would argue that they are sub-array, and thus should be reversed too. This is in fact what my APL solution does when fed normal strings, as APL does not have a string datatype, only character datatypes. Strings are therefore one-dimensional character arrays. If you want strings to remain in normal order, you just have to make them objects with a display form. \$\endgroup\$
    – Adám
    Mar 17, 2016 at 12:27
  • \$\begingroup\$ @Nᴮᶻ Do you believe that the -50% Bytecount is too generous? I may do something along the lines of -30% Bytecount for various data types, and something like -10% Bytecount for reversing Strings, -15% Bytecount for reversing an integer type (123 -> 321) and -15% Bytecount for reversing a floating type (3.14 -> 41.3). \$\endgroup\$
    – MrPublic
    Mar 17, 2016 at 12:32
  • 1
    \$\begingroup\$ I generally dislike bonuses. Reversing integers and floats is ... interesting. \$\endgroup\$
    – Adám
    Mar 17, 2016 at 12:36
  • 4
    \$\begingroup\$ Leave it for now, but next time, you may want to use the sandbox to figure out such things. \$\endgroup\$
    – Adám
    Mar 17, 2016 at 12:38
  • 5
    \$\begingroup\$ About bonuses... \$\endgroup\$ Mar 17, 2016 at 13:07

17 Answers 17

10
\$\begingroup\$

Pyth, 11 - 50% = 5.5 bytes

L?+IbY_yMbb

Try it online: Demonstration or Test Suite.

This defines a function y. The additional 3 bytes <newline>yQ simply call the function with the input list and therefore doesn't need to be counted towards the bytes total.

Explanation:

L?+IbY_yMbb
L             define a function y(b), that returns:
 ?+IbY           if b + [] == b (test if b is a list):
      _yMb           recursively call y on all elements in b, then reverse the list
          b      else: b
\$\endgroup\$
7
\$\begingroup\$

Dyalog APL, 14 - 50% = 7 bytes

{∇¨⍣(×|≡⍵)⌽⍵}

⌽⍵ reverse argument
⍣(×|≡⍵) if the argument is not an atom (sign of the [absolute] depth)...
∇¨ ... apply the function to each element (of the reversed argument).

If ⎕ML←3 (IBM style), which is the case on systems that migrated from APL2, one byte can be saved by removing |.

Try APL online.

For curiosity, the proposed int and float reversing:

{∇¨⍣(×≡⍵){0::⌽⍵⋄⍎⌽⍕⍵}⍵}

The inner function:

0::⌽⍵ if any error occurs, just return the revesed argument
⍎⌽⍕ make into string, reverse, make into number

\$\endgroup\$
5
\$\begingroup\$

Prolog, 40 - 50% = 20 bytes

a(X,Y):-reverse(X,Z),maplist(a,Z,Y);X=Y.

This recursively calls predicate a/2 with maplist/3, for each member of the list, until reverse/2 fails (i.e. last element wasn't a list).

\$\endgroup\$
5
\$\begingroup\$

Python 2, 40 - 50% = 20

f=lambda x:map(f,x)[::-1]if"">x>[]else x

Only some minor modifications needed from the basic way to do it are needed to get the bonus. Uses the fact that all lists are less than the empty string, and all numbers are less than the empty list.

All test cases

\$\endgroup\$
1
  • \$\begingroup\$ Just a note that the version without the bonus is f=lambda x:map(f,x)[::-1]if x>[]else x. \$\endgroup\$
    – mbomb007
    Mar 17, 2016 at 18:12
3
\$\begingroup\$

Emacs Lisp, 46 bytes * 0.5 = 23

(defun g(x)(if(atom x)x(mapcar'g(reverse x))))

Usage example: (g '((1 2) 3 (four 5))) -> ((5 four) 3 (2 1))

Classic recursive approach: if the argument isn't a list, take it unchanged, if it's a list, map the function over the reverse of the list.

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

Mathematica, 34/2=17 bytes

Quiet[Reverse//@#]/.Reverse->(#&)&

Or just Reverse//@#& if you want a ton of errors and Reverses everywhere.

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

Clojure 43/2=21.5 bytes

(defn f[x](if(coll? x)(reverse(map f x))x))
\$\endgroup\$
2
\$\begingroup\$

Brachylog, 5 - 50% = 2.5 bytes

ċ↔↰ᵐ|

Try it online!

         The input
ċ        which is a list
 ↔       reversed
   ᵐ     with each element
  ↰      passed through this same predicate
    |    is the output. If the input isn't a list,
         it is the output.

Since can also reverse strings and integers, we have to explicitly fail non-lists with ċ.

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

Wolfram Language (Mathematica), 23 22 21 bytes

-50% bonus

#0/@Reverse@*List@@#&

Try it online!

Only works on nested Lists of atoms. Reverse a list, then reverse its elements. @@ and /@ are no-ops on atoms.

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

JavaScript ES6, 42 - 50% = 21 bytes

My score is perfect in so many ways. Implements a function r which recursively applies itself to the members of its input.

r=a=>Array.isArray(a)?a.reverse().map(r):a

If we assume no object has the property pop, then this becomes (31 - 50% = 15.5), thanks to dev-null:

r=a=>a.pop?a.reverse().map(r):a

Or, if we assume the object has a sane reverse property, we could do that as well (35 - 50% = 17.5):

r=a=>a[R="reverse"]?a[R]().map(r):a
\$\endgroup\$
1
  • \$\begingroup\$ I guess you could safely check for an array like this: a.pop?a.reverse().map(r):a. Assuming there is no need to handle void 0 and custom objects. \$\endgroup\$ Mar 17, 2016 at 14:18
1
\$\begingroup\$

Lua, 111 99 * .5 = 55.5 49.5 bytes

function r(a)local t={}for i,v in next,a do t[#a+1-i]=type(v)=="table"and r(v)or v end return t end

Good bit of recursion

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

CJam, 20 bytes * 50% = 10

{_`0='[={W%{F}%}&}:F

Defines the named block F which can be applied to an array on top of the stack (or anything else, in which case it's a no-op).

Test it here.

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

Clojure, 38 bytes

(and a bonus I guess, but Clojure is a dynamic language so it comes for free)

(fn f[x](if(seq? x)(map f(into()x))x))

This is a good start but didn't employ these optimizations:

  • Define an anonymous function with fn instead of a named one with defn. But we still need a "scoped" name f for recursion
  • Take input as a list instead of vector, then we can use seq? instead of coll?
  • Use (into () ...) instead of reverse
  • Reverse x before mapping, we don't need as many spaces then
\$\endgroup\$
1
\$\begingroup\$

Clojure, 40 38 -50% = 19 bytes

(fn r[s](if(coll? s)(map r(rseq s))s))

Try it online!

A translation of the JavaScript answer. Matched the score with the best Clojure answer ;)

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

Haskell + free, 8.5 bytes (17 bytes -50% bonus)

In order to represent a ragged list in Haskell we use a free monad of lists. We use the free library to get these free monads.

hoistFree reverse

Try it online!

Explanation

hoistFree takes a natural transformation from some functor \$F\$ to another functor \$G\$ and makes a natural transformation from \$\mathrm{Free}(F)\$ to \$\mathrm{Free}(G)\$. Here the natural transformation is reverse, from lists to lists.

Because hoistFree must work with any natural transformation we know it must apply reverse exactly once to every sublist. For example imagine we had a natural transformation:

newtype Reversed f a
  = Reversed (f a)

reverse' :: [a] -> Reversed [] a
reverse' =
  Reversed . reverse

This is functionally identical to reverse but the types prove it must be applied exactly once to every list.

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

Ruby, 32 - 50% = 16 bytes

Recursive function. Using rescue to catch the NoMethodError that triggers when trying to reverse a number or map a string turns out to be 2 bytes shorter than checking if the input is an array via a==[*a].

f=->a{a.reverse.map(&f)rescue a}

Try it online!

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

Julia 1.0, 27 -50% = 13.5

!x=x
!x::Array=reverse(.!x)

Try it online!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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