Обратный N-мерный массив

10

подробности

Напишите функцию или программу, которая, учитывая массив (или список), содержащий только целые числа, возвращает или выводит массив со всеми обращенными субэлементами. То есть, поверните все элементы самого глубокого массива, затем второй самый глубокий и т. Д. Размеры указывать не нужно, но функция или программа должны работать для зубчатых массивов в собственном формате вашего языка программирования.


Примеры

Эта:

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

Стало бы это:

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

Эта:

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

Стало бы это:

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

Эта:

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

Стало бы это:

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

бонус

Мы надеемся, что это поощрит ответы на некоторых объектно-ориентированных языках программирования ...

-50% Bytecount Если ваша программа может принимать в качестве входных данных массив (или список) со своими членами различных типов (они могут быть в форме объектов) и успешно реверсировать все массивы.

Эта:

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

Стало бы это:

[[3.14,[3,["Qux"]]],
 ["Baz"],
  2,
 [[1,"Bar"],"Foo"]]
MrPublic
источник
1
В вашем примере бонуса вы рассматриваете строки как атомы. Я бы сказал, что они являются суб-массивом, и поэтому их тоже следует обратить в обратную сторону. На самом деле это то, что делает мое решение APL при подаче обычных строк, поскольку APL не имеет строкового типа данных, только символьные типы данных. Следовательно, строки - это одномерные массивы символов. Если вы хотите, чтобы строки оставались в обычном порядке, вам просто нужно сделать их объектами с отображаемой формой.
Адам
@ Nᴮᶻ Считаете ли вы, что -50% Bytecount слишком великодушен? Я могу сделать что-то вроде -30% Bytecount для различных типов данных, и что-то вроде -10% Bytecount для обращения строк, -15% Bytecount для обращения целого типа (123 -> 321) и -15% Bytecount для обращения плавающий тип (3.14 -> 41.3).
MrPublic
1
Я вообще не люблю бонусы. Поменять местами целые числа и числа с плавающей запятой ... интересно.
Адам
4
Оставьте это сейчас, но в следующий раз вы можете использовать песочницу, чтобы выяснить такие вещи.
Адам
5
О бонусах ...
Мартин Эндер

Ответы:

9

Pyth, 11 - 50% = 5,5 байт

L?+IbY_yMbb

Попробуйте онлайн: демонстрация или тестовый набор .

Это определяет функцию y. Дополнительные 3 байта <newline>yQпросто вызывают функцию со списком ввода и, следовательно, не должны учитываться в общем количестве байтов.

Объяснение:

L?+IbY_yMbb
L             define a function y(b), that returns:
 ?+IbY           if b + [] == b (test if b is a list):
      _yMb           recursively call y on all elements in b, then reverse the list
          b      else: b
Jakube
источник
6

Dyalog APL , 14 - 50% = 7 байт

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

⌽⍵обратный аргумент,
⍣(×|≡⍵)если аргумент не является атомом (знак [абсолютной] глубины) ...
∇¨... применить функцию к каждому элементу (обратного аргумента).

Если ⎕ML←3(стиль IBM), что имеет место в системах, которые мигрировали из APL2, один байт можно сохранить, удалив |.

Попробуйте APL онлайн.

Для любопытства, предлагаемые int и float реверс:

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

Внутренняя функция:

0::⌽⍵если возникает какая-либо ошибка, просто верните найденный аргумент
⍎⌽⍕make в строку, переверните, make в число

Адам
источник
4

Пролог, 40 - 50% = 20 байт

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

Это рекурсивно вызывает предикат a/2с maplist/3, для каждого члена списка, до reverse/2сбоя (т.е. последний элемент не был списком).

Fatalize
источник
4

Python 2, 40 - 50% = 20

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

Для получения бонуса необходимы лишь незначительные изменения, необходимые для базового способа сделать это. Используется тот факт, что все списки меньше пустой строки, а все числа меньше пустого списка.

Все тесты

FryAmTheEggman
источник
Просто обратите внимание, что версия без бонуса есть f=lambda x:map(f,x)[::-1]if x>[]else x.
mbomb007
3

Emacs Lisp, 46 байт * 0,5 = 23

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

Пример использования: (g '((1 2) 3 (four 5)))->((5 four) 3 (2 1))

Классический рекурсивный подход: если аргумент не является списком, возьмите его без изменений, если это список, сопоставьте функцию с обратным списком.

Ними
источник
2

Mathematica, 34/2 = 17 байт

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

Или просто, Reverse//@#&если вы хотите кучу ошибок и Reverseповсюду.

CalculatorFeline
источник
2

Clojure 43/2 = 21,5 байт

(defn f[x](if(coll? x)(reverse(map f x))x))
wilkesybear
источник
1

JavaScript ES6, 42 - 50% = 21 байт

Мой счет идеален во многих отношениях. Реализует функциюr которая рекурсивно применяет себя к членам своего ввода.

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

Если мы предположим, что ни один объект не имеет свойства pop , то это становится (31 - 50% = 15,5) благодаря dev-null:

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

Или, если мы предположим, что объект обладает вменяемым reverseсвойством, мы могли бы сделать это также (35 - 50% = 17,5):

r=a=>a[R="reverse"]?a[R]().map(r):a
Конор О'Брайен
источник
Я думаю , вы могли бы безопасно проверить массив как это: a.pop?a.reverse().map(r):a. При условии, что нет необходимости обрабатывать void 0и настраиваемые объекты.
andlrc
1

Lua, 111 99 * .5 = 55,5 49,5 байт

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

Хорошая часть рекурсии

Trebuchette
источник
1

CJam, 20 байтов * 50% = 10

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

Определяет названный блок F который может быть применен к массиву поверх стека (или чего-либо еще, в этом случае это неоперация).

Проверьте это здесь.

Мартин Эндер
источник
1

Брахилог , 5 - 50% = 2,5 байта

ċ↔↰ᵐ|

Попробуйте онлайн!

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

Так как может также переворачивать строки и целые числа, мы должны явно отказывать в не-списках с помощью ċ.

Несвязанная строка
источник
1

Wolfram Language (Mathematica) , 23 -50% = 11,5 байт

#/.List->Reverse@*List&

Попробуйте онлайн!

Lists в Mathematica ( {...}) эквивалентны List[...]. @*является оператором композиции, поэтому замена каждого вхождения Listс Reverse@*Listобращает все списки, которые встречаются на входе ( Reverse@*List[...]= Reverse[{...}]).


24 -50% = 12 байт

#~Reverse~Range@Depth@#&

Попробуйте онлайн!

Работает не только на Listс.

attinat
источник
1

Clojure, 38 байт

(и бонус, я думаю, но Clojure - динамический язык, поэтому он поставляется бесплатно)

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

Это хорошее начало, но я не использовал эти оптимизации:

  • Определите анонимную функцию с помощью fnвместо именованной с помощью defn. Но нам все еще нужно «ограниченное» имя fдля рекурсии
  • Возьмите ввод как список вместо вектора, тогда мы можем использовать seq?вместоcoll?
  • Используйте (into () ...)вместоreverse
  • Обратно xперед отображением, нам не нужно столько пробелов
NikoNyrh
источник
0

Рубин , 32 - 50% = 16 байт

Рекурсивная функция. Использование rescueдля перехвата того, NoMethodErrorчто срабатывает при попытке reverseполучить число или mapстроку, оказывается на 2 байта короче, чем проверка, является ли входной массив массивом через a==[*a].

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

Попробуйте онлайн!

Значение чернил
источник