Языки более низкого уровня, такие как C и C ++, фактически не имеют понятия многомерных массивов. (Кроме векторов и динамических массивов) При создании многомерного массива с
int foo[5][10];
Это на самом деле просто синтаксический сахар . Что на самом деле делает С, так это создает единый непрерывный массив 5 * 10 элементов. это
foo[4][2]
также синтаксический сахар. Это действительно относится к элементу в
4 * 10 + 2
или 42-й элемент. В общем, индекс элемента [a][b]
в массивеfoo[x][y]
равен
a * y + b
То же самое относится и к 3D-массивам. Если у нас есть, foo[x][y][z]
и мы получаем доступ к элементу[a][b][c]
мы действительно к элементу:
a * y * z + b * z + c
Эта концепция применима к n- мерным массивам. Если у нас есть массив с измерениями, D1, D2, D3 ... Dn
и мы получаем доступ к элементу, S1, S2, S3 ... Sn
формула
(S1 * D2 * D3 ... * Dn) + (S2 * D3 * D4 ... * Dn) + (S3 * D4 ... * Dn) ... + (Sn-1 * Dn) + Sn
Соревнование
Вы должны написать программу или функцию, которая вычисляет индекс многомерного массива в соответствии с формулой выше. На вход будет два массива. Первый массив - это размеры, а второй - индексы. Длина этих двух массивов всегда будет равна и не меньше 1.
Вы можете смело предполагать, что каждое число в массивах будет неотрицательным целым числом. Вы также можете предположить, что вы не получите a 0
в массиве измерений, хотя 0
может быть в индексах. Также можно предположить, что индексы не будут больше размеров.
Тест IO
Dimensions: [5, 10]
Indices: [4, 2]
Output: 42
Dimensions: [10, 10, 4, 62, 7]
Indices: [1, 2, 3, 4, 5]
Output: 22167
Dimensions: [5, 1, 10]
Indices: [3, 0, 7]
Output: 37
Dimensions: [6, 6, 6, 6, 6, 6, 6, 6, 6, 6]
Indices: [3, 1, 5, 5, 3, 0, 5, 2, 5, 4]
Output: 33570178
источник
int[10]
.Ответы:
APL, 1 байт
Проверьте это на TryAPL .
источник
J, 2 байта
Где есть APL, там есть J! Что-то вроде. Принимает размеры как левый аргумент и индекс как правый арг. «Индексирование многомерного массива - это, по сути, смешанное базовое преобразование».
источник
JavaScript (ES6), 34 байта
Конечно,
reduce
должно быть лучше, чемmap
.источник
Python, 43 байта
Проверьте это на Ideone .
источник
Желе ,
76 байтПопробуйте онлайн! или проверьте все тесты .
Как это работает
источник
Pyth, 10 байт
Попробуйте онлайн: демонстрация или тестовый набор
Использование метода Хорнера для расчета индекса.
источник
MATL , 9 байт
При этом используется индексирование на основе 1 (теперь это разрешено задачей), что является естественным выбором в MATL.
Чтобы сравнить с тестовыми примерами в задании, добавьте
1
к каждой записи во входном индексе вектор и вычтите1
из выходных данных.Попробуйте онлайн!
объяснение
Код основан на встроенной
X]
функции, которая преобразует многомерные индексы в один линейный индекс (например,sub2ind
функцию Matlab или Octave ).источник
Юлия,
2927 байтПопробуйте онлайн!
источник
MATL , 11 байт
При этом используется индексирование на основе 0, как в исходной задаче.
Попробуйте онлайн!
объяснение
Код явно делает необходимые умножения и сложения.
источник
Python, 85 байт
Я, вероятно, получу удовольствие от лучших игроков в гольф на питоне.
источник
Python 3.5, 69
Тест здесь
источник
Haskell, 34 байта
Пример использования:
[10,10,4,62,7] # [1,2,3,4,5]
->22167
.Как это работает:
источник
C ++, 66 байт
Быстрый макрос:
Используйте как:
Это может быть немного злоупотреблением правилами. Создает массив с заданным размером, затем проверяет, насколько далеко заданные индексы смещают указатель. Выходы в STDOUT.
Это так грязно ... Но мне просто нравится тот факт, что это действительно.
источник
Mathematica, 27 байт
Безымянная функция, которая принимает список индексов в качестве первого аргумента, а список измерений - второй. Основываясь на том же наблюдении, что и ответ Денниса APL, вычисление индекса на самом деле является просто смешанным преобразованием.
источник
Октава,
5854 байтаСпасибо @AlexA. за его предложение, которое удалило 4 байта
Вход и выход основаны на 1. Для сравнения с тестовыми примерами добавьте
1
каждую запись во входные данные и вычтите1
из выходных данных.Это анонимная функция. Чтобы вызвать его, присвойте его переменной.
Попробуй здесь .
объяснение
Это работает на самом деле построение многомерного массива (
reshape(...)
), заполненные значения1
,2
... в линейном порядке (1:prod(d)
), а затем индексации с помощью многомерного индекса, чтобы получить соответствующее значение.Индексация выполняется путем преобразования входного многомерного индекса
i
в массив ячеек (num2cell(...)
), а затем в список через запятую ({:}
).Две
flip
операции необходимы для адаптации порядка размеров от C до Octave.источник
reshape
? Это не синтаксическое в Matlab, но принято в Octave. Он работает в качестве индекса@(...) ...
в первой строке своего кода, а затемf = ans;
во второй. Это делает длину первой строки равной количеству байтов для отчета.CJam, 7 байтов
Попробуйте онлайн!
Как это работает
источник
Haskell, 47 байтов
Два решения одинаковой длины:
Вызывается , как:
((sum.).s)[4,2][5,10]
.Вот инфиксная версия:
источник
Октава,
47/43/31 байт@(d,i)sub2ind(flip(d),num2cell(flip(i+1)){:})-1
Проверьте это здесь .
Сказав, что, как это было сказано в комментарии , индексирование на основе 1 считается нормальным, когда это естественно для используемого языка. В этом случае мы можем сохранить 4 байта:
@(d,i)sub2ind(flip(d),num2cell(flip(i)){:})
По аналогии, я утверждаю, что если целью кода является линейное индексирование массива в пределах этого языка , то переворачивание целого и учет главного порядка столбцов MATLAB / Octave также не должны быть необходимыми. В этом случае мое решение становится
@(d,i)sub2ind(d,num2cell(i){:})
Проверьте это здесь .
источник
Mathematica, 47 байт
(Unicode - это U + F3C7 или
\[Transpose]
.) Для этого я переписал выражение как D n ( D n -1 (⋯ ( D 3 ( D 2 S 1 + S 2 ) + S 3 ) ⋯) + S n -1 ) + S n . ПростоFold
с функцией над обоими списками.источник
На самом деле, 13 байтов
Попробуйте онлайн!
Эта программа принимает список индексов в качестве первого ввода и список измерений в качестве второго ввода.
Объяснение:
источник
Ракетка 76 байт
Ungolfed:
Тестирование:
Выход:
источник
C #, 73 байта
Полная программа с тестовыми примерами:
источник
Perl 6, 39 байт
Здесь довольно наивный гольф, только что раздавленный анонимный саб.
Perl 6 имеет анонимную переменную состояния,
$
которая полезна для создания счетчика в цикле (например, с использованием постинкремента$++
или предварительного инкремента++$
). Я предварительно увеличиваю эту переменную состояния, чтобы увеличить начальный индекс фрагмента массива измерений внутри карты.Вот функция ungolfed, которая создает подсписки
Тогда нужно просто сократить подсписки с помощью
×
оператора multiplication ( ) и получитьsum
результаты.источник
Perl, 71 байт
Ungolfed:
источник
С ++ 17,
133115 байт-18 байт для использования
auto...
Ungolfed:
Использование:
Альтернатива, только функции, 116 байт
Ungolfed:
Использование:
источник