Ordenar por lo que describen los pares de dígitos

17

Dado un número entero positivo, podemos formar un nuevo número que se describe por sus dígitos tomados por pares (con un 0 inicial agregado para números con un número impar de dígitos).

Por ej .:

  • 1234 se puede leer como un 2, tres 4s, por lo que la salida para 1234 es 2444.

  • 643 tiene un número impar de dígitos, por lo que se agrega un cero inicial para que sea par. Entonces, 0643 se puede leer como: cero 6s, cuatro 3s, por lo tanto, la salida sería 3333.

(Esto es OEIS A056967 ).

Tarea: Dada una matriz de enteros positivos, ordénelos por su valor descrito por par de dígitos, en orden ascendente. El orden no importa entre los números de entrada que conducen al mismo valor.

Entrada : una matriz / lista / conjunto de enteros positivos. Los ceros iniciales en la entrada no están permitidos, y la entrada como cadenas / listas de dígitos / etc. no están permitidos: las entradas deben estar tan cerca de un tipo entero / numérico como sea capaz de usar su idioma.

Salida : la matriz ordenada de la manera mencionada anteriormente, devuelta en cualquiera de las formas habituales (valor de retorno de función / STDOUT / gritando al vacío / etc.) Puede imprimirlos individualmente, devolverlos como números, cadenas o listas de dígitos

Casos de prueba

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]

(En el cuarto caso de prueba, 1, 4 y 5 se evalúan a 0, por lo que se pueden clasificar entre sí en cualquier orden. De manera similar en el quinto caso de prueba, 10 y 1 se evalúan a 0, por lo que se pueden ordenar en cualquier orden)

(Relacionado: di lo que ves , uno 1, dos 1, uno 2 uno 1

Gracias a Kevin Cruijssen por ayudarnos a aclarar la pregunta en el Sandbox.

sundar - Restablecer a Monica
fuente
2
¿Podemos tomar una lista de listas de dígitos como entrada? ¿Podemos generar una lista de listas de dígitos?
Sr. Xcoder
@ Mr.Xcoder La entrada debe ser como una lista de enteros, no como listas de dígitos. Sin embargo, la salida puede ser una lista de listas de dígitos, si eso es de alguna manera más conveniente.
sundar - Restablece a Mónica el
como lo señaló @mnel, mi respuesta no funcionará para números de más de 10 dígitos. ¿Es legítimo mantenerlo como está o debería modificarlo a costa de 32 bytes?
JayCe
@ JayCe Si entiendo correctamente, la limitación es porque ese es el límite del tipo entero en R - porque strtoi devuelve un entero, ¿correcto? Si es así, está bien, es legal como es.
Sundar - Restablece a Mónica el
¡estás en lo correcto! Lo mantendré como está.
JayCe

Respuestas:

5

APL (Dyalog) , 26 bytes

Gracias por guardar 1 byte :)

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

Pruébalo en línea!

Toma inspiración de dzaima & ngn

H.PWiz
fuente
100⊥⍣¯1⊢⍵-> ⍵⊤⍨⍵/100funciona para 26.
jslip
Realmente no quiero WSFULLs en los casos de prueba dados
H.PWiz
26 es posible con MAXWS = 1M
ngn
100⊥⍣¯1⊢⍵->⍵⊤⍨⍴⍨100
ngn
1
@ H.PWiz y he aquí una solución diferente para 26 bytes:{⍵[⍋⌽↑,⍨⌿⍴⌿⊃⊥⍣¯1/10 100⍵]}
NGN
3

R , 141 bytes

(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=""))))]

Pruébalo en línea!

Respuesta bastante laboriosa, pero funciona en todos los casos de prueba. Construye la salida de par de dígitos y ordena la entrada de acuerdo con esto.

JayCe
fuente
Publiqué mi enfoque en otra respuesta ya que estaba trabajando en ello esta tarde, pero fui interrumpido. Solo para asegurarles que no obtuve inspiración de ustedes sin créditos;)
digEmAll
@digEmAll no te preocupes :) - En realidad creo que tomé el nombre vde la variable de tus otras respuestas - Nunca vantes lo había usado . Y buen uso de intToUtf8!
JayCe
ahah estoy realmente celosa de mis nombres de variables de una sola letra! No, en serio ... viniendo de StackOverflow cada vez que publico una alternativa "similar" se siente como robar;)
digEmAll
strtoi devolverá NA para enteros de más de 10 dígitos (como no lo hará el número)
mnel
@mnel gracias por señalar! Lo comprobé con sundar y, dado que es una limitación del tipo entero, puedo dejarlo como está :)
JayCe
3

R , 120 bytes

(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))))]

Pruébalo en línea!

  • -11 bytes gracias a la sugerencia "aritmética" de @sundar.

Código sin golf con explicación:

# 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'
digEmAll
fuente
El [!1:0]truco es realmente agradable, nunca lo había visto antes.
JayCe
@sundar: explicación agregada;)
digEmAll
1
Agradable. Sabía que esos [!1:0]muchachos estaban escondiendo algo ordenado. Estaba jugando con esto y los consejos sobre el golf R, tratando de obtener el número de los dígitos aritméticamente (sin as.double), pero solo se me ocurrió una versión de 132 bytes: TIO
sundar - Restablecer Mónica
@sundar: No pensé en el enfoque aritmético ... Ahorré 11 bytes, ¡gracias!
digEmAll
2

Pyth , 14 bytes

oir9c.[Z2jNT2T

Pruébalo aquí! El | ¡Banco de pruebas! El | 12 bytes con lista de dígitos de E / S

¿Cómo funciona?

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.
Sr. Xcoder
fuente
2

Jalea , 10 bytes

ṚẋƝm2ṚFḌµÞ

Pruébalo en línea!

¡Mira un paquete de prueba!

Cómo funciona

ṚẋƝm2ṚFḌµÞ Enlace monádico / Programa completo. El | Ejemplo: [25257, 725, 91, 5219, 146125, 14620512]
        µÞ Ordenar la lista de entrada por el resultado del enlace monádico: | Ejemplo: 725
Ṛ Promueva N a su matriz de dígitos y revertirlo. El | [5, 2, 7]
 ẋƝ Por cada dos dígitos consecutivos x, y, repita xy veces. El | [[5, 5], [2, 2, 2, 2, 2, 2, 2]]
   m2 Modular 2. Tome todos los demás elementos de esta matriz. El | [[5, 5]]
     Ṛ Reverso. El | [[5, 5]]
      F Acoplar. El | [5, 5]
       Ḍ Convertir de decimal a entero. El | 55
Sr. Xcoder
fuente
Definitivamente es una coincidencia: 2537y 3725no representan el mismo número.
Erik the Outgolfer
¿Podría darme un caso de prueba que capte eso, y lo agregaré a la pregunta?
sundar - Restablece a Mónica el
@sundar Como Erik dijo [2537, 3725]. Nunca dudé de que esto sea una coincidencia, por lo tanto, incluí esa nota en la respuesta
incluí
@ Mr.Xcoder Testcase agregado, gracias.
sundar - Restablece a Mónica el
2

Perl 6 , 53 bytes

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

Pruébalo en línea!

Anónimo Cualquier lambda que toma una lista de valores y la ordena según lo que describen los pares de números.

En este caso, estoy invirtiendo el número, luego rotoragrego la lista por dos para obtener cada par de números. Esto excluirá el primer dígito para números de longitud impar, pero como eso se traduce en 0veces ese número, está bien. Además, alinea los valores para usar [x]correctamente.

Jo King
fuente
2

Haskell , 89 88 bytes

Guardado un byte gracias a los 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 última línea define una función anónima que se puede usar así:

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

La funcionalidad principal es proporcionada por el operador infijo (?)que realiza un seguimiento de un multiplicador my la entrada RLE restante n. (?)resta continuamente 10 de nmientras haya un dígito para restar, y al hacerlo empuja otra copia del último dígito al frente de la salida (a través del multiplicador m, que se incrementa en 10 cada vez). Cuando se agota el lugar de las decenas, se descartan los dos últimos dígitos y el proceso se repite hasta que el número se reduce a 0. Finalmente, usamos el operador (con un multiplicador inicial de 1) como una clave de clasificación.

nitroso
fuente
1
m?n|n<1=0|n%100<10=m?div n 100|w<-n-10=m*10?w+m*n%10Es un byte más corto.
ovs
2

Casco , 10 bytes

ÖödṁΓ*C_2d

Pruébalo en línea!

Explicación

Öö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
Sophia Lechner
fuente
2

Dyalog APL, 41 39 36 35 31 30 29 bytes

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

Pruébalo en línea!

-2 gracias a Cows quack
-4 (más -4 por la idea de conversión de base) gracias a ngn
-2 gracias, así que H.PWiz

dzaima
fuente
⊃,/puede convertirse
Kritixi Lithos
@Cowsquack Sabía que estaba olvidando un incorporado: p
dzaima
{⍺⍴⍨⍎⍵}->⍴⍨∘⍎
ngn
@ngn, por supuesto, nunca puedo recordar todas las cosas de
jot
aquí hay otro truco para -1 byte - trainify {⍵[⍋F ⍵]}as⊂⌷¨⍨∘⍋F
ngn
2

C (gcc) (sistemas de 32 bits), 188 177 176 bytes

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);}

Pruébalo en línea!

en amd64agregar bandera -m32para compilar.

Uso : s(x,n);donde xapunta a una matriz de enteros para ordenar y nes la longitud de esa matriz.

El segundo caso de prueba da un resultado incorrecto porque la conversión 25257da lo 2222277777que desborda un entero de 32 bits; se agregó un quinto caso de prueba sin ese número.

Explicación:

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
Felix Palmen
fuente
Su función d()es larga debido a las cadenas y funciones relacionadas con ellas, puede guardar muchos bytes simplemente leyendo los últimos 2 dígitos y creando la salida de esta manera: 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);}también ahorrará bytes evitando declarar e inicializar chars.
Annyo
Buena idea: creo que trabajar en los valores enteros hace que este sea un enfoque completamente diferente, ¿debería considerar publicar una respuesta? :)
Felix Palmen
Sugerir en b-~sprintf(b+1,"%d",x)%2lugar deb+!(sprintf(b+1,"%d",x)&1)
ceilingcat
@Annyo sugiere en x/10%10lugar dex%100/10
ceilingcat
1

Python 2 , 102 101 97 101 bytes

lambda l:sorted(l,key=lambda x:int(''.join(v*int(c)for c,v in zip(*[iter(`x`[len(`x`)%2:])]*2))or 0))

Pruébalo en línea!

TFeld
fuente
@sundar Sin preocupaciones, arreglado
TFeld
1

Brachylog , 18 bytes

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

Pruébalo en línea!

Explicación

Se necesitaban muchas cosas pequeñas para explicar los tres casos diferentes: número impar de dígitos, par de 0 veces un número y pares 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
Fatalizar
fuente
Creo que no |Ȯtes necesario y, de hecho, lo hace incorrecto: es equivalente a rellenar con un 1 en lugar de un 0, por lo que dado [125, 26, 1], lo ordena como [1, 26, 125] en lugar de [1 125, 26].
Sundar - Restablecer Monica
1

Perl 5 , 76 bytes

Una función en lugar de una línea por una vez.

Muy sencillo: gordena las entradas numéricamente, utilizando hpara convertir los números. hhace esto usando la expresión regular s/(.)(.)/$2x$1/gre(que probablemente es lo suficientemente legible). Y el 0relleno izquierdo se hace con0 x("@_"=~y///c%2)."@_" (donde y///chay una forma abreviada de escritura length, xes el operador de repetición y .la concatenación).

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

Pruébalo en línea!

¡Sin embargo, espero ver algunas respuestas más cortas de Perl!

Dada
fuente
1

Retina , 44 bytes

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

Pruébalo en línea!Generar la clave de clasificación al comienzo de la línea es más difícil, pero la etapa de clasificación corta da como resultado un ahorro general de 3 bytes. Explicación:

%)`

Aplique las dos primeras etapas en cada línea individualmente.

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

Une y copia un número par de dígitos finales.

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

Reemplace cada par de dígitos con su valor descrito. los\G\d hace que el partido se detenga en el espacio.

N`

Ordenar numéricamente.

.+ 

Eliminar las claves de clasificación.

Neil
fuente
Es un truco inteligente para ordenar por clave. Bueno uno
sundar - Restablece a Mónica el
1

05AB1E , 20 19 bytes

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

Corrección de errores para +1 byte, y luego golfizado por -2 bytes gracias a @sundar .

Pruébelo en línea o verifique todos los casos de prueba .

Definitivamente se puede jugar al golf ... No estoy muy feliz por eso tbh ...

Explicación:

Σ                    # 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
Kevin Cruijssen
fuente
1

Adjunto , 50 bytes

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

Pruébalo en línea!

Explicación

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
Conor O'Brien
fuente
1

JavaScript (ES8), 72 70 bytes

a=>a.sort((a,b)=>(g=n=>n&&g(n/100|0)+''.padEnd(n/10%10,n%10))(a)-g(b))

Pruébalo en línea!

Arnauld
fuente
1

Japt, 13 bytes

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

Pruébalo o ejecuta todos los casos de prueba


Explicación

ñ_                :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
Lanudo
fuente
0

Java 11, 204 189 bytes

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);}

Toma una lista de Longs como parámetro y clasifica esta lista de entrada (sin devolver una nueva lista).

Pruébelo en línea (NOTA: String.repeat(int)se emula repeat(String,int)porque Java 11 todavía no está en TIO. El recuento de bytes sigue siendo el mismo).

Explicación:

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
Kevin Cruijssen
fuente
Hola, el desafío no permite explícitamente la entrada de cadenas, lo siento. (Estoy tentado a permitir que para Java, pero no sería justo para las otras respuestas.)
Sundar - Restablecer Monica
@sundar Ah, omití ese requisito; mi mal ... Por suerte, es una solución fácil de simplemente agregar a 2x +""para convertir el número a String. Debería arreglarse ahora. :)
Kevin Cruijssen
1
Agradable. No esperaba eso de Java. :)
sundar - Restablecer Monica