Diga-me como fracassar

29

Como cientistas da computação, você provavelmente conhece todas as operações básicas da lista de pop e push . Estas são operações simples que modificam uma lista de elementos. No entanto, você já ouviu falar do fracasso da operação ? (como no flip- flop )? É bem simples. Dado um número n , inverta os primeiros n elementos da lista. Aqui está um exemplo:

>>> a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> a.flop(4)
[4, 3, 2, 1, 5, 6, 7, 8, 9, 10]

O legal da operação do flop é que você pode usá-lo para fazer algumas coisas legais em uma lista, como classificá-la . Vamos fazer algo semelhante com os flops:

Dada uma lista de números inteiros, "Vizinho". Em outras palavras, classifique-o para que cada elemento duplicado apareça consecutivamente.

Isso pode ser feito com flops! Por exemplo, pegue a seguinte lista:

>>> a = [3, 2, 1, 4, 3, 3, 2]
>>> a.flop(4)
[4, 1, 2, 3, 3, 3, 2]
>>> a.flop(3)
[2, 1, 4, 3, 3, 3, 2]
>>> a.flop(6)
[3, 3, 3, 4, 1, 2, 2]

Isso nos leva à definição do desafio de hoje:

Dada uma lista de números inteiros, imprima qualquer conjunto de fracassos que resultem na vizinhança da lista.

Usando a última lista como exemplo, você deve gerar:

4
3
6

porque flopping a lista por 4, depois por 3 e por 6 resultará em uma lista vizinha. Lembre-se de que você não precisa imprimir a lista mais curta possível de fracassos vizinhos a uma lista. Se você tivesse impresso:

4
4
4
3
1
1
6
2
2

em vez disso, isso ainda seria uma saída válida. No entanto, você pode não sempre número uma saída maior do que o comprimento da lista. Isso ocorre porque, para uma lista a = [1, 2, 3], chamar não a.flop(4)faz sentido.

aqui estão alguns exemplos:

#Input:
[2, 6, 0, 3, 1, 5, 5, 0, 5, 1]

#Output
[3, 7, 8, 6, 9]


#Input
[1, 2]

#Output
<any list of integers under 3, including an empty list>


#Input
[2, 6, 0, 2, 1, 4, 5, 1, 3, 2, 1, 5, 6, 4, 4, 1, 4, 6, 6, 0]

#Output
[3, 19, 17, 7, 2, 4, 11, 15, 2, 7, 13, 4, 14, 2]


#Input
[1, 1, 1, 1, 2, 2, 2, -1, 4]

#Output
[]


#Input
[4, 4, 8, 8, 15, 16, 16, 23, 23, 42, 42, 15]

#Output
[12, 7]

Lembre-se de que, em cada um desses exemplos, a saída fornecida é apenas uma saída potencial válida. Como eu disse antes, qualquer conjunto de flops vizinhos à lista fornecida é uma saída válida . Você pode usar esse script python para verificar se uma determinada lista de fracassos contorna corretamente uma lista.

Você pode receber entrada e saída em qualquer formato razoável. Por exemplo, argumentos da função / valor de retorno, STDIN / STDOUT, leitura / gravação de um arquivo etc. são todos válidos. Como sempre, esse é o , então faça o programa mais curto possível e divirta-se! :)

DJMcMayhem
fonte
3
Eu ouvi isso como ponto de partida (operação).
Weijun Zhou 31/01
3
@WeijunZhou Essa é uma medida da velocidade computacional, para contar operações realizadas em um pedaço de hardware. pt.wikipedia.org/wiki/FLOPS
iPhoenix
3
Os envios precisam ser determinísticos ou posso flopar pseudo-aleatoriamente até que o array seja agrupado?
Dennis
3
É permitido que zero flops apareça na saída?
Laikoni 31/01
4
Relacionado . NB: qualquer resposta a essa pergunta seria uma resposta a essa pergunta, mas como ser classificada é uma condição mais forte do que "ser vizinha", pode ser possível jogar fora do campo de golfe para que isso não seja uma duplicata (embora o único responder até agora não é encorajador).
Peter Taylor

Respostas:

7

Haskell , 98 71 bytes

h.r
h(x:s)|(a,b)<-span(/=x)s=l b:l s:h(b++r a)
h e=e
r=reverse
l=length

Experimente online!

Explicação

Para uma lista de comprimento, nesse método produz 2*nflops. Ele funciona olhando o último elemento da lista, procurando o mesmo elemento na lista anterior e passando-o para a penúltima posição. Em seguida, a lista com o último elemento removido é recursivamente "vizinhança".

Para a lista, [1,2,3,1,2]o algoritmo funciona assim:

[1,2,3,1,2]  flip longest prefix that ends in 2: flop 2
[2,1,3,1,2]  bring first element to second to last position: flop n-1 = flop 4
[1,3,1,2,2]  recursively work on n-1 list
[1,3,1,2]    there is no other 2: flop 0
[1,3,1,2]    flop n-1 = flop 3
[1,3,1,2]    recurse
[1,3,1]      flop 1
[1,3,1]      flop 2
[3,1,1]      recurse
[3,1]        flop 0
[3,1]        flop 1
 ...

Tudo isso resulta nos fracassos [2,4,0,3,1,2,0,1,0,0]e na lista de vizinhos [3,1,1,2,2].

Laikoni
fonte
6

Wolfram Language (Mathematica) , 71 bytes

If[(n=Tr[1^#])<1,{},{i=Last@Ordering@#,n,n-1,i-1}~Join~#0[#~Drop~{i}]]&

Experimente online!

Como funciona

Dada uma matriz de comprimento n, gera uma sequência de 4nflops que classificam a matriz em ordem crescente: em particular, colocando elementos duplicados um ao lado do outro.

A idéia é que, para classificar uma matriz, movemos seu maior elemento para o final e, em seguida, classificamos os primeiros n-1elementos da matriz. Para evitar a implementação da operação de flop, movemos o elemento maior para o final de uma maneira que não perturbe os outros elementos:

{3, 2, 1, 5, 3, 3, 2}    starting array, with largest element in position 4
{5, 1, 2, 3, 3, 3, 2}    flop 4 to put the largest element at the beginning
{2, 3, 3, 3, 2, 1, 5}    flop 7 to put the largest element at the end
{1, 2, 3, 3, 3, 2, 5}    flop 6 (7-1) to reverse the effect of flop 7 on other elements
{3, 2, 1, 3, 3, 2, 5}    flop 3 (4-1) to reverse the effect of flop 4 on other elements

Em geral, se o elemento maior estiver em posição i, a sequência de flops que o move até o fim é i, n, n-1, i-1.

Misha Lavrov
fonte
Você pode mover o elemento maior para o final com apenas i, n. Por que então fazer n-1, i-1? Não há necessidade de uma classificação estável .
Peter Taylor
@ PeterTaylor Eu não acho que a resposta realmente faça flops, em vez disso, ele remove o maior elemento de cada vez e gera o equivalente a essa operação em termos de flops.
Neil
3

Geléia , 19 17 bytes

ỤỤạ‘Ḣ
ỤÇÐƤĖµUż’ṚF

Classifica a lista.

Experimente online!

Dennis
fonte
Eu acho que as ỤŒ¿’Æ!‘ṚĖµUż’ṚFinversas Œ¿são modulos L!.
Jonathan Allan
Por qualquer motivo, isso não funciona para o último caso de teste, o que provavelmente significa que meu código também falhará em alguns casos obscuros ...
Dennis
E de fato falha na entrada [4, 3, 2, 1, 3]. Vadio.
Dennis
Oh, boo; isso é uma vergonha.
Jonathan Allan
Ụ>Ṫ$ƤSạỤĖµUż’ṚFeconomizando 2 bytes substituindo o link auxiliar.
miles
2

Limpo , 88 bytes

Acho que há um possivelmente mais curto com guardas, mas ainda não o encontrei.

import StdEnv
$[h:t]#(a,b)=span((<>)h)t
=map length[b,t]++ $(b++r a)
$e=e
r=reverse

$o r

Experimente online!

Como uma função literal. Funciona da mesma maneira que a resposta Haskell de Laikoni , mas jogava golfe de maneira um pouco diferente e, é claro, também em um idioma diferente.

Furioso
fonte
1

JavaScript, 150 bytes

(a,f=n=>(a=[...a.slice(0, n).reverse(),...a.slice(n)],n),l=a.length,i=0)=>a.reduce(c=>[...c,f(a.indexOf(Math.max(...a.slice(0, l-i)))+1),f(l-i++)],[])

Experimente online!

JavaScript, 151 bytes

a=>{f=n=>(a=[...a.slice(0,n).reverse(),...a.slice(n)],n),r=[];for(i=a.length+1;--i>0;)r.push(f(a.indexOf(Math.max(...a.slice(0, i)))+1),f(i));return r}

Experimente online!

Ambos basicamente classificam a matriz lançando o número máximo no início e depois na parte traseira, repetindo isso com a matriz restante. O primeiro usa reduzir, o segundo usa um loop for.

Ungolfed:

array => {
  let flop = n => {
    array = [...array.slice(0, n).reverse(), ...array.slice(n)]; 
    return n;
  }
  let flops = [];
  for (let i = array.length + 1; --i > 0;) 
  {
    let maxIndex = array.indexOf(Math.max(...array.slice(0, i)));
    flops.push(flop(maxIndex + 1), flop(i));
  }
  return flops;
}
mdatsev
fonte
0

Perl 5.10 (ou superior), 66 bytes

Inclui +3para -n o use 5.10.0trazer a linguagem para nível perl 5.10 é considerado livre

#!/usr/bin/perl -n
use 5.10.0;
$'>=$&or$.=s/(\S+) \G(\S+)/$2 $1/*say"$. 2 $."while$.++,/\S+ /g

Execute com a entrada como uma linha no STDIN:

flop.pl <<< "1 8 3 -5 6"

Classifica a lista localizando repetidamente qualquer inversão, colocando-a na frente e depois com a inversão e devolvendo tudo à sua antiga posição.

Foi surpreendentemente difícil entrar no mesmo estádio que o python neste :-)

Ton Hospel
fonte
0

C (gcc) , 165 160 bytes

  • Agradecimentos ao ceilingcat por salvar cinco bytes.
m,j,t;f(A,l)int*A;{for(j=0;j+j<l;A[j]=A[l+~j],A[l+~j++]=t)t=A[j];}F(A,l)int*A;{for(;l;f(A,++m),printf("%d,%d,",m,l),f(A,l--))for(j=m=0;j<l;j++)m=A[j]>A[m]?j:m;}
Jonathan Frech
fonte
@ceilingcat Obrigado.
Jonathan Frech