Valuta l'indice delle coordinate multidimensionali


9

Viene fornita una raccolta di coordinate N dimensionali. Un esempio è di seguito:

{2,3,4}

Questo può essere pensato come un array tridimensionale con 2x, 3y e 4z; potrebbe esserci un numero qualsiasi di dimensioni. Nell'esempio, ci sono 24 nodi totali. Ogni nodo può essere indicizzato usando {x, y, z}. Per accedere al 5 ° nodo, gli indici forniti sarebbero {0, 1, 0} in base alla tabella seguente.

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

Lo scopo di questa applicazione è di lavorare all'indietro per determinare un indice se viene assegnato un numero di nodo.

Se viene richiesto l'indice "y" dell'ottavo nodo, il programma dovrebbe stampare "2".

Con il seguente input fornito:

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

È necessario stampare quanto segue:

2

Puoi presumere che l'input verrà fornito in qualche modo conveniente nella tua lingua preferita e non richiede il controllo dei limiti. Ad esempio, si può presumere che l'indice di scelta fornito ("y" nell'esempio) sia valido rispetto alle coordinate fornite. È possibile utilizzare l'indicizzazione basata su 0 o 1; l'esempio presuppone 0 in base.

Questa è una specie del rovescio di questa domanda: indice di un array multidimensionale


1
Forse aggiungere alcuni casi di test
Luis Mendo

1
Possiamo lasciare che le coordinate corrano da 1 a x anziché da 0 a x-1? Quindi il nodo # 0 sarebbe (1,1,1) e il nodo # 23 (2,3,4).
nimi,

@nimi Sì, l'indicizzazione basata su 1 va bene.
Mark Johnson,

Risposte:


4

MATL , 8 byte

PiX[vPi)

Questo utilizza l'indicizzazione basata su 1 per il nodo e per le dimensioni. Quindi i primi nodi sono 1, 2ecc .; e la dimensione "x" è 1, "y" è 2ecc.

Provalo online!

Spiegazione

La chiave è usare la funzione X[(corrispondente a ind2subin Matlab o Octave), che converte un indice lineare in indici multidimensionali. Tuttavia, l'ordine delle dimensioni è l'opposto, come definito nella sfida, quindi P( flip) è necessario prima di chiamare la funzione e di nuovo dopo aver concatenato ( v) i suoi output.

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 byte

(#)accetta tre argomenti e restituisce un numero intero, usa come [2,3,4]#8$1.

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

Provalo online!

Come funziona

  • lè l'elenco delle coordinate, nil numero del nodo. l#nè una funzione che accetta l'indice finale i.
  • Dato l'elenco di esempio [2,3,4]e il nodo 8, prima viene presa la coda dell'elenco, dando [3,4]. Quindi questo viene scanrichiesto dall'ight r, dividentificando il numero del nodo da ciascun elemento consecutivamente, fornendo l'elenco [0,2,8].
  • Poi la lista [0,2,8]e l'originale l=[2,3,4]sono zipPED withl' modoperatore di Ulus, dando [0,2,0].
  • Finalmente l' !!operatore di indicizzazione dell'elenco viene parzialmente applicato, con la funzione risultante pronta per ricevere l'indice finale.

3

APL (Dyalog Classic) , 5 byte

⎕⌷⎕⊤⎕

No, non ti manca un carattere. Ecco come dovrebbe apparire.

Questo è un programma REPL che accetta input da STDIN: il numero di nodo, le dimensioni e l'indice (in quell'ordine). Quest'ultimo può essere basato su 0 o 1, a seconda del valore di ⎕IO.

Provalo online!

Come funziona

L'indicizzazione di array multidimensionale è essenzialmente una conversione di base mista, quindi fa ciò che richiede la prima parte della sfida. Ogni ricorrenza di letture ed elimina una riga da STDIN, quindi

        
⎕:
      8
⎕:
      2 3 4
0 2 0

Infine, prende l'elemento nell'indice specificato. L'estrema sinistra legge il terzo e l'ultimo input da STDIN e

        (0 2 0)
⎕:
      1
2

La conversione di basi miste colpisce ancora!
Adám,

3

Haskell, 38 30 29 28 byte

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

Utilizza indici e coordinate basati su 0 a partire da 1. Provalo online!

Trasforma ogni dimensione xdell'input in un elenco [1..x], ad es. [2,3,4]-> [[1,2],[1,2,3],[1,2,3,4]]. mapMcrea un elenco di tutte le possibili n-tuple in cui il primo elemento viene preso dal primo elenco, ecc. Due volte !!per indicizzare la n-tupla e la dimensione.

Modifica: @ Ørjan Johansen ha salvato 8 9 byte. Grazie!


Ooh, intelligente! Ma mapM id.map f=mapM f. Ed (`take`[0..])è più corto.
Ørjan Johansen,

@ ØrjanJohansen: 8 byte, è enorme! Molte grazie! Ancora in attesa di una risposta dell'OP se sono consentite coordinate basate su 1.
nimi,

Inoltre, l#n=(mapM(`take`[0..])l!!n!!)è più corto. (Per inciso, non hai bisogno delle f=, le funzioni possono essere anonime. Oh, immagino che non le stia contando.)
Ørjan Johansen,

@ ØrjanJohansen: grazie ancora. Si f=è verificato un errore di copia e incolla da TIO.
nimi,

2

Brachylog , 25 23 byte

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

Provalo online!

Il secondo argomento è 1 indicizzato, gli altri 2 sono 0 indicizzati.

Spiegazione

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 byte

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

Utilizzo dell'indicizzazione in base 1 per l'input e indicizzazione in base 0 per l'output.

Perché Or? Perché è la funzione integrata più breve con l'attributo Flat.

Esempio:

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

Out[1]= 2

1

APL (Dyalog) , 6 byte

Per ottenere l'indicizzazione basata su 0 ⎕IO←0, impostazione predefinita su molti sistemi. Richiede le dimensioni, quindi un elenco racchiuso tra (nodo, coordinate).

⎕⊃↑,⍳⎕

Provalo online!

 richiedere dimensioni

 genera un array di quella forma con ogni elemento che è l' i nice per quell'elemento

, ravel (trasformalo in elenco di indici)

 converti un livello di profondità in un livello aggiuntivo di rango

⎕⊃ richiede un elenco chiuso di (nodo, coordinate) e usalo per selezionare un elemento da quello


1

Gelatina , 7 6 byte

Œp⁴ị⁵ị

Provalo online!

Questo utilizza 1-indicizzazione per input e output.

Come funziona

Œ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 byte

@.n]@*FUMQEE

Provalo online!

Come funziona

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

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

restituisce una funzione anonima, indicizzata 1.

per esempio. expand.gridgenera l'elenco, ma il primo argomento varia più velocemente, quindi dobbiamo inserirli in ordine inverso, cioè z,y,x. Quindi possiamo semplicemente indicizzare [n,4-i], dove 4-iè necessario per l'ordine invertito, e sottrarre 1 per assicurarsi che vengano eseguiti0:(x-1) , ecc.

Provalo online!



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]

Purtroppo reduceè più lungo di due byte:

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

Sembra che abbiamo avuto la stessa idea \ / /
Leaky Nun

@LeakyNun Beh, non è davvero sorprendente, dato come funziona l'indicizzazione.
Neil,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.