Partition lexicale triée d'un nombre


17

Le défi est vraiment simple: étant donné un nombre, vous divisez ses chiffres en un tableau de plus petits nombres de sorte que les nombres résultants ne diminuent pas. Le hic, c'est que vous devez le diviser de telle sorte que la longueur du tableau soit maximale.

Confus?

  • Vous obtenez un entier positif via STDIN (ou l'alternative la plus proche), l'argument de ligne de commande ou l'argument de fonction dans n'importe quel format d'entrée pratique et sans ambiguïté.
  • Vous devez partitionner les chiffres décimaux du numéro en groupes contigus et disjoints.
  • Le tableau de nombres représenté par ces groupes de chiffres doit être trié (dans l'ordre habituel et non décroissant) sans réorganiser les groupes .
  • Dans les cas où plusieurs partitions de ce type existent, vous devez partitionner l'entrée en autant de nombres que possible. En cas d'égalité, renvoyez un de ces résultats.
  • Vous pouvez sortir le tableau vers STDOUT (ou l'alternative la plus proche) ou comme valeur de retour de fonction. Dans le cas de STDOUT (ou de l'alternative la plus proche), le tableau doit être imprimé dans n'importe quel format de liste pratique et sans ambiguïté.
  • Les nombres séparés ne doivent pas avoir de zéros en tête. Ainsi, par exemple, 1002003ne peut pas être imprimé comme ou [1, 002, 003]ou [1, 2, 3]et la seule réponse valable est [100, 2003].

Cas de test:

123456 -> [1, 2, 3, 4, 5, 6]
345823 -> [3, 4, 5, 8, 23]
12345678901234567890 -> [1, 2, 3, 4, 5, 6, 7, 8, 90, 123, 456, 7890]
102 -> [102]
302 -> [302]
324142 -> [3, 24, 142] OR [32, 41, 42]
324142434445 -> [32, 41, 42, 43, 44, 45]
1356531 -> [1, 3, 5, 6, 531]
11121111111 -> [1, 1, 1, 2, 11, 11, 111]
100202003 -> [100, 202003]

Notation

C'est le code-golf donc le code le plus court en octets gagne.

Réponses:


10

Pyth, 34

FNyUz#aYmv:zhdedC,+0N+NlzB)efqSTTY

Essayez-le en ligne ici . Remarquez, cela a une complexité temporelle (et spatiale) de O (n). Par conséquent, le scénario de test 12345678901234567890prend trop de temps dans le compilateur en ligne. Utilisez plutôt le mode hors connexion (1 minute sur mon ordinateur portable).

Ce n'est que ma première tentative. Il pourrait y avoir de la place pour des améliorations.

D'abord quelques idées sur le fonctionnement de mon algorithme.

  • J'interprète l'entrée comme une chaîne et non comme un nombre.
  • Ensuite, je crée tous les sous-ensembles possibles de [0, 1, 2, ..., len(n-1)]
  • Pour chacun de ces sous-ensembles (prenons [1, 4, 5]), je divise la chaîne d'entrée en partie en utilisant ces nombres.[input[0:1], input[1, 4], input[4,5], input[5,len(input)]].
  • Ensuite, j'essaie de convertir ces nombres en chaînes. Il peut y avoir deux problèmes. Pyth (ou Python) lève une exception pour une chaîne vide et pour une chaîne de nombres commençant par 0. J'utilise donc un try - catchbloc (en fait une boucle infinie avec une coupure immédiate). Si la conversion a réussi, j'ajoute le résultat à une liste Y.
  • Après avoir géré tous les sous-ensembles, je filtre la liste Ydes résultats, qui sont déjà triés et imprime le dernier (le dernier a le plus de groupes).

Maintenant l'explication détaillée:

                            Implicit: z = input() (z is a String!)
                                      Y = empty list
FNyUz                       for each subset N of [0, 1, 2, ..., len(z)-1]:

     #                         start try-catch block (actually an infinite loop, 
                               but the Python implementation uses a try catch. 

      aY                          append to Y:
                C,+0N+Nlz            zip([0] + N, N + [len(z)])
        m                            map each element d to
          :zhded                     z[d[0]:d[-1]]
         v                           evaluated
                         B        if this didn't throw an exception already, end the infinite loop
                          ) end for loop   

 f    Y      filter Y for elements T, for which
  qSTT           sorted(T) == T
e            and print the last one (the subsets generated with yUz are sorted 
             by length, so the last one has the most groups)

Vous pouvez utiliser à la aYplace de~Y]
FryAmTheEggman

@FryAmTheEggman que j'oublie toujours a. Je ne sais pas pourquoi.
Jakube

@Jakube Peut-être parce que ce n'est pas dans les documents?
Sp3000

J'avais une solution pour ~ 45 caractères. Je n'étais pas conscient du fait qu'il int("01")s'agissait d'une erreur en Pyth (cela ne se produit pas en Python).
orlp

3
@Jakube haha, bien que cela semble logique, mais nest généralement la longueur de l'entrée.
Optimizer

6

Mathematica, 134 127 octets

C'est assez inefficace car il génère beaucoup plus de partitions que les partitions valides. Le 324142434445cas de test s'exécute en quelques secondes, mais je n'essaierais pas 12345678901234567890.

f/@Last@Select[Needs@"Combinatorica`";f=FromDigits;SetPartitions[d=IntegerDigits@#],0<=##&@@f/@#&&Join@@#==d&&#~FreeQ~{0,__}&]&

Ceci définit une fonction sans nom qui prend un entier et retourne une liste d'entiers.

Explication

L'ordre de lecture de ce code est un peu partout, donc je vais décomposer dans l'ordre dans lequel il est destiné à être lu (et évalué pour la plupart):

  • d=IntegerDigits@#obtenir les chiffres décimaux de l'entrée et affecter cette liste à d.
  • SetPartitions(ce qui nécessite Needs@"Combinatorica`";) m'en donne toutes les partitions. Cependant, il retourne beaucoup plus que je ne le souhaite, car il traite l'entrée comme un ensemble . C'est ce qui le rend inefficace, mais j'utilise cela parce que le moyen le plus court que je connaisse pour obtenir toutes les partitions de liste est beaucoup plus long. Par exemple, si la liste était, {1, 2, 3}la fonction retournerait:

    {{{1, 2, 3}}, {{1}, {2, 3}}, {{1, 2}, {3}}, {{1, 3}, {2}}, {{1}, {2}, {3}}}
    

    Notez que a) les partitions consécutives sont toutes dans le bon ordre et b) les partitions sont triées de la plus grossière à la plus fine.

  • Select[...,...&] filtre ensuite cette liste par la fonction anonyme transmise comme deuxième argument.
    • Join @@ # == d vérifie que nous avons effectivement une partition de liste au lieu d'une partition d'ensemble générale.
    • #~FreeQ~{0, __} vérifie qu'aucune partition ne commence par un zéro non significatif.
    • 0 <= ## & @@ f /@ #est un peu plus obscur. D'abord, nous mappons FromDigitssur chaque liste de la partition pour récupérer les nombres représentés par les chiffres. Ensuite, nous appliquons 0 <= ##à ces numéros, où ##fait référence à tous les numéros. Si la partition est {1, 23, 45}alors celle-ci se développe 0 <= 1 <= 23 <= 45, elle vérifie donc que le tableau est trié.
  • Last@me donne ensuite la dernière partition restante après le filtrage - cela fonctionne parce que SetPartitionsdéjà trié les partitions, de telle sorte que les plus fines sont à la fin.
  • Enfin, f/@récupère les numéros des listes de chiffres.

5

Python 3, 134 octets

def f(s,n=0,L=[],R=[],i=0):
 while s[i:]:i+=1;m=int(s[:i]);R=max([f(s[i:],m,L+[m]),R][m<n or"1">s[i:]>"":],key=len)
 return[L,R][s>""]

C'est un peu désordonné, mais bon. Le programme génère simplement toutes les partitions valides de manière récursive. La partie intéressante est que pour interdire les zéros non significatifs, tout ce qui était nécessaire était un supplémentor "1">s[i:]>"" condition .

Prend l'entrée comme f("12345678901234567890")et retourne une liste d'entiers.


4

Pyth, 62 61 60

JlzKkef&qJsml`dTqTSTolNmmibTcjKsC,z+m>Ndt>+*J]0jk2_JKNU^2-J1

Explication

L'algorithme fonctionne en générant tous les nombres binaires entre 0(inclus) et 2^(n-1)(exclusif), où nest la longueur de l'entrée.

Les chiffres binaires de chacun sont ensuite mappés sur un séparateur (N ) pour 1 et rien pour 0.

Ces caractères sont ensuite insérés entre chaque caractère saisi et le résultat est divisé par N , ce qui donne une liste.

Les valeurs dans les listes sont ensuite analysées en entiers et les listes sont triées par longueur. Ensuite, tout ce qui reste est de filtrer ceux qui ne sont pas triés et ceux qui ont été divisés aux zéros en tête, après quoi la liste la plus longue est sélectionnée.

Jlz                                                   set J to len(input)
Kk                                                    set K to ""
e                                                     take the last of:
 f&                                                    only take lists where:
   qJsml`dT                                             sum of string lengths of items
                                                        is equal to length of input and
           qTST                                         list is in order
               olN                                       sort by length
                  m                                       map k over...
                   mibT                                    convert items to int (base-10)
                       c                        N           split by N
                        jK                                   join by ""
                          s                                   sum to combine tuples
                           C,z                                 zip input with
                              +                K                append [""] for equal lengths
                               m>Nd                              replace 1 with N, 0 with ""
                                   t                              take all but first
                                    >        _J                    take len(input) last values
                                     +                              pad front of binary with
                                      *J]0                           [0] times input's length
                                          jk2                        current k in binary
                                                 U^2-J1  range 0..2^(len(input)-1)-1

1

(NON CONCURRENT) Pyth, 25 octets

ef&&Fmnhd\0T.A<V=NsMTtN./

Essayez-le en ligne!

Comment ça fonctionne:

ef&&Fmnhd\0T.A<V=NsMTtN./  Q = eval(input())
                         ./  all partitions of Q
 f                       ./  filter all partitions of Q where:
  &                            both:
   &Fmnhd\0T                     neither substring starts with "0"
                               and:
            .A<V=NsMTtN          all entries are less than their proceeding ones
e                            returns the last amongst the filtered partitions

0

J, 109 octets

Très longue mais prend au moins O (n * (2n)!) Mémoire et O (n * log (n) * (2n)!) Temps où n est la longueur de l'entrée. (N'essayez donc pas de l'exécuter avec plus de 5 chiffres.)

f=.3 :0
>({~(i.>./)@:(((-:/:~)@(#$])*#)@>))<@".(' 0';' _1')rplc"1~(#~y-:"1' '-."#:~])(i.!2*#y)A.y,' '#~#y
)

La fonction prend l'entrée comme une chaîne.

Exemples:

   f every '5423';'103';'1023'
  5 423
103   0
 10  23

Méthode:

  • Ajoutez le même nombre d'espaces à l'entrée que sa longueur.
  • Permutez-le de toutes les manières possibles.
  • Vérifiez si la chaîne sans espace est la même que l'entrée (c'est-à-dire qu'elle en est une partition).
  • Remplacez les «0» par les «_1» pour invalider les premières solutions à zéro.
  • Évaluez chaque chaîne.
  • Trouvez la liste la plus longue qui est également triée. Il s'agit de la valeur de retour.

0

Haskell, 161 octets

(#)=map
f[x]=[[[x]]]
f(h:t)=([h]:)#f t++(\(a:b)->(h:a):b)#f t
g l=snd$maximum[(length x,x::[Int])|x<-[read#y|y<-f l,all((/='0').head)y],and$zipWith(>=)=<<tail$x]

Essai:

*Main> mapM_ (print . g) ["123456","345823","12345678901234567890","102","302","324142","324142434445","1356531","11121111111","100202003"]
[1,2,3,4,5,6]
[3,4,5,8,23]
[1,2,3,4,5,6,7,8,90,123,456,7890]
[102]
[302]
[32,41,42]
[32,41,42,43,44,45]
[1,3,5,6,531]
[1,1,1,2,11,11,111]
[100,202003]

Comment cela fonctionne: la fonction d'assistance fdivise la liste d'entrée en chaque liste possible de sous-listes. gélimine d'abord ceux dont la sous-liste commence par 0, puis ceux qui n'ont pas le bon ordre. Associez chaque liste restante à sa longueur, prenez le maximum et jetez à nouveau la partie de longueur.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.