Оценить индекс многомерных координат


9

Предоставляется коллекция из N размерных координат. Пример ниже:

{2,3,4}

Это можно представить как трехмерный массив с 2x, 3y и 4z; может быть любое количество измерений. В этом примере всего 24 узла. Каждый узел может быть проиндексирован с помощью {x, y, z}. Чтобы получить доступ к 5-му узлу, предоставленные индексы будут {0, 1, 0} на основе таблицы ниже.

## | x y z
     0 1 2
-----------
0  | 0 0 0
1  | 0 0 1
2  | 0 0 2
3  | 0 0 3
4  | 0 1 0
5  | 0 1 1
6  | 0 1 2
7  | 0 1 3
8  | 0 2 0
...
23 | 1 2 3

Цель этого приложения - работать в обратном направлении, чтобы определить индекс, если ему присвоен номер узла.

Если запрашивается индекс «y» 8-го узла, программа должна вывести «2».

При условии следующего ввода:

{2,3,4}|8|1
<List of Coordinates>|<Node>|<Index>

Следующее должно быть напечатано:

2

Вы можете предположить, что ввод будет предоставлен удобным способом на выбранном вами языке и не требует проверки границ. Например, вы можете предположить, что предоставленный индекс выбора (в данном примере «y») действителен по отношению к предоставленным координатам. Вы можете использовать индексирование на основе 0 или 1; пример предполагает 0 на основе.

Это своего рода обратная сторона этого вопроса: индекс многомерного массива


1
Возможно, добавим несколько тестовых случаев
Луис Мендо

1
Можем ли мы позволить координатам идти от 1 до x вместо 0 до x-1? Таким образом, узел № 0 будет (1,1,1), а узел № 23 (2,3,4).
Ними

@nimi Да, индексирование на основе 1 - это хорошо.
Марк Джонсон

Ответы:


4

MATL , 8 байт

PiX[vPi)

При этом используется индексирование на основе 1 для узла и измерений. Таким образом, первые узлы 1, и 2т.д.; и размер "х" есть 1, "у" 2и т. д.

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

объяснение

Ключ должен использовать функцию X[(соответствующую ind2subв Matlab или Octave), которая преобразует линейный индекс в многомерные индексы. Однако порядок измерений, если он противоположен определенному в вызове, поэтому P( flip) необходим перед вызовом функции и снова после конкатенации ( v) ее выходных данных.

P    % Implicit input: size as a row vector. Flip
i    % Input: node (linear) index
X[   % Convert from linear index to multidimensional indices. Produces
     % as many outputs as entries there are in the size vector
v    % Concatenate all outputs into a column vector
P    % Flip
i    % Input: dimension
)    % Index: select result for that dimension. Implicitly display

3

Haskell , 45 байт

(#)принимает три аргумента и возвращает целое число, используйте как [2,3,4]#8$1.

l#n=(zipWith mod(scanr(flip div)n$tail l)l!!)

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

Как это работает

  • lсписок координат, nномер узла. l#nэто функция , которая принимает окончательный индекс i.
  • Учитывая пример списка [2,3,4]и узла 8, сначала берется хвост списка, давая [3,4]. Затем это scanned от right, divпоследовательно идентифицируя номер узла каждым элементом, давая список [0,2,8].
  • Затем список [0,2,8]и оригинал l=[2,3,4]являются zipпед withв modулусе оператора, что дают [0,2,0].
  • Наконец, !!оператор индексации списка применяется частично, и результирующая функция готова получить окончательный индекс.

3

APL (Dyalog Classic) , 5 байтов

⎕⌷⎕⊤⎕

Нет, вы не пропустите шрифт. Вот как это должно выглядеть.

Это программа REPL, которая принимает входные данные из STDIN: номер узла, измерения и индекс (в этом порядке). Последний может быть 0 или 1, в зависимости от значения ⎕IO.

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

Как это работает

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

        
⎕:
      8
⎕:
      2 3 4
0 2 0

Наконец, берет элемент по указанному индексу. Крайний левый читает третий и последний ввод из STDIN и

        (0 2 0)
⎕:
      1
2

Смешанные базовые конверсионные удары снова!
Адам

3

Haskell, 38 30 29 28 байт

l#n=(mapM(\x->[1..x])l!!n!!)

При этом используются 0-ориентированные индексы и координаты, начиная с 1. Попробуйте онлайн!

Превратите каждое измерение xввода в список [1..x], например [2,3,4]-> [[1,2],[1,2,3],[1,2,3,4]]. mapMсоздает список всех возможных n-кортежей, где первый элемент берется из первого списка, и т. д. Два раза !!для индексации n-кортежа и измерения.

Редактировать: @ Ørjan Йохансен сэкономил 8 9 байт. Спасибо!


Ой, умный! Но mapM id.map f=mapM f. И (`take`[0..])короче.
Орджан Йохансен

@ ØrjanJohansen: 8 байтов, это огромный! Большое спасибо! Все еще жду ответа от OP, если разрешены координаты на основе 1.
Ними

Также l#n=(mapM(`take`[0..])l!!n!!)короче. (Между прочим, функции вам не нужны f=, функции могут быть анонимными. О, я полагаю, вы не
Орджан Йохансен

@ ØrjanJohansen: Еще раз спасибо. f=Было скопировать и вставить ошибку из TIO.
Ними

2

Брахилог , 25 23 байта

tT&bhH&h{>ℕ}ᵐ:H≜ᶠ⁾t:T∋₎

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

Второй аргумент индексируется 1, остальные 2 индексируются 0.

объяснение

tT                          Input = [_, _, T]
  &bhH                      Input = [_, H, T]
      &h{>ℕ}ᵐ               Create a list where each element is between 0 and the
                              corresponding element in the first element of the Input
             :H≜ᶠ⁾          Find the first H possible labelings of that list
                  t         Take the last one
                   :T∋₎     Output is the T'th element

1

Mathematica, 26 23 байта

Array[f,#,0,Or][[##2]]&

Использование индексации на основе 1 для ввода и индексации на основе 0 для вывода.

Почему Or? Потому что это самая короткая встроенная функция с атрибутом Flat.

Пример:

In[1]:= Array[f,#,0,Or][[##2]]&[{2,3,4},9,2]

Out[1]= 2

1

APL (Dyalog) , 6 байтов

Для получения индексации на основе 0 ⎕IO←0, которая используется по умолчанию во многих системах. Запрашивает размеры, затем вложенный список (узел, координата).

⎕⊃↑,⍳⎕

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

 подскажите размеры

 генерировать массив этой формы с каждым элементом , являющимся I ndices для этого элемента

, Равель (внести в список показателей)

 преобразовать один уровень глубины в дополнительный уровень ранга

⎕⊃ запросить закрытый список (узел, координата) и использовать его, чтобы выбрать элемент из этого





0

R, 52 байта

function(x,y,z,n,i)expand.grid(1:z,1:y,1:x)[n,4-i]-1

возвращает анонимную функцию с 1 индексированием.

для примера. expand.gridгенерирует список, но первый аргумент меняется быстрее, поэтому мы должны ввести их в обратном порядке, то есть z,y,x. Затем мы можем просто проиндексировать [n,4-i], где 4-iэто необходимо для обратного порядка, и вычесть 1, чтобы убедиться, что они выполняются 0:(x-1), и т. Д.

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



0

JavaScript (ES6), 44 байта

(a,n,i,g=j=>a[++j]?g(j)/a[j]|0:n)=>g(i)%a[i]

Ungolfed:

(a,n,i)=>a.reduceRight(([n,...a],e)=>[n/e|0,n%e,...a],[n])[i+1]

К сожалению, reduceна два байта длиннее:

(a,n,i)=>a.reduce((r,d,j)=>j>i?r/d|0:r,n)%a[i]

Похоже, мы придумали ту же идею \ o /
Leaky Nun

@ LeakyNun Ну, это не удивительно, учитывая, как работает индексация.
Нил

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