Para ser justo, isso é baseado em uma pergunta do StackExchange - mas é uma boa pergunta.
O desafio é bastante simples:
- Pegue uma sequência de numerais
- Encontre e imprima o maior número primo contíguo na sequência
Pontuação:
- O menor número de personagens vence.
- Victor provavelmente será um participante do golfscript, mas não vamos defender isso contra eles, porque todos nos divertimos e aprendemos as coisas, certo.
- O vencedor é premiado quando percebo que não marquei o botão verde.
Premissas:
- A string é apenas números
- Se a sequência contiver letras, você poderá ter um comportamento indefinido
- A cadeia contém pelo menos 1 prime
- Se a sequência não contiver 1 número primo válido, você poderá ter um comportamento indefinido
- A velocidade não é uma restrição
- Use um algoritmo principal mais curto do que um mais rápido.
- Se a sua entrada terminar, tudo bem, apenas certifique-se de que seja provável que aconteça antes da morte pelo calor do universo.
- O comprimento da cadeia pode ser assumido com menos de 15 caracteres
Por exemplo:
>> Input: 3571
<< Output: 3571
>> Input: 123
<< Output: 23
>> Input: 1236503
<< Output: 236503
>> Input: 46462
<< Output: 2
>> Input: 4684
<< Output: ValueError: max() arg is an empty sequence
>> Input: 460
<< Output: 0 # Note, zero is not a prime, but the above string has no valid prime
>> Input: 4601
<< Output: 601
>> Input: "12 monkeys is a pretty good movie, but not as good as se7en"
<< Output: ValueError: Fight Club was also good, I find Brad Pitt to be a consistantly good actor.
Possíveis implementações:
- Encontre todas as substrings da entrada, verifique se elas são primárias. - Legostormtroopr (original)
- Encontre todos os números inteiros abaixo da entrada, verifique se estão na entrada e verifique se é primo - Ben Reich
- Pegue uma lista de todos os números primos menores que a entrada, verifique se está na entrada - daniero
Respostas:
GolfScript
40.37.Isso examina todos os números menores ou iguais à entrada, filtra os que são substrings da entrada e depois filtra ainda mais os números primos. Em seguida, é necessário o maior elemento desse tipo (que obviamente garante o maior número de dígitos).
Vamos dividir em duas seções principais:
Esta parte do código é filtrada para todas as seqüências de números inteiros contidas na entrada. Ele usa sotaque grave para transformar números em seqüências de caracteres e, em seguida,
?
para determinar o índice da substring. Como?
retornos-1
no caso de não haver confinamento, aumente usando)
para que a saída seja0
para não substrings, que se comportará bem com a,
filtragem.Essa parte do código é filtrada até os números primos contando o número de fatores menor que o número especificado (um número inteiro é um fator apenas se
number factor %!
for 1. Um número primo terá exatamente 1 fator estritamente menor que ele mesmo, o mesmo acontece1=
.Como os números estão em ordem, pegue o último e limpe a pilha usando
)\;
Obviamente, isso não é tão eficiente quanto possível (uma vez que itera desnecessariamente sobre todos os números inteiros menos que a entrada), mas ainda termina com uma entrada grande como
1236503
relativamente rápida no meu computador (1 minuto).fonte
Python 2.7 - 84
Aqui está uma implementação de referência a ser batida, eu a usei como exemplo de saída na pergunta, portanto, é garantida que funcione * Não é uma garantia real
Melhoria descarada baseada na solução muito melhor de Ben Reich do que a original. Com grande assistência da Volatility
Os encantamentos anteriores da segunda linha incluem:
A versão original - 143
fonte
p
e substitua-onot p(x)
porsum(x%i for i in range(2,x))<1
- ele deve funcionar e reduz a 86 caracteres.sum(x%i for i in range(2,x))
será bastante alto para a maioria dos números. Mas o gerador é uma ótima idéia e eu consegui-lo para 91.all(x%i for i in range(2,x))
.all
e(`x`in`N`)
salvar os Salvas também mais alguns!Ruby 61
Pegue todos os números primos até N e veja se estão na sequência
Eu acho que isso só funciona no Ruby 1.9 e mais recente, mas não tenho certeza.
fonte
Scala (83 caracteres)
Eu não tinha certeza de como fornecer entradas para o programa, então considerei
n
a entrada. Aqui está a solução real (com base na qual o comprimento da solução é avaliado). Abaixo disso, há uma forma executável da solução (que ainda não foi jogada) para execução junto com a saída (para as amostras que o OP possui).Solução:
Solução executável:
Saída de amostra:
Explicação:
Os passos são bem diretos.
entrada -> Encontre todas as substrings -> não primos de filtro -> encontre o valor mais longo
main(Array[String])
: Method fornece entrada de amostra e executa o métodoq(String)
para cada entradaq(String)
: Agrupa a lógica real do programap(String)
para que quaisquer exceções sejam relatadas adequadamente. Ajuda a formatar melhor a saída, porque entradas inválidas vão chegarNumberFormatException
onde, pois a falta de um primo lançará umUnsupportedOperationException
p(String)
: Lógica atual do programa. Vamos dividir a explicação para isso em partesn.inits
: Cria umIterator
para iterar sobre a entrada String (n
)flatMap(f)
: Aplica uma operação noIterator
e empurra o resultado para umList
_.tails.toList.init.map(BigInt(_))
: DivideString
e removeString
s vazios do resultanteList
. Finalmente converte o emString
para oBigInt
qual é equivalente ajava.math.BigInteger
. Por razões de golfe,BigInt
é selecionado (nome mais curto).filter(f)
: sef
retornarfalse
, o valor será removido do resultadoList
_ isProbablePrime 1
: Esta linha poderia ter sido escrita,_.isProbablePrime(1)
mas a representação usada economiza 1 byte. Essa linha realmente verifica se o valor é primo (probabilisticamente; desde quecertainty
esteja definido como1
, o tempo de execução aumenta, mas o sistema garante (mais ou menos) que o número seja primo.max
: Localiza o valor máximo (String
comprimento não baseado. Valor máximo real)fonte
J (
2422)Ler do teclado é realmente mais curto do que definir uma função.
Teste:
Explicação:
1!:1[1
: lê uma linha de texto do teclado".\.\
: a avaliação (".
) de cada sufixo (\.
) de cada prefixo (\
) da sequência.;
: achatar a matriz*1&p:
: multiplique cada valor pelo fato de ser primo ou não (portanto, todos os não primos serão zero)>./
: obtenha o maior valor da listafonte
Haskell, 94
main=getLine>>=print.maximum.filter(\x->and$map((0/=).mod x)[2..x-1]).map read.init.scanr(:)[]
fonte
main = getLine >>= print . maximum . filter isPrime . map read . allNums
é a forma original. ele obtém uma linha e a entrega (>>=
) à grande função combinada - combinada com o.
operador infix, que simplesmente coloca o resultado da função correta na esquerda. coisas como(\x -> ...)
são expressões lambda. os parâmetros de função são aplicados sem parênteses e as funções podem ser parcialmente aplicadas ((0/=)
por exemplo, é uma função que verifica se um número não é 0).allNums = init . scanr (:) []
.scanr
scans e init remove o último valor do resultado do scanr, que é uma string vazia, que não pode ser lida para um número inteiro.map read
lê uma lista de cadeias de caracteres para seus valores destinados. nesse caso, número inteiro ou qualquer outra coisa da classe Type, porqueisPrime
precisa de um número inteiro .filter isPrime
Faça exatamente o que isso diz.isPrime x = and $ map ((0/=). mod x) [2..(x-1)]
significa que, dada uma lista de 2 a (x-1), faça a verificação da divisão e apliqueand
à lista Bool.Perl 6 (40 caracteres, 41 bytes)
Primeira
get
entrada$_
, isso torna a chamada de correspondência regex mais curta.:ex
fornece uma correspondência exaustiva para regex, oferece todas as possibilidades. A hiperoperação+«
(ou+<<
funciona também) criará números dos objetos Match, que são passados paragrep
com&is-prime
sub como seletor. Por fim, pegue o máximo da lista restante e faça a saída.fonte
Mathematica
6747Explicação
O código é uma função pura. Não tem nome. Nele,
#
representa a cadeia de entrada completa.StringCases
pega a entrada, # e verifica as substrings,a
de um caractere ou mais (é por isso que __ foi usado em vez de _) que são primos; O PrimeQ deve retornar True para a substring.Todos os casos favoráveis, ou seja, as substrings que são primos, são retornados por padrão em uma lista.
〚1〛
, ou[[1]]
pega a primeira parte, ou seja, o primeiro elemento dessa lista de números primos.element[[1]]
é uma abreviação dePart[element, 1]
. Se houver mais de um primo, o primeiro será o primer mais longo (StringCases
verifica primeiro os substrings mais longos).Exemplos
fonte
〚1〛
caracteres era sádico para nós, não mathematica, programadores. (sugestão me freneticamente preocupado que eu estou ficando cego, em seguida, olhando para outros suportes com a confusão que eles vejam nitidamente, enquanto este não é!)〚1〛
tem colchetes duplos e é equivalente a[[1]]
. Eu os usei porque um colchete duplo conta como um único caractere.Perl 6 (50 caracteres, 51 bytes)
+«
mapeia seqüências de caracteres para números,max
obtém o maior número,get
recebe uma linha./(.+)<?{(+$0).is-prime}>/
é uma expressão regular que obtém todos os números primos<?{}>
é uma asserção de código.is-prime
éInt
um método de classe que verifica se o número é primo. Eu preciso converter valor para número usando+
, porque éStr
por padrão.:ex
significa que ele tenta encontrar TODAS as correspondências (incluindo as que se sobrepõem a outras). Por causa do bug do Rakudo Perl, atualmente é impossível usarm//
aqui.Isso funciona para qualquer número e, se você removê-lo
max
(ou substituí-lo porsort
), obterá uma lista de todos os números primos do número, para um bônus extra (não que isso dê pontos ou algo assim). Por exemplo (sort
neste caso):fonte