Le principe de la permutation des pigeonniers

25

Dans le jeu de sudoku, de nombreux joueurs aiment "saisir" les nombres possibles qui peuvent aller dans chaque carré:

Ligne Sudoku

La ligne ci-dessus peut être représentée sous forme de tableau:

[[1,2,9], [6], [5], [7], [1,2,9], [1,2,9], [3], [1,2,4], [8]]

Maintenant, notez qu'il n'y a qu'un seul endroit où 4aller. Cela nous permet effectivement de simplifier la liste ci-dessus pour:

[[1,2,9], [6], [5], [7], [1,2,9], [1,2,9], [3], [4], [8]]

Le but de ce défi est de prendre une liste de nombres possibles dans une permutation, et de déduire quelles possibilités peuvent être éliminées .

Comme autre exemple, disons que vous avez le tableau de possibilités suivant:

[[0,1,3], [0,2,3], [1,2], [1,2]]

Les deux dernières places doivent être remplies par 1 et 2. Par conséquent, nous pouvons supprimer ces possibilités des deux premiers éléments du tableau:

[[0,3], [0,3], [1,2], [1,2]]

Comme autre exemple:

[[0,1,2,3], [0,2], [0,2], [0,2]]

Il est impossible de construire une permutation à partir des possibilités ci-dessus, car il n'y a qu'un seul emplacement pour les deux 1et 3, et vous voudriez retourner un tableau vide.

Vous devez entrer une liste de possibilités et sortir les possibilités restantes une fois que le nombre maximum de possibilités a été éliminé.

  • Si un tableau particulier est impossible, vous devez soit renvoyer un tableau vide, soit un tableau dans lequel l'un des sous-tableaux est vide.
  • Vous pouvez supposer que le tableau sera bien formé et comportera au moins 1 élément.
  • Étant donné un tableau de taille N, vous pouvez supposer que les nombres dans le sous- tableau seront toujours dans la plage [0:N), et queN <= 10
  • Vous ne pouvez pas supposer que chaque numéro de 0à N-1sera présent
  • Vous pouvez supposer que les nombres dans un seul sous-tableau sont uniques.
  • Si un sous-tableau ne contient qu'une seule possibilité, vous pouvez représenter la possibilité dans un tableau ou par lui-même. [[1],[2],[0]], [1,2,0], [[1,2],0,[1,2]]Sont tous valides.
  • Vous pouvez accepter le tableau dans un format de chaîne raisonnable ou au format liste / tableau.
  • Les sous-réseaux peuvent être dans n'importe quel ordre.
  • Au lieu de traiter des tableaux en lambeaux, vous pouvez remplir les emplacements vides avec -1.

Cas de test

[[0]]                                         -> [[0]]
[[1],[0]]                                     -> [[1],[0]]
[[1],[1]]                                     -> []
[[1],[0,1]]                                   -> [[1],[0]]
[[0,1,2],[1,2],[1,2]]                         -> [[0],[1,2],[1,2]]
[[0,1],[1,2],[0,2]]                           -> [[0,1],[1,2],[0,2]]
[[2,1],[1,2],[1,2]]                           -> []
[[0,3],[2,1],[3,0],[3,2]]                     -> [[0,3],[1],[0,3],[2]]
[[0,1],[0,1],[2,3],[2,3,0]]                   -> [[0,1],[0,1],[2,3],[2,3]]
[[0,1],[0,3],[3,2],[0]]                       -> [[1],[3],[2],[0]]
[[3,5,2],[0,2,4],[4,0],[0,1,3,5],[2,1],[2,4]] -> [[3,5],[0,2,4],[4,0],[3,5],[1],[2,4]]
[[6,9,8,4],[4,5],[5,3,6],[3,8,6,1,4],[3,1,9,6],[3,7,0,2,4,5],[9,5,6,8],[6,5,8,1,3,7],[8],[8,0,6,2,5,6,3]] -> [[6,9,4],[4,5],[5,3,6],[3,6,1,4],[3,1,9,6],[0,2],[9,5,6],[7],[8],[0,2]]
[[3,5,0],[5,7],[5,1,2],[1,3,0],[5,3],[5,0],[5,3,7,8,0,6],[7,5,0,1,8],[1,0,8],[0,6]] -> []
[[9,0,2,3,7],[0,7,6,5],[6,9,4,7],[9,1,2,3,0,5],[2,8,5,7,4,6],[6,5,7,1],[5,9,4],[5,9,3,8,1],[5,0,6,4],[0,7,2,1,3,4,8]] -> [[9,0,2,3,7],[0,7,6,5],[6,9,4,7],[9,1,2,3,0,5],[2,8,5,7,4,6],[6,5,7,1],[5,9,4],[5,9,3,8,1],[5,0,6,4],[0,7,2,1,3,4,8]]
[[2,6,0],[0,4,3],[0,6,2],[0,7],[0,9,2,3,6,1,4],[1,7,2],[2,7,8],[8,6,7],[6,5,2,8,0],[5,8,1,4]] -> [[2,6,0],[3],[0,6,2],[0,7],[9],[1],[2,7,8],[8,6,7],[5],[4]]
[[8],[8,0,6,5,7,2,4,1],[8,6,9,3,5,0,7],[3,9,1,0],[9],[9,2,6],[2,8,3],[3,1,6,8,2],[6],[6,4,5,3,0,7]] -> [[8],[5,7,4],[5,7],[0],[9],[2],[3],[1],[6],[4,5,7]]
[[8,1,0],[5,8,7,6,2,0],[6,8,2],[2,4,0,9],[4,1,7,3,6,8],[8,1],[8,0,3],[0,8,2],[0,8,3],[1,8,0]] -> []

Il s'agit d'un alors répondez le plus brièvement possible!

Nathan Merrill
la source
Tout nombre supérieur à 9?
Leaky Nun
Vous n'avez pas besoin de prendre en charge des nombres supérieurs à 9.
Nathan Merrill
Puis-je retourner avec des doublons dans les sous-réseaux?
Leaky Nun
@LeakyNun no. Les sous-réseaux ne peuvent contenir que des éléments uniques.
Nathan Merrill
Je pense que vous avez des erreurs dans votre quatrième cas de test; l'une des sous-listes est entre crochets.
TheBikingViking du

Réponses:

17

Brachylog , 21 octets

:1fz:da|,[]
:2a#d
:Am

Essayez-le en ligne!

Essayez-le en ligne!

Prédicat 0 (prédicat principal)

:1fz:da|,[]
:1f            Find all solutions of Predicate 1 using Input as Input.
   z           Transpose
    :da        Deduplicate each.
       |,[]    If there is no solution, return [] instead.

Prédicat 1 (prédicat auxiliaire 1)

:2a#d
:2a     Each element of Output satisfies Predicate 2 with each element of Input as Input
   #d   Each element is different

Prédicat 2 (prédicat auxiliaire 2)

:Am     Output is member of Input
Leaky Nun
la source
8

Gelée , 10 octets

Œp⁼Q$ÐfZQ€

Essayez-le en ligne!

Œp⁼Q$ÐfZQ€   Main chain, argument: z

Œp           Cartesian product
  ⁼Q$Ðf      Filter for those that remain unchanged when uniquified
       Z     Transpose
        Q€   Uniquify each subarray
Leaky Nun
la source
Il semble un peu fallacieux de revendiquer 10 octets lorsque Jelly utilise des caractères en dehors de latin1. Représentée comme UTF-8, la séquence ci-dessus nécessite 16 octets.
Chris Becke
1
@ChrisBecke Jelly a son propre jeu de caractères
Robin Gertenbach
Et pourtant - si je l'essaye en ligne! - J'ai besoin d'envoyer 16 octets.
Chris Becke
@ChrisBecke Oui, mais si vous téléchargez Jelly, vous n'auriez qu'à écrire un programme de 10 octets.
Leaky Nun
Et l'enregistrer dans un fichier texte que je ne peux pas modifier avec autre chose que Jelly? Par cet argument, si Jelly a compressé son programme, nous devrions seulement compter les octets compressés?
Chris Becke
7

Pyth , 11 octets

{MC{I#.nM*F

Essayez-le en ligne!

{MC{I#.nM*F
         *F  reduce by Cartesian product
             produces nested arrays
      .nM    flatten each
   {I#       filter for invariant under deduplication
  C          transpose
{M           deduplicate each
Leaky Nun
la source
6

Haskell, 100 octets

import Data.List
p z=map nub$transpose$filter(and.(flip$zipWith elem)z)$permutations[0..length z-1]
Geoff Reedy
la source
Bonne solution! and.flip(zipWith elem)zest plus court
Damien
2

Python 3, 101 99 octets

Merci à @TLW pour -2 octets

from itertools import*
lambda x:list(map(set,zip(*[i for i in product(*x)if len(i)==len(set(i))])))

Une fonction anonyme qui prend l'entrée via l'argument d'une liste de listes et retourne une liste d'ensembles.

Comment ça marche

from itertools import*        Import Python's library for iterator generation
lambda x                      Anonymous function with input possibilities x as a
                              list of lists
...for i in product(*x)...    For i in the Cartesian product of x, ie all candidate
                              arrangements:
[...if len(i)==len(set(i))]    Filter into list by non-duplicity (set removes
                               duplicates, so there are no duplicates if the length
                               of i is the same as the length of the set of
                               the elements of i)
zip(*...)                     Unpack and take the transpose, leaving the modified
                              possibilities with duplicates
map(set,...)                  Remove duplicates
:list(...)                    Return the modified possibilities as a list of sets

Essayez-le sur Ideone

TheBikingViking
la source
list(map(set,est plus court, je pense
TLW
2

Mathematica, 46 octets

Union/@Thread@Select[Tuples@#,DuplicateFreeQ]&
alephalpha
la source
0

PHP, 245 231 octets

131 117 pour la fonction produit cartésien, 114 pour les autres trucs

function c($a){if ($a){if($u=array_pop($a))foreach(c($a)as$p)foreach($u as$v)yield $p+[count($p)=>$v];}else yield[];}
function p($a){foreach(c($a)as$i)if(max(array_count_values($i))<2)foreach($i as$k=>$v)$r[$k][$v]=$v;return$r?:[];}

J'ai rencontré des problèmes de mémoire sur certains des cas de test, avec une fonction récursive pour le produit cartésien. Fonctionné mieux avec cette classe de générateur et function c($a){$b=[];foreach($a as$i)$b[]=new \ArrayIterator($i);return new CartesianProductIterator($b);}.
Mais mon générateur est plus court et fait le même travail.

Les exemples plus importants, cependant, entraînent une erreur de serveur interne (à la fois avec l'itérateur et le générateur) après un certain temps sur ma machine. Actuellement, pas le temps de vérifier les journaux du serveur, malheureusement.

Titus
la source