Évaluer l'index des coordonnées multidimensionnelles

9

Une collection de coordonnées dimensionnelles N est fournie. Un exemple est ci-dessous:

{2,3,4}

Cela peut être considéré comme un tableau tridimensionnel avec 2x, 3y et 4z; il peut y avoir n'importe quel nombre de dimensions. Dans l'exemple, il y a 24 nœuds au total. Chaque nœud peut être indexé à l'aide de {x, y, z}. Pour accéder au 5e nœud, les indices fournis seraient {0, 1, 0} sur la base du tableau ci-dessous.

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

Le but de cette application est de travailler en arrière pour déterminer un index si on lui donne un numéro de nœud.

Si on lui demande l'index "y" du 8ème nœud, le programme devrait afficher "2".

Avec l'entrée suivante fournie:

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

Les éléments suivants doivent être imprimés:

2

Vous pouvez supposer que l'entrée sera fournie d'une manière pratique dans la langue de votre choix et ne nécessite pas de vérification des limites. Par exemple, vous pouvez supposer que l'index de choix fourni ("y" dans l'exemple) est valide par rapport aux coordonnées fournies. Vous pouvez utiliser une indexation basée sur 0 ou 1; l'exemple suppose une base de 0.

C'est en quelque sorte l'inverse de cette question: Index d'un tableau multidimensionnel

Mark Johnson
la source
1
Ajoutez peut-être quelques cas de test
Luis Mendo
1
Pouvons-nous laisser les coordonnées aller de 1 à x au lieu de 0 à x-1? Le nœud # 0 serait donc (1,1,1) et le nœud # 23 (2,3,4).
nimi
@nimi Oui, 1 indexation basée est très bien.
Mark Johnson

Réponses:

4

MATL , 8 octets

PiX[vPi)

Cela utilise une indexation basée sur 1 pour le nœud et pour les dimensions. Ainsi, les premiers nœuds sont 1, 2etc; et la dimension "x" est 1, "y" est 2etc.

Essayez-le en ligne!

Explication

La clé est d'utiliser la fonction X[(correspondant à ind2subMatlab ou Octave), qui convertit un indice linéaire en indices multidimensionnels. Cependant, l'ordre des dimensions si l'opposé tel que défini dans le défi, so P( flip) est nécessaire avant d'appeler la fonction, et de nouveau après avoir concaténé ( v) ses sorties.

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
Luis Mendo
la source
3

Haskell , 45 octets

(#)prend trois arguments et retourne un entier, utilisez as [2,3,4]#8$1.

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

Essayez-le en ligne!

Comment ça fonctionne

  • lest la liste des coordonnées, nle numéro de nœud. l#nest une fonction qui prend l'index final i.
  • Étant donné l'exemple de liste [2,3,4]et de nœud 8, la queue de la liste est d'abord prise, donnant[3,4] . Ensuite, c'est scanned à partir du right, dividentifiant le numéro de nœud par chaque élément consécutivement, donnant la liste [0,2,8].
  • Ensuite, la liste [0,2,8]et l'originall=[2,3,4] sont zipconsultés par withl' modopérateur ulus, donnant [0,2,0].
  • L' !!opérateur d'indexation de liste est enfin partiellement appliqué, la fonction résultante étant prête à recevoir l'index final.
Ørjan Johansen
la source
3

APL (Dyalog Classic) , 5 octets

⎕⌷⎕⊤⎕

Non, vous ne manquez pas de police. Voilà à quoi ça doit ressembler.

Il s'agit d'un programme REPL qui prend en entrée STDIN: le numéro de nœud, les dimensions et l'index (dans cet ordre). Ce dernier peut être basé sur 0 ou 1, selon la valeur de ⎕IO.

Essayez-le en ligne!

Comment ça fonctionne

L'indexation de tableaux multidimensionnels est essentiellement une conversion de base mixte, tout comme ce que demande la première partie du défi. Chaque occurrence de lit et évalue une ligne de STDIN, donc

        
⎕:
      8
⎕:
      2 3 4
0 2 0

Enfin, prend l'élément à l'index spécifié. Le plus à gauche lit la troisième et dernière entrée de STDIN et

        (0 2 0)
⎕:
      1
2
Dennis
la source
La conversion de base mixte frappe à nouveau!
Adám
3

Haskell, 38 30 29 28 octets

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

Il utilise des indices et des coordonnées basés sur 0 à partir de 1. Essayez-le en ligne!

Transformez chaque dimension xde l'entrée en une liste [1..x], par exemple [2,3,4]-> [[1,2],[1,2,3],[1,2,3,4]]. mapMfait une liste de tous les n-tuples possibles où le premier élément est tiré de la première liste, etc. Deux fois !!pour indexer le n-tuple et la dimension.

Edit: @ Ørjan Johansen a enregistré 8 9 octets. Merci!

nimi
la source
Ooh, intelligent! Mais mapM id.map f=mapM f. Et (`take`[0..])est plus court.
Ørjan Johansen
@ ØrjanJohansen: 8 octets, c'est énorme! Merci beaucoup! Toujours en attente d'une réponse de l'OP si les coordonnées basées sur 1 sont autorisées.
nimi
En outre, l#n=(mapM(`take`[0..])l!!n!!)est plus court. (Soit dit en passant, vous n'aviez pas besoin des f=fonctions, elles peuvent être anonymes. Oh, je suppose que vous ne les comptez pas.)
Ørjan Johansen
@ ØrjanJohansen: Merci encore. Il f=s'agissait d'une erreur de copier-coller de TIO.
nimi
2

Brachylog , 25 23 octets

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

Essayez-le en ligne!

Le deuxième argument est indexé 1, les 2 autres sont indexés 0.

Explication

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
Fatalize
la source
1

Mathematica, 26 23 octets

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

Utilisation d'une indexation basée sur 1 pour l'entrée et d'une indexation basée sur 0 pour la sortie.

Pourquoi Or? Parce que c'est la fonction intégrée la plus courte avec l'attribut Flat.

Exemple:

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

Out[1]= 2
alephalpha
la source
1

APL (Dyalog) , 6 octets

Pour obtenir une indexation basée sur 0 ⎕IO←0, qui est par défaut sur de nombreux systèmes. Demande les dimensions, puis la liste jointe de (nœud, coordonnées).

⎕⊃↑,⍳⎕

Essayez-le en ligne!

 demander des dimensions

 générer un tableau de cette forme avec chaque élément étant le i ndices pour cet élément

, ravel (faire dans la liste des indices)

 convertir un niveau de profondeur en un niveau de rang supplémentaire

⎕⊃ demander la liste jointe de (nœud, coordonnées) et l'utiliser pour choisir un élément

Adam
la source
1

Gelée , 7 6 octets

Œp⁴ị⁵ị

Essayez-le en ligne!

Cela utilise l'indexation 1 pour l'entrée et la sortie.

Comment ça fonctionne

Œp⁴ị⁵ị
Œp      Cartesian product of the first input
        numbers are converted to 1-based ranges
  ⁴ị    index specified by second input
    ⁵ị  index specified by third input
Leaky Nun
la source
0

Pyth , 12 octets

@.n]@*FUMQEE

Essayez-le en ligne!

Comment ça fonctionne

@.n]@*FUMQEE
       UMQ    map each element in the first input to
              [0,1,...,that element]
     *F       reduce by Cartesian product
    @     E   obtain index at second input
 .n]          listify and flatten
@          E  obtain index at third input
Leaky Nun
la source
0

R, 52 octets

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

renvoie une fonction anonyme, indexée sur 1.

pour l'exemple. expand.gridgénère la liste, mais le premier argument varie le plus rapidement, nous devons donc les saisir dans l'ordre inverse, c'est-à-dire z,y,x. Ensuite, nous pouvons simplement indexer [n,4-i], où cela 4-iest nécessaire pour l'ordre inversé, et soustraire 1 pour nous assurer qu'ils partent de 0:(x-1), etc.

Essayez-le en ligne!

Giuseppe
la source
0

Java , 77 octets

int f(int[]a,int m,int n){for(int i=a.length-1;i>n;m/=a[i--]);return m%a[n];}

Essayez-le en ligne!

Leaky Nun
la source
0

JavaScript (ES6), 44 octets

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

Non golfé:

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

Malheureusement, reducedeux octets de plus:

(a,n,i)=>a.reduce((r,d,j)=>j>i?r/d|0:r,n)%a[i]
Neil
la source
On dirait que nous avons eu la même idée \ o /
Leaky Nun
@LeakyNun Eh bien, ce n'est pas vraiment surprenant, étant donné le fonctionnement de l'indexation.
Neil