Faites les plus grands et les plus petits nombres

13

Inspiré par ce post sur Puzzling. Les spoilers pour ce puzzle sont ci-dessous.

Étant donné trois entiers positifs en entrée, (x, y, z)construisez la plage inclusive [x, y], concaténez cette plage ensemble, puis supprimez zles chiffres non nécessairement consécutifs pour produire les entiers positifs les plus grands et les plus petits possibles. Les zéros non significatifs ne sont pas autorisés (c'est-à-dire que les nombres doivent commencer par [1-9]). Sortez ces deux nombres dans l'un ou l'autre ordre.

Pour l'exemple du post Puzzling, pour la saisie (1, 100, 100), le plus grand nombre possible est 99999785960616263646566676869707172737475767778798081828384858687888990919293949596979899100,
et le plus petit nombre est 10000012340616263646566676869707172737475767778798081828384858687888990919293949596979899100,
suivant la logique ci-dessous de la réponse de jafe postée ici:

  • Nous ne pouvons pas influencer la longueur du numéro (il y a un nombre fixe de chiffres), donc pour maximiser la valeur, nous prenons le premier chiffre maximal, puis le deuxième chiffre, etc.
  • Supprimez les 84 premiers non-neuf (il reste 16 chiffres à supprimer): 999995051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  • Le plus grand nombre parmi les 17 chiffres suivants est 7, donc à partir d'ici, le chiffre suivant dans la réponse peut être au plus 7 (nous ne pouvons pas supprimer plus de 16 chiffres). Donc, supprimez 15 non-7 ... (1 chiffre à gauche pour supprimer):999997585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  • À partir d'ici, le chiffre suivant peut être au plus 8, alors supprimez un non-8 du milieu: 99999785960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  • Logique similaire, mais inversée (c'est-à-dire que nous voulons des 1s au lieu de s au début 9) pour le plus petit nombre.

Voici un petit exemple: (1, 10, 5).

Nous construisons la plage 12345678910et déterminons quels 5chiffres nous pouvons supprimer en laissant le plus grand nombre possible. Évidemment, cela signifie que nous voulons maximiser le premier chiffre, car nous ne pouvons pas influencer la longueur de la sortie. Donc, si nous supprimons 12345, nous nous retrouvons avec 678910, et c'est le plus grand que nous puissions faire. Faire le plus petit est un peu plus délicat, car nous pouvons plutôt extraire les nombres du milieu, en laissant 123410le plus petit possible.

Car (20, 25, 11), le résultat est plutôt ennuyeux, au fur 5et à mesure 1.

Enfin, pour exclure les réponses qui essaient de mettre des zéros en tête, (9, 11, 3)donne 91011qui à son tour donne 91et 10comme le plus grand et le plus petit.

E / S et règles

  • Si c'est plus facile / plus court, vous pouvez coder deux programmes / fonctions - un pour le plus grand et un pour le plus petit - auquel cas votre score est la somme des deux parties.
  • L'entrée et la sortie peuvent être fournies par n'importe quelle méthode pratique .
  • L'entrée peut être supposée correspondre au type de numéro natif de votre langue, mais ni le numéro concaténé ni la sortie ne peuvent être supposés le faire.
  • Un programme complet ou une fonction sont acceptables. S'il s'agit d'une fonction, vous pouvez renvoyer la sortie plutôt que de l'imprimer.
  • Les failles standard sont interdites.
  • Il s'agit de donc toutes les règles de golf habituelles s'appliquent et le code le plus court (en octets) l'emporte.
AdmBorkBork
la source
une liste de chiffres est acceptable en sortie?
Rod
Un cas de test qui donnerait un minimum faux lors de l'évaluation de ceux avec des zéros en tête peut être utile - je pense que ce 9, 11, 3serait le cas.
Jonathan Allan
@Rod Yep, une liste de chiffres convient pour la sortie.
AdmBorkBork
@Rod Je ne sais pas de quoi vous parlez, j'ai clairement tapé "sortie" ci-dessus. ;-)
AdmBorkBork
@JonathanAllan Bon appel. Ajoutée.
AdmBorkBork

Réponses:

5

Haskell , 162 octets

l=length
((m,f)%n)s|n>=l s=[]|n>0,(p,c:r)<-span(/=m(f$take(n+1)s))s=c:((m,id)%(n-l p)$r)|1>0=s
(x#y)z=[p%z$show=<<[x..y]|p<-[(maximum,id),(minimum,filter(>'0'))]]

Essayez-le en ligne!

Utilise l'algorithme décrit par jafe. Peut-être plus court pour utiliser une méthode moins efficace, mais c'était plus amusant à écrire :)

L' %opération prend 4 arguments (en fait 3, mais peu importe): mqui est une fonction qui sélectionne le membre "optimal" dans une liste (soit maximumou minimumselon ce que nous voulons); fqui est une fonction "filtre"; nle nombre de chiffres restant à supprimer; et sla chaîne. Nous vérifions d'abord si n est égal au nombre de chiffres restants dans la chaîne (j'ai utilisé >=pour la sécurité) et supprimons le reste ssi c'est le cas. Sinon, nous vérifions si nous devons encore supprimer les chiffres ( n>0), puis nous utilisons spanpour diviser notre chaîne en trois morceaux: ples chiffres à supprimer, la chaîne restante. Pour ce faire, nous transmettons un prédicat qui vérifie l'égalité par rapport à notre chiffre optimal. Pour trouver ce chiffre, nous prenons le premierc le chiffre optimal accessible, etrn+1chiffres de la chaîne, filtrez-la, puis passez-la à notre fonction "sélecteur". Maintenant, nous produisons simplement notre chiffre optimal et réapparaissons, en soustrayant la longueur de p(le nombre de chiffres supprimés) de n. Notez que nous ne transmettons pas notre fonction de filtrage à l'appel récursif et que nous le remplaçons plutôt par id. En effet, le filtre est uniquement là pour éviter de sélectionner les 0 en tête dans leminimum cas, ce qui n'est pertinent que lors de la première itération. Après cela, nous n'avons plus besoin de filtre.

%est vraiment seulement une fonction d'aide pour ce #qui est notre fonction « réelle », en prenant x, yet z. Nous utilisons une compréhension de liste juste pour éviter un peu de répétition, en itérant sur nos tuples de fonction et en les passant %avec zet la chaîne concaténée. Cette chaîne est créée en utilisant l'opérateur de monade magique (=<<)qui, dans ce contexte, fonctionne comme concatMap.

user1472751
la source
3

Gelée , 17 octets

r/VDœcL_¥¥ḷ/ƇVṢ.ị

Essayez-le en ligne!

Calcule toutes les possibilités puis conserve les plus grandes et les plus petites.

Argument de gauche: x,ypour construire la plage. Argument de droite: zchiffres à supprimer.

r/VDœcL_¥¥ḷ/ƇVṢ.ị
r/                 Inclusive range from x to y
  V                Concatenate the digits together
   D               Get the resulting digits
         ¥         Dyad:
        ¥            Dyad:
      L                Length of the list of digits in the concatenated number.
       _               Subtract the number of digits to be removed.
    œc               Combinations without replacement. (remove z digits)
            Ƈ      Keep lists of digits that:
          ḷ/       have a positive first element (no leading zeros).
             V     Combine digits into integers. (vectorizes to ldepth 1)
              Ṣ    Sort the numbers
               .ị  Indexes at value 0.5 which yields the first and last elements.
dylnan
la source
2

Python 2 , 143 octets

import itertools
s,e,r=input()
l=''.join(map(str,range(s,e+1)))
L=[i for i in itertools.combinations(l,len(l)-r)if'0'<i[0]]
print min(L),max(L)

Essayez-le en ligne!

Cela fonctionne en calculant toutes les combinaisons de la taille cible (l'ordre des éléments est préservé) et en obtenant les plus petits / plus grands nombres

Barre
la source
Oh ... je suppose que ça marche lol. J'essayais vraiment de créer un programme qui le calcule de façon déterministe.
Don Thousand
@RushabhMehta Les calculs de force brute sont encore déterministes, juste plus lents.
dylnan
2

Charbon de bois , 56 octets ou 21 + 46 35 = 67 56 octets

≔⪫…·NNωθFN≔⌈EθΦθ⁻λνθθ

Essayez-le en ligne! Le lien est vers la version détaillée du code. Explication:

≔⪫…·NNωθ

Saisissez xet y, créez une plage inclusive et joignez les nombres dans une chaîne.

FN

Boucle une fois pour chaque chiffre à supprimer.

≔⌈EθΦθ⁻λνθ

Créez une liste de chaînes formées en supprimant chaque caractère possible de la chaîne actuelle et prenez le maximum.

θ

Imprimez le résultat.

≔⪫…·NNωθF⊕N⊞υωΦθ∧⁼ι⌊Φ✂θκLυ¹∨κIλ⊞Oυω

Essayez-le en ligne! Le lien est vers la version détaillée du code. Explication:

≔⪫…·NNωθ

Saisissez xet y, créez une plage inclusive et joignez les nombres dans une chaîne.

F⊕N⊞υω

Saisissez-le zet incrémentez-le. Je crée ensuite une liste de cette longueur: j'ai besoin de pouvoir incrémenter zà l'intérieur du filtre suivant, mais seules les commandes sont autorisées à incrémenter les variables; il y a une faille qui PushOperatoraugmente la longueur de la liste.

 θ                      String of digits
Φ                       Filter over characters
         κ              Current index
          Lυ            Length of list i.e. current `z` value
            ¹           Literal 1
       ✂θ               Slice string of digits
      Φ                 Filter over characters
              κ         Outer index
               Iλ       Cast inner character to number
             ∨          Logical OR
     ⌊                  Minimum
   ⁼ι                   Equals the outer character
  ∧              ⊞Oυω   And also push to list i.e. increment `z`
                        Implicitly print

Filtrez les caractères recherchés en vérifiant qu'il n'y a pas de caractères inférieurs dans la zone à découper. La région commence par les premiers z+1caractères (puisqu'il est possible de découper le premierz si nécessaire) et les incréments de point final pour chaque caractère conservé. On prend soin de ne pas choisir un zéro pour le premier caractère.

L'algorithme le plus rapide fait 30 octets lorsqu'il est utilisé pour calculer le plus grand nombre possible:

≔⪫…·NNωθF⊕N⊞υωΦθ∧⁼ι⌈✂θκLυ¹⊞Oυω

Essayez-le en ligne! Le lien est vers la version détaillée du code. Edit: j'ai depuis été en mesure de combiner les deux ci-dessus dans une deuxième solution de 56 octets qui génère les deux résultats:

≔⪫…·NNωθF⊕N⊞υω≔⮌υη⟦Φθ∧⁼ι⌈✂θκLυ¹⊞OυωΦθ∧⁼ι⌊Φ✂θκLη¹∨κIλ⊞Oηω

Essayez-le en ligne! Le lien est vers la version détaillée du code. Explication:

≔⪫…·NNωθ

Générez la chaîne initiale.

F⊕N⊞υω

Représentez z+1comme la longueur de la liste.

≔⮌υη

Inversez ainsi la liste en la clonant et enregistrez le résultat.

Imprimez les deux résultats sur des lignes distinctes. (Une autre façon de procéder consiste à séparer les résultats par un \rcaractère littéral .)

Φθ∧⁼ι⌈✂θκLυ¹⊞Oυω

Générez le plus grand nombre possible.

Φθ∧⁼ι⌊Φ✂θκLη¹∨κIλ⊞Oηω

Générez le plus petit nombre possible en utilisant la liste clonée pour garder une trace de z.

Neil
la source
1

Gelée ,  19  18 octets

rDẎœcL_⁵Ɗ$ị@Ƈ1ḌṢ.ị

Essayez-le en ligne!

Très inefficace, orientez certainement pas aller pour 1, 100, 100que(19292)=305812874887035355118559193163641366325011573739619723360

Jonathan Allan
la source
1

05AB1E , 16 octets

ŸSDg³-.Æʒ¬Ā}{Ć`‚

Essayez-le en ligne!

Programme complet, lecture des entrées dans cet ordre: y, x, z . Génère une liste de deux listes de caractères.

Explication

ŸSDg³-.Æʒ¬Ā}{Ć`‚    Full program. Inputs: y, x, z.
Ÿ                   Inclusive binary range from x to y. Push [x ... y].
 S                  Dump the digits separately in a list.
  Dg                Duplicate, and use the second copy to get its length.
    ³-              Subtract z from the length.
      .Æ            Retrieve all combinations of length - z elements from the digits.
        ʒ  }        Keep only those that...
         ¬Ā         Don't start with a 0 (head, then Python-style boolean).
            {       Sort the remaining elements.
             Ć      Enclose. Pushes list + list[0] (appends its tail to itself)
              `     Dump all elements separately on the stack.
               ,    Pair, to get the last two, min and max (after enclosing)
M. Xcoder
la source
Oh, Ć`‚c'est assez intelligent, belle réponse!
Kevin Cruijssen
0

Matlab, 95 octets

function[m]=f(s,e,c),a=sprintf('%d',s:e);x=str2num(combnk(a,length(a)-c));m=[min(x),max(x)];end

Essayez-le en ligne!

Renvoie une matrice 1x2 avec min et max.

Comment ça fonctionne

% Full code
function[m]=f(s,e,c),a=sprintf('%d',s:e);x=str2num(combnk(a,length(a)-c));m=[min(x),max(x)];end

% The function
function[m]=f(s,e,c),                                                                       end

                     % Creates the range in a single string
                     a=sprintf('%d',s:e);

                                                   % Gets all the combinations
                                                   combnk(a,length(a)-c)

                                         % Converts the string combinations to integers
                                         x=str2num(                     );

                                                                          % Finds min and max
                                                                          m=[min(x),max(x)];
DimChtz
la source