Index der mehrdimensionalen Koordinaten auswerten


9

Eine Sammlung von N Dimensionskoordinaten wird bereitgestellt. Ein Beispiel ist unten:

{2,3,4}

Dies kann als dreidimensionales Array mit 2x, 3y und 4z betrachtet werden; Es kann eine beliebige Anzahl von Dimensionen geben. Im Beispiel gibt es insgesamt 24 Knoten. Jeder Knoten kann mit {x, y, z} indiziert werden. Um auf den 5. Knoten zuzugreifen, wären die bereitgestellten Indizes {0, 1, 0} basierend auf der folgenden Tabelle.

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

Der Zweck dieser Anwendung besteht darin, rückwärts zu arbeiten, um einen Index zu bestimmen, wenn eine Knotennummer angegeben wird.

Wenn Sie nach dem "y" -Index des 8. Knotens gefragt werden, sollte das Programm "2" ausgeben.

Mit folgender Eingabe:

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

Folgendes sollte gedruckt werden:

2

Sie können davon ausgehen, dass die Eingabe in einer Sprache Ihrer Wahl auf bequeme Weise bereitgestellt wird und keine Überprüfung der Grenzen erforderlich ist. Beispielsweise können Sie davon ausgehen, dass der angegebene Index der Wahl (im Beispiel "y") in Bezug auf die angegebenen Koordinaten gültig ist. Sie können eine 0- oder 1-basierte Indizierung verwenden. Das Beispiel setzt 0 basierend voraus.

Dies ist eine Art Umkehrung dieser Frage: Index eines mehrdimensionalen Arrays


1
Vielleicht ein paar Testfälle hinzufügen
Luis Mendo

1
Können wir die Koordinaten von 1 nach x anstatt von 0 nach x-1 laufen lassen? Knoten Nr. 0 wäre also (1,1,1) und Knoten Nr. 23 (2,3,4).
Nimi

@nimi Ja, 1-basierte Indizierung ist in Ordnung.
Mark Johnson

Antworten:


4

MATL , 8 Bytes

PiX[vPi)

Dies verwendet eine 1-basierte Indizierung für den Knoten und für die Dimensionen. So sind die ersten Knoten sind 1, 2etc; und die "x" Dimension ist 1, "y" ist 2usw.

Probieren Sie es online aus!

Erläuterung

Der Schlüssel ist die Verwendung einer Funktion X[(entsprechend ind2subMatlab oder Octave), die einen linearen Index in mehrdimensionale Indizes konvertiert. Die Reihenfolge der Dimensionen ist jedoch erforderlich, wenn das Gegenteil wie in der Herausforderung definiert ist, also P( flip) vor dem Aufrufen der Funktion und erneut nach dem Verketten ( v) ihrer Ausgaben.

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 Bytes

(#)Nimmt drei Argumente und gibt eine Ganzzahl zurück, verwenden Sie als [2,3,4]#8$1.

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

Probieren Sie es online aus!

Wie es funktioniert

  • list die Liste der Koordinaten, ndie Knotennummer. l#nist eine Funktion, die den endgültigen Index übernimmt i.
  • In Anbetracht der Beispielliste [2,3,4]und des Knotens 8wird zuerst der Schwanz der Liste genommen und gegeben [3,4]. Dann wird dies scanvon der rNacht an ned , divwobei die Knotennummer durch jedes Element nacheinander identifiziert wird und die Liste gegeben wird [0,2,8].
  • Dann wird die Liste [0,2,8]und das Original l=[2,3,4]werden zipped withden modulus Betreiber geben [0,2,0].
  • Zuletzt wird der !!Listenindizierungsoperator teilweise angewendet, wobei die resultierende Funktion bereit ist, den endgültigen Index zu erhalten.

3

APL (Dyalog Classic) , 5 Bytes

⎕⌷⎕⊤⎕

Nein, Ihnen fehlt keine Schriftart. So soll es aussehen.

Dies ist ein REPL-Programm, das Eingaben von STDIN entgegennimmt: die Knotennummer, die Dimensionen und den Index (in dieser Reihenfolge). Letzteres kann je nach Wert von 0- oder 1-basiert sein ⎕IO.

Probieren Sie es online aus!

Wie es funktioniert

Bei der mehrdimensionalen Array-Indizierung handelt es sich im Wesentlichen um eine gemischte Basiskonvertierung. Dies gilt auch für den ersten Teil der Herausforderung. Jedes Auftreten von liest und wertet eine Zeile von STDIN aus, also

        
⎕:
      8
⎕:
      2 3 4
0 2 0

Nimmt schließlich das Element am angegebenen Index. Ganz links liest die dritte und letzte Eingabe von STDIN und

        (0 2 0)
⎕:
      1
2

Mixed Base Conversion schlägt wieder zu!
Adám

3

Haskell, 38 30 29 28 Bytes

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

Dies verwendet 0-basierte Indizes und Koordinaten ab 1. Probieren Sie es online aus!

Verwandeln Sie jede Dimension xder Eingabe in eine Liste [1..x], z . B. [2,3,4]-> [[1,2],[1,2,3],[1,2,3,4]]. mapMErstellt eine Liste aller möglichen n-Tupel, bei denen das erste Element aus der ersten Liste usw. entnommen wird. Zweimal, !!um das n-Tupel und die Dimension zu indizieren.

Edit: @ Ørjan Johansen hat 8 9 Bytes gespeichert . Vielen Dank!


Oh, klug! Aber mapM id.map f=mapM f. Und (`take`[0..])ist kürzer.
Ørjan Johansen

@ ØrjanJohansen: 8 Bytes, das ist riesig! Vielen Dank! Ich warte immer noch auf eine Antwort des OP, wenn 1-basierte Koordinaten zulässig sind.
Nimi

Auch l#n=(mapM(`take`[0..])l!!n!!)ist kürzer. (Übrigens brauchten Sie das nicht f=, Funktionen können anonym sein. Oh, ich denke, Sie zählen es nicht.)
Ørjan Johansen

@ ØrjanJohansen: Nochmals vielen Dank. Das f=war ein Fehler beim Kopieren und Einfügen von TIO.
Nimi

2

Brachylog , 25 23 Bytes

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

Probieren Sie es online aus!

Das zweite Argument ist 1-indiziert, die anderen 2 sind 0-indiziert.

Erläuterung

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 Bytes

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

Verwenden der 1-basierten Indizierung für die Eingabe und der 0-basierten Indizierung für die Ausgabe.

Warum Or? Weil es die kürzeste integrierte Funktion mit dem Attribut ist Flat.

Beispiel:

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

Out[1]= 2

1

APL (Dyalog) , 6 Bytes

So erhalten Sie eine 0-basierte Indizierung ⎕IO←0, die auf vielen Systemen standardmäßig verwendet wird. Fordert zur Eingabe von Dimensionen auf und enthält dann eine Liste von (Knoten, Koordinate).

⎕⊃↑,⍳⎕

Probieren Sie es online aus!

 Eingabeaufforderung für Dimensionen

 ein Array von dieser Form erzeugen , die jedes Element das Wesen i ndices für das Element

, Ravel (in Liste der Indizes einarbeiten)

 Wandle eine Tiefenstufe in eine zusätzliche Rangstufe um

⎕⊃ Eingabeaufforderung für die beiliegende Liste von (Knoten, Koordinate) und verwenden Sie diese, um ein Element daraus auszuwählen


1

Gelee , 7 6 Bytes

Œp⁴ị⁵ị

Probieren Sie es online aus!

Dies verwendet 1-Indizierung für Eingabe und Ausgabe.

Wie es funktioniert

Œ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


0

Pyth , 12 Bytes

@.n]@*FUMQEE

Probieren Sie es online aus!

Wie es funktioniert

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

0

R, 52 Bytes

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

Gibt eine anonyme Funktion mit 1 Index zurück.

für das Beispiel. expand.gridgeneriert die Liste, aber das erste Argument variiert am schnellsten, daher müssen wir sie in umgekehrter Reihenfolge eingeben, d z,y,x. h . Dann können wir einfach indizieren [n,4-i], wo 4-idies für die umgekehrte Reihenfolge erforderlich ist, und 1 subtrahieren, um sicherzustellen, dass sie ablaufen 0:(x-1)usw.

Probieren Sie es online aus!



0

JavaScript (ES6), 44 Byte

(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]

Leider reducesind zwei Bytes länger:

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

Sieht so aus, als hätten wir die gleiche Idee. \ O /
Leaky Nun

@LeakyNun Nun, es ist nicht wirklich überraschend, wenn man bedenkt, wie die Indizierung funktioniert.
Neil

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.