Introdução e Crédito
Hoje sem um prelúdio sofisticado: implemente takewhile
.
Uma variação disso (em uma estrutura de dados não trivial) foi uma tarefa no meu curso de programação funcional da universidade. Esta tarefa está encerrada e foi discutida em sala de aula e tenho a permissão do meu professor para publicá-la aqui (perguntei explicitamente).
Especificação
Entrada
A entrada será uma lista (ou o conceito equivalente do seu idioma) de números inteiros positivos.
Saída
A saída deve ser uma lista (ou o conceito equivalente do seu idioma) de números inteiros positivos.
O que fazer?
Sua tarefa é implementar takewhile
(built-ins de idioma são permitidos) com o predicado de que o número em consideração é par (para focar no tempo de espera).
Então, você itera sobre a lista do início ao fim e, enquanto a condição (é par) é mantida, copia para a lista de saída e, assim que atinge um elemento que não torna a condição verdadeira, aborta a operação e a saída (um exemplo passo a passo está abaixo). Essa funcionalidade de ordem superior também é chamada de takeWhile ( takewhile
).
Casos de canto em potencial
A ordem da lista de saída comparada à lista de entrada não pode ser alterada, por exemplo, [14,42,2]
pode não se tornar [42,14]
.
A lista vazia é uma entrada e saída válida.
Quem ganha?
Isso é código-golfe, então a resposta mais curta em bytes vence!
Regras padrão se aplicam, é claro.
Vetores de teste
[14, 42, 2324, 97090, 4080622, 171480372] -> [14, 42, 2324, 97090, 4080622, 171480372]
[42, 14, 42, 2324] -> [42, 14, 42, 2324]
[7,14,42] -> []
[] -> []
[171480372, 13, 14, 42] -> [171480372]
[42, 14, 42, 43, 41, 4080622, 171480372] -> [42, 14, 42]
Exemplo passo a passo
Example Input: [42, 14, 42, 43, 41, 4080622, 171480372]
Consider first element: 42
42 is even (21*2)
Put 42 into output list, output list is now [42]
Consider second element: 14
14 is even (7*2)
Put 14 into output list, output list is now [42,14]
Consider third element: 42
42 is even (21*2)
Put 42 into output list, output list is now [42,14,42]
Consider fourth element: 43
43 is not even (2*21+1)
Drop 43 and return the current output list
return [42,14,42]
fonte
Respostas:
Mathematica, 18 bytes
Outro glorioso built-in que é batido por um fator de 3 por idiomas de golfe sem o built-in ...
fonte
Haskell, 13 bytes
span
divide a lista de entrada em um par de listas imediatamente antes do primeiro elemento em que o predicado (->even
) é falso.fst
pega o primeiro elemento do par.Versão alternativa, 13 bytes:
break
é o oposto despan
, ou seja, divide a lista no primeiro elemento em que o predicado é verdadeiro.Claro que há também
mas isso é 14 bytes.
fonte
MATL , 6 bytes
Experimente online!
Explicação
fonte
to~Y<)
também funciona, mas eu gosto mais deste :-)Hexagonia , 19
Legível:
Experimente online!
Provavelmente isso pode ser jogado com um byte ou dois, mas isso pode exigir um layout realmente engenhoso, que pode ser encontrado com mais facilidade por força bruta (mesmo que demore um pouco para encontrá-lo).
Explicação de alto nível
O programa segue principalmente esse pseudocódigo:
O que abusa de como o Hexagony tenta ler um número quando STDIN está vazio (retorna um zero). Muito obrigado a Martin pela ajuda na criação dessa abordagem.
Explicação completa
Ainda não brinquei com o Mono para executar o fantástico IDE esotérico de Timwi , por isso me apoiei no Martin para me fornecer algumas fotos bonitas e úteis!
Primeiro, uma pequena cartilha sobre o fluxo de controle básico no Hexagony. O primeiro ponteiro de instrução (IP), que é o único usado neste programa, começa no canto superior esquerdo do código-fonte hexagonal e começa a se mover para a direita. Sempre que o IP sai da borda do hexágono, ele se move
side_length - 1
linhas em direção ao meio do hexágono. Como este programa usa um hexágono lateral de três lados, o IP sempre moverá duas linhas quando isso acontecer. A única exceção é se sair da linha do meio, onde se moverá condicionalmente para a parte superior ou inferior do hexágono, dependendo do valor da borda da memória atual.Agora um pouco sobre condicionais. Os únicos condicionais no Hexagony para fluxo de controle são
>
,<
e a borda média do hexágono. Todos eles seguem uma regra constante: se o valor na borda da memória atual for zero ou se o fluxo de controle negativo se mover para a esquerda e se for positivo, o controle fluirá para a direita. Os colchetes maior e menor que o redirecionam o IP em ângulos de sessenta graus, enquanto a borda do hexágono controla para qual linha o IP salta.A Hexagony também possui um modelo de memória especial, onde todos os dados são armazenados nas bordas de uma grade hexagonal infinita. Este programa usa apenas três arestas: uma para armazenar duas, uma para o número atualmente lido e uma para o módulo número dois. Parece algo como:
Não vou explicar cuidadosamente onde estamos na memória em cada ponto durante a explicação do programa; portanto, volte aqui se você ficar confuso com o local em que estamos na memória.
Com tudo isso fora do caminho, a explicação real pode começar. Primeiro, preenchemos a borda "2" na memória com um 2, depois executamos um no-op e movemos o ponteiro da memória para a direita (
2.}
).Em seguida, começamos o loop principal do programa. Lemos o primeiro número de STDIN e, em seguida, atingimos um condicional (
?<
). Se não houver mais números no STDIN, isso indica um zero na borda da memória atual; portanto, vire à esquerda na@
, que encerra o programa. Caso contrário, saltamos de um espelho, movemos o ponteiro de memória para trás e para a esquerda, envolvemos o hexágono para calcular o restante da divisão da entrada por 2 e, em seguida, atingimos outra condição (/"%>
).Se o restante for um (ou seja, o número era ímpar), viramos à direita seguindo o caminho azul acima, iniciando novamente o no-op, depois envolvemos a parte inferior do hexágono, multiplicamos a aresta atual por 10 e adicionamos oito, rebate alguns espelhos, faça a mesma multiplicação e adição novamente, colocando 188 na borda atual, voltando para o topo do hexágono, executando o no-op novamente e finalmente encerrando o programa (
.8/\8.@
). Esse resultado complicado foi um acidente feliz, eu originalmente havia escrito um pouco mais lógico da lógica, mas percebi que podia removê-lo em favor do no-op, que eu achava mais no espírito da Hexagony.Se o restante for zero, vire à esquerda seguindo o caminho vermelho acima. Isso faz com que movamos o ponteiro da memória para a esquerda e imprima o valor lá (o valor de entrada) como um número. O espelho que encontramos age como não operacional por causa da direção que estamos seguindo ( ). Como 77 é positivo, movemos para a direita na parte inferior do hexágono e, por causa do trampolim, pulamos a primeira instrução ( ). Em seguida, multiplicamos a borda da memória atual por 10 e adicionamos 8, obtendo 778. Em seguida, emitimos esse valor mod 256 (10) como um caractere ASCII, que passa a ser uma nova linha. Finalmente, saímos do hexágono e retornamos ao primeiro, que substitui o 778 pelo próximo valor de entrada.
{/!
). Em seguida, atingimos a borda do hexágono, que age condicional com apenas um resultado, já que o valor de entrada de antes já foi testado como positivo, então sempre avançamos para a direita (se você se imaginar voltado para a IP) . Em seguida, multiplicamos a entrada por 10 e adicionamos duas, apenas para mudar de direção, envolver e exagerar o novo valor com o valor ASCII da letra maiúscula M, 77. Em seguida, atingimos alguns espelhos e saímos pela borda do meio da tela. o hexágono com um trampolim (2<M\>$
!
?
fonte
Pitão,
1397 bytesCréditos para @FryAmTheEggman por 2 (bastante complicados) bytes!
Explicação:
Teste aqui .
fonte
G
s introduzidos, um para a condiçãos%R2G
e outro como argumento para a funçãoP
.Gelatina , 5 bytes
Experimente online! ou verifique todos os casos de teste .
Como funciona
fonte
Python 2,
4342 bytesA função modifica seu argumento no lugar .
Obrigado ao @xnor por jogar um byte de uma maneira realmente inteligente!
Teste em Ideone .
fonte
"1'"in`map(bin,x)`
para Python 2.ed, 13
Como programadores reais usam o Editor de texto padrão .
Recebe a entrada como um número inteiro em cada linha; saídas no mesmo formato.
Isso simplesmente localiza o primeiro número ímpar (número que termina em um dígito ímpar) e exclui essa linha até o final do arquivo.
fonte
Clojure, 21 bytes
Clojure está quase competindo finalmente! (graças à tarefa ser incorporada) Veja-o on-line https://ideone.com/BEKmez
fonte
Python,
4544 bytesTeste em Ideone .
fonte
R, 25 bytes
Ou equivalente
fonte
05AB1E,
87 bytesExplicação
Experimente online
Solução anterior de 8 bytes
Explicação
Experimente online
fonte
Brainf ***, 263 bytes
Peguei um pequeno trecho daqui
Eu daria uma explicação, mas mesmo eu não tenho idéia de como isso funciona mais.
Espera entrada como números separados por espaço (por exemplo
2 432 1
)fonte
+
e>
usar alguma lógica?>
mais eficientes, mas não as entendo o suficiente agoraPitão, 7 bytes
Experimente aqui!
O que eu tentei fazer no Pyke, mas o índice está quebrado nesse atm
fonte
Raquete, 22 bytes
o
λ
caractere é contado como 2 bytes.Eu nunca vi o Racket usado antes em nenhuma das respostas de código de golfe que eu vi, então tive que fazer isso pelo menos uma vez!
fonte
Labirinto , 14 bytes
Entrada e saída são listas separadas por avanço de linha (embora, em princípio, a entrada possa usar qualquer separador que não seja um dígito).
Experimente online!
Este é provavelmente o programa de labirinto mais compacto que já escrevi.
Curiosamente,
takewhile(odd)
é muito mais simples:Explicação
A cartilha usual do labirinto:
?
neste caso), movendo-se para leste.O fluxo principal do programa é um loop único ao redor do perímetro:
Por acaso, sabemos que o topo da pilha é zero depois
!
e,"
portanto, é garantido que o IP não volte para o centro.`
e,%
por outro lado, são usados como condicionais nos quais o IP pode se mover em direção ao centro, de modo que@
encerre o programa, ou pode continuar se movendo pelo perímetro.Vamos dar uma olhada no código no loop:
E então o loop recomeça.
Isso levanta a questão de por que
takewhile(odd)
é muito mais simples. Há duas razões:0
(que é par), não precisamos de uma verificação EOF separada. A lista seria cortada nesse ponto de qualquer maneira.N % 2
is0
(em oposição a1
), o que significa que, em vez do fluxo de controle condicional, podemos simplesmente dividir a outra cópiaN
porN % 2
: se a entrada é ímpar, isso simplesmente saiN
e até nos livramos daN % 2
(então não fazemos ' Não é necessário;
), mas se a entrada for par, isso simplesmente encerra o programa com um erro (silencioso) de divisão por zero.Portanto, o outro código é um loop simples que não permite nenhuma ramificação.
fonte
Braquilog ,
1916 bytesExplicação
Hoje eu aprendi um truque interessante (que foi usado na resposta de 19 bytes):
~b.hH
é mais curto do:[H]rc.
que acrescentar um elemento no início de uma lista. O primeiro significa "Saída é o resultado com um item extra no início, e o primeiro item da Saída éH
" , enquanto o outro é diretamente "Saída é a concatenação de[[H], Result]
".fonte
J, 10 bytes
Explicação
fonte
1{.2&|<;._2]
é interessante (embora mais longo) #$
vez de{.
Python, 41 bytes
Trunca
l
até o índice da primeira ocorrência de um número ímpar. O índice é encontrado procurando um1
no módulo de valores2
. Para evitar que nenhum número ímpar seja encontrado, a1
é colocado no final.fonte
C #, 50 bytes
fonte
a=>a.TakeWhile(x=>x%2<1);
CJam , 11 bytes
Graças a @Dennis por duas correções e um byte de folga!
Este é um bloco de código (equivalente a uma função; permitido por padrão) que espera a matriz de entrada na pilha e deixa a matriz de saída na pilha.
Experimente online!
Explicação
fonte
Retina , 17 bytes
O avanço de linha à direita é significativo. Entrada e saída são listas separadas por espaço.
Experimente online!
Esta é uma substituição simples de regex, corresponde ao primeiro número ímpar (ou seja, um número que termina em um dígito ímpar) e, se possível, o espaço que o precede, bem como tudo o que está a seguir, e o substitui por uma sequência vazia, ou seja, todos os elementos de lá em diante são removidos da entrada.
Como Leaky Nun aponta, pegando a lista em binário, podemos economizar 6 bytes, mas parece um pouco barato, então provavelmente continuarei contando a versão decimal:
fonte
JavaScript (Firefox 30-57), 30 bytes
fonte
V , 13 bytes
Experimente online!
Explicação:
Convenientemente, o mesmo código funciona para verificar todos os casos de teste simultaneamente.
fonte
Dyalog APL , 11 bytes
2|
divisão restante da divisão com 2~
negar∧\
AND-scan (desativa desde o primeiro 0)/⍨
selecione ondefonte
Ruby, 25 bytes
Acho que perco ...
fonte
->a{a.take_while &:even?}
ou pelo menos->a{a.take_while(&:even?)}
?Pyke, 8 bytes
Intérprete corrigido, use outros links
Utiliza o método de Dennis, exceto que minha função split_at inclui a alteração - provavelmente um bug
Ou com correção de bug, 7 bytes
Experimente aqui!
Ou após o segundo bugfix, 6 bytes
Experimente aqui!
Explicação:
fonte
GolfScript, 11 bytes
Este é um programa completo do GolfScript que lê uma matriz GolfScript com string (por exemplo
[28 14 7 0]
) e imprime a mesma matriz com o primeiro elemento ímpar e tudo depois de removido:Experimente online. (Também: versão estendida com equipamento de teste. )
Versão descolada com comentários:
Esta solução é baseada no
{ },
operador de filtro GolfScript , que executa o conteúdo do bloco de código em cada elemento de uma matriz e seleciona os elementos da matriz para os quais o código no bloco retorna um valor verdadeiro (ou seja, não zero) em topo da pilha.Assim, por exemplo,
{1&},
selecionaria todos os números ímpares em uma matriz e{~1&},
selecionaria todos os números pares. O desafio, então, é criar um filtro que selecione números pares até encontrar o primeiro número ímpar e, a partir de então, nenhum número.A solução que usei é substituir a máscara de bits constante
1
(usada para extrair o bit mais baixo de cada número de entrada) por uma variável na pilha que armazena o resultado (0 ou 1) da iteração anterior do loop de filtro (e é inicializada para 1 antes do loop). Assim, assim que o filtro retornar 0 uma vez, a máscara de bit também será definida como 0, impedindo que o filtro retorne 1 novamente.fonte
Quarto, 114 bytes
Quarto realmente não tem listas. Os parâmetros devem ser empurrados para a pilha na ordem inversa, como é típico em Forth. O resultado será deixado na pilha na mesma ordem. Por algum motivo, isso não funciona no Ideone, mas funciona no repl. A nova linha é necessária para remover a ambiguidade de algum tipo?
Experimente online
Ungolfed, com comentários:
Este programa (minha tentativa anterior) imprime os resultados até atingir um número ímpar. Tudo o que resta (não tirado) será deixado na pilha.
Falha se apenas números inteiros
fonte
Befunge, 35 bytes
Este código lida com números entre 0 e 65535
Formato de entrada :
Aqui está uma versão que exibe os valores no final do processo:
Você pode testar o código aqui , mas precisará adicionar uma linha à direita com espaços à direita, pois esta interpretação especifica:
Não sei se isso é aceitável, pois não contei esse resultado na contagem de bytes
: parece que, como estou armazenando número no código, o intérprete não permitirá que esse programa seja executado duas vezes na correta maneira. Você terá que recarregá-lo.
Como é que isso funciona: O intérprete segue as setas e pula uma instrução ao cruzar '#'
Pontos cinza são testados e a linha vermelha remove variáveis desnecessárias da pilha
Usando o aqui no intérprete acima, os valores salvos são exibidos no código usando suas representações (não sei o formato). Sim, o Befunge é uma linguagem bastante reflexiva
fonte