Coordenadas de identificação automática

27

Escreva um programa ou função que, dado um número inteiro n, construa uma matriz com ndimensões de ncomprimento, em que cada elemento seja um identificador de suas próprias coordenadas. Ou seja, começando com uma matriz, preencha-a com nmatrizes, onde cada uma delas contém nmais matrizes, até uma profundidade de n-1. Os elementos das matrizes mais profundas são as coordenadas que descrevem onde estão na matriz completa.

Alguns exemplos, caso minha explicação seja confusa.

n = 1

["1"]

n = 2

[
 ["11", "12"],
 ["21", "22"]
]

n = 3

[
  [
    ["111","112","113"],
    ["121","122","123"],
    ["131","132","133"]
  ],
  [
    ["211","212","213"],
    ["221","222","223"],
    ["231","232","233"]
  ],
  [
    ["311","312","313"],
    ["321","322","323"],
    ["331","332","333"]
  ]
]

Aqui, "321" significa que é o 1º elemento do 2º elemento da 3ª matriz.

Regras:

  • As coordenadas e a dimensão ( n) podem ser 0 ou 1 indexadas
  • Você pode assumir que né um dígito, abaixo de 10 para ambas as opções de indexação, para evitar resultados ambíguos
  • IO é flexível.
    • Em particular, as coordenadas podem ser matrizes, seqüências de caracteres etc., desde que sejam claras. "321" => [3,2,1]
    • A saída pode ser números inteiros na base 10 com ou sem zeros à esquerda.
    • As coordenadas podem estar na ordem inversa, se desejar, desde que seja consistente. "321" => "123"
    • A saída não precisa necessariamente ser uma estrutura de matriz no seu idioma. Desde que haja marcadores distintos e claros para o início de uma matriz, o fim de uma matriz e para a separação de elementos.
    • A saída para n=1pode ser apenas 1
    • Se sua saída for atípica, certifique-se de explicar o formato.
  • Isso é e a solução mais curta em cada idioma vence!
Brincadeira
fonte
Sandbox (excluído)
Jo King
Eu estava tendo problemas para escrever isso em Haskell, antes de perceber que o sistema de tipos torna isso impossível.
Wheat Wizard
@ CatWizard: Você sempre pode definir uma nova estrutura de dados para contornar isso, por exemplo. data L a = L [L a] | E a.
ბიმო
2
Relacionado .
Adám
1
@ToddSewell Você não pode ter uma função cujo tipo dependa da entrada. Esta função poderia ter tipo Int -> [String]ou Int -> [[String]]e assim por diante, dependendo do que a entrada é
H.PWiz

Respostas:

19

Dyalog APL , 5 3 bytes

⍳⍴⍨

-2 bytes graças ao FrownyFrog

Experimente online!

fornece todos os índices com o formato de uma matriz. por exemplo 2 3 .
reformula o argumento da direita para ser o tamanho do argumento da esquerda. faz com que ambos sejam o argumento certo.

dzaima
fonte
10

Python 3 , 56 bytes

f=lambda n,*l:len(l)//n*l or[f(n,*l,k)for k in range(n)]

Experimente online!

O Sr. Xcoder economizou 2 bytes mudando para o Python 3 por descompactar as estrelas.

xnor
fonte
3
Se você alternar para Python ≥3,5, f=lambda n,*l:len(l)//n*l or[f(n,*l,k)for k in range(n)]funciona por 56 bytes.
Sr. Xcoder
6

J , 18 bytes

,"1/^:(]{:)~@,.@i.

Experimente online!

Solução iterativa, nenhum produto cartesiano embutido. É assim que o pico J se parece.

                       input                                    2
                i.     range                                 0, 1
             ,.@       reshape each element
                       into a one-dimensional array        [0],[1]   (A)
    ^:(]{:)            (input−1) times...             (1 iteration)
,"1/       ~@             prepend the contents of each 1d array in A    |
                          to every 1d array from the previous iteration,|  
                          assembling the results for each A[n] into     |!CANTEXPLAINTHIS!
                          a larger array                                |
                                                         [ [0,0],       |
                                                           [0,1] ],     |
                                                         [ [1,0],       |
                                                           [1,1] ]      |
FrownyFrog
fonte
No início, a contagem de bytes maior colocar-me fora, mas este é realmente bela J
Jonah
6

Geléia , 8 7 bytes

ṗ³s³$³¡

Experimente online!

Explicação

Use o argumento 2 como exemplo.

ṗ³s³$³¡   
ṗ        Cartesian power with power
 ³       2 (the argument). Autoranges the left arg.
         Yields [[1,1],[1,2],[2,1],[2,2]]
    $³¡  Do 2 times:
  s³     Split into segments of length 2. 
         This last step molds the array of indices into the proper shape.

Se ¡não variou, o argumento correto sobre iterações para díades seria de 4 bytes:ṗs³¡

dylnan
fonte
Parece um programa completo para mim. Você tem certeza de que a saída (STDOUT) 1é válida?
Erik, o Outgolfer
@EriktheOutgolfer Eu estou bem com a saída para 1
Jo King
@JoKing Mas, neste caso, não existem "marcadores distintos e claros para o início de uma matriz, o fim de uma matriz". Deseja editar a pergunta? (muitas respostas não as contêm)
Erik, o Outgolfer
5

J, 13 bytes

[:{[;/@$,:@i.

Experimente online!

Interessante é muito mais tempo do que a resposta da APL (embora possa ser minha incapacidade de ver uma tradução melhor)

explicação

[: { [ ;/@$ ,:@i.


     [                NB. the argument
            ,:@i.     NB. range 0..arg, considered as one item: ,: is "itemize" 
          $           NB. repeat the right range the left number of times
       ;/@            NB. and then put boxes around them. so, eg, if we had
                      NB. an arg of 3, now we have the list of boxes 
                      NB. [0 1 2][0 1 2][0 1 2]
[: {                  NB. { is "Catalog", it creates the cartesian product
                      NB. in exactly the format we desire.
Jonah
fonte
@FrownyFrog Usar um gancho para evitar #.invé muito inteligente, +1.
Cole
@FrownyFrog Agora que eu olhei para a sua solução "conte em bases diferentes", acho que a abordagem é diferente o suficiente para você adicioná-la como outra postagem. É uma solução muito boa.
Jonah
Jonah, @cole obrigado
FrownyFrog
5

MATLAB, 92 89 55 bytes

Tenho uma resposta diferente depois de reler as regras do desafio, mas deixarei a tentativa anterior abaixo, pois é diferente e ainda divertido de se olhar.

reshape(string(dec2base(0:n^n-1,n+(n<2))),[~(1:n)+n 1])

Explicação

                        0:n^n-1                        % [0,1,...,n^n-1]
               dec2base(       ,n+(n<2))               % Put into base n (base 2 if n=1)
        string(                         )              % Convert to strings
                                          [~(1:n)+n 1] % Dimension array [n,n,...,n] (length n)
reshape(                                 ,            )% Use dim array to reshape

Isso gera uma matriz n-dimensional de cadeias que são 0 indexadas.

Resposta anterior (89 bytes)

Meu primeiro golfe! Provavelmente isso pode ser reduzido mais, mas pensei em publicar o que tenho.

x=(1:n)';for d=2:n;y=((1:n)*10^(d-1));o=[];for p=1:nnz(y);o=cat(d,o,(x+y(p)));end;x=o end

Explicação

x=(1:n)';                       % Create array x=[1,2,...n]'
for d=2:n                       % d for dimension
    y=((1:n)*10^(d-1));         % Creates an array for each d where
                                %   y=[10,20,30,...] for n=2
                                %   y=[100,200,...] for n=3 etc.
    o=[];                       % o for output
    for p=1:nnz(y)              % For each value of y
        o=cat(d,...             % Concatenate in the dth dimension:
            o,...               % - The current output
            x+y(p));            % - The sum of
                                %   - The array from the last dimension
                                %   - The current value in y (e.g. 100)
    end
    x=o                         % Send the output to x for the next loop
end

Saídas x no final para dar solução

Semelhante ao outro post do MATLAB, a saída é uma matriz n-dimensional, exceto que usa números para exibir as coordenadas. Funciona com qualquer valor, embora, como os loops sejam ruins no MATLAB, ele comece a desacelerar significativamente em torno de n = 8.

Edit: -2 bytes graças a Luis Mendo. Também foi removido ponto-e-vírgula final para imprimir a saída.

Jacob Watson
fonte
4
Bem-vindo ao PPCG!
Shaggy
Eu acho que você pode substituir lengthpor nnzpara salvar alguns bytes. Além disso, de acordo com as regras do PPCG, o código precisa produzir alguma saída real, normalmente exibindo-o em STDOUT (não é suficiente ter a saída armazenada em uma variável) ou deve ser uma função que retorna a saída
Luis Mendo
5

Ferrugem ,201 176 167 166 154 bytes

enum L{S(String),L(Vec<L>)}fn
h(n:u8,d:u8,s:&str)->L{if
d<1{L::S(s.into())}else{L::L((0..n).map(|i|h(n,d-1,&format!("{}{}",s,i))).collect())}}|n|h(n,n,"")

Experimente online!

O tipo de saída é um tipo de soma com duas variantes, pois o idioma é estritamente digitado. Pode ser Lum tipo de lista que contém esse tipo de soma ou Sum tipo de resultado (uma sequência). O resultado pode ser assim.

L::L([
 L::L([ L::S("00"), L::S("01") ]),
 L::L([ L::S("10"), L::S("11") ]),
])

Além disso, reformatado usando rustfmt:

enum L {
    S(String),
    L(Vec<L>),
}
fn h(n: u8, d: u8, s: &str) -> L {
    if d < 1 {
        L::S(s.into())
    } else {
        L::L(
            (0..n)
                .map(|i| h(n, d - 1, &format!("{}{}", s, i)))
                .collect(),
        )
    }
}
|n| h(n, n, "")
Konrad Borowski
fonte
4

R , 102 bytes

function(n,m=array(T,rep(n,n)))`if`(n<2,'1',{m[]=apply(which(m,T)[,`[<-`(1:n,1:2,2:1)],1,toString);m})

Experimente online!

  • 1 indexado, invertido
  • infelizmente R armazena matriz por coluna, caso contrário, poderíamos descer para 73 bytes
  • -9 bytes salvos graças à sugestão de Giuseppe para usar a whichindexação de array
digEmAll
fonte
sua resposta de 76 bytes pode ter 73 bytes, e é como eu a implementei antes de verificar se já havia uma resposta R. Você pode alterar algumas abordagens, no entanto? Não tenho certeza.
Giuseppe
1
@ Giuseppe: indexação de array whiché o que eu estava procurando, obrigado! Guardados 9 bytes
digEmAll
4

Java 10, 144 bytes

A solução é método f. Produz uma representação de seqüência de caracteres da matriz.

String h(int n,int d,String s){if(d<1)return s;var r="[";for(int i=0;i++<n;)r+=h(n,d-1,s+i)+",";return r+"]";}String f(int n){return h(n,n,"");}

Experimente Online

Ungolfed

String h(int n, int d, String s) {
    if (d < 1)
        return s;
    var r = "[";
    for (int i = 0; i++ < n;)
        r += h(n, d - 1, s + i) + ",";
    return r + "]";
}
String f(int n) {
    return h(n, n, "");
}

Agradecimentos

Jakob
fonte
1
No Java 10, você pode substituir Object[]por var. Além disso, acho que esse elsebloco é desnecessário, como você tem returnno ifbloco.
Konrad Borowski
3

05AB1E , 7 bytes

LsãsGsô

Experimente online!

Explicação

L          # push range [1 ... input]
 sã        # input repeated cartesian products of the list
   sG      # input - 1 times do:
     sô    # split into input parts
Emigna
fonte
3

JavaScript (Node.js) , 62 60 58 bytes

f=(n,i=n,s='')=>i?[...Array(n)].map((_,j)=>f(n,i-1,s+j)):s

Experimente online! A saída é indexada em 0. Editar: salvou 2 bytes graças a @JoKing e mais 2 bytes graças a @Arnauld.

Neil
fonte
3

MATLAB, 116 108 104 bytes

Eu sinto que deve haver uma maneira mais curta de fazer isso, dada a afinidade do MATLAB em relação a matrizes multidimensionais ... Obrigado a Luis pelos 4 bytes de algumas letras curtas

a=~(1:n)+n;c=cell(1,n);[c{:}]=ind2sub(a,1:n^n);reshape(arrayfun(@(varargin)[varargin{:}],c{:},'un',0),a)

Explicação

% For using twice, define the array of dimension sizes [n, n, .., n]
a=~(1:n)+n;
% To group variable number of outputs from ind2sub into a cell array
c=cell(1,n);   
% Convert linear indices to self-describing coordinates
[c{:}]=ind2sub(a,1:n^n);     
% reshape to make it the n-dimensional array
% arrayfun to loop over the numerous ind2sub outputs simultaneously
% varargin and {:} usage to account for various numbers of inputs
reshape(arrayfun(@(varargin)[varargin{:}],c{:},'uni',0),a)

A saída é uma matriz de células n-dimensional, em que cada elemento é uma matriz dos valores de coordenadas. Funciona para qualquer um que nnão tenha ambiguidade por causa da saída da matriz numérica, desde que uma n^(n+1)matriz de elemento possa ser armazenada na RAM!

Wolfie
fonte
3

Carvão , 26 bytes

Nθ≔EXθθ⪫⪪◧⍘ιθθ ¦0υFθ≔⪪υθυυ

Experimente online! Link é a versão detalhada do código. Explicação:

Nθ

Entrada n.

≔EXθθ⪫⪪◧⍘ιθθ ¦0υ

Gere todos os nⁿ nnúmeros de dígitos na base n.

Fθ≔⪪υθυ

Divida-os nem uma nmatriz dimensional onde cada dimensão é do tamanho n.

υ

Imprima a matriz. O formato de saída padrão é cada elemento em sua própria linha; depois, cada bloco de nlinhas é finalizado por uma linha em branco; em seguida, cada bloco de nblocos de nlinhas é finalizado por uma segunda linha em branco, e assim por diante, até n-1as linhas em branco no nível superior. .

Neil
fonte