Considérons une permutation des entiers 1
, ... n
,, comme celui-ci pour n = 6
:
[5,2,4,3,6,1]
Si vous voyez la permutation comme un mappage de [1,2,3,4,5,6]
à [5,2,4,3,6,1]
, la permutation peut être décomposée en cycles disjoints . Un cycle est un sous-ensemble d'éléments qui se mappent les uns aux autres. Par exemple, 1
obtient mappé sur 5
, qui est mappé sur 6
, qui est mappé sur 1
. Donc, un cycle est [1,5,6]
. Les autres cycles sont[2]
et [3,4]
. Ainsi, le nombre de cycles pour cette permutation est 3
.
En général, les cycles d'une permutation sont uniques (dans l'ordre) et le nombre de cycles pour une permutation de taille n
varie de 1
à n
.
Le défi
Étant donné une permutation non vide, affichez son nombre de cycles.
L' entrée est une matrice formée par les n
nombres entiers 1
, 2
...,n
où n > 0
. Chaque entier apparaît exactement une fois. L'ordre dans lequel ils apparaissent définit la permutation, comme dans l'exemple ci-dessus.
Au lieu d'un tableau, vous pouvez utiliser une liste, une chaîne avec un séparateur entre les nombres, une entrée distincte pour chaque numéro, ou tout ce qui est raisonnable.
Pour une permutation de taille n
, au lieu de l'ensemble basé sur 1 d'entiers 1
, ..., n
vous pouvez toujours utiliser l'ensemble basé sur 00
, ..., n-1
. Si oui, veuillez l'indiquer dans votre réponse.
Le code devrait fonctionner n
jusqu'à 20
un délai raisonnable, disons moins d'une minute.
Code golf. Tous les buildins autorisés.
Cas de test
Cela suppose une entrée de tableau basée sur 1.
[1] -> 1
[3,2,1] -> 2
[2,3,4,5,1] -> 1
[5,2,4,3,6,1] -> 3
[8,6,4,5,2,1,7,3] -> 2
[4,5,11,12,7,1,3,9,10,6,8,2] -> 1
[4,2,5,11,12,7,1,3,9,10,6,8] -> 5
[5,8,6,18,16,9,14,10,11,12,4,20,15,19,2,17,1,13,7,3] -> 3
[14,5,17,15,10,18,1,3,4,13,11,16,2,12,9,7,20,6,19,8] -> 7
en relation
Ce défi connexe demande les cycles réels de la permutation, pas le nombre d'entre eux. Ne nécessiter que le nombre de cycles peut conduire à des algorithmes plus courts qui contournent la génération des cycles réels.
la source
1
, ...,n
dans cet ordre. Pouvez-vous préciser comment un mappage peut être une entrée? Est-ce une structure de données?dict
. Je veux avoir{1: 2, 2: 1}
une entrée au lieu de[2, 1]
.Réponses:
J, 4 octets
Cela suppose que la permutation est basée sur 0. Il utilise la fonction intégrée
C.
qui, à partir d'une liste représentant une permutation directe, génère une liste de cycles. Puis#
composé@
sur qui renvoie le nombre de cycles dans cette liste.Essayez-le ici.
la source
JavaScript,
9998 octetsCette solution suppose que le tableau et ses valeurs sont indexés à zéro (par exemple
[2, 1, 0]
).Explication
la source
Mathematica, 45 octets
Il génère un graphique et compte ses composants connectés.
la source
Mathematica,
372827 octetsMerci à @alephalpha d'avoir enregistré 9 octets et à @miles pour 1 octet de plus.
la source
PermutationCycles[#,Length]&
PermutationCycles
pouvait prendre un deuxième argument pour modifier la tête de sa sortie. Vous pouvez également utiliser la notation infixe pour enregistrer un autre octet#~PermutationCycles~Length&
.#&
est un peu plus court queIdentity
. ;)Python,
776967 octetsla source
(not p[i-1])
peut être fait comme0**p[i-1]
Gelée,
12109 octets1 octet enregistré grâce à @ Dennis .
Cela utilise des permutations basées sur 1. Il fonctionne en appliquant la permutation à plusieurs reprises jusqu'à ce qu'il atteigne une permutation précédente tout en conservant ses valeurs précédentes. En gardant une trace des changements, il créera l'orbite pour chaque valeur le long des colonnes de cette table. Ensuite, en trouvant le minimum ou le maximum de chaque colonne, une étiquette pour ce cycle peut être créée. Dédupliquez ensuite cette liste d'étiquettes et obtenez sa longueur qui sera le nombre de cycles disjoints.
Essayez-le ici.
Explication
la source
ị³$ÐĿ«/QL
devrait marcher.Python, 64 octets
Ce code golfé est idiomatique et lisible. Utilise l'indexation 0.
Chaque valeur examine ce vers quoi elle pointe et vers quoi pointe la valeur pointée et pointe vers la plus petite des deux. Après suffisamment de répétitions, chaque élément pointe vers le plus petit élément de son cycle. Le nombre d'éléments distincts pointés est alors le nombre de cycles.
Il suffit de faire des
n
itérations. Alternativement, nous pourrions répéter jusqu'à ce que la liste ne change plus. Cette stratégie m'a donné une fonction récursive de même longueur, 64 octets:La réduction était de 65 octets
Les
set(_)
conversions peuvent être raccourcies{*_}
en Python 3.5, économisant 2 octets.la source
Haskell, 111 octets
Utilise l'indexation basée sur 0
la source
1l!i|iIi!!1ll1|
Pyth, 9 octets
Utilise des index basés sur 0. Essayez-le en ligne .
Comment ça marche
la source
JavaScript (ES6), 49 octets
Utilise une indexation à base zéro. Explication:
reduce
est utilisée pour appeler la fonction interneg
sur chaque élément du tableau.c
est le nombre de cycles,e
est l'élément de tableau,i
est l'indice de tableau. Si l'élément est inférieur à l'index, alors c'est un cycle potentiel - l'élément est utilisé pour indexer dans le tableau pour trouver l'élément suivant dans le cycle de manière récursive. Si nous avons commencé ou fini avec l'index d'origine, alors c'est un nouveau cycle et nous incrémentons le nombre de cycles. Si à un moment donné, nous trouvons une valeur supérieure à l'indice, nous comptons ce cycle plus tard.la source
[2,1,0,3,4,5]
, il s'est écrasé avec ce message "La taille maximale de la pile d'appels a été dépassée".C, 90 octets
Appelez
f()
avec unint
tableau mutable , 1 indexation basée. Le deuxième paramètre est la taille du tableau. La fonction renvoie le nombre de cycles.Essayez-le sur ideone .
L'algorithme:
la source
GAP , 30 octets
Simple, le deuxième argument
Cycles
donne l’ensemble sur lequel la permutation doit agir:la source