Обратный 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"]]

1
В вашем примере бонуса вы рассматриваете строки как атомы. Я бы сказал, что они являются суб-массивом, и поэтому их тоже следует обратить в обратную сторону. На самом деле это то, что делает мое решение APL при подаче обычных строк, поскольку APL не имеет строкового типа данных, только символьные типы данных. Следовательно, строки - это одномерные массивы символов. Если вы хотите, чтобы строки оставались в обычном порядке, вам просто нужно сделать их объектами с отображаемой формой.
Адам

@ Nᴮᶻ Считаете ли вы, что -50% Bytecount слишком великодушен? Я могу сделать что-то вроде -30% Bytecount для различных типов данных, и что-то вроде -10% Bytecount для обращения строк, -15% Bytecount для обращения целого типа (123 -> 321) и -15% Bytecount для обращения плавающий тип (3.14 -> 41.3).
MrPublic

1
Я вообще не люблю бонусы. Поменять местами целые числа и числа с плавающей запятой ... интересно.
Адам

4
Оставьте это сейчас, но в следующий раз вы можете использовать песочницу, чтобы выяснить такие вещи.
Адам

Ответы:


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

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сбоя (т.е. последний элемент не был списком).


4

Python 2, 40 - 50% = 20

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

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

Все тесты


Просто обратите внимание, что версия без бонуса есть 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повсюду.



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

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



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


1

Clojure, 38 байт

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

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

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

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

0

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

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

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

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.