Há um número par de elementos em sua entrada:
say elems <1 1 0 2 0 2 1 2 2 2 4 4 3 3>; # 14
Seu grepbloco consome dois elementos de cada vez:
{$^a eq $^b}
Portanto, se você adicionar ou remover um elemento, receberá o erro que ocorrerá quando o bloco for executado no único elemento restante no final.
Existem muitas maneiras de resolver seu problema.
Mas você também perguntou sobre a opção de permitir sobreposição, por exemplo, você recebe duas (2 2)sub-listas quando a sequência 2 2 2é encontrada. E, de maneira semelhante, você presumivelmente deseja ver duas correspondências, não zero, com entradas como:
<1 2 2 3 3 4>
Então, vou me concentrar em soluções que lidam com esses problemas também.
Apesar do estreitamento do espaço da solução para lidar com os problemas extras, ainda existem muitas maneiras de expressar soluções funcionalmente.
Uma maneira de adicionar um pouco mais de código ao final do seu:
my @s = <1 1 0 2 0 2 1 2 2 2 4 4 3 3>;
say grep {$^a eq $^b}, @s .rotor( 2 => -1 ) .flat
O .rotormétodo converte uma lista em uma lista de sub-listas, cada uma com o mesmo comprimento. Por exemplo, é say <1 2 3 4> .rotor: 2exibido ((1 2) (3 4)). Se o argumento do comprimento for um par, a chave será o comprimento e o valor será um deslocamento para iniciar o próximo par. Se o deslocamento for negativo, você terá sobreposição da sub-lista. Assim é say <1 2 3 4> .rotor: 2 => -1exibido ((1 2) (2 3) (3 4)).
O .flatmétodo "nivela" seu invocante. Por exemplo, é say ((1,2),(2,3),(3,4)) .flatexibido (1 2 2 3 3 4).
Uma maneira talvez mais legível de escrever a solução acima seria omitir flate usar .[0]e .[1]indexar nas sub-listas retornadas por rotor:
say @s .rotor( 2 => -1 ) .grep: { .[0] eq .[1] }
Veja também o comentário de Elizabeth Mattijsen para outra variação generalizada para qualquer tamanho de sub-lista.
Se você precisava de um padrão de codificação mais geral, escreva algo como:
say @s .pairs .map: { .value xx 2 if .key < @s - 1 and [eq] @s[.key,.key+1] }
O .pairsmétodo em uma lista retorna uma lista de pares, cada par correspondendo a cada um dos elementos em sua lista invocante. O .keyde cada par é o índice do elemento na lista invocante; o .valueé o valor do elemento.
.value xx 2poderia ter sido escrito .value, .value. (Veja xx.)
@s - 1é o número de elementos em @smenos 1.
A [eq]na [eq] listé uma redução .
Se você precisar de correspondência de padrão de texto para decidir o que constitui elementos iguais contíguos, poderá converter a lista de entrada em uma sequência, faça a correspondência com essa usando um dos advérbios de correspondência que geram uma lista de correspondências e mapeie a partir da lista de correspondências resultante para a desejada resultado. Para combinar com sobreposições (por exemplo, 2 2 2resultados em ((2 2) (2 2))uso :ov:
say @s .Str .match( / (.) ' ' $0 /, :ov ) .map: { .[0].Str xx 2 }
2 2 2 2ele imprime 3(2 2)s, conforme o esperado. Nunca ouvi falar do métodorotor. Inicialmente, inventei osquishmétodo e verifiquei se ele possui características ou argumentos semelhantes,@s.squish(:length 2, :multiple_instances yes)mas não possuía essas características e não era adequado para a tarefa. Comparado com osquish,rotorparece bastante adequado. Na verdade, pode até ser o mais adequado para esse tipo de operação.