Multi-dimensional reversal
Clash Royale CLAN TAG#URR8PPP
up vote
23
down vote
favorite
Given an N-dimensional orthogonal (non-ragged) array of non-negative integers, and an indication of which dimensions to reverse, return the array but reversed along those dimensions. The indication may be given as a Boolean list of length N or a list of a subset of the first N dimensions indexed from 0 or 1.
Please state your input formats. Code explanations are much appreciated.
Walked-through example
We are given the 2-layer 3-row 4-column 3D-array
[[[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9,10,11,12]],
[[13,14,15,16],
[17,18,19,20],
[21,22,23,24]]]
and one of
[true,false,true]
(Boolean list)[0,2]
(0-indexed list)[1,3]
(1-indexed list)
We need to reverse order of the first and last dimensions, that is the layers and the elements of the rows (the columns), but not the rows of each layer. First (the actual order you do this in does not matter) we reverse the order of the layers:
[[[13,14,15,16],
[17,18,19,20],
[21,22,23,24]],
[[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9,10,11,12]]]
and then we reverse the order of the elements of each row:
[[[16,15,14,13],
[20,19,18,17],
[24,23,22,21]],
[[ 4, 3, 2, 1],
[ 8, 7, 6, 5],
[12,11,10, 9]]]
Test cases
[[[1,2,3,4],[5,6,7,8],[9,10,11,12]],[[13,14,15,16],[17,18,19,20],[21,22,23,24]]]
[true,false,true]
/[0,2]
/[1,3]
âÂÂâÂÂâÂÂ[[[16,15,14,13],[20,19,18,17],[24,23,22,21]],[[4,3,2,1],[8,7,6,5],[12,11,10,9]]]
[[1,2,3],[4,5,6]]
[true,false]
/[0]
/[1]
âÂÂâÂÂ[[4,5,6],[1,2,3]]
[[1],[4]]
[true,false]
/[0]
/[1]
âÂÂâÂÂ[[4],[1]]
[[7]]
[true,true]
/[0,1]
/[1,2]
âÂÂâÂÂ[[7]]
[1,2,3,4,5,6,7]
[true]
/[0]
/[1]
âÂÂâÂÂ[7,6,5,4,3,2,1]
[true]
/[0]
/[1]
âÂÂâÂÂ
[,]
[false,false]
//
âÂÂâÂÂ[,]
[[[[3,1,4,1],[5,9,2,6]],[[5,3,5,8],[9,7,9,3]]],[[[2,3,8,4],[6,2,6,4]],[[3,3,8,3],[2,7,9,5]]]]
[true,false,true,true]
/[0,2,3]
/[1,3,4]
âÂÂâÂÂ[[[[4,6,2,6],[4,8,3,2]],[[5,9,7,2],[3,8,3,3]]],[[[6,2,9,5],[1,4,1,3]],[[3,9,7,9],[8,5,3,5]]]]
[[[[3,1,4,1],[5,9,2,6]],[[5,3,5,8],[9,7,9,3]]],[[[2,3,8,4],[6,2,6,4]],[[3,3,8,3],[2,7,9,5]]]]
[false,true,false,false]
/[1]
/[2]
âÂÂâÂÂ[[[[5,3,5,8],[9,7,9,3]],[[3,1,4,1],[5,9,2,6]]],[[[3,3,8,3],[2,7,9,5]],[[2,3,8,4],[6,2,6,4]]]]
[[[[3,1,4,1],[5,9,2,6]],[[5,3,5,8],[9,7,9,3]]],[[[2,3,8,4],[6,2,6,4]],[[3,3,8,3],[2,7,9,5]]]]
[false,false,false,false]
//
âÂÂâÂÂ[[[[3,1,4,1],[5,9,2,6]],[[5,3,5,8],[9,7,9,3]]],[[[2,3,8,4],[6,2,6,4]],[[3,3,8,3],[2,7,9,5]]]]
code-golf array-manipulation
add a comment |Â
up vote
23
down vote
favorite
Given an N-dimensional orthogonal (non-ragged) array of non-negative integers, and an indication of which dimensions to reverse, return the array but reversed along those dimensions. The indication may be given as a Boolean list of length N or a list of a subset of the first N dimensions indexed from 0 or 1.
Please state your input formats. Code explanations are much appreciated.
Walked-through example
We are given the 2-layer 3-row 4-column 3D-array
[[[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9,10,11,12]],
[[13,14,15,16],
[17,18,19,20],
[21,22,23,24]]]
and one of
[true,false,true]
(Boolean list)[0,2]
(0-indexed list)[1,3]
(1-indexed list)
We need to reverse order of the first and last dimensions, that is the layers and the elements of the rows (the columns), but not the rows of each layer. First (the actual order you do this in does not matter) we reverse the order of the layers:
[[[13,14,15,16],
[17,18,19,20],
[21,22,23,24]],
[[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9,10,11,12]]]
and then we reverse the order of the elements of each row:
[[[16,15,14,13],
[20,19,18,17],
[24,23,22,21]],
[[ 4, 3, 2, 1],
[ 8, 7, 6, 5],
[12,11,10, 9]]]
Test cases
[[[1,2,3,4],[5,6,7,8],[9,10,11,12]],[[13,14,15,16],[17,18,19,20],[21,22,23,24]]]
[true,false,true]
/[0,2]
/[1,3]
âÂÂâÂÂâÂÂ[[[16,15,14,13],[20,19,18,17],[24,23,22,21]],[[4,3,2,1],[8,7,6,5],[12,11,10,9]]]
[[1,2,3],[4,5,6]]
[true,false]
/[0]
/[1]
âÂÂâÂÂ[[4,5,6],[1,2,3]]
[[1],[4]]
[true,false]
/[0]
/[1]
âÂÂâÂÂ[[4],[1]]
[[7]]
[true,true]
/[0,1]
/[1,2]
âÂÂâÂÂ[[7]]
[1,2,3,4,5,6,7]
[true]
/[0]
/[1]
âÂÂâÂÂ[7,6,5,4,3,2,1]
[true]
/[0]
/[1]
âÂÂâÂÂ
[,]
[false,false]
//
âÂÂâÂÂ[,]
[[[[3,1,4,1],[5,9,2,6]],[[5,3,5,8],[9,7,9,3]]],[[[2,3,8,4],[6,2,6,4]],[[3,3,8,3],[2,7,9,5]]]]
[true,false,true,true]
/[0,2,3]
/[1,3,4]
âÂÂâÂÂ[[[[4,6,2,6],[4,8,3,2]],[[5,9,7,2],[3,8,3,3]]],[[[6,2,9,5],[1,4,1,3]],[[3,9,7,9],[8,5,3,5]]]]
[[[[3,1,4,1],[5,9,2,6]],[[5,3,5,8],[9,7,9,3]]],[[[2,3,8,4],[6,2,6,4]],[[3,3,8,3],[2,7,9,5]]]]
[false,true,false,false]
/[1]
/[2]
âÂÂâÂÂ[[[[5,3,5,8],[9,7,9,3]],[[3,1,4,1],[5,9,2,6]]],[[[3,3,8,3],[2,7,9,5]],[[2,3,8,4],[6,2,6,4]]]]
[[[[3,1,4,1],[5,9,2,6]],[[5,3,5,8],[9,7,9,3]]],[[[2,3,8,4],[6,2,6,4]],[[3,3,8,3],[2,7,9,5]]]]
[false,false,false,false]
//
âÂÂâÂÂ[[[[3,1,4,1],[5,9,2,6]],[[5,3,5,8],[9,7,9,3]]],[[[2,3,8,4],[6,2,6,4]],[[3,3,8,3],[2,7,9,5]]]]
code-golf array-manipulation
I feel like the hardest part in most statically typed languages will be golfing the type signatures involved.
â ÃÂurous
Sep 3 at 22:07
@ÃÂurous How do those languages normally deal with arbitrary array data?
â Adám
Sep 3 at 22:29
1
there's three cases for "normal" use as I see it: only worrying about one level of the array (eg:reverse
works on arbitrary arrays but only cares about the first level), generics, or recursive classes (type / object classes depending on functional or OOP, but similar use-case). The latter two are usually far more verbose.
â ÃÂurous
Sep 3 at 22:39
Can we store the matrix as arrays of pointers to pointers (in C or asm), instead of proper multi-dimensional arrays where everything is contiguous in memory? I'm pretty sure all the normal higher-level / dynamically-typed languages with arbitrary nesting of lists are already treating things as lists of lists, not matrices, so I'm going to assume it's fine.
â Peter Cordes
Sep 5 at 3:42
@PeterCordes Sure, go ahead.
â Adám
Sep 5 at 5:35
add a comment |Â
up vote
23
down vote
favorite
up vote
23
down vote
favorite
Given an N-dimensional orthogonal (non-ragged) array of non-negative integers, and an indication of which dimensions to reverse, return the array but reversed along those dimensions. The indication may be given as a Boolean list of length N or a list of a subset of the first N dimensions indexed from 0 or 1.
Please state your input formats. Code explanations are much appreciated.
Walked-through example
We are given the 2-layer 3-row 4-column 3D-array
[[[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9,10,11,12]],
[[13,14,15,16],
[17,18,19,20],
[21,22,23,24]]]
and one of
[true,false,true]
(Boolean list)[0,2]
(0-indexed list)[1,3]
(1-indexed list)
We need to reverse order of the first and last dimensions, that is the layers and the elements of the rows (the columns), but not the rows of each layer. First (the actual order you do this in does not matter) we reverse the order of the layers:
[[[13,14,15,16],
[17,18,19,20],
[21,22,23,24]],
[[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9,10,11,12]]]
and then we reverse the order of the elements of each row:
[[[16,15,14,13],
[20,19,18,17],
[24,23,22,21]],
[[ 4, 3, 2, 1],
[ 8, 7, 6, 5],
[12,11,10, 9]]]
Test cases
[[[1,2,3,4],[5,6,7,8],[9,10,11,12]],[[13,14,15,16],[17,18,19,20],[21,22,23,24]]]
[true,false,true]
/[0,2]
/[1,3]
âÂÂâÂÂâÂÂ[[[16,15,14,13],[20,19,18,17],[24,23,22,21]],[[4,3,2,1],[8,7,6,5],[12,11,10,9]]]
[[1,2,3],[4,5,6]]
[true,false]
/[0]
/[1]
âÂÂâÂÂ[[4,5,6],[1,2,3]]
[[1],[4]]
[true,false]
/[0]
/[1]
âÂÂâÂÂ[[4],[1]]
[[7]]
[true,true]
/[0,1]
/[1,2]
âÂÂâÂÂ[[7]]
[1,2,3,4,5,6,7]
[true]
/[0]
/[1]
âÂÂâÂÂ[7,6,5,4,3,2,1]
[true]
/[0]
/[1]
âÂÂâÂÂ
[,]
[false,false]
//
âÂÂâÂÂ[,]
[[[[3,1,4,1],[5,9,2,6]],[[5,3,5,8],[9,7,9,3]]],[[[2,3,8,4],[6,2,6,4]],[[3,3,8,3],[2,7,9,5]]]]
[true,false,true,true]
/[0,2,3]
/[1,3,4]
âÂÂâÂÂ[[[[4,6,2,6],[4,8,3,2]],[[5,9,7,2],[3,8,3,3]]],[[[6,2,9,5],[1,4,1,3]],[[3,9,7,9],[8,5,3,5]]]]
[[[[3,1,4,1],[5,9,2,6]],[[5,3,5,8],[9,7,9,3]]],[[[2,3,8,4],[6,2,6,4]],[[3,3,8,3],[2,7,9,5]]]]
[false,true,false,false]
/[1]
/[2]
âÂÂâÂÂ[[[[5,3,5,8],[9,7,9,3]],[[3,1,4,1],[5,9,2,6]]],[[[3,3,8,3],[2,7,9,5]],[[2,3,8,4],[6,2,6,4]]]]
[[[[3,1,4,1],[5,9,2,6]],[[5,3,5,8],[9,7,9,3]]],[[[2,3,8,4],[6,2,6,4]],[[3,3,8,3],[2,7,9,5]]]]
[false,false,false,false]
//
âÂÂâÂÂ[[[[3,1,4,1],[5,9,2,6]],[[5,3,5,8],[9,7,9,3]]],[[[2,3,8,4],[6,2,6,4]],[[3,3,8,3],[2,7,9,5]]]]
code-golf array-manipulation
Given an N-dimensional orthogonal (non-ragged) array of non-negative integers, and an indication of which dimensions to reverse, return the array but reversed along those dimensions. The indication may be given as a Boolean list of length N or a list of a subset of the first N dimensions indexed from 0 or 1.
Please state your input formats. Code explanations are much appreciated.
Walked-through example
We are given the 2-layer 3-row 4-column 3D-array
[[[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9,10,11,12]],
[[13,14,15,16],
[17,18,19,20],
[21,22,23,24]]]
and one of
[true,false,true]
(Boolean list)[0,2]
(0-indexed list)[1,3]
(1-indexed list)
We need to reverse order of the first and last dimensions, that is the layers and the elements of the rows (the columns), but not the rows of each layer. First (the actual order you do this in does not matter) we reverse the order of the layers:
[[[13,14,15,16],
[17,18,19,20],
[21,22,23,24]],
[[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9,10,11,12]]]
and then we reverse the order of the elements of each row:
[[[16,15,14,13],
[20,19,18,17],
[24,23,22,21]],
[[ 4, 3, 2, 1],
[ 8, 7, 6, 5],
[12,11,10, 9]]]
Test cases
[[[1,2,3,4],[5,6,7,8],[9,10,11,12]],[[13,14,15,16],[17,18,19,20],[21,22,23,24]]]
[true,false,true]
/[0,2]
/[1,3]
âÂÂâÂÂâÂÂ[[[16,15,14,13],[20,19,18,17],[24,23,22,21]],[[4,3,2,1],[8,7,6,5],[12,11,10,9]]]
[[1,2,3],[4,5,6]]
[true,false]
/[0]
/[1]
âÂÂâÂÂ[[4,5,6],[1,2,3]]
[[1],[4]]
[true,false]
/[0]
/[1]
âÂÂâÂÂ[[4],[1]]
[[7]]
[true,true]
/[0,1]
/[1,2]
âÂÂâÂÂ[[7]]
[1,2,3,4,5,6,7]
[true]
/[0]
/[1]
âÂÂâÂÂ[7,6,5,4,3,2,1]
[true]
/[0]
/[1]
âÂÂâÂÂ
[,]
[false,false]
//
âÂÂâÂÂ[,]
[[[[3,1,4,1],[5,9,2,6]],[[5,3,5,8],[9,7,9,3]]],[[[2,3,8,4],[6,2,6,4]],[[3,3,8,3],[2,7,9,5]]]]
[true,false,true,true]
/[0,2,3]
/[1,3,4]
âÂÂâÂÂ[[[[4,6,2,6],[4,8,3,2]],[[5,9,7,2],[3,8,3,3]]],[[[6,2,9,5],[1,4,1,3]],[[3,9,7,9],[8,5,3,5]]]]
[[[[3,1,4,1],[5,9,2,6]],[[5,3,5,8],[9,7,9,3]]],[[[2,3,8,4],[6,2,6,4]],[[3,3,8,3],[2,7,9,5]]]]
[false,true,false,false]
/[1]
/[2]
âÂÂâÂÂ[[[[5,3,5,8],[9,7,9,3]],[[3,1,4,1],[5,9,2,6]]],[[[3,3,8,3],[2,7,9,5]],[[2,3,8,4],[6,2,6,4]]]]
[[[[3,1,4,1],[5,9,2,6]],[[5,3,5,8],[9,7,9,3]]],[[[2,3,8,4],[6,2,6,4]],[[3,3,8,3],[2,7,9,5]]]]
[false,false,false,false]
//
âÂÂâÂÂ[[[[3,1,4,1],[5,9,2,6]],[[5,3,5,8],[9,7,9,3]]],[[[2,3,8,4],[6,2,6,4]],[[3,3,8,3],[2,7,9,5]]]]
code-golf array-manipulation
edited Sep 3 at 13:54
asked Sep 3 at 12:44
Adám
27.7k268185
27.7k268185
I feel like the hardest part in most statically typed languages will be golfing the type signatures involved.
â ÃÂurous
Sep 3 at 22:07
@ÃÂurous How do those languages normally deal with arbitrary array data?
â Adám
Sep 3 at 22:29
1
there's three cases for "normal" use as I see it: only worrying about one level of the array (eg:reverse
works on arbitrary arrays but only cares about the first level), generics, or recursive classes (type / object classes depending on functional or OOP, but similar use-case). The latter two are usually far more verbose.
â ÃÂurous
Sep 3 at 22:39
Can we store the matrix as arrays of pointers to pointers (in C or asm), instead of proper multi-dimensional arrays where everything is contiguous in memory? I'm pretty sure all the normal higher-level / dynamically-typed languages with arbitrary nesting of lists are already treating things as lists of lists, not matrices, so I'm going to assume it's fine.
â Peter Cordes
Sep 5 at 3:42
@PeterCordes Sure, go ahead.
â Adám
Sep 5 at 5:35
add a comment |Â
I feel like the hardest part in most statically typed languages will be golfing the type signatures involved.
â ÃÂurous
Sep 3 at 22:07
@ÃÂurous How do those languages normally deal with arbitrary array data?
â Adám
Sep 3 at 22:29
1
there's three cases for "normal" use as I see it: only worrying about one level of the array (eg:reverse
works on arbitrary arrays but only cares about the first level), generics, or recursive classes (type / object classes depending on functional or OOP, but similar use-case). The latter two are usually far more verbose.
â ÃÂurous
Sep 3 at 22:39
Can we store the matrix as arrays of pointers to pointers (in C or asm), instead of proper multi-dimensional arrays where everything is contiguous in memory? I'm pretty sure all the normal higher-level / dynamically-typed languages with arbitrary nesting of lists are already treating things as lists of lists, not matrices, so I'm going to assume it's fine.
â Peter Cordes
Sep 5 at 3:42
@PeterCordes Sure, go ahead.
â Adám
Sep 5 at 5:35
I feel like the hardest part in most statically typed languages will be golfing the type signatures involved.
â ÃÂurous
Sep 3 at 22:07
I feel like the hardest part in most statically typed languages will be golfing the type signatures involved.
â ÃÂurous
Sep 3 at 22:07
@ÃÂurous How do those languages normally deal with arbitrary array data?
â Adám
Sep 3 at 22:29
@ÃÂurous How do those languages normally deal with arbitrary array data?
â Adám
Sep 3 at 22:29
1
1
there's three cases for "normal" use as I see it: only worrying about one level of the array (eg:
reverse
works on arbitrary arrays but only cares about the first level), generics, or recursive classes (type / object classes depending on functional or OOP, but similar use-case). The latter two are usually far more verbose.â ÃÂurous
Sep 3 at 22:39
there's three cases for "normal" use as I see it: only worrying about one level of the array (eg:
reverse
works on arbitrary arrays but only cares about the first level), generics, or recursive classes (type / object classes depending on functional or OOP, but similar use-case). The latter two are usually far more verbose.â ÃÂurous
Sep 3 at 22:39
Can we store the matrix as arrays of pointers to pointers (in C or asm), instead of proper multi-dimensional arrays where everything is contiguous in memory? I'm pretty sure all the normal higher-level / dynamically-typed languages with arbitrary nesting of lists are already treating things as lists of lists, not matrices, so I'm going to assume it's fine.
â Peter Cordes
Sep 5 at 3:42
Can we store the matrix as arrays of pointers to pointers (in C or asm), instead of proper multi-dimensional arrays where everything is contiguous in memory? I'm pretty sure all the normal higher-level / dynamically-typed languages with arbitrary nesting of lists are already treating things as lists of lists, not matrices, so I'm going to assume it's fine.
â Peter Cordes
Sep 5 at 3:42
@PeterCordes Sure, go ahead.
â Adám
Sep 5 at 5:35
@PeterCordes Sure, go ahead.
â Adám
Sep 5 at 5:35
add a comment |Â
15 Answers
15
active
oldest
votes
up vote
8
down vote
APL (Dyalog), 20 9 bytes
âÂÂâ½[âº]âµ/
Try it online!
How?
/
- reduce - take the rightmost element in the input (the array) and apply the function with next left element as left argument
â½[âº]âµ
- reverse in the left argument
(âº
) dimension
âÂÂ
- flatten the enclosed array
add a comment |Â
up vote
8
down vote
APL (Dyalog Unicode), 9 bytes
âÂÂâÂÂ[âº]âµâ¿
Try it online!
It looks like Uriel edited into something almost identical first, but I developed it independently. I thought this input format is invalid.
add a comment |Â
up vote
7
down vote
JavaScript (Node.js), 58 55 53 45 bytes
Saved 8 bytes thanks to @Shaggy
Takes input as (indications)(array)
, where indications is a Boolean list.
f=([r,...b])=>a=>1/r?a.sort(_=>r).map(f(b)):a
Try it online!
Commented
f = ( // f is a function taking:
[r, // r = next 'reverse' Boolean flag
...b] // b = array of remaining flags
) => // and returning an anonymous function taking:
a => // a = array (or sub-array) to process, or atomic element
1 / r ? // if r is defined:
a.sort(_ => r) // reverse a if r = 1; leave it unchanged otherwise
.map(f(b)) // for each element in the resulting array: do a recursive call,
// using f to generate a new callback function for the next flag
: // else:
a // a must be an atomic element and is simply left unchanged
Just usingr
inplace ofr||-1
seems to work.
â Shaggy
Sep 3 at 15:18
Wouldf=([r,...b])=>a=>1/r?a.sort(_=>r).map(f(b)):a
work? On my phone so can't test properly.
â Shaggy
Sep 3 at 22:10
@Shaggy Nice! I like this rather unusual processing flow.
â Arnauld
Sep 4 at 3:24
add a comment |Â
up vote
6
down vote
Python 2, 56 55 bytes
f=lambda a,t:t and[f(l,t[1:])for l in a][::1|-t[0]]or a
Try it online!
add a comment |Â
up vote
5
down vote
Jelly, 8 bytes
âÂÂâ¬áºÂâÂÂá¹ÂpFv
Takes a 0-indexed list of dimensions.
Try it online!
How it works
âÂÂâ¬áºÂâÂÂá¹ÂpFv Main link. Left arg: D (dimensions, 0-based), Right arg: A (array)
âÂÂâ¬ẠRepeat 'â¬' d times, for each d in D.
âÂÂá¹Âp Perform Cartesian product of ['á¹Â'] and each string of 'â¬'s, prepending a
'á¹Â' to each string of 'â¬'s.
F Flatten the result.
If, e.g., D = [0,2,4], we build the string "á¹Âá¹Â≬á¹Â≉‰¬".
v Eval the resulting string, using A as left argument.
1
That's horrible. Very nice!
â Adám
Sep 3 at 17:58
add a comment |Â
up vote
5
down vote
R, 80 78 77 bytes
Create the call to R's extractor [
by creating a list of sequences reversed where indicated. They actually contain zeros, which are silently ignored. The drop=F
is needed to prevent R's default dropping of dimensions. We need the rev
call to the dimension reverse indicator, because of the way R fills arrays.
-2 thanks @Giuseppe
-1 using in-line assignment.
function(x,a,d=dim(x))do.call("[",c(list(x),Map(seq,r<-d*rev(a),d-r),drop=F))
Try it online!
Honorable mention to @JayCe who came up with a variation that gets the same result in the same length:
function(x,a,d=dim(x))array(x[t(t(expand.grid(Map(seq,r<-d*rev(a),d-r))))],d)
Try it online!
1
78 bytes very nice answer!
â Giuseppe
Sep 3 at 19:38
1
Very profound answer. It took me a while to understand it completely. I tried replicating it without usingdo.call
- it's longer at 83 bytes, still posting this here as a comment for reference: TIO
â JayCe
Sep 4 at 14:01
Well actually, @JayCe, your great answer can also be golfed to 78 bytes!
â J.Doe
Sep 4 at 14:11
add a comment |Â
up vote
5
down vote
Haskell, 120 119 bytes
the function f takes the N-dimensional list and a list of bool as input
class F r where f::[Bool]->r->r
instance F Int where f=seq
instance F r=>F[r]where f(a:y)=last(id:[reverse|a]).map(f y)
1
You don't need parentheses aroundF r
.
â Ãrjan Johansen
Sep 3 at 18:01
1
TIO link with test cases and OJ's 1-byte golf.
â Scrooble
Sep 3 at 19:37
add a comment |Â
up vote
4
down vote
05AB1E, 23 11 10 bytes
'â¬sÃÂ'RëJ.V
Try it online.
-12 bytes thanks to @Mr.Xcoder.
Input as 0-indexed truthy-values (i.e. [0,2,3]
), which is the first input.
Explanation:
'â¬sà# Repeat "â¬" the indices amount of times
# i.e. [0,2,3] â ["","≬","≉¬"]
'Rë # Append each with "R"
# i.e. ["","≬","≉¬"] â ["R","≬R","≉¬R"]
J # Join them all together
# i.e. ["R","≬R","≉¬R"] â R≬R≉¬R
.V # Execute string as 05AB1E code
For example: if the indices input-list is [0,2,3]
, it will create the following string:
R≬R≉¬R
Which will:
≉¬R # Reverse the items in the most inner (4th level) lists
≬R # Reverse the most inner (3rd level) lists themselves
# Do nothing with the inner (2nd level) lists
R # Reverse the entire outer (1st level) list
Original 23 byte answer:
ÃÂURvyâ RèJâ¦õÿ}}â RXèJ.V
Input as boolean-list (i.e. [1,0,1,1]
), which is the first input.
Try it online.
Explanation:
ÃÂU # Pop and save the first boolean in variable `X`
R # Reverse the remaining boolean-list
v } # Loop `y` over each of them:
â Rè # Take the string "R ", and index the current boolean (0 or 1) in it
J # Join it together with the string of the previous iteration
â¦õÿ} # Surround it with "õ" and "}"
â RXè # Index variable `X` also in "R "
J # Join it together with the rest
.V # Execute string as 05AB1E code
For example: If the boolean input-list is [1,0,1,1]
, it will create the following string:
õõõR}R} }R
Which will:
õR} # Reverse the items in the most inner (4th level) lists
õ R} # Reverse the most inner (3rd level) lists themselves
õ } # Do nothing with the inner (2nd level) lists
R # Reverse the entire outer (1st level) list
1
Nice answer, but... uhm... would this 11 byter work?
â Mr. Xcoder
Sep 3 at 15:31
@Mr.Xcoder Thanks! That's indeed a lot easier. And been able to golf 1 more byte by appending each, instead of prepending and then reversing.
â Kevin Cruijssen
Sep 3 at 17:10
@Mr.Xcoder Btw, why does'x*
work to repeatx
n amount of times without using as
wap, but it doesn't work with'â¬*
?.. EDIT: Only in the legacy though..
â Kevin Cruijssen
Sep 3 at 17:12
The legacy version is quite buggy, it might be due to the fact thatâ¬
is still parsed as an operator even though it's in a char literal? Not sure to be honest. In the new version,*
doesn't behave the same way nonetheless.
â Mr. Xcoder
Sep 3 at 17:18
add a comment |Â
up vote
3
down vote
JavaScript (Node.js), 60 bytes
A different (recursive) approach. doesn't beat Arnauld's answer ... yet....
Takes the input as array, boolean list
f=(a,r)=>r>?(r[0]?a.reverse():a).map(c=>f(c,r.slice(1))):a
f=(a,r)=>r>?(r[0]?a.reverse():a).map(c=>f(c,r.slice(1))):a
console.log(f([[[[3,1,4,1],[5,9,2,6]],[[5,3,5,8],[9,7,9,3]]],[[[2,3,8,4],[6,2,6,4]],[[3,3,8,3],[2,7,9,5]]]],[true,false,true,true]))
add a comment |Â
up vote
3
down vote
Pyth, 15 bytes
.v+jk.n*_*LME
Try it here!
Annoyingly, handling the empty dimension list case takes no less than 2 bytes... I'd rather use ss
in place of jk.n
but :| Assumes that the list to be transformed can be given in native Pyth syntax, as a string. I've written a converter to Pyth syntax to make testing easier. In the unfortunate case that the OP chooses not to allow this, a 17-byter will "fix" it:
.v+jk.n*_*LMEE
add a comment |Â
up vote
3
down vote
Japt, 15 14 bytes
With some inspiration from Arnauld's solution.
Takes the indications as the first input, as a boolean array of 1
s and 0
s.
ÃÂ?Vn@ÃÂÃÂãÃÂUÃÂ
X:V
Try it
Explanation
:Implicit input of boolean array U=indications and multi-dimensional integer array V
ÃÂ :Get the length of U
? :If truthy (i.e., >0)
Vn : Sort V
@ÃÂÃÂ : Function that gets the first element of U; 0 will leave the array untouched, 1 will reverse it.
ã : Map each X
ÃÂ : Run the programme again with the following inputs
UÃÂ
: U with the first element removed
X : X will serve as the new value of V
: :Else
V : Just return V
add a comment |Â
up vote
3
down vote
Clean, 122 112 bytes
import StdEnv
class$r::[Bool]->r->r
instance$r where$_=id
instance$[r]| $r where$[a:y]=if(a)reverse id o map($y)
Try it online!
A version of Damien's Haskell answer using Clean's golfier type system. Really shows the extensive similarities between the two languages.
Explained:
import StdEnv // import basic stuff
class $ r :: [Bool] -> r -> r // $ takes a boolean list and returns a function on r to r
instance $ r // instance on all types, taken when no more specific instances exist
where $ _ = id // return the identity function for all arguments
instance $ [r] | $ r // instance for lists of a type which has an instance itself
where $ [a: y]
= if(a) reverse id // reverse if the head of the argument is true
o map ($ y) // composed with the map function acting on $ applied to the tail
add a comment |Â
up vote
2
down vote
Ruby, 54 bytes
f=->a,dr,*z=d;r&&a.reverse!;d==?a:a.map
Try it online!
add a comment |Â
up vote
1
down vote
(untested but I think correct. compiler asm output looks like what I expect. Will update if/when I find time to write a test harness that creates and prints this data structure.)
GNU C++ (portable) 148 bytes
#include<algorithm>
#include<cstdint>
struct mintptr_t d,l,a;void R(int*r)if(*r)std::reverse(a,a+l);for(int i=0;d&&i<l;((m*)a[i++])->R(r+1));;
GNU C++ (int=pointer and falls off a non-void function UB) 120 bytes
#include<algorithm>
struct mint d,l,a,R(int*r)if(*r)std::reverse(a,a+l);for(int i=0;d&&i<l;((m*)a[i++])->R(r+1));;
This is a struct of depth counter, length, array of integers or pointers. In the bottom level of this non-binary tree (depth==0
), the array of intptr_t
is an array of integers. In higher levels, it's a struct m*
stored in intptr_t
. Traversal takes a cast.
The R()
reverse function is a member function because that saves declaring an arg, and saves a lot of p->
syntax to reference the struct members vs. the implicit this
pointer.
The only GNU extension is the C99 flexible array member to make a variable-sized struct, which is supported in C++ as a GNU extension. I could have used a *a
member pointing to a separately-allocated array and have this be plain ISO C++. (And that would actually save a byte without requiring any other changes). I wrote this as a mockup / reference implementation for an asm version.
The shorter version with just int
also declares R()
as returning int
instead of void
. These two bits of hackery are unrelated; this is just the "works on at least one implementation" version.
It should work fine on 32-bit targets (where int
can hold a pointer), as long as you compile with gcc7 or older, or disable optimizations. (gcc8 -O3
assumes that execution can't reach the bottom of a non-void
function because that would be UB.) x86 gcc -m32 -O3
should work fine with gcc7, like on Godbolt where I included both versions (in different namespaces) and a non-member-function version.
Ungolfed
The function arg, int r
, is an array of 0 / non-zero integers that indicate whether a given depth should be swapped, starting with the outer-most level.
#include<algorithm> // for std::reverse
#include<cstdint> // for intptr_t. GNU C defines __intptr_t, so we could use that...
struct m
__intptr_t d,l,a; // depth = 0 means values, >0 means pointers.
// l = length
//__intptr_t a; // flexible array member: array contiguous with the struct
void R(int r)
if(*r)
std::reverse(a, a+l); // *r && std::reverse() doesn't work because it returns void.
if(d) // recurse if this isn't the bottom depth
for(int i=0 ; i<l ; i++) // tree traversal
((m*)a[i])->R(r+1); // with the rest of the depth list
; // struct m
When we recurse, we pass r+1
, so checking the current depth is always *r
.
An earlier version just passed r
unchanged, and checked r[d]
. With a flexible array member, I needed to store some kind of last-level indicator because a
is not a pointer, it's a true array with no indirection. But with a intptr_t *a
member, I couldn't just have that be nullptr
for the leaf level, because I want it to be values.
Reversing the current level before or after the tree traversal shouldn't matter. I didn't try to do it during.
I'm not sure that std::reverse
is worth the byte count vs. a manual loop, especially if I can work in calling R()
on each pointer exactly once somewhere inside that loop. But only if d!=0
Whoa, impressive.
â Adám
Sep 5 at 8:08
@Adám: thanks, it golfed down surprisingly naturally and well after I wrote it. I'm curious to see what I can do in x86 machine code :P
â Peter Cordes
Sep 5 at 8:29
add a comment |Â
up vote
1
down vote
Mathematica, 7 bytes
Reverse
Function. Give it a nested list as the first argument, and the 1-based list of levels/dimensions to reverse as the second argument. Try it online!
Finally, another challenge where Mathematica has a builtin!
layers to reverse? TIO link maybe?
â Adám
Sep 5 at 1:52
@Adám That is, the list of dimensions to reverse, generally referred to as levels in Mathematica.
â LegionMammal978
Sep 5 at 10:18
add a comment |Â
15 Answers
15
active
oldest
votes
15 Answers
15
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
8
down vote
APL (Dyalog), 20 9 bytes
âÂÂâ½[âº]âµ/
Try it online!
How?
/
- reduce - take the rightmost element in the input (the array) and apply the function with next left element as left argument
â½[âº]âµ
- reverse in the left argument
(âº
) dimension
âÂÂ
- flatten the enclosed array
add a comment |Â
up vote
8
down vote
APL (Dyalog), 20 9 bytes
âÂÂâ½[âº]âµ/
Try it online!
How?
/
- reduce - take the rightmost element in the input (the array) and apply the function with next left element as left argument
â½[âº]âµ
- reverse in the left argument
(âº
) dimension
âÂÂ
- flatten the enclosed array
add a comment |Â
up vote
8
down vote
up vote
8
down vote
APL (Dyalog), 20 9 bytes
âÂÂâ½[âº]âµ/
Try it online!
How?
/
- reduce - take the rightmost element in the input (the array) and apply the function with next left element as left argument
â½[âº]âµ
- reverse in the left argument
(âº
) dimension
âÂÂ
- flatten the enclosed array
APL (Dyalog), 20 9 bytes
âÂÂâ½[âº]âµ/
Try it online!
How?
/
- reduce - take the rightmost element in the input (the array) and apply the function with next left element as left argument
â½[âº]âµ
- reverse in the left argument
(âº
) dimension
âÂÂ
- flatten the enclosed array
edited Sep 3 at 18:07
answered Sep 3 at 13:05
Uriel
11.5k4936
11.5k4936
add a comment |Â
add a comment |Â
up vote
8
down vote
APL (Dyalog Unicode), 9 bytes
âÂÂâÂÂ[âº]âµâ¿
Try it online!
It looks like Uriel edited into something almost identical first, but I developed it independently. I thought this input format is invalid.
add a comment |Â
up vote
8
down vote
APL (Dyalog Unicode), 9 bytes
âÂÂâÂÂ[âº]âµâ¿
Try it online!
It looks like Uriel edited into something almost identical first, but I developed it independently. I thought this input format is invalid.
add a comment |Â
up vote
8
down vote
up vote
8
down vote
APL (Dyalog Unicode), 9 bytes
âÂÂâÂÂ[âº]âµâ¿
Try it online!
It looks like Uriel edited into something almost identical first, but I developed it independently. I thought this input format is invalid.
APL (Dyalog Unicode), 9 bytes
âÂÂâÂÂ[âº]âµâ¿
Try it online!
It looks like Uriel edited into something almost identical first, but I developed it independently. I thought this input format is invalid.
edited Sep 3 at 18:31
answered Sep 3 at 16:55
Erik the Outgolfer
29.4k42698
29.4k42698
add a comment |Â
add a comment |Â
up vote
7
down vote
JavaScript (Node.js), 58 55 53 45 bytes
Saved 8 bytes thanks to @Shaggy
Takes input as (indications)(array)
, where indications is a Boolean list.
f=([r,...b])=>a=>1/r?a.sort(_=>r).map(f(b)):a
Try it online!
Commented
f = ( // f is a function taking:
[r, // r = next 'reverse' Boolean flag
...b] // b = array of remaining flags
) => // and returning an anonymous function taking:
a => // a = array (or sub-array) to process, or atomic element
1 / r ? // if r is defined:
a.sort(_ => r) // reverse a if r = 1; leave it unchanged otherwise
.map(f(b)) // for each element in the resulting array: do a recursive call,
// using f to generate a new callback function for the next flag
: // else:
a // a must be an atomic element and is simply left unchanged
Just usingr
inplace ofr||-1
seems to work.
â Shaggy
Sep 3 at 15:18
Wouldf=([r,...b])=>a=>1/r?a.sort(_=>r).map(f(b)):a
work? On my phone so can't test properly.
â Shaggy
Sep 3 at 22:10
@Shaggy Nice! I like this rather unusual processing flow.
â Arnauld
Sep 4 at 3:24
add a comment |Â
up vote
7
down vote
JavaScript (Node.js), 58 55 53 45 bytes
Saved 8 bytes thanks to @Shaggy
Takes input as (indications)(array)
, where indications is a Boolean list.
f=([r,...b])=>a=>1/r?a.sort(_=>r).map(f(b)):a
Try it online!
Commented
f = ( // f is a function taking:
[r, // r = next 'reverse' Boolean flag
...b] // b = array of remaining flags
) => // and returning an anonymous function taking:
a => // a = array (or sub-array) to process, or atomic element
1 / r ? // if r is defined:
a.sort(_ => r) // reverse a if r = 1; leave it unchanged otherwise
.map(f(b)) // for each element in the resulting array: do a recursive call,
// using f to generate a new callback function for the next flag
: // else:
a // a must be an atomic element and is simply left unchanged
Just usingr
inplace ofr||-1
seems to work.
â Shaggy
Sep 3 at 15:18
Wouldf=([r,...b])=>a=>1/r?a.sort(_=>r).map(f(b)):a
work? On my phone so can't test properly.
â Shaggy
Sep 3 at 22:10
@Shaggy Nice! I like this rather unusual processing flow.
â Arnauld
Sep 4 at 3:24
add a comment |Â
up vote
7
down vote
up vote
7
down vote
JavaScript (Node.js), 58 55 53 45 bytes
Saved 8 bytes thanks to @Shaggy
Takes input as (indications)(array)
, where indications is a Boolean list.
f=([r,...b])=>a=>1/r?a.sort(_=>r).map(f(b)):a
Try it online!
Commented
f = ( // f is a function taking:
[r, // r = next 'reverse' Boolean flag
...b] // b = array of remaining flags
) => // and returning an anonymous function taking:
a => // a = array (or sub-array) to process, or atomic element
1 / r ? // if r is defined:
a.sort(_ => r) // reverse a if r = 1; leave it unchanged otherwise
.map(f(b)) // for each element in the resulting array: do a recursive call,
// using f to generate a new callback function for the next flag
: // else:
a // a must be an atomic element and is simply left unchanged
JavaScript (Node.js), 58 55 53 45 bytes
Saved 8 bytes thanks to @Shaggy
Takes input as (indications)(array)
, where indications is a Boolean list.
f=([r,...b])=>a=>1/r?a.sort(_=>r).map(f(b)):a
Try it online!
Commented
f = ( // f is a function taking:
[r, // r = next 'reverse' Boolean flag
...b] // b = array of remaining flags
) => // and returning an anonymous function taking:
a => // a = array (or sub-array) to process, or atomic element
1 / r ? // if r is defined:
a.sort(_ => r) // reverse a if r = 1; leave it unchanged otherwise
.map(f(b)) // for each element in the resulting array: do a recursive call,
// using f to generate a new callback function for the next flag
: // else:
a // a must be an atomic element and is simply left unchanged
edited Sep 4 at 3:21
answered Sep 3 at 13:29
Arnauld
63.6k580268
63.6k580268
Just usingr
inplace ofr||-1
seems to work.
â Shaggy
Sep 3 at 15:18
Wouldf=([r,...b])=>a=>1/r?a.sort(_=>r).map(f(b)):a
work? On my phone so can't test properly.
â Shaggy
Sep 3 at 22:10
@Shaggy Nice! I like this rather unusual processing flow.
â Arnauld
Sep 4 at 3:24
add a comment |Â
Just usingr
inplace ofr||-1
seems to work.
â Shaggy
Sep 3 at 15:18
Wouldf=([r,...b])=>a=>1/r?a.sort(_=>r).map(f(b)):a
work? On my phone so can't test properly.
â Shaggy
Sep 3 at 22:10
@Shaggy Nice! I like this rather unusual processing flow.
â Arnauld
Sep 4 at 3:24
Just using
r
inplace of r||-1
seems to work.â Shaggy
Sep 3 at 15:18
Just using
r
inplace of r||-1
seems to work.â Shaggy
Sep 3 at 15:18
Would
f=([r,...b])=>a=>1/r?a.sort(_=>r).map(f(b)):a
work? On my phone so can't test properly.â Shaggy
Sep 3 at 22:10
Would
f=([r,...b])=>a=>1/r?a.sort(_=>r).map(f(b)):a
work? On my phone so can't test properly.â Shaggy
Sep 3 at 22:10
@Shaggy Nice! I like this rather unusual processing flow.
â Arnauld
Sep 4 at 3:24
@Shaggy Nice! I like this rather unusual processing flow.
â Arnauld
Sep 4 at 3:24
add a comment |Â
up vote
6
down vote
Python 2, 56 55 bytes
f=lambda a,t:t and[f(l,t[1:])for l in a][::1|-t[0]]or a
Try it online!
add a comment |Â
up vote
6
down vote
Python 2, 56 55 bytes
f=lambda a,t:t and[f(l,t[1:])for l in a][::1|-t[0]]or a
Try it online!
add a comment |Â
up vote
6
down vote
up vote
6
down vote
Python 2, 56 55 bytes
f=lambda a,t:t and[f(l,t[1:])for l in a][::1|-t[0]]or a
Try it online!
Python 2, 56 55 bytes
f=lambda a,t:t and[f(l,t[1:])for l in a][::1|-t[0]]or a
Try it online!
edited Sep 3 at 13:57
answered Sep 3 at 13:02
TFeld
11.2k2833
11.2k2833
add a comment |Â
add a comment |Â
up vote
5
down vote
Jelly, 8 bytes
âÂÂâ¬áºÂâÂÂá¹ÂpFv
Takes a 0-indexed list of dimensions.
Try it online!
How it works
âÂÂâ¬áºÂâÂÂá¹ÂpFv Main link. Left arg: D (dimensions, 0-based), Right arg: A (array)
âÂÂâ¬ẠRepeat 'â¬' d times, for each d in D.
âÂÂá¹Âp Perform Cartesian product of ['á¹Â'] and each string of 'â¬'s, prepending a
'á¹Â' to each string of 'â¬'s.
F Flatten the result.
If, e.g., D = [0,2,4], we build the string "á¹Âá¹Â≬á¹Â≉‰¬".
v Eval the resulting string, using A as left argument.
1
That's horrible. Very nice!
â Adám
Sep 3 at 17:58
add a comment |Â
up vote
5
down vote
Jelly, 8 bytes
âÂÂâ¬áºÂâÂÂá¹ÂpFv
Takes a 0-indexed list of dimensions.
Try it online!
How it works
âÂÂâ¬áºÂâÂÂá¹ÂpFv Main link. Left arg: D (dimensions, 0-based), Right arg: A (array)
âÂÂâ¬ẠRepeat 'â¬' d times, for each d in D.
âÂÂá¹Âp Perform Cartesian product of ['á¹Â'] and each string of 'â¬'s, prepending a
'á¹Â' to each string of 'â¬'s.
F Flatten the result.
If, e.g., D = [0,2,4], we build the string "á¹Âá¹Â≬á¹Â≉‰¬".
v Eval the resulting string, using A as left argument.
1
That's horrible. Very nice!
â Adám
Sep 3 at 17:58
add a comment |Â
up vote
5
down vote
up vote
5
down vote
Jelly, 8 bytes
âÂÂâ¬áºÂâÂÂá¹ÂpFv
Takes a 0-indexed list of dimensions.
Try it online!
How it works
âÂÂâ¬áºÂâÂÂá¹ÂpFv Main link. Left arg: D (dimensions, 0-based), Right arg: A (array)
âÂÂâ¬ẠRepeat 'â¬' d times, for each d in D.
âÂÂá¹Âp Perform Cartesian product of ['á¹Â'] and each string of 'â¬'s, prepending a
'á¹Â' to each string of 'â¬'s.
F Flatten the result.
If, e.g., D = [0,2,4], we build the string "á¹Âá¹Â≬á¹Â≉‰¬".
v Eval the resulting string, using A as left argument.
Jelly, 8 bytes
âÂÂâ¬áºÂâÂÂá¹ÂpFv
Takes a 0-indexed list of dimensions.
Try it online!
How it works
âÂÂâ¬áºÂâÂÂá¹ÂpFv Main link. Left arg: D (dimensions, 0-based), Right arg: A (array)
âÂÂâ¬ẠRepeat 'â¬' d times, for each d in D.
âÂÂá¹Âp Perform Cartesian product of ['á¹Â'] and each string of 'â¬'s, prepending a
'á¹Â' to each string of 'â¬'s.
F Flatten the result.
If, e.g., D = [0,2,4], we build the string "á¹Âá¹Â≬á¹Â≉‰¬".
v Eval the resulting string, using A as left argument.
edited Sep 3 at 14:57
answered Sep 3 at 14:48
Dennisâ¦
182k32291722
182k32291722
1
That's horrible. Very nice!
â Adám
Sep 3 at 17:58
add a comment |Â
1
That's horrible. Very nice!
â Adám
Sep 3 at 17:58
1
1
That's horrible. Very nice!
â Adám
Sep 3 at 17:58
That's horrible. Very nice!
â Adám
Sep 3 at 17:58
add a comment |Â
up vote
5
down vote
R, 80 78 77 bytes
Create the call to R's extractor [
by creating a list of sequences reversed where indicated. They actually contain zeros, which are silently ignored. The drop=F
is needed to prevent R's default dropping of dimensions. We need the rev
call to the dimension reverse indicator, because of the way R fills arrays.
-2 thanks @Giuseppe
-1 using in-line assignment.
function(x,a,d=dim(x))do.call("[",c(list(x),Map(seq,r<-d*rev(a),d-r),drop=F))
Try it online!
Honorable mention to @JayCe who came up with a variation that gets the same result in the same length:
function(x,a,d=dim(x))array(x[t(t(expand.grid(Map(seq,r<-d*rev(a),d-r))))],d)
Try it online!
1
78 bytes very nice answer!
â Giuseppe
Sep 3 at 19:38
1
Very profound answer. It took me a while to understand it completely. I tried replicating it without usingdo.call
- it's longer at 83 bytes, still posting this here as a comment for reference: TIO
â JayCe
Sep 4 at 14:01
Well actually, @JayCe, your great answer can also be golfed to 78 bytes!
â J.Doe
Sep 4 at 14:11
add a comment |Â
up vote
5
down vote
R, 80 78 77 bytes
Create the call to R's extractor [
by creating a list of sequences reversed where indicated. They actually contain zeros, which are silently ignored. The drop=F
is needed to prevent R's default dropping of dimensions. We need the rev
call to the dimension reverse indicator, because of the way R fills arrays.
-2 thanks @Giuseppe
-1 using in-line assignment.
function(x,a,d=dim(x))do.call("[",c(list(x),Map(seq,r<-d*rev(a),d-r),drop=F))
Try it online!
Honorable mention to @JayCe who came up with a variation that gets the same result in the same length:
function(x,a,d=dim(x))array(x[t(t(expand.grid(Map(seq,r<-d*rev(a),d-r))))],d)
Try it online!
1
78 bytes very nice answer!
â Giuseppe
Sep 3 at 19:38
1
Very profound answer. It took me a while to understand it completely. I tried replicating it without usingdo.call
- it's longer at 83 bytes, still posting this here as a comment for reference: TIO
â JayCe
Sep 4 at 14:01
Well actually, @JayCe, your great answer can also be golfed to 78 bytes!
â J.Doe
Sep 4 at 14:11
add a comment |Â
up vote
5
down vote
up vote
5
down vote
R, 80 78 77 bytes
Create the call to R's extractor [
by creating a list of sequences reversed where indicated. They actually contain zeros, which are silently ignored. The drop=F
is needed to prevent R's default dropping of dimensions. We need the rev
call to the dimension reverse indicator, because of the way R fills arrays.
-2 thanks @Giuseppe
-1 using in-line assignment.
function(x,a,d=dim(x))do.call("[",c(list(x),Map(seq,r<-d*rev(a),d-r),drop=F))
Try it online!
Honorable mention to @JayCe who came up with a variation that gets the same result in the same length:
function(x,a,d=dim(x))array(x[t(t(expand.grid(Map(seq,r<-d*rev(a),d-r))))],d)
Try it online!
R, 80 78 77 bytes
Create the call to R's extractor [
by creating a list of sequences reversed where indicated. They actually contain zeros, which are silently ignored. The drop=F
is needed to prevent R's default dropping of dimensions. We need the rev
call to the dimension reverse indicator, because of the way R fills arrays.
-2 thanks @Giuseppe
-1 using in-line assignment.
function(x,a,d=dim(x))do.call("[",c(list(x),Map(seq,r<-d*rev(a),d-r),drop=F))
Try it online!
Honorable mention to @JayCe who came up with a variation that gets the same result in the same length:
function(x,a,d=dim(x))array(x[t(t(expand.grid(Map(seq,r<-d*rev(a),d-r))))],d)
Try it online!
edited Sep 4 at 14:45
answered Sep 3 at 17:41
J.Doe
6018
6018
1
78 bytes very nice answer!
â Giuseppe
Sep 3 at 19:38
1
Very profound answer. It took me a while to understand it completely. I tried replicating it without usingdo.call
- it's longer at 83 bytes, still posting this here as a comment for reference: TIO
â JayCe
Sep 4 at 14:01
Well actually, @JayCe, your great answer can also be golfed to 78 bytes!
â J.Doe
Sep 4 at 14:11
add a comment |Â
1
78 bytes very nice answer!
â Giuseppe
Sep 3 at 19:38
1
Very profound answer. It took me a while to understand it completely. I tried replicating it without usingdo.call
- it's longer at 83 bytes, still posting this here as a comment for reference: TIO
â JayCe
Sep 4 at 14:01
Well actually, @JayCe, your great answer can also be golfed to 78 bytes!
â J.Doe
Sep 4 at 14:11
1
1
78 bytes very nice answer!
â Giuseppe
Sep 3 at 19:38
78 bytes very nice answer!
â Giuseppe
Sep 3 at 19:38
1
1
Very profound answer. It took me a while to understand it completely. I tried replicating it without using
do.call
- it's longer at 83 bytes, still posting this here as a comment for reference: TIOâ JayCe
Sep 4 at 14:01
Very profound answer. It took me a while to understand it completely. I tried replicating it without using
do.call
- it's longer at 83 bytes, still posting this here as a comment for reference: TIOâ JayCe
Sep 4 at 14:01
Well actually, @JayCe, your great answer can also be golfed to 78 bytes!
â J.Doe
Sep 4 at 14:11
Well actually, @JayCe, your great answer can also be golfed to 78 bytes!
â J.Doe
Sep 4 at 14:11
add a comment |Â
up vote
5
down vote
Haskell, 120 119 bytes
the function f takes the N-dimensional list and a list of bool as input
class F r where f::[Bool]->r->r
instance F Int where f=seq
instance F r=>F[r]where f(a:y)=last(id:[reverse|a]).map(f y)
1
You don't need parentheses aroundF r
.
â Ãrjan Johansen
Sep 3 at 18:01
1
TIO link with test cases and OJ's 1-byte golf.
â Scrooble
Sep 3 at 19:37
add a comment |Â
up vote
5
down vote
Haskell, 120 119 bytes
the function f takes the N-dimensional list and a list of bool as input
class F r where f::[Bool]->r->r
instance F Int where f=seq
instance F r=>F[r]where f(a:y)=last(id:[reverse|a]).map(f y)
1
You don't need parentheses aroundF r
.
â Ãrjan Johansen
Sep 3 at 18:01
1
TIO link with test cases and OJ's 1-byte golf.
â Scrooble
Sep 3 at 19:37
add a comment |Â
up vote
5
down vote
up vote
5
down vote
Haskell, 120 119 bytes
the function f takes the N-dimensional list and a list of bool as input
class F r where f::[Bool]->r->r
instance F Int where f=seq
instance F r=>F[r]where f(a:y)=last(id:[reverse|a]).map(f y)
Haskell, 120 119 bytes
the function f takes the N-dimensional list and a list of bool as input
class F r where f::[Bool]->r->r
instance F Int where f=seq
instance F r=>F[r]where f(a:y)=last(id:[reverse|a]).map(f y)
edited Sep 6 at 6:18
answered Sep 3 at 14:43
Damien
2,379317
2,379317
1
You don't need parentheses aroundF r
.
â Ãrjan Johansen
Sep 3 at 18:01
1
TIO link with test cases and OJ's 1-byte golf.
â Scrooble
Sep 3 at 19:37
add a comment |Â
1
You don't need parentheses aroundF r
.
â Ãrjan Johansen
Sep 3 at 18:01
1
TIO link with test cases and OJ's 1-byte golf.
â Scrooble
Sep 3 at 19:37
1
1
You don't need parentheses around
F r
.â Ãrjan Johansen
Sep 3 at 18:01
You don't need parentheses around
F r
.â Ãrjan Johansen
Sep 3 at 18:01
1
1
TIO link with test cases and OJ's 1-byte golf.
â Scrooble
Sep 3 at 19:37
TIO link with test cases and OJ's 1-byte golf.
â Scrooble
Sep 3 at 19:37
add a comment |Â
up vote
4
down vote
05AB1E, 23 11 10 bytes
'â¬sÃÂ'RëJ.V
Try it online.
-12 bytes thanks to @Mr.Xcoder.
Input as 0-indexed truthy-values (i.e. [0,2,3]
), which is the first input.
Explanation:
'â¬sà# Repeat "â¬" the indices amount of times
# i.e. [0,2,3] â ["","≬","≉¬"]
'Rë # Append each with "R"
# i.e. ["","≬","≉¬"] â ["R","≬R","≉¬R"]
J # Join them all together
# i.e. ["R","≬R","≉¬R"] â R≬R≉¬R
.V # Execute string as 05AB1E code
For example: if the indices input-list is [0,2,3]
, it will create the following string:
R≬R≉¬R
Which will:
≉¬R # Reverse the items in the most inner (4th level) lists
≬R # Reverse the most inner (3rd level) lists themselves
# Do nothing with the inner (2nd level) lists
R # Reverse the entire outer (1st level) list
Original 23 byte answer:
ÃÂURvyâ RèJâ¦õÿ}}â RXèJ.V
Input as boolean-list (i.e. [1,0,1,1]
), which is the first input.
Try it online.
Explanation:
ÃÂU # Pop and save the first boolean in variable `X`
R # Reverse the remaining boolean-list
v } # Loop `y` over each of them:
â Rè # Take the string "R ", and index the current boolean (0 or 1) in it
J # Join it together with the string of the previous iteration
â¦õÿ} # Surround it with "õ" and "}"
â RXè # Index variable `X` also in "R "
J # Join it together with the rest
.V # Execute string as 05AB1E code
For example: If the boolean input-list is [1,0,1,1]
, it will create the following string:
õõõR}R} }R
Which will:
õR} # Reverse the items in the most inner (4th level) lists
õ R} # Reverse the most inner (3rd level) lists themselves
õ } # Do nothing with the inner (2nd level) lists
R # Reverse the entire outer (1st level) list
1
Nice answer, but... uhm... would this 11 byter work?
â Mr. Xcoder
Sep 3 at 15:31
@Mr.Xcoder Thanks! That's indeed a lot easier. And been able to golf 1 more byte by appending each, instead of prepending and then reversing.
â Kevin Cruijssen
Sep 3 at 17:10
@Mr.Xcoder Btw, why does'x*
work to repeatx
n amount of times without using as
wap, but it doesn't work with'â¬*
?.. EDIT: Only in the legacy though..
â Kevin Cruijssen
Sep 3 at 17:12
The legacy version is quite buggy, it might be due to the fact thatâ¬
is still parsed as an operator even though it's in a char literal? Not sure to be honest. In the new version,*
doesn't behave the same way nonetheless.
â Mr. Xcoder
Sep 3 at 17:18
add a comment |Â
up vote
4
down vote
05AB1E, 23 11 10 bytes
'â¬sÃÂ'RëJ.V
Try it online.
-12 bytes thanks to @Mr.Xcoder.
Input as 0-indexed truthy-values (i.e. [0,2,3]
), which is the first input.
Explanation:
'â¬sà# Repeat "â¬" the indices amount of times
# i.e. [0,2,3] â ["","≬","≉¬"]
'Rë # Append each with "R"
# i.e. ["","≬","≉¬"] â ["R","≬R","≉¬R"]
J # Join them all together
# i.e. ["R","≬R","≉¬R"] â R≬R≉¬R
.V # Execute string as 05AB1E code
For example: if the indices input-list is [0,2,3]
, it will create the following string:
R≬R≉¬R
Which will:
≉¬R # Reverse the items in the most inner (4th level) lists
≬R # Reverse the most inner (3rd level) lists themselves
# Do nothing with the inner (2nd level) lists
R # Reverse the entire outer (1st level) list
Original 23 byte answer:
ÃÂURvyâ RèJâ¦õÿ}}â RXèJ.V
Input as boolean-list (i.e. [1,0,1,1]
), which is the first input.
Try it online.
Explanation:
ÃÂU # Pop and save the first boolean in variable `X`
R # Reverse the remaining boolean-list
v } # Loop `y` over each of them:
â Rè # Take the string "R ", and index the current boolean (0 or 1) in it
J # Join it together with the string of the previous iteration
â¦õÿ} # Surround it with "õ" and "}"
â RXè # Index variable `X` also in "R "
J # Join it together with the rest
.V # Execute string as 05AB1E code
For example: If the boolean input-list is [1,0,1,1]
, it will create the following string:
õõõR}R} }R
Which will:
õR} # Reverse the items in the most inner (4th level) lists
õ R} # Reverse the most inner (3rd level) lists themselves
õ } # Do nothing with the inner (2nd level) lists
R # Reverse the entire outer (1st level) list
1
Nice answer, but... uhm... would this 11 byter work?
â Mr. Xcoder
Sep 3 at 15:31
@Mr.Xcoder Thanks! That's indeed a lot easier. And been able to golf 1 more byte by appending each, instead of prepending and then reversing.
â Kevin Cruijssen
Sep 3 at 17:10
@Mr.Xcoder Btw, why does'x*
work to repeatx
n amount of times without using as
wap, but it doesn't work with'â¬*
?.. EDIT: Only in the legacy though..
â Kevin Cruijssen
Sep 3 at 17:12
The legacy version is quite buggy, it might be due to the fact thatâ¬
is still parsed as an operator even though it's in a char literal? Not sure to be honest. In the new version,*
doesn't behave the same way nonetheless.
â Mr. Xcoder
Sep 3 at 17:18
add a comment |Â
up vote
4
down vote
up vote
4
down vote
05AB1E, 23 11 10 bytes
'â¬sÃÂ'RëJ.V
Try it online.
-12 bytes thanks to @Mr.Xcoder.
Input as 0-indexed truthy-values (i.e. [0,2,3]
), which is the first input.
Explanation:
'â¬sà# Repeat "â¬" the indices amount of times
# i.e. [0,2,3] â ["","≬","≉¬"]
'Rë # Append each with "R"
# i.e. ["","≬","≉¬"] â ["R","≬R","≉¬R"]
J # Join them all together
# i.e. ["R","≬R","≉¬R"] â R≬R≉¬R
.V # Execute string as 05AB1E code
For example: if the indices input-list is [0,2,3]
, it will create the following string:
R≬R≉¬R
Which will:
≉¬R # Reverse the items in the most inner (4th level) lists
≬R # Reverse the most inner (3rd level) lists themselves
# Do nothing with the inner (2nd level) lists
R # Reverse the entire outer (1st level) list
Original 23 byte answer:
ÃÂURvyâ RèJâ¦õÿ}}â RXèJ.V
Input as boolean-list (i.e. [1,0,1,1]
), which is the first input.
Try it online.
Explanation:
ÃÂU # Pop and save the first boolean in variable `X`
R # Reverse the remaining boolean-list
v } # Loop `y` over each of them:
â Rè # Take the string "R ", and index the current boolean (0 or 1) in it
J # Join it together with the string of the previous iteration
â¦õÿ} # Surround it with "õ" and "}"
â RXè # Index variable `X` also in "R "
J # Join it together with the rest
.V # Execute string as 05AB1E code
For example: If the boolean input-list is [1,0,1,1]
, it will create the following string:
õõõR}R} }R
Which will:
õR} # Reverse the items in the most inner (4th level) lists
õ R} # Reverse the most inner (3rd level) lists themselves
õ } # Do nothing with the inner (2nd level) lists
R # Reverse the entire outer (1st level) list
05AB1E, 23 11 10 bytes
'â¬sÃÂ'RëJ.V
Try it online.
-12 bytes thanks to @Mr.Xcoder.
Input as 0-indexed truthy-values (i.e. [0,2,3]
), which is the first input.
Explanation:
'â¬sà# Repeat "â¬" the indices amount of times
# i.e. [0,2,3] â ["","≬","≉¬"]
'Rë # Append each with "R"
# i.e. ["","≬","≉¬"] â ["R","≬R","≉¬R"]
J # Join them all together
# i.e. ["R","≬R","≉¬R"] â R≬R≉¬R
.V # Execute string as 05AB1E code
For example: if the indices input-list is [0,2,3]
, it will create the following string:
R≬R≉¬R
Which will:
≉¬R # Reverse the items in the most inner (4th level) lists
≬R # Reverse the most inner (3rd level) lists themselves
# Do nothing with the inner (2nd level) lists
R # Reverse the entire outer (1st level) list
Original 23 byte answer:
ÃÂURvyâ RèJâ¦õÿ}}â RXèJ.V
Input as boolean-list (i.e. [1,0,1,1]
), which is the first input.
Try it online.
Explanation:
ÃÂU # Pop and save the first boolean in variable `X`
R # Reverse the remaining boolean-list
v } # Loop `y` over each of them:
â Rè # Take the string "R ", and index the current boolean (0 or 1) in it
J # Join it together with the string of the previous iteration
â¦õÿ} # Surround it with "õ" and "}"
â RXè # Index variable `X` also in "R "
J # Join it together with the rest
.V # Execute string as 05AB1E code
For example: If the boolean input-list is [1,0,1,1]
, it will create the following string:
õõõR}R} }R
Which will:
õR} # Reverse the items in the most inner (4th level) lists
õ R} # Reverse the most inner (3rd level) lists themselves
õ } # Do nothing with the inner (2nd level) lists
R # Reverse the entire outer (1st level) list
edited Sep 3 at 17:10
answered Sep 3 at 13:03
Kevin Cruijssen
29.5k550162
29.5k550162
1
Nice answer, but... uhm... would this 11 byter work?
â Mr. Xcoder
Sep 3 at 15:31
@Mr.Xcoder Thanks! That's indeed a lot easier. And been able to golf 1 more byte by appending each, instead of prepending and then reversing.
â Kevin Cruijssen
Sep 3 at 17:10
@Mr.Xcoder Btw, why does'x*
work to repeatx
n amount of times without using as
wap, but it doesn't work with'â¬*
?.. EDIT: Only in the legacy though..
â Kevin Cruijssen
Sep 3 at 17:12
The legacy version is quite buggy, it might be due to the fact thatâ¬
is still parsed as an operator even though it's in a char literal? Not sure to be honest. In the new version,*
doesn't behave the same way nonetheless.
â Mr. Xcoder
Sep 3 at 17:18
add a comment |Â
1
Nice answer, but... uhm... would this 11 byter work?
â Mr. Xcoder
Sep 3 at 15:31
@Mr.Xcoder Thanks! That's indeed a lot easier. And been able to golf 1 more byte by appending each, instead of prepending and then reversing.
â Kevin Cruijssen
Sep 3 at 17:10
@Mr.Xcoder Btw, why does'x*
work to repeatx
n amount of times without using as
wap, but it doesn't work with'â¬*
?.. EDIT: Only in the legacy though..
â Kevin Cruijssen
Sep 3 at 17:12
The legacy version is quite buggy, it might be due to the fact thatâ¬
is still parsed as an operator even though it's in a char literal? Not sure to be honest. In the new version,*
doesn't behave the same way nonetheless.
â Mr. Xcoder
Sep 3 at 17:18
1
1
Nice answer, but... uhm... would this 11 byter work?
â Mr. Xcoder
Sep 3 at 15:31
Nice answer, but... uhm... would this 11 byter work?
â Mr. Xcoder
Sep 3 at 15:31
@Mr.Xcoder Thanks! That's indeed a lot easier. And been able to golf 1 more byte by appending each, instead of prepending and then reversing.
â Kevin Cruijssen
Sep 3 at 17:10
@Mr.Xcoder Thanks! That's indeed a lot easier. And been able to golf 1 more byte by appending each, instead of prepending and then reversing.
â Kevin Cruijssen
Sep 3 at 17:10
@Mr.Xcoder Btw, why does
'x*
work to repeat x
n amount of times without using a s
wap, but it doesn't work with 'â¬*
?.. EDIT: Only in the legacy though..â Kevin Cruijssen
Sep 3 at 17:12
@Mr.Xcoder Btw, why does
'x*
work to repeat x
n amount of times without using a s
wap, but it doesn't work with 'â¬*
?.. EDIT: Only in the legacy though..â Kevin Cruijssen
Sep 3 at 17:12
The legacy version is quite buggy, it might be due to the fact that
â¬
is still parsed as an operator even though it's in a char literal? Not sure to be honest. In the new version, *
doesn't behave the same way nonetheless.â Mr. Xcoder
Sep 3 at 17:18
The legacy version is quite buggy, it might be due to the fact that
â¬
is still parsed as an operator even though it's in a char literal? Not sure to be honest. In the new version, *
doesn't behave the same way nonetheless.â Mr. Xcoder
Sep 3 at 17:18
add a comment |Â
up vote
3
down vote
JavaScript (Node.js), 60 bytes
A different (recursive) approach. doesn't beat Arnauld's answer ... yet....
Takes the input as array, boolean list
f=(a,r)=>r>?(r[0]?a.reverse():a).map(c=>f(c,r.slice(1))):a
f=(a,r)=>r>?(r[0]?a.reverse():a).map(c=>f(c,r.slice(1))):a
console.log(f([[[[3,1,4,1],[5,9,2,6]],[[5,3,5,8],[9,7,9,3]]],[[[2,3,8,4],[6,2,6,4]],[[3,3,8,3],[2,7,9,5]]]],[true,false,true,true]))
add a comment |Â
up vote
3
down vote
JavaScript (Node.js), 60 bytes
A different (recursive) approach. doesn't beat Arnauld's answer ... yet....
Takes the input as array, boolean list
f=(a,r)=>r>?(r[0]?a.reverse():a).map(c=>f(c,r.slice(1))):a
f=(a,r)=>r>?(r[0]?a.reverse():a).map(c=>f(c,r.slice(1))):a
console.log(f([[[[3,1,4,1],[5,9,2,6]],[[5,3,5,8],[9,7,9,3]]],[[[2,3,8,4],[6,2,6,4]],[[3,3,8,3],[2,7,9,5]]]],[true,false,true,true]))
add a comment |Â
up vote
3
down vote
up vote
3
down vote
JavaScript (Node.js), 60 bytes
A different (recursive) approach. doesn't beat Arnauld's answer ... yet....
Takes the input as array, boolean list
f=(a,r)=>r>?(r[0]?a.reverse():a).map(c=>f(c,r.slice(1))):a
f=(a,r)=>r>?(r[0]?a.reverse():a).map(c=>f(c,r.slice(1))):a
console.log(f([[[[3,1,4,1],[5,9,2,6]],[[5,3,5,8],[9,7,9,3]]],[[[2,3,8,4],[6,2,6,4]],[[3,3,8,3],[2,7,9,5]]]],[true,false,true,true]))
JavaScript (Node.js), 60 bytes
A different (recursive) approach. doesn't beat Arnauld's answer ... yet....
Takes the input as array, boolean list
f=(a,r)=>r>?(r[0]?a.reverse():a).map(c=>f(c,r.slice(1))):a
f=(a,r)=>r>?(r[0]?a.reverse():a).map(c=>f(c,r.slice(1))):a
console.log(f([[[[3,1,4,1],[5,9,2,6]],[[5,3,5,8],[9,7,9,3]]],[[[2,3,8,4],[6,2,6,4]],[[3,3,8,3],[2,7,9,5]]]],[true,false,true,true]))
f=(a,r)=>r>?(r[0]?a.reverse():a).map(c=>f(c,r.slice(1))):a
console.log(f([[[[3,1,4,1],[5,9,2,6]],[[5,3,5,8],[9,7,9,3]]],[[[2,3,8,4],[6,2,6,4]],[[3,3,8,3],[2,7,9,5]]]],[true,false,true,true]))
f=(a,r)=>r>?(r[0]?a.reverse():a).map(c=>f(c,r.slice(1))):a
console.log(f([[[[3,1,4,1],[5,9,2,6]],[[5,3,5,8],[9,7,9,3]]],[[[2,3,8,4],[6,2,6,4]],[[3,3,8,3],[2,7,9,5]]]],[true,false,true,true]))
edited Sep 3 at 14:03
answered Sep 3 at 13:21
Luis felipe De jesus Munoz
2,9761044
2,9761044
add a comment |Â
add a comment |Â
up vote
3
down vote
Pyth, 15 bytes
.v+jk.n*_*LME
Try it here!
Annoyingly, handling the empty dimension list case takes no less than 2 bytes... I'd rather use ss
in place of jk.n
but :| Assumes that the list to be transformed can be given in native Pyth syntax, as a string. I've written a converter to Pyth syntax to make testing easier. In the unfortunate case that the OP chooses not to allow this, a 17-byter will "fix" it:
.v+jk.n*_*LMEE
add a comment |Â
up vote
3
down vote
Pyth, 15 bytes
.v+jk.n*_*LME
Try it here!
Annoyingly, handling the empty dimension list case takes no less than 2 bytes... I'd rather use ss
in place of jk.n
but :| Assumes that the list to be transformed can be given in native Pyth syntax, as a string. I've written a converter to Pyth syntax to make testing easier. In the unfortunate case that the OP chooses not to allow this, a 17-byter will "fix" it:
.v+jk.n*_*LMEE
add a comment |Â
up vote
3
down vote
up vote
3
down vote
Pyth, 15 bytes
.v+jk.n*_*LME
Try it here!
Annoyingly, handling the empty dimension list case takes no less than 2 bytes... I'd rather use ss
in place of jk.n
but :| Assumes that the list to be transformed can be given in native Pyth syntax, as a string. I've written a converter to Pyth syntax to make testing easier. In the unfortunate case that the OP chooses not to allow this, a 17-byter will "fix" it:
.v+jk.n*_*LMEE
Pyth, 15 bytes
.v+jk.n*_*LME
Try it here!
Annoyingly, handling the empty dimension list case takes no less than 2 bytes... I'd rather use ss
in place of jk.n
but :| Assumes that the list to be transformed can be given in native Pyth syntax, as a string. I've written a converter to Pyth syntax to make testing easier. In the unfortunate case that the OP chooses not to allow this, a 17-byter will "fix" it:
.v+jk.n*_*LMEE
edited Sep 3 at 16:10
answered Sep 3 at 16:05
Mr. Xcoder
30.3k758193
30.3k758193
add a comment |Â
add a comment |Â
up vote
3
down vote
Japt, 15 14 bytes
With some inspiration from Arnauld's solution.
Takes the indications as the first input, as a boolean array of 1
s and 0
s.
ÃÂ?Vn@ÃÂÃÂãÃÂUÃÂ
X:V
Try it
Explanation
:Implicit input of boolean array U=indications and multi-dimensional integer array V
ÃÂ :Get the length of U
? :If truthy (i.e., >0)
Vn : Sort V
@ÃÂÃÂ : Function that gets the first element of U; 0 will leave the array untouched, 1 will reverse it.
ã : Map each X
ÃÂ : Run the programme again with the following inputs
UÃÂ
: U with the first element removed
X : X will serve as the new value of V
: :Else
V : Just return V
add a comment |Â
up vote
3
down vote
Japt, 15 14 bytes
With some inspiration from Arnauld's solution.
Takes the indications as the first input, as a boolean array of 1
s and 0
s.
ÃÂ?Vn@ÃÂÃÂãÃÂUÃÂ
X:V
Try it
Explanation
:Implicit input of boolean array U=indications and multi-dimensional integer array V
ÃÂ :Get the length of U
? :If truthy (i.e., >0)
Vn : Sort V
@ÃÂÃÂ : Function that gets the first element of U; 0 will leave the array untouched, 1 will reverse it.
ã : Map each X
ÃÂ : Run the programme again with the following inputs
UÃÂ
: U with the first element removed
X : X will serve as the new value of V
: :Else
V : Just return V
add a comment |Â
up vote
3
down vote
up vote
3
down vote
Japt, 15 14 bytes
With some inspiration from Arnauld's solution.
Takes the indications as the first input, as a boolean array of 1
s and 0
s.
ÃÂ?Vn@ÃÂÃÂãÃÂUÃÂ
X:V
Try it
Explanation
:Implicit input of boolean array U=indications and multi-dimensional integer array V
ÃÂ :Get the length of U
? :If truthy (i.e., >0)
Vn : Sort V
@ÃÂÃÂ : Function that gets the first element of U; 0 will leave the array untouched, 1 will reverse it.
ã : Map each X
ÃÂ : Run the programme again with the following inputs
UÃÂ
: U with the first element removed
X : X will serve as the new value of V
: :Else
V : Just return V
Japt, 15 14 bytes
With some inspiration from Arnauld's solution.
Takes the indications as the first input, as a boolean array of 1
s and 0
s.
ÃÂ?Vn@ÃÂÃÂãÃÂUÃÂ
X:V
Try it
Explanation
:Implicit input of boolean array U=indications and multi-dimensional integer array V
ÃÂ :Get the length of U
? :If truthy (i.e., >0)
Vn : Sort V
@ÃÂÃÂ : Function that gets the first element of U; 0 will leave the array untouched, 1 will reverse it.
ã : Map each X
ÃÂ : Run the programme again with the following inputs
UÃÂ
: U with the first element removed
X : X will serve as the new value of V
: :Else
V : Just return V
edited Sep 3 at 16:12
answered Sep 3 at 15:38
Shaggy
16.3k21560
16.3k21560
add a comment |Â
add a comment |Â
up vote
3
down vote
Clean, 122 112 bytes
import StdEnv
class$r::[Bool]->r->r
instance$r where$_=id
instance$[r]| $r where$[a:y]=if(a)reverse id o map($y)
Try it online!
A version of Damien's Haskell answer using Clean's golfier type system. Really shows the extensive similarities between the two languages.
Explained:
import StdEnv // import basic stuff
class $ r :: [Bool] -> r -> r // $ takes a boolean list and returns a function on r to r
instance $ r // instance on all types, taken when no more specific instances exist
where $ _ = id // return the identity function for all arguments
instance $ [r] | $ r // instance for lists of a type which has an instance itself
where $ [a: y]
= if(a) reverse id // reverse if the head of the argument is true
o map ($ y) // composed with the map function acting on $ applied to the tail
add a comment |Â
up vote
3
down vote
Clean, 122 112 bytes
import StdEnv
class$r::[Bool]->r->r
instance$r where$_=id
instance$[r]| $r where$[a:y]=if(a)reverse id o map($y)
Try it online!
A version of Damien's Haskell answer using Clean's golfier type system. Really shows the extensive similarities between the two languages.
Explained:
import StdEnv // import basic stuff
class $ r :: [Bool] -> r -> r // $ takes a boolean list and returns a function on r to r
instance $ r // instance on all types, taken when no more specific instances exist
where $ _ = id // return the identity function for all arguments
instance $ [r] | $ r // instance for lists of a type which has an instance itself
where $ [a: y]
= if(a) reverse id // reverse if the head of the argument is true
o map ($ y) // composed with the map function acting on $ applied to the tail
add a comment |Â
up vote
3
down vote
up vote
3
down vote
Clean, 122 112 bytes
import StdEnv
class$r::[Bool]->r->r
instance$r where$_=id
instance$[r]| $r where$[a:y]=if(a)reverse id o map($y)
Try it online!
A version of Damien's Haskell answer using Clean's golfier type system. Really shows the extensive similarities between the two languages.
Explained:
import StdEnv // import basic stuff
class $ r :: [Bool] -> r -> r // $ takes a boolean list and returns a function on r to r
instance $ r // instance on all types, taken when no more specific instances exist
where $ _ = id // return the identity function for all arguments
instance $ [r] | $ r // instance for lists of a type which has an instance itself
where $ [a: y]
= if(a) reverse id // reverse if the head of the argument is true
o map ($ y) // composed with the map function acting on $ applied to the tail
Clean, 122 112 bytes
import StdEnv
class$r::[Bool]->r->r
instance$r where$_=id
instance$[r]| $r where$[a:y]=if(a)reverse id o map($y)
Try it online!
A version of Damien's Haskell answer using Clean's golfier type system. Really shows the extensive similarities between the two languages.
Explained:
import StdEnv // import basic stuff
class $ r :: [Bool] -> r -> r // $ takes a boolean list and returns a function on r to r
instance $ r // instance on all types, taken when no more specific instances exist
where $ _ = id // return the identity function for all arguments
instance $ [r] | $ r // instance for lists of a type which has an instance itself
where $ [a: y]
= if(a) reverse id // reverse if the head of the argument is true
o map ($ y) // composed with the map function acting on $ applied to the tail
edited Sep 4 at 1:37
answered Sep 3 at 22:33
ÃÂurous
5,2131931
5,2131931
add a comment |Â
add a comment |Â
up vote
2
down vote
Ruby, 54 bytes
f=->a,dr,*z=d;r&&a.reverse!;d==?a:a.map
Try it online!
add a comment |Â
up vote
2
down vote
Ruby, 54 bytes
f=->a,dr,*z=d;r&&a.reverse!;d==?a:a.map
Try it online!
add a comment |Â
up vote
2
down vote
up vote
2
down vote
Ruby, 54 bytes
f=->a,dr,*z=d;r&&a.reverse!;d==?a:a.map
Try it online!
Ruby, 54 bytes
f=->a,dr,*z=d;r&&a.reverse!;d==?a:a.map
Try it online!
edited Sep 6 at 7:30
answered Sep 6 at 7:11
G B
6,3571324
6,3571324
add a comment |Â
add a comment |Â
up vote
1
down vote
(untested but I think correct. compiler asm output looks like what I expect. Will update if/when I find time to write a test harness that creates and prints this data structure.)
GNU C++ (portable) 148 bytes
#include<algorithm>
#include<cstdint>
struct mintptr_t d,l,a;void R(int*r)if(*r)std::reverse(a,a+l);for(int i=0;d&&i<l;((m*)a[i++])->R(r+1));;
GNU C++ (int=pointer and falls off a non-void function UB) 120 bytes
#include<algorithm>
struct mint d,l,a,R(int*r)if(*r)std::reverse(a,a+l);for(int i=0;d&&i<l;((m*)a[i++])->R(r+1));;
This is a struct of depth counter, length, array of integers or pointers. In the bottom level of this non-binary tree (depth==0
), the array of intptr_t
is an array of integers. In higher levels, it's a struct m*
stored in intptr_t
. Traversal takes a cast.
The R()
reverse function is a member function because that saves declaring an arg, and saves a lot of p->
syntax to reference the struct members vs. the implicit this
pointer.
The only GNU extension is the C99 flexible array member to make a variable-sized struct, which is supported in C++ as a GNU extension. I could have used a *a
member pointing to a separately-allocated array and have this be plain ISO C++. (And that would actually save a byte without requiring any other changes). I wrote this as a mockup / reference implementation for an asm version.
The shorter version with just int
also declares R()
as returning int
instead of void
. These two bits of hackery are unrelated; this is just the "works on at least one implementation" version.
It should work fine on 32-bit targets (where int
can hold a pointer), as long as you compile with gcc7 or older, or disable optimizations. (gcc8 -O3
assumes that execution can't reach the bottom of a non-void
function because that would be UB.) x86 gcc -m32 -O3
should work fine with gcc7, like on Godbolt where I included both versions (in different namespaces) and a non-member-function version.
Ungolfed
The function arg, int r
, is an array of 0 / non-zero integers that indicate whether a given depth should be swapped, starting with the outer-most level.
#include<algorithm> // for std::reverse
#include<cstdint> // for intptr_t. GNU C defines __intptr_t, so we could use that...
struct m
__intptr_t d,l,a; // depth = 0 means values, >0 means pointers.
// l = length
//__intptr_t a; // flexible array member: array contiguous with the struct
void R(int r)
if(*r)
std::reverse(a, a+l); // *r && std::reverse() doesn't work because it returns void.
if(d) // recurse if this isn't the bottom depth
for(int i=0 ; i<l ; i++) // tree traversal
((m*)a[i])->R(r+1); // with the rest of the depth list
; // struct m
When we recurse, we pass r+1
, so checking the current depth is always *r
.
An earlier version just passed r
unchanged, and checked r[d]
. With a flexible array member, I needed to store some kind of last-level indicator because a
is not a pointer, it's a true array with no indirection. But with a intptr_t *a
member, I couldn't just have that be nullptr
for the leaf level, because I want it to be values.
Reversing the current level before or after the tree traversal shouldn't matter. I didn't try to do it during.
I'm not sure that std::reverse
is worth the byte count vs. a manual loop, especially if I can work in calling R()
on each pointer exactly once somewhere inside that loop. But only if d!=0
Whoa, impressive.
â Adám
Sep 5 at 8:08
@Adám: thanks, it golfed down surprisingly naturally and well after I wrote it. I'm curious to see what I can do in x86 machine code :P
â Peter Cordes
Sep 5 at 8:29
add a comment |Â
up vote
1
down vote
(untested but I think correct. compiler asm output looks like what I expect. Will update if/when I find time to write a test harness that creates and prints this data structure.)
GNU C++ (portable) 148 bytes
#include<algorithm>
#include<cstdint>
struct mintptr_t d,l,a;void R(int*r)if(*r)std::reverse(a,a+l);for(int i=0;d&&i<l;((m*)a[i++])->R(r+1));;
GNU C++ (int=pointer and falls off a non-void function UB) 120 bytes
#include<algorithm>
struct mint d,l,a,R(int*r)if(*r)std::reverse(a,a+l);for(int i=0;d&&i<l;((m*)a[i++])->R(r+1));;
This is a struct of depth counter, length, array of integers or pointers. In the bottom level of this non-binary tree (depth==0
), the array of intptr_t
is an array of integers. In higher levels, it's a struct m*
stored in intptr_t
. Traversal takes a cast.
The R()
reverse function is a member function because that saves declaring an arg, and saves a lot of p->
syntax to reference the struct members vs. the implicit this
pointer.
The only GNU extension is the C99 flexible array member to make a variable-sized struct, which is supported in C++ as a GNU extension. I could have used a *a
member pointing to a separately-allocated array and have this be plain ISO C++. (And that would actually save a byte without requiring any other changes). I wrote this as a mockup / reference implementation for an asm version.
The shorter version with just int
also declares R()
as returning int
instead of void
. These two bits of hackery are unrelated; this is just the "works on at least one implementation" version.
It should work fine on 32-bit targets (where int
can hold a pointer), as long as you compile with gcc7 or older, or disable optimizations. (gcc8 -O3
assumes that execution can't reach the bottom of a non-void
function because that would be UB.) x86 gcc -m32 -O3
should work fine with gcc7, like on Godbolt where I included both versions (in different namespaces) and a non-member-function version.
Ungolfed
The function arg, int r
, is an array of 0 / non-zero integers that indicate whether a given depth should be swapped, starting with the outer-most level.
#include<algorithm> // for std::reverse
#include<cstdint> // for intptr_t. GNU C defines __intptr_t, so we could use that...
struct m
__intptr_t d,l,a; // depth = 0 means values, >0 means pointers.
// l = length
//__intptr_t a; // flexible array member: array contiguous with the struct
void R(int r)
if(*r)
std::reverse(a, a+l); // *r && std::reverse() doesn't work because it returns void.
if(d) // recurse if this isn't the bottom depth
for(int i=0 ; i<l ; i++) // tree traversal
((m*)a[i])->R(r+1); // with the rest of the depth list
; // struct m
When we recurse, we pass r+1
, so checking the current depth is always *r
.
An earlier version just passed r
unchanged, and checked r[d]
. With a flexible array member, I needed to store some kind of last-level indicator because a
is not a pointer, it's a true array with no indirection. But with a intptr_t *a
member, I couldn't just have that be nullptr
for the leaf level, because I want it to be values.
Reversing the current level before or after the tree traversal shouldn't matter. I didn't try to do it during.
I'm not sure that std::reverse
is worth the byte count vs. a manual loop, especially if I can work in calling R()
on each pointer exactly once somewhere inside that loop. But only if d!=0
Whoa, impressive.
â Adám
Sep 5 at 8:08
@Adám: thanks, it golfed down surprisingly naturally and well after I wrote it. I'm curious to see what I can do in x86 machine code :P
â Peter Cordes
Sep 5 at 8:29
add a comment |Â
up vote
1
down vote
up vote
1
down vote
(untested but I think correct. compiler asm output looks like what I expect. Will update if/when I find time to write a test harness that creates and prints this data structure.)
GNU C++ (portable) 148 bytes
#include<algorithm>
#include<cstdint>
struct mintptr_t d,l,a;void R(int*r)if(*r)std::reverse(a,a+l);for(int i=0;d&&i<l;((m*)a[i++])->R(r+1));;
GNU C++ (int=pointer and falls off a non-void function UB) 120 bytes
#include<algorithm>
struct mint d,l,a,R(int*r)if(*r)std::reverse(a,a+l);for(int i=0;d&&i<l;((m*)a[i++])->R(r+1));;
This is a struct of depth counter, length, array of integers or pointers. In the bottom level of this non-binary tree (depth==0
), the array of intptr_t
is an array of integers. In higher levels, it's a struct m*
stored in intptr_t
. Traversal takes a cast.
The R()
reverse function is a member function because that saves declaring an arg, and saves a lot of p->
syntax to reference the struct members vs. the implicit this
pointer.
The only GNU extension is the C99 flexible array member to make a variable-sized struct, which is supported in C++ as a GNU extension. I could have used a *a
member pointing to a separately-allocated array and have this be plain ISO C++. (And that would actually save a byte without requiring any other changes). I wrote this as a mockup / reference implementation for an asm version.
The shorter version with just int
also declares R()
as returning int
instead of void
. These two bits of hackery are unrelated; this is just the "works on at least one implementation" version.
It should work fine on 32-bit targets (where int
can hold a pointer), as long as you compile with gcc7 or older, or disable optimizations. (gcc8 -O3
assumes that execution can't reach the bottom of a non-void
function because that would be UB.) x86 gcc -m32 -O3
should work fine with gcc7, like on Godbolt where I included both versions (in different namespaces) and a non-member-function version.
Ungolfed
The function arg, int r
, is an array of 0 / non-zero integers that indicate whether a given depth should be swapped, starting with the outer-most level.
#include<algorithm> // for std::reverse
#include<cstdint> // for intptr_t. GNU C defines __intptr_t, so we could use that...
struct m
__intptr_t d,l,a; // depth = 0 means values, >0 means pointers.
// l = length
//__intptr_t a; // flexible array member: array contiguous with the struct
void R(int r)
if(*r)
std::reverse(a, a+l); // *r && std::reverse() doesn't work because it returns void.
if(d) // recurse if this isn't the bottom depth
for(int i=0 ; i<l ; i++) // tree traversal
((m*)a[i])->R(r+1); // with the rest of the depth list
; // struct m
When we recurse, we pass r+1
, so checking the current depth is always *r
.
An earlier version just passed r
unchanged, and checked r[d]
. With a flexible array member, I needed to store some kind of last-level indicator because a
is not a pointer, it's a true array with no indirection. But with a intptr_t *a
member, I couldn't just have that be nullptr
for the leaf level, because I want it to be values.
Reversing the current level before or after the tree traversal shouldn't matter. I didn't try to do it during.
I'm not sure that std::reverse
is worth the byte count vs. a manual loop, especially if I can work in calling R()
on each pointer exactly once somewhere inside that loop. But only if d!=0
(untested but I think correct. compiler asm output looks like what I expect. Will update if/when I find time to write a test harness that creates and prints this data structure.)
GNU C++ (portable) 148 bytes
#include<algorithm>
#include<cstdint>
struct mintptr_t d,l,a;void R(int*r)if(*r)std::reverse(a,a+l);for(int i=0;d&&i<l;((m*)a[i++])->R(r+1));;
GNU C++ (int=pointer and falls off a non-void function UB) 120 bytes
#include<algorithm>
struct mint d,l,a,R(int*r)if(*r)std::reverse(a,a+l);for(int i=0;d&&i<l;((m*)a[i++])->R(r+1));;
This is a struct of depth counter, length, array of integers or pointers. In the bottom level of this non-binary tree (depth==0
), the array of intptr_t
is an array of integers. In higher levels, it's a struct m*
stored in intptr_t
. Traversal takes a cast.
The R()
reverse function is a member function because that saves declaring an arg, and saves a lot of p->
syntax to reference the struct members vs. the implicit this
pointer.
The only GNU extension is the C99 flexible array member to make a variable-sized struct, which is supported in C++ as a GNU extension. I could have used a *a
member pointing to a separately-allocated array and have this be plain ISO C++. (And that would actually save a byte without requiring any other changes). I wrote this as a mockup / reference implementation for an asm version.
The shorter version with just int
also declares R()
as returning int
instead of void
. These two bits of hackery are unrelated; this is just the "works on at least one implementation" version.
It should work fine on 32-bit targets (where int
can hold a pointer), as long as you compile with gcc7 or older, or disable optimizations. (gcc8 -O3
assumes that execution can't reach the bottom of a non-void
function because that would be UB.) x86 gcc -m32 -O3
should work fine with gcc7, like on Godbolt where I included both versions (in different namespaces) and a non-member-function version.
Ungolfed
The function arg, int r
, is an array of 0 / non-zero integers that indicate whether a given depth should be swapped, starting with the outer-most level.
#include<algorithm> // for std::reverse
#include<cstdint> // for intptr_t. GNU C defines __intptr_t, so we could use that...
struct m
__intptr_t d,l,a; // depth = 0 means values, >0 means pointers.
// l = length
//__intptr_t a; // flexible array member: array contiguous with the struct
void R(int r)
if(*r)
std::reverse(a, a+l); // *r && std::reverse() doesn't work because it returns void.
if(d) // recurse if this isn't the bottom depth
for(int i=0 ; i<l ; i++) // tree traversal
((m*)a[i])->R(r+1); // with the rest of the depth list
; // struct m
When we recurse, we pass r+1
, so checking the current depth is always *r
.
An earlier version just passed r
unchanged, and checked r[d]
. With a flexible array member, I needed to store some kind of last-level indicator because a
is not a pointer, it's a true array with no indirection. But with a intptr_t *a
member, I couldn't just have that be nullptr
for the leaf level, because I want it to be values.
Reversing the current level before or after the tree traversal shouldn't matter. I didn't try to do it during.
I'm not sure that std::reverse
is worth the byte count vs. a manual loop, especially if I can work in calling R()
on each pointer exactly once somewhere inside that loop. But only if d!=0
edited Sep 5 at 8:26
answered Sep 5 at 7:53
Peter Cordes
1,912917
1,912917
Whoa, impressive.
â Adám
Sep 5 at 8:08
@Adám: thanks, it golfed down surprisingly naturally and well after I wrote it. I'm curious to see what I can do in x86 machine code :P
â Peter Cordes
Sep 5 at 8:29
add a comment |Â
Whoa, impressive.
â Adám
Sep 5 at 8:08
@Adám: thanks, it golfed down surprisingly naturally and well after I wrote it. I'm curious to see what I can do in x86 machine code :P
â Peter Cordes
Sep 5 at 8:29
Whoa, impressive.
â Adám
Sep 5 at 8:08
Whoa, impressive.
â Adám
Sep 5 at 8:08
@Adám: thanks, it golfed down surprisingly naturally and well after I wrote it. I'm curious to see what I can do in x86 machine code :P
â Peter Cordes
Sep 5 at 8:29
@Adám: thanks, it golfed down surprisingly naturally and well after I wrote it. I'm curious to see what I can do in x86 machine code :P
â Peter Cordes
Sep 5 at 8:29
add a comment |Â
up vote
1
down vote
Mathematica, 7 bytes
Reverse
Function. Give it a nested list as the first argument, and the 1-based list of levels/dimensions to reverse as the second argument. Try it online!
Finally, another challenge where Mathematica has a builtin!
layers to reverse? TIO link maybe?
â Adám
Sep 5 at 1:52
@Adám That is, the list of dimensions to reverse, generally referred to as levels in Mathematica.
â LegionMammal978
Sep 5 at 10:18
add a comment |Â
up vote
1
down vote
Mathematica, 7 bytes
Reverse
Function. Give it a nested list as the first argument, and the 1-based list of levels/dimensions to reverse as the second argument. Try it online!
Finally, another challenge where Mathematica has a builtin!
layers to reverse? TIO link maybe?
â Adám
Sep 5 at 1:52
@Adám That is, the list of dimensions to reverse, generally referred to as levels in Mathematica.
â LegionMammal978
Sep 5 at 10:18
add a comment |Â
up vote
1
down vote
up vote
1
down vote
Mathematica, 7 bytes
Reverse
Function. Give it a nested list as the first argument, and the 1-based list of levels/dimensions to reverse as the second argument. Try it online!
Finally, another challenge where Mathematica has a builtin!
Mathematica, 7 bytes
Reverse
Function. Give it a nested list as the first argument, and the 1-based list of levels/dimensions to reverse as the second argument. Try it online!
Finally, another challenge where Mathematica has a builtin!
edited Sep 5 at 10:34
answered Sep 4 at 22:44
LegionMammal978
14.8k41752
14.8k41752
layers to reverse? TIO link maybe?
â Adám
Sep 5 at 1:52
@Adám That is, the list of dimensions to reverse, generally referred to as levels in Mathematica.
â LegionMammal978
Sep 5 at 10:18
add a comment |Â
layers to reverse? TIO link maybe?
â Adám
Sep 5 at 1:52
@Adám That is, the list of dimensions to reverse, generally referred to as levels in Mathematica.
â LegionMammal978
Sep 5 at 10:18
layers to reverse? TIO link maybe?
â Adám
Sep 5 at 1:52
layers to reverse? TIO link maybe?
â Adám
Sep 5 at 1:52
@Adám That is, the list of dimensions to reverse, generally referred to as levels in Mathematica.
â LegionMammal978
Sep 5 at 10:18
@Adám That is, the list of dimensions to reverse, generally referred to as levels in Mathematica.
â LegionMammal978
Sep 5 at 10:18
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodegolf.stackexchange.com%2fquestions%2f171627%2fmulti-dimensional-reversal%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
I feel like the hardest part in most statically typed languages will be golfing the type signatures involved.
â ÃÂurous
Sep 3 at 22:07
@ÃÂurous How do those languages normally deal with arbitrary array data?
â Adám
Sep 3 at 22:29
1
there's three cases for "normal" use as I see it: only worrying about one level of the array (eg:
reverse
works on arbitrary arrays but only cares about the first level), generics, or recursive classes (type / object classes depending on functional or OOP, but similar use-case). The latter two are usually far more verbose.â ÃÂurous
Sep 3 at 22:39
Can we store the matrix as arrays of pointers to pointers (in C or asm), instead of proper multi-dimensional arrays where everything is contiguous in memory? I'm pretty sure all the normal higher-level / dynamically-typed languages with arbitrary nesting of lists are already treating things as lists of lists, not matrices, so I'm going to assume it's fine.
â Peter Cordes
Sep 5 at 3:42
@PeterCordes Sure, go ahead.
â Adám
Sep 5 at 5:35