Multi-dimensional reversal

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
23
down vote

favorite
2












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]]]]







share|improve this question






















  • 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














up vote
23
down vote

favorite
2












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]]]]







share|improve this question






















  • 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












up vote
23
down vote

favorite
2









up vote
23
down vote

favorite
2






2





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]]]]







share|improve this question














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]]]]









share|improve this question













share|improve this question




share|improve this question








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
















  • 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










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






share|improve this answer





























    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.






    share|improve this answer





























      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





      share|improve this answer






















      • 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










      • @Shaggy Nice! I like this rather unusual processing flow.
        – Arnauld
        Sep 4 at 3:24

















      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!






      share|improve this answer





























        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.





        share|improve this answer


















        • 1




          That's horrible. Very nice!
          – Adám
          Sep 3 at 17:58

















        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!






        share|improve this answer


















        • 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 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


















        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)





        share|improve this answer


















        • 1




          You don't need parentheses around F 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


















        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





        share|improve this answer


















        • 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 repeat x n amount of times without using a swap, 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


















        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]))








        share|improve this answer





























          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





          share|improve this answer





























            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 1s and 0s.



            Ê?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





            share|improve this answer





























              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





              share|improve this answer





























                up vote
                2
                down vote














                Ruby, 54 bytes





                f=->a,dr,*z=d;r&&a.reverse!;d==?a:a.map


                Try it online!






                share|improve this answer





























                  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






                  share|improve this answer






















                  • 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

















                  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!






                  share|improve this answer






















                  • 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










                  Your Answer




                  StackExchange.ifUsing("editor", function ()
                  return StackExchange.using("mathjaxEditing", function ()
                  StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
                  StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
                  );
                  );
                  , "mathjax-editing");

                  StackExchange.ifUsing("editor", function ()
                  StackExchange.using("externalEditor", function ()
                  StackExchange.using("snippets", function ()
                  StackExchange.snippets.init();
                  );
                  );
                  , "code-snippets");

                  StackExchange.ready(function()
                  var channelOptions =
                  tags: "".split(" "),
                  id: "200"
                  ;
                  initTagRenderer("".split(" "), "".split(" "), channelOptions);

                  StackExchange.using("externalEditor", function()
                  // Have to fire editor after snippets, if snippets enabled
                  if (StackExchange.settings.snippets.snippetsEnabled)
                  StackExchange.using("snippets", function()
                  createEditor();
                  );

                  else
                  createEditor();

                  );

                  function createEditor()
                  StackExchange.prepareEditor(
                  heartbeatType: 'answer',
                  convertImagesToLinks: false,
                  noModals: false,
                  showLowRepImageUploadWarning: true,
                  reputationToPostImages: null,
                  bindNavPrevention: true,
                  postfix: "",
                  onDemand: true,
                  discardSelector: ".discard-answer"
                  ,immediatelyShowMarkdownHelp:true
                  );



                  );













                   

                  draft saved


                  draft discarded


















                  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






























                  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






                  share|improve this answer


























                    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






                    share|improve this answer
























                      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






                      share|improve this answer















                      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







                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited Sep 3 at 18:07

























                      answered Sep 3 at 13:05









                      Uriel

                      11.5k4936




                      11.5k4936




















                          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.






                          share|improve this answer


























                            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.






                            share|improve this answer
























                              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.






                              share|improve this answer















                              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.







                              share|improve this answer














                              share|improve this answer



                              share|improve this answer








                              edited Sep 3 at 18:31

























                              answered Sep 3 at 16:55









                              Erik the Outgolfer

                              29.4k42698




                              29.4k42698




















                                  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





                                  share|improve this answer






















                                  • 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










                                  • @Shaggy Nice! I like this rather unusual processing flow.
                                    – Arnauld
                                    Sep 4 at 3:24














                                  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





                                  share|improve this answer






















                                  • 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










                                  • @Shaggy Nice! I like this rather unusual processing flow.
                                    – Arnauld
                                    Sep 4 at 3:24












                                  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





                                  share|improve this answer















                                  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






                                  share|improve this answer














                                  share|improve this answer



                                  share|improve this answer








                                  edited Sep 4 at 3:21

























                                  answered Sep 3 at 13:29









                                  Arnauld

                                  63.6k580268




                                  63.6k580268











                                  • 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










                                  • @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











                                  • 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















                                  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










                                  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!






                                  share|improve this answer


























                                    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!






                                    share|improve this answer
























                                      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!






                                      share|improve this answer















                                      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!







                                      share|improve this answer














                                      share|improve this answer



                                      share|improve this answer








                                      edited Sep 3 at 13:57

























                                      answered Sep 3 at 13:02









                                      TFeld

                                      11.2k2833




                                      11.2k2833




















                                          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.





                                          share|improve this answer


















                                          • 1




                                            That's horrible. Very nice!
                                            – Adám
                                            Sep 3 at 17:58














                                          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.





                                          share|improve this answer


















                                          • 1




                                            That's horrible. Very nice!
                                            – Adám
                                            Sep 3 at 17:58












                                          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.





                                          share|improve this answer















                                          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.






                                          share|improve this answer














                                          share|improve this answer



                                          share|improve this answer








                                          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












                                          • 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










                                          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!






                                          share|improve this answer


















                                          • 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 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















                                          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!






                                          share|improve this answer


















                                          • 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 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













                                          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!






                                          share|improve this answer















                                          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!







                                          share|improve this answer














                                          share|improve this answer



                                          share|improve this answer








                                          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 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













                                          • 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 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








                                          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











                                          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)





                                          share|improve this answer


















                                          • 1




                                            You don't need parentheses around F 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















                                          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)





                                          share|improve this answer


















                                          • 1




                                            You don't need parentheses around F 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













                                          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)





                                          share|improve this answer














                                          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)






                                          share|improve this answer














                                          share|improve this answer



                                          share|improve this answer








                                          edited Sep 6 at 6:18

























                                          answered Sep 3 at 14:43









                                          Damien

                                          2,379317




                                          2,379317







                                          • 1




                                            You don't need parentheses around F 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




                                            You don't need parentheses around F 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











                                          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





                                          share|improve this answer


















                                          • 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 repeat x n amount of times without using a swap, 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















                                          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





                                          share|improve this answer


















                                          • 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 repeat x n amount of times without using a swap, 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













                                          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





                                          share|improve this answer















                                          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






                                          share|improve this answer














                                          share|improve this answer



                                          share|improve this answer








                                          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 repeat x n amount of times without using a swap, 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




                                            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 repeat x n amount of times without using a swap, 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 swap, 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 swap, 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











                                          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]))








                                          share|improve this answer


























                                            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]))








                                            share|improve this answer
























                                              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]))








                                              share|improve this answer















                                              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]))






                                              share|improve this answer














                                              share|improve this answer



                                              share|improve this answer








                                              edited Sep 3 at 14:03

























                                              answered Sep 3 at 13:21









                                              Luis felipe De jesus Munoz

                                              2,9761044




                                              2,9761044




















                                                  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





                                                  share|improve this answer


























                                                    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





                                                    share|improve this answer
























                                                      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





                                                      share|improve this answer















                                                      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






                                                      share|improve this answer














                                                      share|improve this answer



                                                      share|improve this answer








                                                      edited Sep 3 at 16:10

























                                                      answered Sep 3 at 16:05









                                                      Mr. Xcoder

                                                      30.3k758193




                                                      30.3k758193




















                                                          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 1s and 0s.



                                                          Ê?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





                                                          share|improve this answer


























                                                            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 1s and 0s.



                                                            Ê?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





                                                            share|improve this answer
























                                                              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 1s and 0s.



                                                              Ê?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





                                                              share|improve this answer















                                                              Japt, 15 14 bytes



                                                              With some inspiration from Arnauld's solution.



                                                              Takes the indications as the first input, as a boolean array of 1s and 0s.



                                                              Ê?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






                                                              share|improve this answer














                                                              share|improve this answer



                                                              share|improve this answer








                                                              edited Sep 3 at 16:12

























                                                              answered Sep 3 at 15:38









                                                              Shaggy

                                                              16.3k21560




                                                              16.3k21560




















                                                                  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





                                                                  share|improve this answer


























                                                                    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





                                                                    share|improve this answer
























                                                                      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





                                                                      share|improve this answer















                                                                      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






                                                                      share|improve this answer














                                                                      share|improve this answer



                                                                      share|improve this answer








                                                                      edited Sep 4 at 1:37

























                                                                      answered Sep 3 at 22:33









                                                                      Οurous

                                                                      5,2131931




                                                                      5,2131931




















                                                                          up vote
                                                                          2
                                                                          down vote














                                                                          Ruby, 54 bytes





                                                                          f=->a,dr,*z=d;r&&a.reverse!;d==?a:a.map


                                                                          Try it online!






                                                                          share|improve this answer


























                                                                            up vote
                                                                            2
                                                                            down vote














                                                                            Ruby, 54 bytes





                                                                            f=->a,dr,*z=d;r&&a.reverse!;d==?a:a.map


                                                                            Try it online!






                                                                            share|improve this answer
























                                                                              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!






                                                                              share|improve this answer















                                                                              Ruby, 54 bytes





                                                                              f=->a,dr,*z=d;r&&a.reverse!;d==?a:a.map


                                                                              Try it online!







                                                                              share|improve this answer














                                                                              share|improve this answer



                                                                              share|improve this answer








                                                                              edited Sep 6 at 7:30

























                                                                              answered Sep 6 at 7:11









                                                                              G B

                                                                              6,3571324




                                                                              6,3571324




















                                                                                  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






                                                                                  share|improve this answer






















                                                                                  • 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














                                                                                  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






                                                                                  share|improve this answer






















                                                                                  • 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












                                                                                  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






                                                                                  share|improve this answer














                                                                                  (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







                                                                                  share|improve this answer














                                                                                  share|improve this answer



                                                                                  share|improve this answer








                                                                                  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
















                                                                                  • 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










                                                                                  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!






                                                                                  share|improve this answer






















                                                                                  • 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














                                                                                  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!






                                                                                  share|improve this answer






















                                                                                  • 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












                                                                                  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!






                                                                                  share|improve this answer














                                                                                  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!







                                                                                  share|improve this answer














                                                                                  share|improve this answer



                                                                                  share|improve this answer








                                                                                  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
















                                                                                  • 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

















                                                                                   

                                                                                  draft saved


                                                                                  draft discarded















































                                                                                   


                                                                                  draft saved


                                                                                  draft discarded














                                                                                  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













































































                                                                                  Comments

                                                                                  Popular posts from this blog

                                                                                  Long meetings (6-7 hours a day): Being “babysat” by supervisor

                                                                                  Is the Concept of Multiple Fantasy Races Scientifically Flawed? [closed]

                                                                                  Confectionery