Trier par ce que décrivent les paires de chiffres


17

Étant donné un entier positif, nous pouvons former un nouveau nombre qui est décrit par ses chiffres pris deux à deux (avec un 0 en tête ajouté pour les nombres avec un nombre impair de chiffres).

Par exemple:

  • 1234 peut être lu comme un 2, trois 4 - ainsi, la sortie pour 1234 est 2444.

  • 643 a un nombre impair de chiffres, donc un zéro de tête est ajouté pour le rendre pair. Ensuite, 0643 peut être lu comme: zéro 6s, quatre 3s, d'où la sortie serait 3333.

(Il s'agit d' OEIS A056967 ).

Tâche: étant donné un tableau d'entiers positifs, triez-les par leur valeur de paire de chiffres, dans l'ordre croissant. L'ordre n'a pas d'importance entre les numéros d'entrée qui mènent à la même valeur.

Entrée : un tableau / liste / ensemble d'entiers positifs. Les zéros de tête dans l'entrée ne sont pas autorisés et saisis sous forme de chaînes / listes de chiffres / etc. ne sont pas autorisés - les entrées doivent être aussi proches d'un type entier / numérique que votre langue est capable d'utiliser.

Sortie : le tableau trié de la manière mentionnée ci-dessus, retourné de l'une des façons habituelles (valeur de retour de la fonction / STDOUT / criant dans le vide / etc.). Vous pouvez les imprimer individuellement, les renvoyer sous forme de nombres, de chaînes ou de listes de chiffres.

Cas de test

Input 
Output

[19, 91, 2345, 2023]
[19, 2023, 2345, 91]

[25257, 725, 91, 5219, 146125, 14620512]
[725, 5219, 14620512, 91, 146125, 25257]

[123130415 3335 91 111111111 528 88]
[528, 111111111, 123130415, 3335, 88, 91]

[1 21 33 4 5]
[1 4 5 21 33]

[3725, 10, 2537, 1, 1225, 2512]
[10, 1, 1225, 2512, 2537, 3725]

[125, 26, 1115, 1024] 
[1115, 1024, 125, 26]

(Dans le 4ème cas de test, 1, 4 et 5 sont tous évalués à 0 et peuvent donc être triés entre eux dans n'importe quel ordre. De même dans le cinquième cas de test, 10 et 1 sont tous les deux évalués à 0 et peuvent donc être triés dans soit l'ordre.)

(Connexes: dites ce que vous voyez , un 1, deux 1, un 2 un 1

Merci à Kevin Cruijssen d'avoir aidé à clarifier la question dans le bac à sable.


2
Pouvons-nous prendre une liste de listes de chiffres en entrée? Pouvons-nous produire une liste de listes de chiffres?
M. Xcoder

@ Mr.Xcoder L'entrée doit être une liste d'entiers, pas des listes de chiffres. La sortie peut être une liste de listes de chiffres, si cela est plus pratique.
sundar

comme l'a souligné @mnel, ma réponse ne fonctionnera pas pour les nombres supérieurs à 10 chiffres. est-il légitime de le conserver tel quel ou dois-je le modifier au prix de 32 octets.
JayCe

@JayCe Si je comprends bien, la limitation est parce que c'est la limite du type entier dans R - car strtoirenvoie un entier - correct? Si oui, ça va, c'est légal comme ça.
sundar

vous avez raison! le gardera tel quel.
JayCe

Réponses:


5

APL (Dyalog) , 26 octets

Merci ngn pour avoir sauvé 1 octet :)

{⍵[⍋⌽↑,⍨⌿⍴⌿0 10⊤⍵⊤⍨⍴⍨100]}

Essayez-le en ligne!

Inspiration tirée de dzaima & ngn


100⊥⍣¯1⊢⍵-> ⍵⊤⍨⍵/100fonctionne pour 26.
jslip

Je ne veux pas vraiment de WSFULL sur les cas de test donnés
H.PWiz

26 est possible avec MAXWS = 1M
ngn

100⊥⍣¯1⊢⍵->⍵⊤⍨⍴⍨100
ngn

1
@ H.PWiz et voici une solution différente pour 26 octets:{⍵[⍋⌽↑,⍨⌿⍴⌿⊃⊥⍣¯1/10 100⍵]}
ngn

3

R , 141 octets

(s<-scan(,""))[order(strtoi(sapply(s,function(x)paste(strrep((m=matrix(c(if(nchar(x)%%2)0,el(strsplit(x,""))),2))[2,],m[1,]),collapse=""))))]

Essayez-le en ligne!

Réponse plutôt laborieuse - mais elle fonctionne sur tous les cas de test. Construit la sortie de paire de chiffres et trie l'entrée en fonction de cela.


J'ai posté mon approche sur une autre réponse puisque j'y travaillais cet après-midi mais j'ai été interrompu. Juste pour vous assurer que je n'ai pas pu m'inspirer des vôtres sans crédits;)
digEmAll

@digEmAll pas de soucis :) - En fait, je pense que j'ai pris le nom vde la variable de vos autres réponses - Je n'ai jamais utilisé vauparavant. Et bonne utilisation de intToUtf8!
JayCe

ahah je suis vraiment jaloux de mes noms de variables à lettre unique! Non, sérieusement ... venant de StackOverflow à chaque fois que je poste une alternative "similaire", j'ai l'impression de voler;)
digEmAll

strtoi retournera NA pour les entiers supérieurs à 10 chiffres, (comme le numérique ne le fera pas)
mnel

@mnel merci d'avoir souligné! J'ai vérifié avec Sundar et comme c'est une limitation du type entier, je peux le laisser tel quel :)
JayCe

3

R , 120 octets

(v=scan())[order(sapply(v,function(n,e=nchar(n))sum((a=rep((x=n%/%10^(0:(e-1-e%%2))%%10)[!0:1],x[!1:0]))*10^seq(a=a))))]

Essayez-le en ligne!

  • -11 octets grâce à la suggestion "arithmétique" @sundar!

Code non golfé avec explication:

# define a function G which takes a number 'n' and uncompress it multiplied by 10
# e.g. 2735 -> 775550, 61345 -> 355550 etc.
G=function(n){
  e = nchar(n)                   # get the n.of digits in the compressed number

  x = n%/%10^(0:(e-1-e%%2))%%10  # split 'n' into vector of digits reversed adding 
                                 # trailing zero if 'e' is odd (e.g. 123 -> c(0,3,2,1))

  even = x[!0:1]                 # take only the odd elements of 'x' (= even digits)
  odd  = x[!1:0]                 # take only the even elements of 'x' (= odd digits)
                                 # N.B. :
                                 # these tricks work because !0:1 is c(TRUE,FALSE)
                                 # and V[c(TRUE,FALSE)] exploits the fact that R 
                                 # automatically recycles the logical indexes up to the
                                 # length of the vector V

  a = rep(even,odd)              # repeat each value in 'even' 'odd' times obtaining the
                                 # uncompressed number as digits vector. Note that in
                                 #  case of single digit 'n', 'a' will be an empty vector

  sum(a*10^seq(a=a))             # multiplies 'a' * 10^(1:length(a)) and sum 
                                 # obtaining the uncompressed number multiplied by 10
                                 # N.B. in case of empty 'a', we get 0
}

v = scan()                       # take vector v from stdin

w = sapply(v,G(n))               # apply G to all numbers of 'v'

v[order(w)]                      # use the uncompressed values as weights to sort 'v'

L' [!1:0]astuce est vraiment sympa - jamais vue auparavant.
JayCe

@sundar: explication ajoutée;)
digEmAll

1
Agréable. Je savais que ces [!1:0]gars cachaient quelque chose de bien. Je jouais avec cela et les conseils sur le golf R, en essayant d'obtenir le nombre à partir des chiffres de manière arithmétique (sans as.double), mais je n'ai trouvé qu'une version de 132 octets: TIO
sundar - Reinstate Monica

@sundar: Je n'ai pas pensé à l'approche arithmétique ... J'ai économisé 11 octets, merci!
digEmAll

2

Pyth , 14 octets

oir9c.[Z2jNT2T

Essayez-le ici! | Suite de tests! | 12 octets avec liste des chiffres d'E / S

Comment ça fonctionne?

oir9c.[Z2jNT2T – Full program.
o              – Sort the input list by the results of the following code (variable: N).
         jNT   – Cast the current element to a list of digits.
     .[Z2      – Pad it on the left with 0s to the nearest multiple of 2.
    c       2  – Split in pieces of length 2.
  r9           – Run length decode.
 i           T – Cast the list of digits to a base 10 integer.

2

Gelée , 10 octets

ṚẋƝm2ṚFḌµÞ

Essayez-le en ligne!

Découvrez une suite de tests!

Comment ça fonctionne

ṚẋƝm2ṚFḌµÞ Liaison monadique / Programme complet. | Exemple: [25257, 725, 91, 5219, 146125, 14620512]
        µÞ Trier la liste d'entrée en fonction du résultat du lien monadique: | Exemple: 725
Ṛ Promouvez N dans son tableau de chiffres et inversez-le. | [5, 2, 7]
 ẋƝ Pour chaque deux chiffres consécutifs x, y, répétez xy fois. | [[5, 5], [2, 2, 2, 2, 2, 2, 2]]
   m2 Modular 2. Prenez tous les autres éléments de ce tableau. | [[5, 5]]
     Ṛ Inverser. | [[5, 5]]
      F Aplatir. | [5, 5]
       Ḍ Convertir de décimal en entier. | 55

C'est certainement une coïncidence: 2537et 3725ne représentent pas le même nombre.
Erik the Outgolfer

Pourriez-vous me donner un cas de test qui permettrait de comprendre cela, et je vais l'ajouter à la question?
sundar

@sundar Comme Erik dit [2537, 3725]. Je n'ai jamais douté que ce soit une coïncidence, donc j'ai inclus cette note à la réponse
M. Xcoder

@ Mr.Xcoder Testcase ajouté, merci.
sundar

2

Perl 6 , 53 octets

*.sort(+*.flip.comb.rotor(2).map({[x] $_}).join.flip)

Essayez-le en ligne!

Anonyme Quel que soit lambda qui prend une liste de valeurs et la trie selon la description des paires de nombres.

Dans ce cas, j'inverse le nombre, puis rotorj'inclus la liste par deux pour obtenir chaque paire de nombres. Cela exclura le premier chiffre pour les nombres de longueur impaire, mais comme cela se traduit par le 0nombre de fois, ce n'est pas grave. De plus, il aligne les valeurs à utiliser [x]correctement.



2

Haskell , 89 88 octets

Un octet enregistré grâce aux ovs

import Data.List
(%)=mod
m?n|n<1=0|n%100<10=m?div n 100|w<-n-10=m*10?w+m*n%10
sortOn(1?)

La dernière ligne définit une fonction anonyme qui peut être utilisée comme ceci:

> sortOn(1?)[19, 91, 2345, 2023]
[19,2023,2345,91]

La fonctionnalité de base est fournie par l'opérateur infixe (?)qui garde la trace d'un multiplicateur met de l'entrée RLE restante n. (?)soustrait continuellement 10 de ntandis qu'il y a un chiffre de dizaines à soustraire, et ce faisant, il pousse une autre copie du dernier chiffre à l'avant de la sortie (via le multiplicateur m, qui est augmenté de 10 à chaque fois). Lorsque la place des dizaines est épuisée, les deux derniers chiffres sont ignorés et le processus se répète jusqu'à ce que le nombre soit réduit à 0. Enfin, nous utilisons l'opérateur (avec un multiplicateur initial de 1) comme clé de tri.


1
m?n|n<1=0|n%100<10=m?div n 100|w<-n-10=m*10?w+m*n%10est un octet plus court.
ovs

2

Husk , 10 octets

ÖödṁΓ*C_2d

Essayez-le en ligne!

Explication

ÖödṁΓ*C_2d    Full function
Ö             Sort the input list by the result of...
 ö            The composition of these four functions:
         d      Convert to a list of digits
      C_2       Split into length-2 sublists starting at the end
   ṁ            Map the following function and concatenate the results:
    Γ*            Repeat the list tail X times, where X is the list head
  d             Convert back to an integer

2

Dyalog APL, 41 39 36 35 31 30 29 octets

f←⊂⌷¨⍨∘⍋{10⊥∊⍴⌿0 10100⊥⍣¯1⊢⍵}¨

Essayez-le en ligne!

-2 grâce à Cows quack
-4 (plus -4 pour l'idée de conversion de base) grâce à ngn
-2 merci donc H.PWiz


⊃,/peut devenir
Kritixi Lithos

@Cowsquack Je savais que j'oubliais un intégré: p
dzaima

{⍺⍴⍨⍎⍵}->⍴⍨∘⍎
ngn

@ngn bien sûr, je ne me souviens jamais de tout ce qui est jot / train
dzaima

voici une autre astuce pour -1 octet - trainify {⍵[⍋F ⍵]}as⊂⌷¨⍨∘⍋F
ngn

2

C (gcc) (systèmes 32 bits), 188 177 176 octets

char*p,*q,c[99],b[99]="0";i;d(x){for(p=b+!(sprintf(b+1,"%d",x)&1),q=c;i=*p++;++p)for(i-=48;i--;*q++=*p);*q=0;atoi(c);}m(int*a,int*b){return d(*a)-d(*b);}s(l,c){qsort(l,c,4,m);}

Essayez-le en ligne!

sur amd64ajouter un indicateur -m32pour la compilation.

Utilisation : s(x,n);xpointe vers un tableau d'entiers à trier et nest la longueur de ce tableau.

Le deuxième cas de test donne un résultat incorrect car la conversion 25257donne 2222277777qui déborde d'un entier 32 bits - a ajouté un 5ème cas de test sans ce nombre.

Explication:

char*p,                                     // d(): input pointer
    *q,                                     // d(): output pointer
    c[99],                                  // d(): output buffer
    b[99]="0";                              // d(): input buffer
                                            //      (fixed first char 0)
i;                                          // d(): repeat counter

d(x){                                       // conversion function
    for(
            p=b+!(sprintf(b+1,"%d",x)&1),   // print number in decimal to
                                            // input buffer, starting at second
                                            // character, initialize input
                                            // pointer to first or second char
                                            // depending on the length of the
                                            // number
            q=c;                            // initialize output pointer
            i=*p++;                         // set repeat counter to digit and
                                            // point to next digit, stop when
                                            // NUL character is found
            ++p)                            // point to next digit after loop
        for(i-=48;i--;*q++=*p);             // inner loop, append current digit
                                            // i-48 ('0') times to output buffer
    *q=0;                                   // terminate output with NUL
    atoi(c);                                // convert to number, 'return' not
                                            // needed as atoi() leaves result
                                            // on the stack
}

m(int*a,int*b){                             // comparison function for qsort
    return d(*a)-d(*b);                     // return difference of converted
}                                           // values

s(l,c){                                     // sorting function
    qsort(l,c,4,m);                         // only "wrap" qsort, assuming
}                                           // sizeof(int) is 4

Votre fonction d()est longue à cause des chaînes et des fonctions qui leur sont liées, vous pouvez enregistrer de nombreux octets simplement en lisant les 2 derniers chiffres et en construisant la sortie comme ceci: o;u;i;d(x){for(u=1,o=0;x;x/=100)for(i=0;i++<x%100/10;o+=x%10*u,u*=10);x=o;}m(int*a,int*b){u=d(*a)-d(*b);}s(l,c){qsort(l,c,4,m);}vous économiserez également des octets en évitant de déclarer et d'initialiserchar s.
Annyo

Bonne idée - je pense que travailler sur les valeurs entières en fait une approche complètement différente, donc vous devriez envisager de poster une réponse? :)
Felix Palmen

Suggérer b-~sprintf(b+1,"%d",x)%2 place deb+!(sprintf(b+1,"%d",x)&1)
plafondcat

@Annyo suggère à la x/10%10place dex%100/10
plafondcat


1

Brachylog , 18 octets

{↔ġ₂ẹ{Ċj₎|Ȯt}ˢ↔c}ᵒ

Essayez-le en ligne!

Explication

Beaucoup de petites choses nécessaires pour tenir compte des trois cas différents: nombre impair de chiffres, paire de 0 fois un nombre et paires normales.

{               }ᵒ     Order the Input according to the output of this predicate
 ↔                       Reverse the number
  ġ₂                     Group into pairs; the last digit is alone if there are
                           an odd number of them
    ẹ{      }ˢ           For each group:
      Ċ                    If there are two elements
       j₎                  Juxtapose the first one as many times as the second
                             element (won't work if the second element is 0)
         |                 Else
          Ȯ                If there is one element (odd number of digits)
           t               just take that element
                           (Else don't select anything, i.e. 0 repetitions)
              ↔c         Reverse and concatenate back into an integer

Je pense que le |Ȯtn'est pas nécessaire, et en fait, il rend le tri incorrect: c'est équivalent à un remplissage avec un 1 au lieu d'un 0, donc étant donné [125, 26, 1], le trie comme [1, 26, 125] au lieu de [1 , 125, 26].
sundar

1

Perl 5 , 76 octets

Une fonction au lieu d'une doublure pour une fois.

Assez simple: gtrie les entrées numériquement, en utilisant hpour convertir les nombres. hle fait en utilisant l'expression régulière s/(.)(.)/$2x$1/gre(qui est probablement suffisamment lisible). Et le 0remplissage à gauche se fait avec 0 x("@_"=~y///c%2)."@_"(où y///cest un moyen d'écriture raccourci length, xest l'opérateur de répétition et .la concaténation).

sub h{(0 x("@_"=~y///c%2)."@_")=~s/(.)(.)/$2x$1/gre}sub g{sort{h($a)-h$b}@_}

Essayez-le en ligne!

Je m'attends à voir des réponses Perl plus courtes!


1

Rétine , 44 octets

^.?((..)*)$
$1 $&
%)`\G(\d)(.)
$1*$2
N`
.+ 

Essayez-le en ligne! La génération de la clé de tri au début de la ligne est plus difficile, mais la courte étape de tri entraîne une économie globale de 3 octets. Explication:

%)`

Appliquer les deux premières étapes sur chaque ligne individuellement.

^.?((..)*)$
$1 $&

Faites correspondre et copiez un nombre pair de chiffres de fin.

\G(\d)(.)
$1*$2

Remplacez chaque paire de chiffres par leur valeur décrite. La \G\dprovoque l'arrêt de la correspondance dans l'espace.

N`

Trier numériquement.

.+ 

Supprimez les clés de tri.


C'est une astuce astucieuse pour trier par une clé. Bon.
sundar

1

05AB1E , 20 19 octets

ΣDgÉi¦}2ôε`sиJ}J0ìï

Bug corrigé pour +1 octet, puis joué par -2 octets grâce à @sundar .

Essayez-le en ligne ou vérifiez tous les cas de test .

Peut certainement être joué au golf .. Pas trop content à ce sujet ..

Explication:

Σ                    # Sort by:
 Dg                  #  Duplicate the current number, and take it's length
                     #   i.e. 25257 → 5
                     #   i.e. 4 → 1
   Éi }              #  If this length is odd:
     ¦               #   Remove the first digit
                     #    i.e. 25257 → '5257'
                     #    i.e. 4 → ''
       2ô            #  Then split the number in pieces of 2
                     #   i.e. '5257' → ['52','57']
                     #   i.e. '' → []
         ε    }      #  And map each to:
          `          #   Push both digits to the stack
                     #    i.e. '52' → '5' and '2'
           s         #   Swap them
            и        #   Repeat the first digit the second digit amount of times
                     #    i.e. '2' and '5' → ['2','2','2','2','2']
             J       #   Join the list of digits together
                     #    i.e. ['2','2','2','2','2'] → '22222'
               J     #  Join all numbers back together again
                     #   i.e. ['','22222','77777'] → '2222277777'
                     #   i.e. [] → ''
                0ì   #  Prepend a 0 (because `Σ` will put all '' at the back)
                     #   i.e. 2222277777 → '02222277777'
                     #   i.e. '' → '0'
                  ï  #  Cast it to an integer, because sorting is done string-wise by
                     #  default despite 05AB1E's interchangeability of strings and numbers;
                     #  and it's also to remove all leading zeros
                     #   i.e. '02222277777' → 2222277777
                     #   i.e. '0' → 0

1

Attaché , 50 octets

SortBy!N@Flip##~`&&>PadRight&0&2=>Chop&2@Flip@List

Essayez-le en ligne!

Explication

SortBy!N@Flip##~`&&>PadRight&0&2=>Chop&2@Flip@List      anonymous function, argument: [a1..aN]
SortBy!                                                 sort the given array by grading f[ai]
                                                        e.g. 42513
                                              List      digits of ai
                                                        e.g. [4, 2, 5, 1, 3]
                                         Flip@          flip the digits around
                                                        e.g. [3, 1, 5, 2, 4]
                                  Chop&2@               chop into groups of 2
                                                        e.g. [[3, 1], [5, 2], [4]]
                    PadRight&0&2=>                      pad each group to size 2 with 0's
                                                        e.g. [[3, 1], [5, 2], [0, 4]]
                  &>                                    using each sub array as arguments...
               ~`&                                      ...repeat the 2nd the 1st amount of times
                                                        e.g. [[1, 1, 1], [2, 2, 2, 2, 2], []]
             ##                                         then:
         Flip                                           reverse the groups
                                                        e.g. [[2, 2, 2, 2, 2], [1, 1, 1]]
       N@                                               then convert it to an number
                                                        e.g. 22222111


1

Japt, 13 octets

ñ_ì_ò2n)®rçì

Essayez-le ou exécutez tous les cas de test


Explication

ñ_                :Sort by passing each integer through a function
  ì_              :  Split to an array of digits, pass it through the following function and implicitly convert back to an integer
    ò2n)          :    Starting from the end of the array, split at every second element
        ®         :    Map
         rç       :      Reduce X & Y by repeating X Y times
           Ã      :    End mapping
            ¬     :    Join



0

Java 11, 204 189 octets

L->{L.sort((a,b)->Long.compare(s(a+""),s(b+"")));}long s(String s){var r="";for(int l=s.length(),i=l%2;i<l;)r+=s.split("")[++i].repeat(s.charAt(i++-1)-48);return r.isEmpty()?0:new Long(r);}

Prend une liste de Longs comme paramètre et trie cette liste d'entrée (sans retourner une nouvelle liste).

Essayez-le en ligne (REMARQUE: String.repeat(int)est émulé repeat(String,int)car Java 11 n'est pas encore sur TIO. Le nombre d'octets reste le même.)

Explication:

L->{                     // Method with ArrayList<Long> parameter and no return-type
  L.sort(                //  Sort the list by:
   (a,b)->Long.compare(  //   Using a builtin Long-comparator with:
     s(a+""),s(b+"")));} //   The correctly formatted values as described in the challenge

long s(String s){        // Separated method with String parameter and long return-type
  var r="";              //  Temp-String, starting empty
  for(int l=s.length(),  //  The length of the input-String
      i=l%2;i<l;)        //   If the length is even:
                         //    Loop `i` in the range [0,`l`) (in steps of 2)
                         //   Else (the length is odd):
                         //    Loop `i` in the range [1,`l`) (in steps of 2) instead
    r+=                  //   Append the result-String with:
      s.split("")[++i].  //    The digit at index `i+1`
      .repeat(s.charAt(i++-1)-48);
                         //    Repeated the digit at index `i` amount of times
  return r.isEmpty()?    //  If the temp-String is empty:
          0              //   Return 0
         :               //  Else:
          new Long(r);}  //   Convert the temp-String to a long and return it

Salut, le défi interdit explicitement l'entrée de chaîne, désolé! (Je suis tenté de l'autoriser pour Java, mais ce ne serait pas juste pour les autres réponses.)
sundar - Rétablir Monica

@sundar Ah, a raté cette exigence; mon mauvais .. Heureusement, c'est une solution facile d'ajouter simplement 2x +""pour convertir le nombre en chaîne. Devrait être corrigé maintenant. :)
Kevin Cruijssen

1
Agréable. Je ne m'attendais pas à ça de Java. :)
sundar
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.