Índices e valores de swap


29

A tarefa

Escreva um programa ou função cuja entrada seja uma lista / matriz X de números inteiros e cuja saída seja uma lista de conjuntos de números inteiros Y , de modo que para cada elemento e em cada conjunto Y [ i ], X [ e ] = i , e de tal modo que o número total de elementos nos conjuntos em Y é igual ao número de elementos em X .

(Esta é basicamente a mesma operação que reverter uma hashtable / dicionário, exceto aplicada a matrizes.)

Exemplos

Esses exemplos assumem a indexação baseada em 1, mas você pode usar a indexação baseada em 0, se preferir.

X             Y
[4]           [{},{},{},{1}]
[1,2,3]       [{1},{2},{3}]
[2,2,2]       [{},{1,2,3}]
[5,5,6,6]     [{},{},{},{},{1,2},{3,4}]
[6,6,5,5]     [{},{},{},{},{3,4},{1,2}]

Esclarecimentos

  • Você pode representar um conjunto como uma lista, se desejar. Se você fizer isso, a ordem de seus elementos não importa, mas você não pode repetir elementos.
  • Você pode usar qualquer formato de E / S inequívoco razoável; por exemplo, você pode separar elementos de um conjunto com espaços e os conjuntos com novas linhas.
  • Y deve ser finitamente longo e pelo menos longo o suficiente para ter todos os elementos de X como índices de matriz. No entanto, pode ser maior que o elemento máximo de X (os elementos extras seriam conjuntos vazios).
  • Os elementos de X serão todos índices de matriz válidos, ou seja, números inteiros não negativos se você usar a indexação com base em 0 ou números inteiros positivos se você usar a indexação com base em 1.

Condição de vitória

Como um desafio do , quanto menor, melhor.


Relacionado . Na postagem da Sandbox (agora excluída, mas você pode visualizá-la se tiver reputação), decidimos que provavelmente não era uma duplicata, mas fique à vontade para votar para fechar se não concordar.

"A ordem de seus elementos não importa" significa que as saídas [5,5,6,6]e [6,6,5,5]podem ser idênticas?
Freira Furada

11
@LeakyNun A ordem dos elementos dos conjuntos na lista de saída não importa. Portanto, [5,5,6,6]e [6,6,5,5]não pode ter saída idêntica, mas a saída para [5,5,6,6]também poderia ter sido, por exemplo [{},{},{},{},{2,1},{4,3}],.
Ngenisis 10/05

Existe um valor máximo presumível de um índice em X? Os conjuntos vazios também podem ter um 0 em vez de estarem realmente vazios? Por exemplo, seria [{0},{0},{0},{0},{1,2},{3,4}]uma saída válida para [5,5,6,6]?
Skidsdev 10/05

@ Mayube: Não para a primeira resposta (embora se você estiver usando um idioma que tenha um número limitado de números inteiros, você pode escrever o programa como se os números inteiros pudessem ser ilimitadamente grandes, e não se preocupe com isso se alguém lhe der uma inteiro de intervalo como entrada). Com relação à segunda pergunta, essa é uma sintaxe inequívoca (se esquisita) quando você estiver usando a indexação baseada em 1; portanto, nesse caso (obviamente, não, se você estiver usando a indexação baseada em 0, porque o 0 significaria algo) mais.)

Respostas:


9

MATL , 8 bytes

tn:IXQ&D

Entrada é um vetor de coluna, com ;como separador (por exemplo [2;2;2]). Saída é a representação de seqüência de caracteres de uma matriz de células de vetores de linha (por exemplo {[]; [1 2 3]}). Um vetor de linha de um único elemento é igual a um número (portanto, {1; 2; 3}seria a saída em vez de {[1]; [2]; [3]}).

Experimente online! Ou verifique todos os casos de teste .

Explicação

t     % Implicit input, say x. Duplicate
n     % Number of elements, say N
:     % Range: [1 2 ... N]
IXQ   % accumarray(x, [1 2 ... N], [], @(x){sort(x).'})
&D    % String representation

A maior parte do trabalho é realizada pela função de ordem superior do Matlab accumarray, que agrupa elementos na segunda entrada de acordo com os valores correspondentes na primeira e aplica uma função especificada a cada grupo. A função nesse caso é @(x){sort(x).'}, que gera os elementos classificados em cada grupo e faz com que os resultados de todos os grupos sejam compactados em uma matriz de células.


7

Python, 69 bytes

lambda s:[[j for j,x in enumerate(s)if x==i]for i in range(max(s)+1)]

Usa indexação baseada em 0.


7

Geléia , 7 5 bytes

=þṀT€

Experimente online!

Como funciona

=þṀT€  Main link. Argument: A (array)

  Ṁ    Yield m, the maximum of A.
=þ     Equals table; for each t in [1, ..., m], compare all elemnts of A with t,
       yielding a 2D Boolean array.
   T€  Truth each; for each Boolean array, yield all indices of 1.

5

Gelatina , 8 bytes

Jẋ"Ṭ€;"/

Experimente online!

Como funciona

Jẋ"Ṭ€;"/  argument: z           eg. [6,6,4,4]
J         [1 .. len(z)]             [1,2,3,4]
   Ṭ€     untruth each of z         [[0,0,0,0,0,1],
                                     [0,0,0,0,0,1],
                                     [0,0,0,1],
                                     [0,0,0,1]]
 ẋ"       repeat each of ^^         [[[],[],[],[],[],[1]],
          as many times as           [[],[],[],[],[],[2]],
          each of ^                  [[],[],[],[3]],
                                     [[],[],[],[4]]]
       /  reduce by...
     ;"   vectorized concatenation  [[],[],[],[3,4],[],[1,2]]

4

Mathematica, 36 bytes

Join@@@#~Position~n~Table~{n,Max@#}&

Explicação

insira a descrição da imagem aqui

Para cada nin {1, 2, ..., Max@#}, onde Max@#é o maior número inteiro na lista de entrada, calcula os Positions onde naparece na lista de entrada #. Como Position[{6,6,5,5},5](por exemplo) retorna {{3},{4}}, passamos Apply Joina todos os elementos no nível {1}do resultado.


3

Haskell , 45 bytes

spega uma lista de números inteiros e retorna uma lista de listas. Indexado em 1 para manter as entradas do caso de teste não modificadas (embora a saída obtenha algumas listas vazias extras).

s l=[[i|(i,y)<-zip[1..]l,y==x]|x<-[1..sum l]]

Experimente online!

Essas são compreensões de lista aninhadas bastante simples. O único pequeno ajuste é aproveitar a opção de fazer uma lista mais longa usando em sumvez de maximum.


3

PHP, 55 bytes

<?while($i<=max($_GET))print_r(array_keys($_GET,$i++));

Indexado a 0.


3

R, 68 49 47 bytes

lapply(1:max(x<-scan()),function(y)which(y==x)) 

Surpreendentemente, muito mais direto do que as soluções mais longas. Pega um vetor xde STDIN, cria um vetor de 1para max(x), gera implicitamente uma lista de comprimento max(x)e verifica quais índices xcorrespondem aos da nova lista. Imprime implicitamente a saída.

Versão antiga:

o=vector('list',max(x<-scan()));for(i in x)o[[i]]=c(o[[i]],F<-F+1);o

Abordagem ligeiramente diferente da outra resposta R. Leva um vetor para STDIN, cria uma lista com comprimento igual ao valor máximo na entrada. Faz um loop na entrada e adiciona o índice no lugar certo.

Usa indexação baseada em 1.


2

Python 2 , 91 86 85 bytes

Estou programando no meu telefone, mas gostei muito desse desafio. Definitivamente, ainda posso jogar golfe.

def f(a):
 r=[[]for i in range(max(a)+1)]
 for i,j in enumerate(a):r[j]+=[i]
 print r

Experimente online!


Jogou fora novamente por uma compreensão de lista aninhada. : D
totallyhuman

2

Geléia , 9 bytes

Ṭ+\ịĠȧ@"Ṭ

Conjuntos vazios indexados em 1 representados como 0, conjuntos de um item representado como Nconjuntos de vários itens representados como[M,N,...]

Experimente online!

Quão?

Ṭ+\ịĠȧ@"Ṭ - Main link: list a        e.g. [6,6,4,4]
Ṭ         - untruth a                     [0,0,0,1,0,1]
  \       - cumulative reduce with:
 +        -   addition                    [0,0,0,1,1,2]
    Ġ     - group indices of a by value   [[3,4],[1,2]]
   ị      - index into                    [[1,2],[1,2],[1,2],[3,4],[3,4],[1,2]]
        Ṭ - untruth a                     [0,0,0,1,0,1]
       "  - zip with:
     ȧ@   -   and with reversed @rguments [0,0,0,[3,4],0,[1,2]]

2

JavaScript (ES6), 64 62 bytes

Guardado 2 bytes graças a @SteveBennett


Recebe entrada indexada em 0. Retorna uma lista de conjuntos separados por vírgula.

a=>a.map((n,i)=>o[n]=[i,...o[n]||[]],o=[])&&`{${o.join`},{`}}`

Casos de teste


Versão alternativa, 53 bytes

Se uma saída simplificada como '||||3,2|1,0'é aceitável, podemos apenas fazer:

a=>a.map((n,i)=>o[n]=[i,...o[n]||[]],o=[])&&o.join`|`

Uau. Estou tão confuso como `{${o.join`},{`}}`é legal o ES2015.
9788 Steve Bennett #

@SteveBennett, é um modelo literal . Nas versões mais antigas do JS seria "{" + o.join("},{") + "}", se isso tornar mais claro.
Shaggy

Não, eu sei sobre isso - é a citação após a palavra junção que me confunde. Isso é fechar a string (nesse caso, wtf) ou é assim que você escapa de uma chave estreita?
Steve Bennett

Hmm, ok, então neste contexto join`é equivalente a join('. Não tinha ideia de que você poderia fazer isso.
Steve Bennett

Ah, agora eu vejo. É um literal de modelo marcado. Que você pode abusar para salvar um par de personagens sempre chamando uma função que leva um argumento string (e ignora outros): array.join` `. Super confusa aqui porque você está incorporando isso em uma sequência de modelo, e ainda mais confusa, a sequência de junção é },{, que coincidentemente parecia parte da sequência de modelo ... e é estranha e feia de qualquer maneira. :)
Steve Bennett

1

Bash , 109 bytes

Pena que não há built-in para o valor máximo da matriz.

a=($@)
for((x=m=1;x<=m;x++)){ for((y=0;y<$#;)){((m<a[y]))&&((m=a[y]));((a[y++]==x))&&printf "%d " $y;};echo;}

Experimente online!


1

Mathematica 62 bytes

(Y={}~Table~Max@#;Y[[#[[j]]]]~AppendTo~j~Table~{j,Tr[1^#]};Y)&

Eu vou executá-lo para você

(Y={}~Table~Max@#;Y[[#[[j]]]]~AppendTo~j~Table~{j,Tr[1^#]};Y)&[{4,5,2,3,3,8,6,3}]

{{}, {3}, {4, 5, 8}, {1}, {2}, {7}, {}, {6}}

Experimente online (basta colar o código com ctrl-v e pressione Shift + Enter)
não se esqueça de colar a lista de entradas no final, como no exemplo acima


Bem-vindo ao PPCG! Você pode salvar um byte usando a notação infix para AppendTo. Além disso, {j,1,Length[#1]}poderia ser apenas {j,Length@#}, ou até mais curto {j,Tr[1^#]},. Tr[1^#]é um truque bastante comum para economizar um byte Length.
Ngenisis

1

Perl 6 ,  36 32  29 bytes

->\a{map {a.grep(*==$_):k},1..a.max}

Tente

{map {.grep(*==$^a):k},1.. .max}

Tente

{map {.grep($^a):k},1.. .max}

Tente


Expandido:

{  # bare block lambda with implicit parameter 「$_」

  map

    {  # bare block lambda with placeholder parameter 「$a」

      .grep(  # grep for the values in 「$_」
        $^a   # that are equal to the currently tested value (and declare param)
      ) :k    # return the key (index) rather than the value
    },

    1 .. .max # Range from 1 to the maximum value in 「$_」

}

Retorna índices baseados em zero, para obter 1 uso cruzado entre operadores ( X) combinado com +op . (33 bytes)

{1 X+.grep($^a):k}

Para fazê-lo retornar Set s basta adicionarset lá (total de 37 bytes)

{set 1 X+.grep($^a):k}





0

GNU Make , 214 213 208 204 bytes

X=$(MAKECMDGOALS)
M=0
P=$(eval N=$(word $1,$X))$(if $N,$(if $(shell dc -e$Nd$Mds.\>.p),$(eval M=$N),)$(eval A$N+=$1$(call $0,$(shell expr $1 + 1))),)
$(call P,1)$(foreach K,$(shell seq $M),$(info $(A$K)))

E / S: matriz de entrada via argumentos, saída para stdout, uma por linha, separada por espaços.

$ make -f swap.mk 2 2 2

3 2 1
make: *** No rule to make target `2'.  Stop.

Explicação

X=$(MAKECMDGOALS)     # Input array
M=0                   # Max value encountered in X
P=$(eval
    N=$(word $1,$X))  # Get next word from X
  $(if $N,$(if $(shell dc -e$Nd$Mds.\>.p),
    $(eval M=$N),)    # Update M
    $(eval A$N+=$1    # Append index to a variable named after value
      $(call $0,      # Recurse (call returns empty string)
        $(shell expr $1 + 1))),)
$(call P,1)           # Initial call to P. 1 is the first index
$(foreach K,          # Print all values of A* variables
  $(shell seq $M),
  $(info $(A$K)))     # Uninitialized ones default to empty strings

A ordem dos índices em conjuntos é revertida porque P chama recursivamente antes da atualização A$2(chamada executada na avaliação do lado direito).


Tem makealguma maneira de fazer aritmética em si? Chamar programas externos para fazer isso parece um pouco de trapaça, porque você provavelmente poderia colocar muito mais do algoritmo nesses programas e acabar com um programa mais curto.

@ ais523 Não tem. Versão anterior usada bce grep. Eu também poderia usar teste $?. dctem uma sintaxe terser, mas francamente todos parecem iguais.
Eush77

0

Lisp comum, 91 bytes

(lambda(x &aux(l(make-list(eval`(max,@x))))(i 0))(dolist(y x l)(push(incf i)(nth(1- y)l))))

Indexação baseada em 1, retorna os conjuntos como listas.

Experimente online!


0

k , 13 bytes

{(=x)@!1+|/x}

Este é o índice 0.

Experimente online!

{           } /function(x)
 (=x)         /make a map/dictionary of values to their indices
         |/x  /get maximum value in x
      !1+     /make a range from 0 to the value, inclusive
     @        /get map value at each of the values in the range
              /    0N is given where there is no result
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.