Combina dos listas ordenadas

14

Ordenar fusión

En este desafío, implementará la subrutina de fusión del tipo de fusión. Específicamente, debe crear una función o programa o verbo o similar que tome dos listas, cada una ordenada en orden creciente, y las combine en una lista ordenada en orden creciente. Requisitos:

- Su algoritmo debe tomar una cantidad de tiempo asintóticamente lineal en el tamaño de la entrada. Por favor, deje de dar soluciones O (n ^ 2).

  • No puede usar ninguna función incorporada capaz de ordenar una lista, o fusionar una lista, o algo así. Discreción del autor.
  • El código debe poder manejar elementos repetidos.
  • No te preocupes por las listas vacías.

Ejemplos:

merge([1],[0,2,3,4])
[0,1,2,3,4]

merge([1,5,10,17,19],[2,5,9,11,13,20])
[1, 2, 5, 5, 9, 10, 11, 13, 17, 19, 20]

Este es el , ¡así que gane el código más corto!

isaacg
fuente
¿Tenemos que manejar elementos repetidos dentro de una lista, o solo entre las dos listas?
Keith Randall
Digamos los dos. La idea es que debería poder usar esto para hacer una fusión.
isaacg
¿Es kosher golpear las matrices de entrada?
skibrianski
3
No estoy seguro de cómo interpretar algoritmo debe tomar una cantidad de tiempo asintóticamente lineal . Los algoritmos no toman tiempo, las implementaciones sí. El tiempo de ejecución de mi respuesta Golfscript es O (aterrador) con el intérprete Ruby, pero el comprobador de Golfscript en línea se comporta mucho mejor y, de hecho, podría ser lineal (sin embargo, no hay forma real de saberlo sin el código fuente). Mi punto es: b=a;b=b.lengthpodría duplicar toda la matriz a(y dar como resultado un tiempo O (n ^ 2) si se ejecuta para cada elemento) o duplicar solo la referencia a la matriz (tiempo O (n)). ¿Cuál cuenta?
Dennis
1
Supongo que en casos como estos, solo haz tu mejor esfuerzo para resolverlo, pero si honestamente no puedes decirlo, puedes asumir que las cosas funcionan bien, como la segunda alternativa que mencionaste. Puede suponer que el intérprete funciona bien si su idioma no tiene un intérprete estándar.
isaacg

Respuestas:

8

Rebmu ( 35 32 caracteres)

u[iG^aNXa[rvA]apGtkFaM?fA]apGscA

Prueba

>> rebmu/args [u[iG^aNXa[rvA]apGtkFaM?fA]apGscA] [[1 5 10 17 19] [2 5 9 11 13 20]] 
== [1 2 5 5 9 10 11 13 17 19 20]

>> rebmu/args [u[iG^aNXa[rvA]apGtkFaM?fA]apGscA] [[2 5 9 11 13 20] [1 5 10 17 19]] 
== [1 2 5 5 9 10 11 13 17 19 20]

Acerca de

Rebmu es un dialecto de Rebol que permite 'mezclar' el código regular para situaciones que requieren brevedad. Impecable, el código funciona algo así como:

u [                     ; until
    i g^ a nx a [       ; if greater? args next args
       rv a             ; reverse args
    ]                   ; (we want the block containing the next value first)

    ap g tk f a         ; append output take first args
    m? f a              ; empty? first args
]                       ; (first block is now empty)

ap g sc a               ; append output second args
                        ; (add the remainder of the second)

Creo que esto satisface el requisito de O (n) , ya que el bloque hasta se repite tantas veces como la longitud de la entrada (y reversesolo cambia el orden del contenedor de los bloques de entrada, no los bloques en sí). Usar takees quizás una libertad, pero sigue siendo un golpe de eficiencia menor.

Rebol ( 83 75 caracteres)

Solo un poquito diferente: en Rebol, las rutas son una expresión más corta que firsto second.aes el bloque de entrada que contiene los dos bloques:

until[if a/2/1 < a/1/1[reverse a]append o:[]take a/1 tail? a/1]append o a/2
rgchris
fuente
5

Soluciones de OP:

Haskell 49 44 40

k@(p:r)%l@(q:s)|p>=q=q:k%s|0<1=l%k
a%_=a

Python 131 105 101 99 93

Gracias a @Evpok:

f=lambda u,v:v and(v[-1]<u[-1]and f(v,u)or[b.append(a)for a,b in[(v.pop(),f(u,v))]]and b)or u
isaacg
fuente
1
Puede escribir a%b=a++bdespués de la coincidencia del patrón principal para manejar listas vacías, que eliminará un par de caracteres.
swish
¿No falla la solución de Haskell si la primera lista se queda sin contenido primero?
John Dvorak
Si observa la primera función, llama recursivamente a la función con la lista acortada como el segundo argumento, y la lista alargada como el primer argumento, o intercambia los argumentos. Por lo tanto, el primer argumento nunca se acorta. Dado que por el OP no comienza vacío, nunca se vaciará.
isaacg
4

Pitón (79)

from itertools import*
def m(*a):
 while any(a):yield min(compress(a,a)).pop(0)

Python (95, si no se nos permite devolver un generador)

from itertools import*
def m(*a):
 r=[]
 while any(a):r+=[min(compress(a,a)).pop(0)]
 return r

Itertools es la solución para todos los problemas mundanos.

Bonificación: los dos trabajan en un número arbitrario de listas, y SE PREOCUPAN por las listas vacías (como en, felizmente tomarán 2 listas vacías y devolverán una lista vacía, o tomarán 1 lista vacía y 1 lista no vacía, y devolverán el no vacío. Otra característica adicional de los 2 no cedidos: también se ejecutarán sin argumentos, y solo devolverán una lista vacía).

Sin golf:

from itertools import *  # Import all items from itertools
def m(*a):               # Define the function m, that takes any number of arguments, 
                         #  and stores those arguments in list a
    r=[]                 # Create an empty list r                         
    while any(a):        # While any element in a returns True as value:
        b=compress(a,a)  # Remove any element from a that isn't True (empty lists)
                         #  The example in the official documentation is this one:
                         #  compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F
        c=min(b)         # Sort the lists by first value, and take the first one of these.
        d=c.pop(0)       # Take the first element from c
        r.append(d)      # Append this first element to r
    return r             # Gives back r
ɐɔıʇǝɥʇuʎs
fuente
En sus soluciones sin generador, use en r+=[...]lugar de r.append(...)(ahorra 4 caracteres cada vez)
hlt
No me refiero a ninguna ofensa con esto, pero si su respuesta contiene código en un idioma que es solo otro idioma con modificaciones hechas específicamente para jugar al golf, lo rechazaré. Es una pena, las respuestas reales de Python son buenas.
undergroundmonorail
Si los divide en diferentes publicaciones, votaré por Python.
undergroundmonorail
44
@undergroundmonorail ¿Vota abajo todas las respuestas de GolfScript?
Evpok
1
@Evpok Ahora que lo mencionas, también podría incluirlo en meta y ver qué tienen que decir allí.
Aprıʇǝɥʇuʎs
3

C - 75

Esto opera en NULLmatrices terminadas de int *, aunque funcionaría igualmente bien para punteros a otros tipos al sustituir la función de comparación apropiada para **b < **a(por ejemplo, strcmp(*b, *a) < 0).

void m(int**a,int**b,int**c){while(*a||*b)*c++=!*a||*b&&**b<**a?*b++:*a++;}

Sin golf:

void merge(int **a, int **b, int **c)
{
    while(*a || *b)
        *c++ = !*a || *b && **b < **a
            ? *b++
            : *a++;
}
laindir
fuente
3

Golfscript, 29 27 30 29 26 bytes

~{[email protected]=@<{}{\}if(@@.}do;~]p

o

~{[email protected]=@>{\}*(@@.}do;~]p

Cómo funciona

El comando

golfscript merge.gs <<< '[2 3] [1 4]'

se procesará de la siguiente manera:

~            # Interpret the input string.
             #
             # STACK: [2 3] [1 4]
{            #
    .@=0.@=0 # Duplicate the two topmost arrays of the stack and extract their first 
             # elements. This reverses the original order of the first copy.
             #
             # STACK: [1 4] [2 3] 2 1
             #
    >        # Check if the respective first elements of the arrays are ordered.
             #
             # STACK: [1 4] [2 3] 1
             #
    {\}*     # If they are not, swap the arrays. This brings the array with the smallest
             # element to the top of the stack.
             #
             # STACK: [2 3] [1 4]
             #
    (@@      # Shift the first element of the array on top of the stack and rotate it
             # behind the arrays.
             #
             # STACK: 1 [2 3] [4]
             #
    .        # Duplicate the topmost array.
             #
             # STACK: 1 [2 3] [4] [4]
             #
}do          # Repeat this process if the array is non-empty.
             #
             # STACK: 1 [2 3] [4] -> 1 2 [4] [3] -> 1 2 3 [4] []
             #
;~           # Delete the empty array from the stack and dump the non-empty array.
             #
             # STACK: 1 2 3 4
             #
]p           # Combine all elements on the stack into a single array, the to a string and
             # print.

El resultado es:

[1 2 3 4]
Dennis
fuente
¿La duplicación de matrices en la pila lo hace O (n ^ 2)?
swish
@swish: no soy un informático, pero diría que depende de la implementación. Si el intérprete duplica las matrices enteras, supongo que sí.
Dennis
La versión anterior era O (n ^ 2) para matrices muy similares (por ejemplo, [1 1 1 ... 2]y [1 1 1 ... 3]), ya que comparar las matrices (en lugar de sus primeros elementos) sería muy lento en este caso.
Dennis
Las únicas operaciones de matriz que tienen lugar en la nueva versión son la duplicación, el intercambio y la rotación en la pila. Dado que las matrices duplicadas solo se usan para extraer elementos individuales y probar las matrices en busca de vacío (ambas operaciones destructivas en Golfscript), el código anterior se puede ejecutar en tiempo O (n) (duplicando, intercambiando y girando las referencias a la matrices). El rendimiento real depende del intérprete.
Dennis
2

J - 42 33

Versión modificada desde aquí + el comentario de @algorithmshark

k=:(m}.),~0{]
m=:k~`k@.(>&{.) ::,

kantepone la cabecera de la matriz derecha a las colas fusionadas de ambas matrices. k~es lo mismo, pero con las matrices invertidas. (>&{.)está comparando las cabezas. El código arrojará un error si una de las matrices está vacía, en ese caso solo devolveremos su concatenación ,.

silbido
fuente
Supongo que dado que /:~ a,bes la respuesta prohibida (junto con [:/:~,), que está buscando la respuesta más corta que no incluye /:, ¿verdad?
Dane
Señalaré que la pregunta dice: "No se preocupe por las listas vacías".
Dane
@Dane La prueba de vacío requerida para que la recursión se detenga.
swish
m=:k~`k@.(>&{.)`,@.(0=*&#)ahorra 2 char.
algorithmshark
De hecho, puede reducir todo a 33 caracteres: k=:(m}.),~0{]y m=:k~`k@.(>&{.) ::,. Usamos 0{para lanzar un error cuando la lista está vacía, y luego capturamos ese error y salimos con ,.
algorithmshark
2

JavaScript (ES6), 69 79 bytes

f=(a,b,c=[])=>(x=a[0]<b[0]?a:b).length?f(a,b,c.concat(x.shift())):c.concat(a,b)

Cómo funciona

f = (a, b, c = []) =>          // `f' is a function that takes arguments `a', `b' and `c' -
                               // `c' defaults to `[]' - which returns the following
                               // expression:
                               //
 (x = a[0] < b[0] ? a : b)     // Store the array among `a' and `b' with the smaller first 
                               // element in `x'.
                               //
 .length ?                     // If it's non-empty,
                               //
  f(a, b, c.concat(x.shift())) // append the first element of array `x' to array `c' and run
                               // `f' again;
                               //
  : c.concat(a,b)              // otherwise, append the arrays `a' and `b' to `c'.
                               //
)
Dennis
fuente
Al comparar las matrices con el <operador no es válido como lo hace una comparación de cadenas:f([123, 456, 789], [1, 2, 3, 4, 5]) => [1, 123, 2, 3, 4, 456, 5, 789]
nderscore
@nderscore: Correcto. No habría funcionado de todos modos, ya que comparar las matrices completas podría no ser O (n). Lo mismo parece ser cierto para la prueba de no vacío, que tiene que convertir toda la matriz en una cadena.
Dennis
Sí, no estoy seguro de cuál es el big-o para la conversión de tipo array-> string.
nderscore
1
Concatenar una matriz con []y luego convertirla en una cadena requiere tiempo O (n). Hacerlo una vez para todos los n elementos de la matriz lleva O (n ^ 2) tiempo.
Dennis
Tiene sentido. Entendido.
nderscore
2

Pitón (63) (69) (71)

def m(a,b):
 if a[0]>b[0]:a,b=b,a
 return[a.pop(0)]+(m(a,b)if a else b)

Escribí esto antes de ver los comentarios de OP sobre tiempos de ejecución de otras respuestas, por lo que esta es otra solución que es O (n) en el algoritmo pero no en la implementación.

xnor
fuente
¿Qué algoritmos tienen extractos del frente de las matrices como O (1)? ¿Qué algoritmos tienen las comparaciones de listas con O (1)? Además, puede jugar más al golf cambiando ... si ... más ... a ... y ... o ...
isaacg
@isaacg Dispara, me había olvidado de las repeticiones que posiblemente hagan la comparación de la lista O (n). Entonces, eliminé esa optimización para 6 personajes más. Puede extraer y agregar al frente en O (1) en una lista vinculada. No veo cómo puedes hacer ... y ... o ... jugar bien devolviendo el valor.
xnor
Bien, ahora veo cómo hacerlo ... y ... o ..., pero no guarda caracteres debido a los parens necesarios. return[a.pop(0)]+(a and m(a,b)or b)
xnor
@isaacg: para extraer el frente de una matriz en O (1), simplemente aumente el puntero de la matriz de modo que apunte al segundo elemento y libere la memoria consumida por el primer elemento.
Wrzlprmft
@Wrzlprmft No pude hacer que el truco de la matriz funcione porque ambos elementos de la matriz se evalúan independientemente del valor booleano, que arroja un error cuando a es la lista vacía. ¿Hay alguna forma corta de hacer una "matriz perezosa"?
xnor
2

Haskell, 35 bytes

a#b@(c:d)|a<[c]=b#a|0<1=c:a#d
a#_=a

Haskell, 30 bytes (no competitivos)

Esta versión no competitiva solo garantiza un tiempo de ejecución lineal si ay btiene elementos disjuntos; de lo contrario, todavía se ejecuta correctamente, pero puede usar tiempo cuadrático.

a#b|a<b=b#a|c:d<-b=c:a#d
a#_=a
Anders Kaseorg
fuente
2

PHP 91 98 91 bytes

edit # 1: Empty $brequiere una condición adicional en las llaves (+7).
editar # 2: campos de golf menores
editar # 3: segunda versión agregada

muy claro. La mejor parte es el ternario dentro del array_shift
(que falla si lo intentas sin los rizos)

function m($a,$b){for($c=[];$a|$b;)$c[]=array_shift(${$a&(!$b|$a[0]<$b[0])?a:b});return$c;}

o

function m($a,$b){for($c=[];$a|$b;)$c[]=array_shift(${$a?!$b|$a[0]<$b[0]?a:b:b});return$c;}

sin golf

function m($a,$b)
{
    $c=[];
    while($a||$b)
    {
        $c[] = array_shift(${
            $a&&(!$b||$a[0]<$b[0])
                ?a
                :b
        });
#       echo '<br>', outA($a), ' / ', outA($b) , ' -> ', outA($c);
    }
    return $c;
}

prueba

$cases = array (
    [1],[0,2,3,4], [0,1,2,3,4],
    [1,5,10,17,19],[2,5,9,11,13,20], [1, 2, 5, 5, 9, 10, 11, 13, 17, 19, 20],
    [1,2,3],[], [1,2,3],
    [],[4,5,6], [4,5,6],
);
function outA($a) { return '['. implode(',',$a). ']'; }
echo '<table border=1><tr><th>A</th><th>B</th><th>expected</th><th>actual result</th></tr>';
while ($cases)
{
    $a = array_shift($cases);
    $b = array_shift($cases);
#   echo '<hr>', outA($a), ' / ', outA($b) , ' -> ', outA($c);
    $expect = array_shift($cases);
    $result=m($a,$b);
    echo '<tr><td>',outA($a),'</td><td>',outA($b),'</td><td>', outA($expect), '</td><td>', outA($result),'</td></tr>';
}
echo '</table>';
Titus
fuente
No podía entender por qué no lo haces simple en $a&(!$b|$a[0]<$b[0])?$a:$blugar de${$a&(!$b|$a[0]<$b[0])?a:b}
Jörg Hülsermann
1
@ JörgHülsermann El array_shiftparámetro se utiliza como referencia. Tiene que ser una variable; una expresión no funcionará.
Titus
1

Go, 124 caracteres

func m(a,b[]int)(r[]int){for len(a)>0{if len(b)==0||a[0]>b[0]{a,b=b,a}else{r=append(r,a[0]);a=a[1:]}};return append(r,b...)}
Keith Randall
fuente
1

JavaScript - 133

function m(a,b){c=[];for(i=j=0;i<a.length&j<b.length;)c.push(a[i]<b[j]?a[i++]:b[j++]);return c.concat(a.slice(i)).concat(b.slice(j))}

El mismo tipo de enfoque que los OP.

Mate
fuente
1

perl, 87 caracteres / perl 5.14, 78 + 1 = 79 caracteres

Esta implementación registra las referencias de la matriz de entrada. Aparte de eso, es bastante sencillo: si bien ambas matrices tienen algo, cambie la parte inferior de las dos. Luego, devuelva el bit combinado junto con los bits restantes (solo quedará uno de @ $ x o @ $ y). Perl5 recto, 87 caracteres:

sub M{($x,$y,@o)=@_;push@o,$$x[0]>$$y[0]?shift@$y:shift@$x while@$x&&@$y;@o,@$x,@$y}

Usando perl 5.14.0 y su nuevo cambio de arrayref: 78 caracteres + 1 penalización de char = 79 caracteres:

sub M{($x,$y,@o)=@_;push@o,shift($$x[0]>$$y[0]?$y:$x)while@$x&&@$y;@o,@$x,@$y}
skibrianski
fuente
*en lugar de &&guardará un byte. Y aún más sisub M{map{shift(!@$x+@$y*($$y[0]<$$x[0])?$y:$x)}map@$_,($x,$y)=@_}
usuario2846289
@VadimR, guau. Buen trabajo. Continúe y publique eso si lo desea: nunca hubiera pensado hacer el truco del doble mapa en lugar de presionar una matriz.
skibrianski
1

Java: 144

Esto es bastante sencillo. Una función que toma dos matrices y devuelve una, la versión fusionada, golfizada y sin envoltorio de compilación:

int[]m(int[]a,int[]b){int A=a.length,B=b.length,i,j;int[]c=new int[A+B];for(i=j=0;i+j<A+B;c[i+j]=j==B||i<A&&a[i]<b[j]?a[i++]:b[j++]);return c;}

Sin golf (con envoltorio ejecutable y compilable):

class M{
    public static void main(String[]args){
        int[]a=new int[args[0].split(",").length];
        int i=0;
        for(String arg:args[0].split(","))
            a[i++]=Integer.valueOf(arg);
        int[]b=new int[args[1].split(",").length];
        int j=0;
        for(String arg:args[1].split(","))
            b[j++]=Integer.valueOf(arg);
        int[]c=(new M()).m(a,b);
        for(int d:c)
            System.out.printf(" %d",d);
        System.out.println();
    }
    int[]m(int[]a,int[]b){
        int A=a.length,B=b.length,i,j;
        int[]c=new int[A+B];
        for(i=j=0;i+j<A+B;c[i+j]=j==B||i<A&&a[i]<b[j]?a[i++]:b[j++]);
        return c;
    }
}

Ejecuciones de ejemplo:

$ javac M.java
$ java M 10,11,12 0,1,2,20,30
 0 1 2 10 11 12 20 30
$ java M 10,11,12,25,26 0,1,2,20,30
 0 1 2 10 11 12 20 25 26 30

Cualquier consejo para acortar sería apreciado.

ProgramadorDan
fuente
1

Scala, 97 bytes

Solución recursiva con O (n). Para acortar el código, a veces se realiza una operación cambiando los 2 parámetros intercambiables, es decir, f (a, b) llama a f (b, a).

type L=List[Int];def f(a:L,b:L):L=if(a==Nil)b else if(a(0)<=b(0))a(0)::f(a.drop(1),b) else f(b,a)

Sin golf:

type L=List[Int]

def f(a:L, b:L) : L =
  if (a == Nil)
    b 
  else 
    if (a(0) <= b(0))
      a(0) :: f(a.drop(1), b) 
    else
      f(b,a)
lambruscoAcido
fuente
Excepción si a no está vacío, pero b está vacío
Dan Osipov
1

APL (32)

{⍺⍵∊⍨⊂⍬:⍺,⍵⋄g[⍋g←⊃¨⍺⍵],⊃∇/1↓¨⍺⍵}

Explicación:

{⍺⍵∊⍨⊂⍬                               if one or both of the arrays are empty
        :⍺,⍵                           then return the concatenation of the arrays
             ⋄g[⍋g←⊃¨⍺⍵]              otherwise return the sorted first elements of both arrays
                          ,⊃∇/        followed by the result of running the function with
                               1↓¨⍺⍵}  both arrays minus their first element
marinus
fuente
1

LISP, 117 bytes

El algoritmo termina en n + 1iteraciones, donde nes la longitud de la lista más corta en la entrada.

(defun o(a b)(let((c(car a))(d(car b)))(if(null a)b(if(null b)a(if(< c d)(cons c(o(cdr a)b))(cons d(o a(cdr b))))))))
PieCot
fuente
0

PYG (50)

def m(*a):
 while An(a):yield Mn(ItCo(a,a)).pop(0)

PYG (64, nuevamente, si no se permiten generadores):

def m(*a):
 r=[]
 while An(a):r+=[(Mn(ItCo(a,a)).pop(0)]
 return r

Una adaptación de mi respuesta de Python .

ɐɔıʇǝɥʇuʎs
fuente
0

Python - 69 bytes

def m(A,B):
    C=[]
    while A and B:C+=[[A,B][A>B].pop(0)]
    return C+A+B

Si el orden de entrada y salida descendiera, esto podría acortarse a 61 bytes :

def m(A,B):
    C=[]
    while A+B:C+=[[A,B][A<B].pop(0)]
    return C

Y más abajo a 45 bytes si se permiten generadores:

def m(A,B):
    while A+B:yield[A,B][A<B].pop(0)
Wrzlprmft
fuente
Esto definitivamente no es O (n). .pop (0) y + = son ambas operaciones O (n) que haces O (n) veces.
isaacg
Ni siquiera sabía hasta ahora que las listas no se implementan como listas en Python e incluso entonces pop(0)se pueden implementar en O (1) y +=al menos se pueden implementar mejor que O (n) (vea el enlace). Por cierto, su solución usa +=(es decir, appendy extend) con tanta frecuencia como la mía. De todos modos, todo eso es una pregunta de implementación (hasta donde yo sé), por lo que en una implementación de Python (ficticia), donde las listas se implementan como listas, mi función es O (n). Finalmente, su pregunta requería que el algoritmo fuera O (n), y el mío es.
Wrzlprmft
En realidad, append y extend se implementan de manera diferente en python que + = is. + = crea una nueva lista, mientras .append y .extend modifican una existente.
isaacg
0

Perl 6: 53 caracteres

sub M(\a,\b){{shift a[0]>b[0]??b!!a}...{a^b},a[],b[]}

Pasar de cualquiera de ao btiene el valor más pequeño, hasta aXOR b( a^b) es verdadera. Luego devuelva lo que quede, aplanar ( []) las matrices en la lista (a[],b[] ).

Suponiendo que el cambio desde el comienzo de una matriz es O (n), el peor de los casos es dos comparaciones y un cambio por elemento, por lo que el algoritmo es O (n).

Mouq
fuente
0

JavaScript (ES5) 90 86 90 bytes

function f(a,b){for(o=[];(x=a[0]<b[0]?a:b).length;)o.push(x.shift());return o.concat(a,b)}

editar: (90 -> 86) Se movió el ternario a la condición de bucle for. Idea robada de Dennis.

editar: (86 -> 90) Se eliminó la distribución de matriz a cadena, ya que rompe el requisito de O (n) .

nderscore
fuente
0

Mathematica 137 135

m[a_,b_]:=(l=a;Do[Do[If[b[[f]]<=l[[s]],(l=Insert[l,b[[f]],s];Break[]),If[s==Length@l,l=l~Append~b[[f]]]],{s,Length@l}],{f,Length@b}];l)

Entrada:

m[{2,2,4,6,7,11},{1,2,3,3,3,3,7}]

Salida:

{1, 2, 2, 2, 3, 3, 3, 3, 4, 6, 7, 7, 11}

Sin golf:

mergeList[a_, b_] := (
    list = a;
    Do[
        Do[(
            If[
                b[[f]] <= list[[s]],
                (list = Insert[list, b[[f]], s]; Break[]),
                If[
                    s == Length@list,
                    list = list~Append~b[[f]]
                ]
        ]),
        {s, Length@list}
    ],
    {f, Length@b}
    ];
    list
)

Probablemente podría hacerlo mejor.

kukac67
fuente
m[a:{x___,y_},b:{___,z_}]:=If[y<z,b~m~a,{x}~m~b~Join~{y}];{}~m~b_=b;
alephalpha
0

R, 80

La misma solución que en Scala y otros idiomas. No estoy tan seguro de que x [-1] sea O (1).

f=function(a,b)if(length(a)){if(a[1]<=b[1])c(a[1],f(a[-1],b))else f(b,a)}else b
lambruscoAcido
fuente
0

Mathematica, 104 bytes

Reap[{m,n}=Length/@{##};i=k=1;Do[If[k>n||TrueQ[#[[i]]<#2[[k]]],Sow@#[[i++]],Sow@#2[[k++]]],n+m]][[2,1]]&

La función anónima almacena la longitud de las dos listas de entrada en las variables my n, luego, cada iteración del Dobucle Sowes un elemento de una de las listas que incrementa el contador de esa lista ( ipara el primero, kpara el segundo) en uno. Si uno de los contadores excede la longitud de la lista, la Ifinstrucción siempre será Sowel elemento de la otra lista. Después de las n+moperaciones, todos los elementos han sido atendidos. Reapo más bien parte [[2,1]]de su salida es una lista de elementos en el orden en que han sido Sown.

No estoy seguro de las partes internas (está accediendo a una parte de una lista, una O(1)operación o no), pero los tiempos se veían bastante lineales en mi máquina con respecto a la longitud de la lista de entrada.

LLlAMnYP
fuente