Desafio
A tarefa desta pergunta é dividir uma matriz de entrada de números inteiros na segunda ocorrência de cada número inteiro nessa matriz.
Não está claro o suficiente? Aqui está um exemplo para ajudar
Matriz de entrada:
[2 1 1 2 3 2 2 4 5 6 7 3 7 0 5]
Resultado:
[[2 1] [] [3 2 2 4 5 6 7] [] [0] []]
Explicação:
Aqui está a matriz com apenas o segundo elemento destacado em negrito:
[2 1 1 2 3 2 2 4 5 6 7 3 7 0 5 ]
Agora, colocamos os blocos de matriz divididos em torno dessas ocorrências em segundos em negrito:
[2 1] 1 [] 2 [3 2 2 4 5 6 7] 3 [] 7 [0] 5 []
e agrupe essas matrizes divididas em uma matriz para obter a final
[[2 1] [] [3 2 2 4 5 6 7] [] [0] []]
Observe que quando ocorrem segundas ocorrências adjacentes, haverá matrizes vazias.
Regras
Como de costume, você deve escrever um programa completo ou uma função utilizando a matriz de entrada via STDIN, ARGV ou argumento de função.
Entrada
A entrada consiste em qualquer formato de matriz conveniente (ou semelhante a matriz) de números inteiros.
Por exemplo, qualquer um dos seguintes itens seria aceitável:
2 1 1 1 4 5 6
[2 1 1 1 4 5 6]
[2, 1, 1, 1, 4, 5, 6]
Resultado
Ao enviar para STDOUT, sua matriz também pode ser impressa em qualquer formato conveniente (aninhado) de matriz, por exemplo, um dos
[[2 1] [1 4 5 6]]
[[2, 1], [1, 4, 5, 6]]
{{2, 1}, {1, 4, 5, 6}}
(Geralmente, essa é a representação de string nativa de matrizes no seu idioma.)
Observe também que as matrizes vazias à direita devem ser impressas como parte da matriz.
Pontuação
Este é o código-golfe, pelo que o código mais curto em bytes ganha!
fonte
""
como a matriz vazia? Isso cheira a favor de uma linguagem específica do golfe.2 1, 1 4 5 6
?Respostas:
APL 25
Exemplo:
Antigo:
Essa é uma boa pergunta para o operador principal (⌸) que foi introduzido com o Dyalog APL v14. Ele pega a função de argumento esquerdo ({1 ↑ 1 ↓ ⍵}) e fornece para cada argumento único, os índices do vetor para esse argumento. Aqui estou pegando o segundo índice, depois verifico qual dos índices está presente nesta lista ((⍳⍴⍵) ∊) e uso o booleano resultante para dividir o vetor original.
Pode ser experimentado online aqui:
http://tryapl.org
fonte
1↓¨{1,∨⌿<\2=+\∘.=⍨⍵}⊂1∘,
APL (Diálogo 14) (31)
Esta é uma função que pega uma matriz e retorna uma matriz aninhada.
Teste:
Explicação:
0,⍵
: Adicione0
a à frente⍵
para facilitar o processamento. (Não conta como uma ocorrência.)(
...)⊂
: Divide a matriz de acordo com a máscara de bits fornecida. Um novo grupo começa em cada um1
na máscara de bits.+\∘.=⍨⍵
: para cada valor em (o original)⍵
, encontre todas as ocorrências em⍵
. Em seguida, faça uma soma contínua para cada valor, fornecendo uma matriz quadrada para cada posição em⍵
quantos de cada valor já ocorreu.↓
: Divida a matriz por suas linhas, fornecendo para cada valor uma matriz que mostre a quantidade de vezes que ocorreu em cada posição.2⍳⍨¨
: Em cada uma dessas matrizes, encontre o índice da primeira2
.(⍳⍴⍵)∊
: Para cada índice possível⍵
, veja se está contido na lista de índices de segundas ocorrências. (Eles iniciam cada grupo, exceto o primeiro.)1,
: Adicione um1
à frente, marcando o início do primeiro grupo.1↓¨
: Remova o primeiro elemento de cada grupo. (Estes são os adicionados0
e a segunda ocorrência de cada valor.)fonte
J,
2824 caracteresAgradecimentos especiais a randomra .
Funciona assim. Sobre todos os prefixos (
\
) da matriz de entrada, examinamos quantos (+/@
) elementos do prefixo são iguais ao último elemento (={:
) desse prefixo. Quando esse número é 2, sabemos que esta é a segunda ocorrência desse item na matriz, portanto, dividimos a matriz lá usando<;._1
.Coisa velha usando truques de classificação:
(1&,<;._1~1,1=i.~(]-{)/:@/:)
.fonte
(1&,<;._1~1,2=+/@(={:)\)
é 4 bytes mais curto e muito mais simples. (/:@/:
É um truque bom.)Mathematica,
585149 bytesEsta é uma função sem nome que leva uma lista como
e retorna uma lista aninhada como
Como funciona
Isso usa alguma magia bastante obscura
SplitBy
.Estou acompanhando as ocorrências de cada número em uma função
f
. No Mathematica, você pode definir o valor de uma função para cada entrada separadamente e não precisa especificar o valor para todas as entradas possíveis (é mais como uma tabela de hash para esteróides).Então, iniciando
f
com 0 para valores que estão presentes na entrada com(f@#=0;#)&/@
.Agora
SplitBy
pega uma lista e uma função e "divide a lista em sublistas, consistindo em execuções de elementos sucessivos que dão o mesmo valor quandof
é aplicado" (observe queSplitBy
não remove nenhum elemento). Mas o problema (não documentado) é, quef
é chamado duas vezes em cada elemento - quando comparado ao seu antecessor e seu sucessor. Então, se fizermosnão apenas obtemos cada número uma vez, mas isso imprime
que é 6 solicita 3 comparações.
Podemos dividir a lista antes de cada segunda ocorrência, se escrevermos uma função que sempre retorna,
False
mas retornaTrue
quando uma segunda ocorrência é comparada ao elemento anterior. Essa é a terceira verificação desse elemento (duas verificações na primeira ocorrência, mais a primeira verificação na segunda ocorrência). Por isso, usamos++f[#]==3&
. O bom é que isso já retornaFalse
novamente na segunda verificação da segunda ocorrência, para que eu possa retornarTrue
por segundas ocorrências consecutivas, mas ainda assim dividir entre elas . Da mesma forma, isso não será dividido após a segunda ocorrência, porque a função já retornaFalse
novamente na segunda verificação.Agora, a pergunta quer que também removamos essas segundas ocorrências; portanto, eliminamos o primeiro elemento de cada lista com
Rest/@
. Mas é claro que não queremos remover o primeiro elemento da entrada; portanto, começamos adicionando um elementoa
ao início da lista com{a}~Join~#
.a
é uma variável indefinida, que o Mathematica trata apenas como desconhecida, portanto não afetará nenhum outro valor def
. Isso também garante que o primeiro elemento real na entrada obtenha suas duas verificações como todos os outros elementos.fonte
Boole
de lá.Python, 148 bytes
Solução bastante horrenda. Tem que haver uma maneira melhor ...
Ligue com
s([2, 1, 1, 1, 4, 5, 6])
.Versão ungolfed
fonte
Haskell,
11511310688isso armazena a quantidade que cada elemento apareceu até agora em função dos elementos para a respectiva quantidade, o que é um truque interessante.
isso funciona usando
%
, uma função que recebe uma função f e um argumentox
retorna uma nova função que retornaf
aplicada ao seu argumento se for diferente dex
, e1 + f x
caso contrário.por exemplo,
3 % const 0
é uma função que retorna 0 para cada argumento, exceto 3, para o qual retorna 1. update: fused thefoldl
para obter um programa muito menor.fonte
Demonstração do Ruby 66
Ruby stabby lambda que usa uma matriz como parâmetro e retorna uma matriz de matrizes.
fonte
Python: 100 bytes
Solução simples. Eu percorro a lista, conto quantas vezes um personagem apareceu antes e anexo a parte desde a última verificação à lista de saída.
fonte
Ruby, 66
Explicação
e
é um hash de contagens de ocorrências para cada elemento,r
é uma matriz na qual o resultado é armazenado.1
.2
, precisamos dividir. Adicione um vazioArray
ao resultado.Array
resultado.fonte
CJam,
2524 bytesRecebe entrada do STDIN como
e saídas como
Basicamente, eu estou iterando sobre todos os elementos da matriz, um por um, colocando-os em outra matriz. Então eu recebo a contagem do elemento atual na outra matriz. Se for 2, inicio outra matriz a partir desse local. Esse tipo de arranjo aleatório de matriz só pode ser alcançado em uma linguagem baseada em pilha.
Expansão do código :
Experimente online aqui
1 byte salvo da dica de Martin no chat
fonte
Ruby, 64 bytes
fonte
Perl 5: 36
Não tenho certeza se isso é aceitável, pois nenhuma divisão real acontece aqui.
Exemplo:
fonte
-pa
como dois bytes extras (porque "custa" apenas dois bytes, pois você pode escrevê-lo como em-pae
vez de-e
). Então, isso seria 38, e não 36.CJam, 28 bytes
Recebe entrada em STDIN como
e imprime a saída em STDOUT como
Observe que cadeias vazias e matrizes vazias são a mesma coisa no CJam e são exibidas como
""
padrão (esta é a representação nativa de matrizes vazias).(Comecei a trabalhar nisso um pouco antes do lançamento do desafio, porque estávamos discutindo o quão difícil o desafio seria.)
Explicação
Basicamente, estou duplicando cada elemento da matriz, a menos que seja a segunda ocorrência; nesse caso, substituo a primeira cópia por um espaço. Por razões de golfe, essa matriz modificada é construída ao contrário. Então
[2 1 1 2 3 2 3]
se tornaEntão eu escolho cada segundo elemento do final, que é a matriz original, mas com as segundas ocorrências substituídas por espaços, ou seja,
Finalmente, eu simplesmente divido a matriz em espaços. Aqui está um detalhamento do código:
fonte
""
é explicitamente permitido na primeira revisão da pergunta. A revisão atual afirma "qualquer formato conveniente ... geralmente represtação nativa de strings de matrizes".Ferramentas Unix, 100 bytes
Aceita a entrada via stdin. Basicamente, apenas substitui cada segunda ocorrência por
"] ["
. Não funciona com cadeias vazias,[]
dará uma cadeia vazia, o que eu acho que é uma representação conveniente de uma matriz vazia :)fonte
11
? será convertido para1][
?APL, 42 caracteres
Exemplo:
Resultado:
Testado aqui.
Se eu precisar gerar uma string que seja interpretada exatamente como a estrutura correta no APL ... 49 caracteres
fonte
1↓1
parecia resolver o problema, mas isso parece muito estranho.Java, 223
Isso funciona apenas no Oracle ou no OpenJDK JRE, uma vez que utilizo essa peculiaridade na implementação de quantificação e verificação de comprimento no look-behind para implementar o look-behind de comprimento variável.
A maior parte do trabalho é feita na regex, que é mostrada abaixo na forma bruta:
Antes de examinarmos o regex acima, vejamos o regex .NET equivalente, que é mais simples, pois suporta diretamente look-behind de comprimento variável (o look-behind do .NET é provavelmente feito pelo modo de correspondência da direita para a esquerda) :
*\b(\d+)\b
e*
no final corresponde a um número e os espaços ao redor (se houver). As verificações vinculadas são para impedir que o número parcial seja correspondido, pois os espaços dos dois lados são opcionais. Ele também captura o número para verificar se é a segunda aparição na matriz.(?<=(.*\b\1\b){2})
verifica se duas instâncias do número capturado acima podem ser encontradas.(?<!(.*\b\1\b){3})
verifica se não há 3 instâncias do número capturado. As duas condições combinadas afirmam que existem apenas 2 instâncias do número até o momento. As verificações vinculadas existem para garantir que o número inteiro seja testado.Voltar para a versão Java. Para implementar um olhar de comprimento variável, transformamos
para
Estou acenando um pouco a respeito do fato de
.
excluir separadores de linha, mas ele pode ser corrigido facilmente e não quero complicar ainda mais a sintaxe.O look-ahead tem sempre 0 comprimento e a verificação do comprimento passa devido à implementação de
*
quantificador.o
^
é necessário fazê-lo funcionar, mas existe para fazer com que o caso com falha falhe mais rapidamente. O look-behind na implementação do Oracle / OpenJDK é feito recuando o comprimento mínimo do padrão, depois corresponde, enxágue e repita incrementando o comprimento até que uma correspondência seja encontrada, ou, na pior das hipóteses, com o comprimento máximo do padrão. . Com^
, garanto que a sequência de prefixos seja correspondida apenas uma vez.No entanto, o olhar para frente dentro do olhar para trás não é limitado pelo limite direito do olhar para trás, para que possa corresponder todo o caminho até o final da cadeia. Para afirmar o limite, capturo o restante da string em outro grupo de captura dentro de um olhar à frente e o uso para limitar o reino do padrão de comprimento variável.
Como meu padrão já começa
.*
, não preciso adicionar outro.*
na frente.fonte
Perl 108
Em ação:
Nota: As duas primeiras linhas
$Data::...
existem apenas para uma melhor apresentação e a terceira linha@a=@b=@e=();
existe para tornar a ferramenta funcionando em várias linhas.fonte
R, 76
Saída para o exemplo: Uma lista de cinco elementos, incluindo três vetores vazios. (
numeric(0)
)A propósito: O código gera uma mensagem de aviso que pode ser ignorada.
fonte
awk 29
Isso requer um pouco de liberdade com os formatos de entrada e saída. A entrada "array" é vertical, um número por linha. A saída também é vertical, um número por linha, com traços separando matrizes.
Entrada:
Resultado:
fonte
Pitão 30
32Esta é minha primeira vez experimentando Pyth. É a mesma solução que na minha solução Python.
Você pode experimentá-lo online: Pyth Compiler / Executor
Por exemplo, a entrada
irá imprimir
Explicação:
fonte
=Y+Y...
?~Y...
Python 2, 84
A lista
l
é a saída até agora. Nós iteramos sobre os elementos. Se a atual for a segunda aparição, iniciaremos uma nova sublist vazia; caso contrário, adicionamos à sublist mais recente. A lista de elementos vistos até agora é armazenadap
. Estranhamente, reconstruir a lista parece mais curto do que cortar a entrada.fonte
Pure bash
1119481 apenas para divisão:
A segunda linha
declare -p c
apenas despeja a variávelAmostra:
Nota: a linha
local b c d i
é necessária apenas para executar a função várias vezes.Para uma apresentação mais sexy (+26)
Renderizará algo como:
fonte
Scala,
122111Pegue a coleção de caracteres, imprima em forma de
[21][][3224567][][0][]
,122111:... ou faça uma coleção de caracteres e retorne listas aninhadas,
135129:Tenho certeza de que há algumas economias que pude obter, não pareci muito.
fonte
Python 220 bytes
O abaixo é de 220 bytes, o que não é ótimo comparado a muitos outros, mas roda rápido o suficiente com números inteiros maiores!
fonte
=
, mudançaxlist
eresult
para nomes mais curtos, e remover os espaços em torno de==
,;
e:
. Se precisar de mais ajuda, basta digitar@NoOneIsHere
(ou qualquer nome de usuário) e eu / o usuário tentarei ajudar.Java: 563 bytes
note que isso usa Java 8, o pré-JDK8 demoraria alguns bytes a mais devido ao foreach.
fonte
Integer.MAX_VALUE
para2147483647
? É o mesmo valor com menos bytes. Além disso,IndexOutOfBoundsException
pode ser encurtado paraException