Linguagens de nível inferior, como C e C ++, na verdade não têm conceito de matrizes multidimensionais. (Diferente de vetores e matrizes dinâmicas) Quando você cria uma matriz multidimensional com
int foo[5][10];
Na verdade, isso é apenas açúcar sintático . O que C realmente faz é criar uma única matriz contígua de 5 * 10 elementos. este
foo[4][2]
também é açúcar sintático. Isso realmente se refere ao elemento em
4 * 10 + 2
ou o 42º elemento. Em geral, o índice do elemento [a][b]
na matriz foo[x][y]
está em
a * y + b
O mesmo conceito se aplica às matrizes 3D. Se temos foo[x][y][z]
e acessamos o elemento [a][b][c]
, estamos realmente acessando o elemento:
a * y * z + b * z + c
Esse conceito se aplica a matrizes n- dimensionais. Se temos uma matriz com dimensões D1, D2, D3 ... Dn
e acessamos S1, S2, S3 ... Sn
o elemento, a fórmula é
(S1 * D2 * D3 ... * Dn) + (S2 * D3 * D4 ... * Dn) + (S3 * D4 ... * Dn) ... + (Sn-1 * Dn) + Sn
O desafio
Você deve escrever um programa ou função que calcule o índice de uma matriz multidimensional de acordo com a fórmula acima. A entrada terá duas matrizes. A primeira matriz são as dimensões e a segunda matriz são os índices. O comprimento dessas duas matrizes sempre será igual e pelo menos 1.
Você pode assumir com segurança que todo número nas matrizes será um número inteiro não negativo. Você também pode assumir que não obterá um 0
na matriz de dimensões, embora um 0
possa estar nos índices. Você também pode assumir que os índices não serão maiores que as dimensões.
Teste de E / S
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
fonte
int[10]
.Respostas:
APL, 1 byte
Teste-o no TryAPL .
fonte
J, 2 bytes
Onde há um APL, há um J! Mais ou menos. Toma dimensões como arg esquerdo e indexa como arg direito. "A indexação de uma matriz multidimensional é essencialmente uma conversão de base mista."
fonte
JavaScript (ES6), 34 bytes
Certamente
reduce
deve ser melhor quemap
.fonte
Python, 43 bytes
Teste em Ideone .
fonte
Geléia ,
76 bytesExperimente online! ou verifique todos os casos de teste .
Como funciona
fonte
Pitão, 10 bytes
Experimente on-line: Demonstration or Test Suite
Usando o método de Horner para calcular o índice.
fonte
MATL , 9 bytes
Isso usa a indexação baseada em 1 (agora permitida pelo desafio), que é a escolha natural no MATL.
Para comparar com os casos de teste no desafio, inclua
1
em cada entrada no vetor de índice de entrada e subtraia1
da saída.Experimente online!
Explicação
O código é baseado na
X]
função interna , que converte índices multidimensionais em um único índice linear (como asub2ind
função Matlab ou Octave ).fonte
Julia,
2927 bytesExperimente online!
fonte
MATL , 11 bytes
Isso usa indexação baseada em 0, como no desafio original.
Experimente online!
Explicação
O código faz explicitamente as multiplicações e adições necessárias.
fonte
Python, 85 bytes
Provavelmente vou ser chutado pelos melhores jogadores de python por aí.
fonte
Python 3.5, 69
Teste aqui
fonte
Haskell, 34 bytes
Exemplo de uso:
[10,10,4,62,7] # [1,2,3,4,5]
->22167
.Como funciona:
fonte
C ++, 66 bytes
Uma macro rápida:
Use como:
Isso pode ser um pouco de abuso das regras. Cria uma matriz com o tamanho especificado, em seguida, verifica se a distância em que os índices determinados compensa o ponteiro. Saídas para STDOUT.
Isso parece tão sujo ... Mas eu simplesmente amo o fato de que isso é válido.
fonte
Mathematica, 27 bytes
Uma função sem nome que leva a lista de índices como o primeiro argumento e a lista de dimensões em segundo. Com base na mesma observação da resposta de Dennis à APL de que calcular o índice é realmente apenas uma conversão de base mista.
fonte
Oitava,
5854 bytesGraças a @AlexA. por sua sugestão, que removeu 4 bytes
Entrada e saída são baseadas em 1. Para comparar com os casos de teste, adicione
1
cada entrada na entrada e subtraia1
da saída.Esta é uma função anônima. Para chamá-lo, atribua-o a uma variável.
Experimente aqui .
Explicação
Isso funciona, realmente construir a matriz multidimensional (
reshape(...)
), cheio de valores1
,2
... de modo linear (1:prod(d)
), e depois indexando com o índice multidimensional para obter pelo valor correspondente.A indexação é feita convertendo o índice multidimensional de entrada
i
em uma matriz de células (num2cell(...)
) e depois em uma lista separada por vírgula ({:}
).As duas
flip
operações são necessárias para adaptar a ordem das dimensões de C para oitava.fonte
reshape
? Isso não é sintático no Matlab, mas é aceito no Octave. Funciona como um índice@(...) ...
na primeira linha do meu código, seguida pelaf = ans;
segunda. Isso torna o comprimento da primeira linha igual ao número de bytes a serem relatados.CJam, 7 bytes
Experimente online!
Como funciona
fonte
Haskell, 47 bytes
Duas soluções de igual comprimento:
Chamado como:
((sum.).s)[4,2][5,10]
.Aqui está uma versão infix:
fonte
Oitava,
47/43/31 bytes@(d,i)sub2ind(flip(d),num2cell(flip(i+1)){:})-1
Teste aqui .
Dito isto, como foi solicitado em um comentário , a indexação baseada em 1 foi considerada boa quando isso é natural para o idioma que está sendo usado. Nesse caso, podemos salvar 4 bytes:
@(d,i)sub2ind(flip(d),num2cell(flip(i)){:})
Por analogia, argumento que, se o objetivo do código é indexar linearmente uma matriz dentro dessa linguagem , todo o movimento e contabilização da ordem principal da coluna do MATLAB / Octave também não seria necessário. Nesse caso, minha solução se torna
@(d,i)sub2ind(d,num2cell(i){:})
Teste esse aqui .
fonte
Mathematica, 47 bytes
(Unicode é U + F3C7, ou
\[Transpose]
.) Para isso, reescrevi a expressão como D n ( D n -1 (⋯ ( D 3 ( D 2 S 1 + S 2 ) + S 3 ) ⋯) + S n -1 ) + S n . É apenasFold
a função nas duas listas.fonte
Na verdade, 13 bytes
Experimente online!
Este programa utiliza a lista de índices como a primeira entrada e a lista de dimensões como a segunda entrada.
Explicação:
fonte
Raquete 76 bytes
Ungolfed:
Teste:
Saída:
fonte
C #, 73 bytes
Programa completo com casos de teste:
fonte
Perl 6, 39 bytes
Um golfe bastante ingênuo aqui, acabou de esmagar um sub anônimo.
O Perl 6 tem uma variável de estado anônima
$
que é útil para criar um contador em um loop (por exemplo, usando pós-incremento$++
ou pré-incremento++$
). Eu pré-incremento essa variável de estado para incrementar o índice inicial da fatia da matriz de dimensão dentro de um mapa.Aqui está uma função não destruída que cria as sub-listas
Depois, basta reduzir as sub-listas com o
×
operador multiplication ( ) e obtersum
os resultados.fonte
Perl, 71 bytes
Ungolfed:
fonte
C ++ 17,
133115 bytes-18 bytes para usar
auto...
Ungolfed:
Uso:
Alternativa, apenas funções, 116 bytes
Ungolfed:
Uso:
fonte