Mesclar Classificação
Nesse desafio, você implementará a sub-rotina de mesclagem da classificação de mesclagem. Especificamente, você deve criar uma função ou programa ou verbo ou similar que utilize duas listas, cada uma classificada em ordem crescente, e as combine em uma lista classificada em ordem crescente. Requisitos:
- Seu algoritmo deve levar uma quantidade de tempo assintoticamente linear no tamanho da entrada. Pare de fornecer soluções O (n ^ 2).
- Você não pode usar nenhuma função interna capaz de classificar uma lista, mesclar uma lista ou algo assim. Discrição do autor.
- O código deve ser capaz de lidar com elementos repetidos.
- Não se preocupe com listas vazias.
Exemplos:
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]
Isso é código-golfe , então o código mais curto pode ganhar!
b=a;b=b.length
pode duplicar toda a matriza
(e resultar em tempo O (n ^ 2) se executado para cada elemento) ou duplicar apenas a referência à matriz (tempo O (n)). Qual conta?Respostas:
Rebmu (
3532 caracteres)Teste
Sobre
Rebmu é um dialeto de Rebol que permite 'mesclar' o código regular para situações que exigem brevidade. Sem silêncio, o código funciona da seguinte forma:
Acredito que isso satisfaça o requisito de O (n) , pois o bloco till é repetidamente repetido tantas vezes quanto o comprimento da entrada (e o
reverse
único alterna a ordem do contêiner dos blocos de entrada, não os próprios blocos). O usotake
é talvez uma liberdade, mas ainda é um pequeno golpe de eficiência.Rebol (
8375 caracteres)Um pouco diferente: no Rebol, os caminhos são uma expressão mais curta que
first
ousecond
.a
é o bloco de entrada que contém os dois blocos:fonte
Soluções da OP:
Haskell
494440Python
1311051019993Com agradecimentos a @Evpok:
fonte
a%b=a++b
após a correspondência principal de padrões para lidar com listas vazias, que eliminarão alguns caracteres.Python (79)
Python (95, se não tivermos permissão para retornar um gerador)
Itertools é a solução para todos os problemas mundanos.
Bônus: os dois trabalham em um número arbitrário de listas e se preocupam com listas vazias (como, eles pegam 2 listas vazias e retornam uma lista vazia ou levam 1 lista vazia e 1 não vazia, e eles retornarão o item não vazio. Outro recurso adicional dos 2 itens não produzidos: eles também serão executados sem argumentos e retornarão uma lista vazia.)
Ungolfed:
fonte
r+=[...]
em vez der.append(...)
(poupa 4 caracteres de cada vez)C - 75
Isso opera em
NULL
matrizes terminadas deint *
, embora funcione igualmente bem para ponteiros para outros tipos, substituindo a função de comparação apropriada por**b < **a
(por exemplo,strcmp(*b, *a) < 0
).Ungolfed:
fonte
Golfscript,
2927302926 bytesou
Como funciona
O comando
será processado da seguinte maneira:
A saída é:
fonte
[1 1 1 ... 2]
e[1 1 1 ... 3]
), pois a comparação das matrizes (em vez de seus primeiros elementos) seria muito lenta nesse caso.J -
42.33Versão modificada daqui + o comentário de @algorithmshark
k
precede o cabeçalho da matriz direita às caudas mescladas de ambas as matrizes.k~
é o mesmo, mas com matrizes invertidas.(>&{.)
está comparando as cabeças. O código emitirá um erro se uma das matrizes estiver vazia; nesse caso, retornamos apenas sua concatenação,
.fonte
/:~ a,b
é a resposta proibida (junto com[:/:~,
), você está procurando a resposta mais curta que não inclua/:
, certo?m=:k~`k@.(>&{.)`,@.(0=*&#)
economiza 2 caracteres.k=:(m}.),~0{]
em=:k~`k@.(>&{.) ::,
. Usamos0{
para lançar um erro quando a lista está vazia e, em seguida, capturar esse erro e sair com,
.JavaScript (ES6),
6979 bytesComo funciona
fonte
<
operador não é válido, pois faz uma comparação de cadeias:f([123, 456, 789], [1, 2, 3, 4, 5]) => [1, 123, 2, 3, 4, 456, 5, 789]
[]
e convertê-la em uma seqüência de caracteres requer tempo O (n). Fazer isso uma vez para todos os n elementos da matriz leva tempo O (n ^ 2).Python
(63) (69)(71)Eu escrevi isso antes de ver os comentários do OP sobre tempos de execução de outras respostas, então essa é outra solução que é O (n) no algoritmo, mas não na implementação.
fonte
return[a.pop(0)]+(a and m(a,b)or b)
Haskell, 35 bytes
Haskell, 30 bytes (não concorrente)
Esta versão não concorrente garante apenas tempo de execução linear se
a
eb
tiver elementos disjuntos; caso contrário, ainda funcionará corretamente, mas poderá usar o tempo quadrático.fonte
PHP
91 9891 byteseditar # 1: Vazio
$b
requer uma condição adicional nos chavetas (+7).edit # 2: golfe menor
edit # 3: segunda versão adicionada
bem direto. A parte mais legal é o ternário dentro do
array_shift
(que falha se você tentar sem os curlys)
ou
destroçado
teste
fonte
$a&(!$b|$a[0]<$b[0])?$a:$b
vez de${$a&(!$b|$a[0]<$b[0])?a:b}
array_shift
parâmetro é usado por referência. Tem que ser uma variável; uma expressão não funciona.Go, 124 caracteres
fonte
JavaScript - 133
Mesmo tipo de abordagem que os OPs.
fonte
perl, 87 caracteres / perl 5.14, 78 + 1 = 79 caracteres
Esta implementação reprova as referências da matriz de entrada. Fora isso, é bem direto: enquanto as duas matrizes têm algo, desative a parte inferior das duas. Em seguida, retorne o bit mesclado associado aos bits restantes (apenas um de @ $ x ou @ $ y permanecerá). Perl5 em linha reta, 87 caracteres:
Usando perl 5.14.0 e seu novo conjunto de variáveisref shift: 78 caracteres + 1 pena de caractere = 79 caracteres:
fonte
*
em vez de&&
salvará um byte. E ainda mais sesub M{map{shift(!@$x+@$y*($$y[0]<$$x[0])?$y:$x)}map@$_,($x,$y)=@_}
Java: 144
Isso é bem direto. Uma função que pega duas matrizes e retorna uma, a versão mesclada, golfed e sem wrapper de compilação:
Ungolfed (com wrapper compilável e executável):
Execuções de exemplo:
Qualquer dica para encurtar seria apreciada.
fonte
Scala, 97 bytes
Solução recursiva com O (n). Para encurtar o código, algumas vezes uma operação é feita alternando os 2 parâmetros intercambiáveis, ou seja, f (a, b) chama f (b, a).
Ungolfed:
fonte
APL (32)
Explicação:
fonte
LISP, 117 bytes
O algoritmo termina em
n + 1
iterações, onden
é o comprimento da lista mais curta da entrada.fonte
PYG (50)
PYG (64, novamente, se nenhum gerador for permitido.):
Uma adaptação da minha resposta Python .
fonte
Python - 69 bytes
Se a ordem de entrada e saída fosse decrescente, isso poderia ser reduzido para 61 bytes :
E ainda mais até 45 bytes, se geradores forem permitidos:
fonte
pop(0)
podem ser implementadas em O (1) e+=
pelo menos podem ser implementadas melhor que O (n) (veja o link). A propósito, sua solução usa+=
(ou seja,append
eextend
) tantas vezes quanto a minha. Enfim, tudo isso é uma questão de implementação (tanto quanto eu sei); portanto, em uma implementação Python (fictícia), onde as listas são implementadas como listas, minha função é O (n). Finalmente, sua pergunta exigia que o algoritmo fosse O (n), e o meu é.Perl 6: 53 caracteres
Desloque-se de qualquer valor que tenha o valor menor
a
oub
atéa
XORb
(a^b
) ser verdadeiro. Em seguida, retorne o que restar, achatando ([]
) as matrizes na lista (a[],b[]
).Supondo que a mudança desde o início de uma matriz seja O (n), o pior caso é duas comparações e uma mudança por elemento; portanto, o algoritmo é O (n).
fonte
JavaScript (ES5)
908690 bytesedit: (90 -> 86) Moveu o ternário para a condição do loop for. Idéia roubada de Dennis.
edit: (86 -> 90) Removida a matriz para a conversão de String, pois quebra o requisito de O (n) .
fonte
Mathematica,
137135Entrada:
Resultado:
Ungolfed:
Provavelmente poderia fazer melhor.
fonte
m[a:{x___,y_},b:{___,z_}]:=If[y<z,b~m~a,{x}~m~b~Join~{y}];{}~m~b_=b;
R, 80
A mesma solução que no Scala e em outros idiomas. Não tenho tanta certeza sobre x [-1] é O (1).
fonte
Mathematica, 104 bytes
Função anônima, armazena o comprimento das duas listas de entrada nas variáveis
m
en
, em seguida, cada iteração doDo
loopSow
é um elemento de uma das listas que incrementam o contador dessa lista (i
para a primeira,k
para a segunda) em uma. Se um dos contadores exceder o comprimento da lista, aIf
instrução sempre seráSow
o elemento da outra lista. Após asn+m
operações, todos os elementos foram resolvidos.Reap
ou melhor, parte[[2,1]]
de sua saída é uma lista de elementos na ordem em que foramSow
n.Não tenho certeza das informações internas (está acessando uma parte de uma lista
O(1)
ou não), mas os tempos pareciam bastante lineares na minha máquina com relação ao tamanho da lista de entrada.fonte