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"]]
-
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– Adám2016年03月17日 12:27:52 +00:00Commented Mar 17, 2016 at 12:27
-
\$\begingroup\$ @NBz 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– MrPublic2016年03月17日 12:32:07 +00:00Commented Mar 17, 2016 at 12:32
-
1\$\begingroup\$ I generally dislike bonuses. Reversing integers and floats is ... interesting. \$\endgroup\$Adám– Adám2016年03月17日 12:36:25 +00:00Commented 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– Adám2016年03月17日 12:38:53 +00:00Commented Mar 17, 2016 at 12:38
-
5\$\begingroup\$ About bonuses... \$\endgroup\$Martin Ender– Martin Ender2016年03月17日 13:07:04 +00:00Commented Mar 17, 2016 at 13:07
17 Answers 17
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
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
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).
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.
-
\$\begingroup\$ Just a note that the version without the bonus is
f=lambda x:map(f,x)[::-1]if x>[]else x
. \$\endgroup\$mbomb007– mbomb0072016年03月17日 18:12:32 +00:00Commented Mar 17, 2016 at 18:12
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.
Mathematica, 34/2=17 bytes
Quiet[Reverse//@#]/.Reverse->(#&)&
Or just Reverse//@#&
if you want a ton of errors and Reverse
s everywhere.
Clojure 43/2=21.5 bytes
(defn f[x](if(coll? x)(reverse(map f x))x))
Brachylog, 5 - 50% = 2.5 bytes
ċ↔↰m|
The input
ċ which is a list
↔ reversed
m 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 ċ
.
Wolfram Language (Mathematica), (削除) 23 (削除ここまで) (削除) 22 (削除ここまで) 21 bytes
-50% bonus
#0/@Reverse@*List@@#&
Only works on nested List
s of atoms. Reverse a list, then reverse its elements. @@
and /@
are no-ops on atoms.
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
-
\$\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 handlevoid 0
and custom objects. \$\endgroup\$Andreas Louv– Andreas Louv2016年03月17日 14:18:20 +00:00Commented Mar 17, 2016 at 14:18
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
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).
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 withdefn
. But we still need a "scoped" namef
for recursion - Take input as a list instead of vector, then we can use
seq?
instead ofcoll?
- Use
(into () ...)
instead ofreverse
- Reverse
x
before mapping, we don't need as many spaces then
Clojure, (削除) 40 (削除ここまで) 38 -50% = 19 bytes
(fn r[s](if(coll? s)(map r(rseq s))s))
A translation of the JavaScript answer. Matched the score with the best Clojure answer ;)
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
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.
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}