Encontre o número mais suave


59

Seu desafio é encontrar o número mais suave em um determinado intervalo. Em outras palavras, encontre o número cujo maior fator primo é o menor.

Um número suave é aquele cujo maior fator primo é pequeno. Números desse tipo são úteis para o algoritmo de transformação rápida de Fourier, análise de criptografia e outros aplicativos.

Por exemplo, acima do intervalo 5, 6, 7, 8, 9, 10, 8 é o número mais suave, porque o maior fator primo de 8 é 2, enquanto todos os outros números têm um fator primo de 3 ou maior.

Entrada: a entrada será dois números inteiros positivos, que definem um intervalo. O número inteiro mínimo permitido no intervalo é 2. Você pode escolher se o intervalo é inclusivo, exclusivo, semi-exclusivo etc., desde que um intervalo arbitrário possa ser especificado dentro dos limites do seu idioma. Você pode pegar os números via entrada de função, stdin, argumento de linha de comando ou qualquer outro método equivalente para o seu idioma. Nenhuma informação extra de codificação na entrada.

Saída: Retorne, imprima ou equivalente a um ou mais números inteiros no intervalo de entrada que sejam maximamente suaves (mínimo fator máximo). O retorno de vários resultados é opcional, mas se você optar por fazê-lo, os resultados deverão ser claramente delimitados. O formato de saída nativo é adequado para vários resultados.

Por favor, indique na sua resposta como você está recebendo informações e dando resultados.

Pontuação: código de golfe. Contar por caracteres, se escritos em ASCII, ou 8 * bytes / 7, se não estiverem em ASCII.

Casos de teste:

Nota: Esses são intervalos no estilo Python, incluindo o low-end, mas não o high-end. Altere conforme apropriado ao seu programa. Apenas um resultado é necessário.

smooth_range(5,11)
8
smooth_range(9,16)
9, 12
smooth_range(9,17)
16
smooth_range(157, 249)
162, 192, 216, 243
smooth_range(2001, 2014)
2002

Os intervalos especificados como (início, comprimento) e não (início, fim) são aceitáveis?
precisa saber é o seguinte

11
@CodesInChaos Sure. Está coberto pela cláusula "ou o que for".
Isaacg

3
Não vejo sentido em penalizar respostas não-ASCII. Seria mais simples contar apenas bytes em todos os casos.
precisa saber é o seguinte

11
@ nyuszika7h Ascii é significativamente menor que um byte - ele usa apenas 7 bits. Portanto, indico um caractere por 7 bits e dimensiono outros idiomas de acordo. No entanto, se o idioma não for ASCII, mas puder empacotar todos os seus caracteres em 7 bits, não aplicarei a sobretaxa. Veja J / K vs. APL. tl; dr Bytes é mais simples, mas fornece APL et. al. uma vantagem sutil, mas injusta.
Isaacg

3
@isaacg, você está incentivando a criação de pseudo-idiomas usando conjuntos de caracteres menores. se pontuarmos conjuntos de caracteres de 7 bits diferentes dos conjuntos de caracteres de 8 bits, alguém poderá agrupar os idiomas mais modernos em 6 bits (64 caracteres nos dão AZ, 0-9, um punhado de espaço em branco, 20 pontuação e alguns de sobra) .
Sparr

Respostas:


99

CJam - 13

q~,>{mfW=}$0=

Experimente em http://cjam.aditsu.net/

Exemplo de entrada: 2001 2014
Exemplo de saída:2002

Explicação:

q~lê e avalia a entrada, pressionando os 2 números na pilha (digamos min e max) forma
,uma matriz [0 1 ... max-1]
>corta a matriz começando em min, resultando em [min ... max-1]
{…}$classifica a matriz usando o bloco para calcular a chave de classificação
mfobtém uma matriz com todos os fatores primos de um número, para
W=obter o último elemento da matriz (W = -1), obtendo, assim, o maior fator primo a ser usado como chave de classificação
0=obtém o primeiro elemento da matriz (classificada)


38
Bem, acho que é isso.
precisa saber é o seguinte

5
Eu preciso adicionar uma função fatorar ao pyth.
Isaacg

6
Essa linguagem é mágica.
Brobin

8
Isso é o mais próximo possível de puxar alguns HQ9 + s ** t, como pode ser, sem se tornar uma brecha. Impressionante!
Ingo Bürk

25
ヽ(ຈ ل͜ ຈ)ノmfWalguém resolveu em 13 caracteres.
internets é feito de catz

66

Regex ( sabor .NET PCRE), 183 129 bytes

Não tente isto em casa!

Este não é realmente um candidato à vitória. Mas Eric Tressler sugeriu resolver esse problema com nada além de um regex, e eu não pude resistir a tentar. Isso também é possível no PCRE (e ainda mais curto, veja abaixo), mas eu escolhi o .NET porque minha solução precisa de lookbehinds de comprimento arbitrário. Aqui vamos nós:

(?<=^(1+),.*)(?=\1)(?=((11+)(?=.*(?=\3$)(?!(11+?)\4+$))(?=\3+$)|(?!(11+)\5+$)1+))(?!.+(?=\1)(?:(?!\2)|(?=((11+)(?=.*(?=\7$)(?!(11+?)\8+$))(?=\7+$)|(?!(11+)\9+$)1+)).*(?=\2$)(?=\6)))1+

A entrada é codificada como um intervalo incluso separado por vírgula, onde ambos os números são fornecidos em notação unária usando 1s. A partida será o S1s à direita, onde Sé o número mais suave do intervalo. Os laços são quebrados em favor do menor número.

Portanto, o segundo exemplo da pergunta seria a seguinte string (correspondência sublinhada)

111111111,1111111111111111
                 =========

Ele é baseado no regex de verificação primária (até agora bastante conhecido) , cujas variações são incorporadas 6 vezes.

Aqui está uma versão usando espaçamento livre e comentários para quem quer saber o que está acontecendo.

# Note that the beginning of the match we're looking for is somewhere
# in the second part of the input.
(?<=^(1+),.*)          # Pick up the minimum range MIN in group 1
(?=\1)                 # Make sure there are at least MIN 1s ahead

                       # Now there will be N 1s ahead of the cursor
                       # where MIN <= N <= MAX.


(?=(                   # Find the largest prime factor of this number
                       # store it in group 2.
  (11+)                # Capture a potential prime factor P in group 3
  (?=                  # Check that it's prime
    .*(?=\3$)          # Move to a position where there are exactly 
                       # P 1s ahead
    (?!(11+?)\4+$)     # Check that the remaining 1s are not composite
  )
  (?=\3+$)             # Now check that P is a divisor of N.
|                      # This does not work for prime N, so we need a 
                       # separate check
  (?!(11+)\5+$)        # Make sure that N is prime.
  1+                   # Match N
))

(?!                    # Now we need to make sure that here is not 
                       # another (smaller) number M with a smaller 
                       # largest prime factor

  .+                   # Backtrack through all remaining positions
  (?=\1)               # Make sure there are still MIN 1s ahead

  (?:
    (?!\2)             # If M is itself less than P we fail 
                       # unconditionally.
  |                    # Else we compare the largest prime factors.
    (?=(               # This is the same as above, but it puts the
                       # prime factor Q in group 6.
      (11+)
      (?=
        .*(?=\7$)
        (?!(11+?)\8+$)
      )
      (?=\7+$)
    |
      (?!(11+)\9+$)
      1+
    ))
    .*(?=\2$)          # Move to a position where there are exactly 
                       # P 1s ahead
    (?=\6)             # Try to still match Q (which means that Q is
                       # less than P)
  )
)
1+                     # Grab all digits for the match

Você pode testá-lo online aqui . Não tente entradas muito grandes, porém, não dou garantias sobre o desempenho desse monstro.

Editar:

Acabei portando isso para o PCRE (que requer apenas duas etapas) e diminuindo o regex em quase um terço. Aqui está a nova versão:

^(1+),.*?\K(?=\1)(?=((11+)(?=.*(?=\3$)(?!(11+?)\4+$))(?=\3+$)|(?!(11+)\5+$)1+))(?!.+(?=\1)(?:(?!\2)|(?=((?2))).*(?=\2$)(?=\6)))1+

É basicamente o mesmo, com duas alterações:

  • O PCRE não suporta lookbehind de comprimento arbitrário (que eu costumava colocar MINno grupo 1). No entanto, PCREsuporta o \Kque redefine o início da correspondência para a posição atual do cursor. Daí (?<=^(1+),.*)se torna ^(1+),.*?\K, que já salva dois bytes.
  • A economia real vem do recurso de recursão do PCRE. Na verdade, não estou usando recursão, mas você pode usar (?n)para corresponder ao grupo nnovamente, semelhante a uma chamada de sub-rotina. Como o regex original continha o código para encontrar o maior fator primo de um número duas vezes, eu fui capaz de substituir a maior parte do segundo por um simples (?2).

37
Santa Mãe de Deus
Newb

11
@ Timwi Preciso verificar se o maior fator primo (grupo 3ou 7) é realmente primo. Isso requer que exista outra cópia do fator após a primeira captura, o que não seria o caso dos números primos. Enquanto eu trabalho em torno disso no .NET, colocando um olhar para trás em algum lugar para que eu possa voltar um pouco para a verificação, isso não seria possível na versão PCRE mais curta devido à falta de olhar para trás de comprimento variável. Provavelmente é possível diminuir esse pouco, mas não acho que apenas mudar +para o *trabalho.
Martin Ender

2
@MartinEnder Hi! Imagino que você já tenha superado esse desafio, mas acabei de navegar, vi uma solução de regex e não pude deixar de ignorar totalmente seu aviso no início deste post :) Acho difícil aplicar o código de outras pessoas, então, depois de olhar para o seu regex e ficar confuso, tentei do zero e criei: (.*),.*?\K(?=(..+)((?=((?(R)\6|\2))*$).*(?=\4$)(?!(..+)\5+$)))(?!.+(?=\1)(?=(..+)(?3)).*(?!\2)\6).+ 99 bytes no PCRE. Além disso, já deparei com muito do seu trabalho neste site e sou um grande fã: D Ansioso por uma batalha regex no futuro!
Jaytea #

11
Eu estava jogando código-golfe com esse comentário, então vou colocar o adendo aqui: você pode interromper o 4b retirando \4$a sonda e colando-a após a negativa, mas isso afeta severamente o desempenho (todos os subgrupos de dígitos <= \ 4 é verificado quanto à composição em vez de apenas \ 4) e falha em entradas mais longas.
Jaytea #

11
@jaytea Desculpe por demorar uma eternidade para responder a você sobre isso. Como você escreveu a coisa do zero, acho que deveria postar uma resposta separada. Essa é uma pontuação excelente e você merece o crédito por isso. :)
Martin Ender

16

Regex (sabor PCRE), 66 (65🐌) bytes

Inspirado ao ver que Martin Ender e Jaytea , dois gênios do regex, escreveram soluções regex para esse código de golfe, escrevi o meu a partir do zero. O famoso regex de verificação principal não aparece em nenhum lugar da minha solução.

Não leia isso se você não quiser que você estrague uma mágica regex unária. Se você quiser tentar descobrir essa mágica, recomendo começar resolvendo alguns problemas no regex do ECMAScript:

  1. Corresponder números primos (se você ainda não está familiarizado com isso na regex)
  2. Combine potências de 2 (se você ainda não o fez). Ou simplesmente trabalhe no Regex Golf , que inclui Prime e Powers. Certifique-se de executar os conjuntos de problemas Classic e Teukon.
  3. Encontre a maneira mais curta de combinar as potências de N, onde N é alguma constante (ou seja, especificada no regex, não na entrada) que pode ser composta (mas não é necessária). Por exemplo, combine potências de 6.

  4. Encontre uma maneira de combinar os enésimos poderes, em que N é uma constante> = 2. Por exemplo, combine quadrados perfeitos. (Para um aquecimento, combine os poderes principais .)

  5. Corresponder as instruções de multiplicação corretas. Combine números triangulares.

  6. Combine os números de Fibonacci (se você é tão louco quanto eu), ou se quiser ficar com algo mais curto, combine as declarações corretas de exponenciação (para um aquecimento, retorne como o logaritmo na base 2 de uma potência de 2 - bônus, faça o mesmo para qualquer número, arredondando-o como quiser) ou números fatoriais (para um aquecimento, combine os números primários ).

  7. Combine números abundantes (se você é tão louco quanto eu)

  8. Calcule um número irracional com a precisão solicitada (por exemplo, divida a entrada pela raiz quadrada de 2, retornando o resultado arredondado como uma correspondência)

(O mecanismo de regex que escrevi pode ser útil, pois é muito rápido em regexes matemáticas unárias e inclui um modo numérico unário que pode testar intervalos de números naturais (mas também possui um modo de seqüências de caracteres que pode avaliar expressões regulares não unárias ou unárias). Por padrão, ele é compatível com ECMAScript, mas possui extensões opcionais (que podem adicionar seletivamente subconjuntos de PCRE, ou mesmo de visual molecular, algo que nenhum outro mecanismo de expressão regular possui).)

Caso contrário, continue lendo e também leia este GitHub Gist (aviso, muitos spoilers) que narra a jornada de pressionar o regex do ECMAScript para lidar com funções numéricas naturais de dificuldade crescente (começando com o conjunto de quebra-cabeças de teukon, nem todos matemáticos, o que provocou isso viagem).

Assim como as outras soluções regex para esse problema, a entrada é fornecida como dois números em bijetivo unário, separados por vírgula, representando um intervalo inclusivo. Somente um número é retornado. A regex pode ser modificada para retornar todos os números que compartilham o mesmo menor fator primo maior, como correspondências separadas, mas isso exigiria uma aparência de comprimento variável e a colocação \Kde uma lookahead ou a devolução do resultado como uma captura em vez de uma correspondência.

A técnica usada aqui de divisão implícita repetida pelo menor fator primo é idêntica à usada nas seqüências de caracteres Match, cujo comprimento é a quarta resposta de potência que eu postei há um tempo.

Sem mais delongas: ((.+).*),(?!.*(?=\1)(((?=(..+)(\5+$))\6)*)(?!\2)).*(?=\1)\K(?3)\2$

Você pode experimentá-lo aqui.

E a versão de espaço livre, com comentários:

                        # No ^ anchor needed, because this algorithm always returns a
                        # match for valid input (in which the first number is less than
                        # or equal to the second number), and even in /g mode only one
                        # match can be returned. You can add an anchor to make it reject
                        # invalid ranges.

((.+).*),               # \1 = low end of range; \2 = conjectured number that is the
                        # smallest number in the set of the largest prime factor of each
                        # number in the range; note, it is only in subsequent tests that
                        # this is implicitly confined to being prime.
                        # We shall do the rest of our work inside the "high end of range"
                        # number.

(?!                     # Assert that there is no number in the range whose largest prime
                        # factor is smaller than \2.
  .*(?=\1)              # Cycle tail through all numbers in the range, starting with \1.

  (                     # Subroutine (?3):
                        # Find the largest prime factor of tail, and leave it in tail.
                        # It will both be evaluated here as-is, and later as an atomic
                        # subroutine call. As used here, it is not wrapped in an atomic
                        # group. Thus after the return from group 3, backtracking back
                        # into it can increase the value of tail – but this won't mess
                        # with the final result, because only making tail smaller could
                        # change a non-match into a match.

    (                   # Repeatedly divide tail by its smallest prime factor, leaving
                        # only the largest prime factor at the end.

      (?=(..+)(\5+$))   # \6 = tool to make tail = \5 = largest nontrivial factor of
                        # current tail, which is implicitly the result of dividing it
                        # by its smallest prime factor.
      \6                # tail = \5
    )*
  )
  (?!\2)                # matches iff tail < \ 2
)

# now, pick a number in the range whose largest prime factor is \2
.*(?=\1)                # Cycle tail through all numbers in the range, starting with \1.
\K                      # Set us up to return tail as the match.
(?3)                    # tail = largest prime factor of tail
\2$                     # Match iff tail == \2, then return the number whose largest
                        # prime factor is \2 as the match.

O algoritmo pode ser facilmente portado para o ECMAScript substituindo a chamada de sub-rotina por uma cópia da sub-rotina e retornando a correspondência como um grupo de captura em vez de usar \ K. O resultado é 80 bytes de comprimento:

((x+)x*),(?!.*(?=\1)((?=(xx+)(\4+$))\5)*(?!\2)).*(?=\1)(((?=(xx+)(\8+$))\9)*\2$)

Experimente online!

Observe que ((.+).*)pode ser alterado para ((.+)+), reduzindo o tamanho em 1 byte (de 66 a 65 bytes ) sem perda da funcionalidade correta - mas o regex explode exponencialmente em lentidão.

Experimente online! (Versão de desaceleração exponencial ECMAScript de 79 bytes)


11

Python 2, 95

i=input()
for a in range(*i):
 s=a;p=2
 while~-a:b=a%p<1;p+=1-b;a/=p**b
 if p<i:i=p;j=s                                        
print j

Encontra a suavidade dos números por divisão de tentativa até que o número seja 1. iarmazena a menor suavidade até agora, jarmazena o número que deu essa suavidade.

Graças a @xnor pelos campos de golfe.


11
Isso if/elsetem que ser reduzido. Meu primeiro pensamento é b=a%p<1;p+=1-b;a/=p**b. Ou um executivo que executa um dos dois em uma sequência intercalada. Além disso, talvez while~-afuncione.
Xnor

isaacg - Adoro esta resposta! Que maneira brilhante você encontrou para procurar o maior fator primordial! Atualizei minha resposta para emprestar seu método, com crédito para você.
Todd Lehman

Ótima solução! Usando s,p=a,2, i,j=p,s, @ idéias de XNOR, removendo recuo redundante e colocando o bloco enquanto em uma linha produz 95 caracteres. Não sei como você veio acima com 98 ...
Falko

esse código está cheio de emoticons :) :)
Rosenthal

@Falko essas duas alterações não salvam caracteres. 7-> 7.
Isaacg

10

J, 22 20 19 caracteres

({.@/:{:@q:)@(}.i.)

Por exemplo

   2001 ({.@/: {:@q:)@(}. i.) 2014
2002

(Funções com dois argumentos estão infixadas em J.)


Eu também tive uma rachadura, não a peguei tão curta quanto esta resposta. Ainda:(#~ (= <./)@:(i:"1&1)@:*@:(_&q:))@:([ + i.@-~)
ɐɔıʇǝɥʇuʎs

Aqui {:é o mesmo que >./e salva 1 byte.
Aleatório # 8/15

@randomra Você está certo - boa ligação!
FireFly

Bela. TIO se você quiser adicioná-lo: Experimente online!
Jonah

9

Haskell, 96 94 93 86 80 caracteres

x%y|x<2=y|mod x y<1=div x y%y|0<1=x%(y+1)
a#b=snd$minimum$map(\x->(x%2,x))[a..b]

uso via GHCi (um shell Haskell):

>5 # 9
8
>9 # 15
9

EDIT: agora um algoritmo muito mais simples.

esta solução inclui os dois números no intervalo (então 8 # 9e 7 # 8são ambos 8)

explicação:

a função (%) usa dois parâmetros, x e y. quando y é 2, a função retorna a suavidade de x.

o algoritmo daqui é simples - obtenha a lista combinada de todas as suavidades de números na entrada, com cada suavidade armazenando uma referência ao seu número original, classifique para obter o menor e retorne o número referenciado.


aqui está uma versão javascript não-golfada com o mesmo algoritmo:

function smoothness(n,p)
{
    p = p || 2
    if (x == 1)
        return p
    if (x % p == 0)
        return smoothness(x/p, p)
    else
        return smoothness(x,p+1);
}
function smoothnessRange(a, b)
{
    var minSmoothness = smoothness(a);
    var min=a;
    for(var i=a+1;i <= b;i++)
        if(minSmoothness > smoothness(i))
        {
            minSmoothness = smoothness(i)
            min = i
        }
    return min;
}

Seria possível alias mínimo a algo mais curto? Parece que isso salvaria alguns personagens.
Isaacg

Eu tentei, mas por causa da restrição monomorphism ele realmente custa um personagem
haskeller orgulhoso

Você não pode simplesmente fazer m = mínimo? Haskell ainda é um mistério.
Isaacg

11
@isaacg Para ignorar a restrição monomorphism um teria que escreverm l=minimum l
haskeller orgulhoso

2
Eu estava indo para postar uma solução Haskell, até que eu vi seu que bate até a minha versão incompleta ... +1
nyuszika7h

9

Mathematica, 61 45 39 caracteres

Range@##~MinimalBy~Last@*FactorInteger&

Implementação muito direta das especificações como uma função sem nome.

  • Obtenha o intervalo (inclusive).
  • Fatore todos os números inteiros.
  • Encontre o mínimo, classificado pelo maior fator primo.

8

Lua - 166 caracteres

Eu não não tem (ainda!) Reputação suficiente para comentar sobre a solução da AndoDaan , mas aqui estão algumas melhorias em seu código

a,b=io.read("*n","*n")s=b for i=a,b do f={}n=i d=2 while n>1 do while n%d<1 do f[#f+1]=d n=n/d end d=d+1 end p=math.max(unpack(f))if p<s then s=p c=i end end print(c)

Alterar :

  • O n%d==0pelo n%d<1qual é equivalente neste caso
  • Removido um espaço
  • Substituído table.insert(f,d)por f[#f+1]=d ( #fé o número de elementos de f)

Ah, que bom que eu olhei aqui. Ah, os dois primeiros que eu deveria ter verificado e capturado, mas sua terceira melhoria é nova para mim (quero dizer, apenas diferente do que estou acostumado). Isso vai me ajudar muito aqui e ali em golf.shinh.com. Obrigado!
AndoDaan

8

Bash + coreutils, 56 bytes

seq $@|factor|sed 's/:.* / /'|sort -nk2|sed '1s/ .*//;q'

A entrada é proveniente de exatamente dois argumentos de linha de comando (Obrigado @ nyuszika7h !!!). A saída é um resultado singular impresso em STDOUT.

  • seq fornece o intervalo de números, um por linha, a partir dos argumentos da linha de comando.
  • factorlê esses números e gera cada número seguido de dois pontos e a lista classificada de fatores primos desse número. Portanto, o maior fator primordial está no final de cada linha.
  • O primeiro sedremove os dois pontos e todos, exceto o último / maior fator primo, deixando uma lista de cada número (coluna 1) e seu maior fator primo (coluna 2).
  • sort numericamente em ordem crescente pela coluna 2.
  • A final sedcorresponde à linha 1 (número cujo maior fator primo é o menor da lista), remove tudo, inclusive e após o primeiro espaço, e sai. sedimprime automaticamente o resultado dessa substituição antes de sair.

Resultado:

$ ./smooth.sh 9 15
12
$ ./smooth.sh 9 16
16
$ ./smooth.sh 157 249
162
$ ./smooth.sh 2001 2014
2002
$ 

Os intervalos de notas nesse contexto incluem os dois pontos de extremidade.


11
seq $@é 3 bytes mais curto, se você puder assumir que existem apenas dois argumentos.
precisa saber é o seguinte

@ nyuszika7h Boa idéia - obrigado!
Digital Trauma

5

Python 2, 67

f=lambda R,F=1,i=2:[n for n in range(*R)if F**n%n<1]or f(R,F*i,i+1)

Pensar em outro golfe me deu uma idéia de um novo algoritmo para verificar a suavidade, daí a resposta tardia.

A fatoração primária do fatorial i!inclui exatamente os primos, no máximo i. Portanto, se né um produto de primos distintos, sua suavidade (maior fator primo) é a menor ida qual né um divisor de i!. Para explicar os fatores primários repetidos n, podemos usar uma potência suficientemente alta de i!. Em particular, (i!)**nbasta.

O código tenta aumentar fatoriais F=i!, atualizados recursivamente. Nós filtramos os divisores de Fno intervalo de entrada e os produzimos, se houver algum, e passamos para (i+1)!.

Caso de teste:

>> f([157, 249])
[162, 192, 216, 243]

4

C,  149   95

Resposta editada:

Não posso reivindicar crédito por esta solução. Esta resposta atualizada empresta o belo método usado por isaacg em sua solução Python. Eu queria ver se era possível escrevê-lo em C como um aninhado for/ whileloop sem chaves, e é!

R(a,b,n,q,p,m){for(;a<b;m=p<q?a:m,q=p<q?p:q,n=++a,p=2)while(n>1)if(n%p)p++;else n/=p;return m;}

Explicação:

  • Função R(a,b,n,q,p,m)varre a gama ade b-1e retorna o primeiro número mais suave encontrados. Invocação exige a adesão a seguinte forma: R(a,b,a,b,2,0)para que variáveis dentro da função são eficazmente inicializado como se segue: n=a;q=b;p=2;m=0;.

Resposta original :

Esta foi a minha resposta original ...

P(n,f,p){for(;++f<n;)p=p&&n%f;return p;}
G(n,f){for(;--f>1;)if(n%f==0&&P(f,1,1))return f;}
R(a,b,p,n){for(;++p;)for(n=a;n<b;n++)if(G(n,n)==p)return n;}

Explicação:

  • A função P(n,f,p)testa o valor nda primalidade e retorna verdadeiro (diferente de zero) se nfor primo ou falso (zero) se nfor não-primo. fe pambos devem ser passados ​​como 1.
  • A função G(n,f)retorna o maior fator primo de n. fdeve ser passado como n.
  • Função R(a,b,p,n)varre a gama ade b-1e retorna o primeiro número mais suave encontrados. pdeve ser passado como 1. npode ser qualquer valor.

Driver de teste:

test(a,b){printf("smooth_range(%d, %d)\n%d\n",a,b,S(a,b,1,0));}
main(){test(5,11);test(9,16);test(9,17);test(157,249);test(2001,2014);}

Resultado:

smooth_range(5, 11)
8
smooth_range(9, 16)
9
smooth_range(9, 17)
16
smooth_range(157, 249)
162
smooth_range(2001, 2014)
2002

Eu argumentaria que isso não é suficiente na cláusula "Nenhuma informação extra de codificação na entrada".
Alchymist

@ Alchymist - Você pode estar certo ... mas não acho que exista nenhuma informação extra real nos pseudo-argumentos. Pelo menos nenhuma informação que seja algum tipo de pista sobre a resposta.
Todd Lehman

4

Haskell - 120

import Data.List
import Data.Ord
x!y=(minimumBy(comparing(%2)))[x..y]
x%y|x<y=y|x`mod`y==0=(x`div`y)%y|otherwise=x%(y+1)

Exemplo de uso:

> 5 ! 10
8
> 9 ! 15
9
> 9 ! 16
16
> 157 ! 248
162
> 2001 ! 2013
2002

11
Você não poderia usar em <1vez de ==0?
dfeuer 5/03

Sim, isso seria uma boa melhoria. Há muitas pequenas coisas que poderiam ser feitas melhor. Felizmente, esta resposta já faz todos eles: codegolf.stackexchange.com/a/36461
Taylor Fausak

4

Q, 91 caracteres K, 78 caracteres

{(x+{where x=min x}{(-2#{x div 2+(where 0=x mod 2_til x)@0}\[{x>0};x])@0}'[(x)_til y+1])@0}

provavelmente rasparia uma dúzia de caracteres

edit: de fato, tratando o limite superior como não inclusivo desta vez

{*:x+{&:x=min x}{*:-2#{6h$x%2+*:&:x={y*6h$x%y}[x]'[2_!x]}\[{x>0};x]}'[(x)_!y]}

4

Nota: Esta resposta não é permitida.

Esta resposta usa vários recursos do Pyth adicionados após o desafio ter sido solicitado.

Adicionei outro novo recurso, chamando intervalo unário em uma tupla de 2 elementos, que reduz a solução em dois caracteres, para isso:

Pitão , 7

hoePNUQ

A entrada agora é separada por vírgula. O resto é o mesmo.


Esta resposta usa um recurso do Pyth que foi adicionado depois que essa pergunta foi feita, especificamente depois de ver a maravilhosa solução CJam do @ aditsu. Dito isto, eu queria demonstrar o que a adição desse recurso tornou possível. O recurso é P, que é uma função arity-1 que na entrada inteira retorna uma lista de todos os fatores primos da entrada, classificados do menor para o maior.

Pitão , 9

hoePNrQvw

Usa intervalos no estilo Python, nova linha separada em STDIN. Produz a menor solução para STDOUT.

Explicação:

      Q = eval(input())                         Implicit, because Q is present.
h     head(                                     First element of
 o         order_by(                            Sort, using lambda expression as key.
                    lambda N:                   Implicit in o
  e                          end(               Last element of
   PN                            pfact(N)),     List containing all prime factors of N.
  r                 range(                      Python-style range, lower inc, upper exc.
   Q                      Q,                    A variable, initialized as shown above.
   vw                     eval(input()))))      The second entry of the range, same way.

Testes:

$ newline='
'

$ echo "9${newline}16" | ./pyth.py -c 'hoePNrQvw'
9

$ echo "9${newline}17" | ./pyth.py -c 'hoePNrQvw'
16

$ echo "157${newline}249" | ./pyth.py -c 'hoePNrQvw'
162

$ echo "2001${newline}2014" | ./pyth.py -c 'hoePNrQvw'
2002

@ MartinBüttner Yep, como sugerido por seu comentário sobre a solução CJam
Adriweb

@ MartinBüttner Sim, P, é o novo recurso. Vou colocar isso na resposta.
Isaacg

11
Permitido ou não, não apenas eu gosto, mas também acho que essas "macros" curtas são legíveis se você prestar atenção - elas se convertem em Python simples, afinal. Algo precisa ser dito para uma linguagem de golfe que seja boa para o golfe, mas não necessariamente ofuscante.
Kuba Ober

@KubaOber Obrigado, Kuba. Essa sempre foi minha intenção ao escrever Pyth, torná-lo o mais golfe e legível possível. Estou feliz que esteja funcionando.
Isaacg

3

Lua - 176 caracteres

a,b=io.read("*n","*n")s=b for i=a,b do f={}n=i d=2 while n>1 do while n%d==0 do table.insert(f, d)n=n/d end d=d+1 end p=math.max(unpack(f))if p<s then s=p c=i end end print(c)

Eu realmente deveria parar de jogar golfe em Lua. Não há sentido.


14
IMHO, o código de golfe é como o boxe: existem classes de peso. Um determinado idioma pode não ser definitivo, mas é divertido e esclarecedor para o golfe nessa classe / idioma.
Michael Easter

3

Clojure - 173 170 caracteres

Eu sou um novato Clojure. Golfe:

(defn g[x,d](if(and(= 0(mod x d))(.isProbablePrime(biginteger d) 1))d 0))(defn f[i](apply max-key(partial g i)(range 2(inc i))))(defn s[a,b](first(sort-by f(range a b))))

Amostras de execuções:

As faixas incluem extremidade baixa e exclusão de extremidade alta: [a, b) Imprime apenas um dos números mais suaves, se ocorrerem vários.

(println (s 5 11))
(println (s 9 16))
(println (s 9 17))
(println (s 157, 249))
(println (s 2001, 2014))

rendimentos:

bash$ java -jar clojure-1.6.0.jar range.clj
8
9
16
192
2002

Ungolfed:

(defn g [x,d] (if (and (= 0(mod x d)) (.isProbablePrime (biginteger d) 1)) d 0))
(defn f [i] (apply max-key (partial g i) (range 2 (inc i))))
(defn s [a,b] (first (sort-by f (range a b))))

11
Um intervalo que inclui o limite mais baixo e exclui o limite mais alto é geralmente escrito [a, b).
precisa saber é o seguinte

sim, obrigado pela nota
Michael Páscoa

3

Ruby, 65 62

require'prime'
s=->a,b{(a..b).min_by{|x|x.prime_division[-1]}}

Com desculpas a https://codegolf.stackexchange.com/a/36484/6828 , esta é a versão mais simples (e um pouco simplificada) disso. Usa um intervalo inclusivo, pois é um personagem mais curto.

1.9.3-p327 :004 > s[157,249]
 => 192 
1.9.3-p327 :005 > s[5,11]
 => 8 
1.9.3-p327 :006 > s[9,15]
 => 12 
1.9.3-p327 :007 > s[9,16]
 => 16 

E obrigado a YenTheFirst por salvar três caracteres.


11
Você pode realmente fugir sem o [0], pois a comparação de matrizes priorizará o primeiro elemento de qualquer maneira. Isso dará resultados diferentes, mas ainda corretos.
YenTheFirst 20/08/14

3

C # LINQ: 317 303 289 262

using System.Linq;class P{static void Main(string[]a){System.Console.Write(Enumerable.Range(int.Parse(a[0]),int.Parse(a[1])).Select(i=>new{i,F=F(i)}).Aggregate((i,j)=>i.F<j.F?i:j).i);}static int F(int a){int b=1;for(;a>1;)if(a%++b<1)while(a%b<1)a/=b;return b;}}

Ungolfed:

using System.Linq;

class P
{
  static void Main(string[]a)
  {
    System.Console.Write(
      Enumerable.Range(int.Parse(a[0]), int.Parse(a[1])) //create an enumerable of numbers containing our range (start, length)
        .Select(i => new { i, F = F(i) }) //make a sort of key value pair, with the key (i) being the number in question and the value (F) being the lowest prime factor
        .Aggregate((i, j) => i.F < j.F ? i : j).i); //somehow sort the array, I'm still not entirely sure how this works
  }
  static int F(int a)
  {
    int b=1;
    for(;a>1;)
      if(a%++b<1)
        while(a%b<1)
          a/=b;
    return b;
  }
}

Ele pega o início e o comprimento da linha de comando e retornará o maior número suave.

Eu usei respostas daqui e aqui para fazer a minha resposta.

Agradecimentos ao VisualMelon por ajustá-lo e remover 12 bytes! Eu também me livrei dos aparelhos nos 2 bytes se salvando, e o CodeInChaos apontou algumas coisas óbvias que eu perdi (obrigado novamente).


Algumas pequenas coisas de uso geral, você pode economizar 4 bytes Fdefinindo int bao lado de m. Em um par de lugares que você realizar a comparação a%b==0, e ae bsão sempre positivos você pode cortar um byte para cada verificando se é inferior a 1 a%b<1. Você também pode salvar um byte, incrementando bna condição if, a%++b<0e não no for, inicializando-o para 1. Eu também acho que, nesse caso, é mais barato qualificar completamente System.Console.WriteLinee evitar a namespacecláusula.
VisualMelon

@VisualMelon Graças, atualizado com as suas ideias :)
ldam

A m=...:m;coisa cai fora do loop while. Portanto, você pode soltar m=0,e substituir return m;por return m=b>m?b:m;. Então, você pode largar m=...:m;completamente.
tomsmeding

Pode parecer estranho, mas isso é - para mim, menos redutível do que CJam e J. Acho que o C # foi projetado para ser detalhado, e as tentativas de torná-lo menos e torná-lo ilegível? Hmm ....
Kuba Ober

Não, eu concordo, o LINQ parece um demônio quando você o vê aqui e ali e nunca brinca com ele. Depois de entender, é muito legal :) Com isso dito, eu ainda não entendo completamente como Aggregatefunciona, apenas tentei depois de ver em outra resposta para chegar ao meu novo objeto em vez de apenas um campo dentro dele, e ele só passou a funcionar perfeitamente :)
ldam

2

R, 83

library(gmp)
n=a:b
n[which.min(lapply(lapply(lapply(n,factorize),max),as.numeric))]

onde a parte inferior do intervalo de entrada é atribuída ae a parte superior (inclusive) é atribuída b.

gmpé um pacote que está disponível no CRAN. Parecia sujo até que vi essa mffunção absurda no CJam. Instale digitando install.packages("gmp")no console.


11
Se você estiver usando lapplytrês vezes, poderá usar o apelido (por exemplo, l=lapplye depois usar l(...). Da mesma forma, já que factorizeé a única função que você usa do pacote, gmpvocê pode usar em gmp::factorizevez de carregar a biblioteca e usá-la factorize. Seu código se tornaria l=lapply;n=a:b;n[which.min(l(l(l(n,gmp::factorize),max),as.numeric))]69 bytes.
plannapus

2

PowerShell - 85

($args[0]..$args[1]|sort{$d=2
while($_-gt1){while(!($_%$d)){$m=$d;$_/=$d}$d++}$m})[0]

Isso classificará um intervalo de números (inclusive) com base no fator primo máximo de cada número. Retorna o elemento classificado mais baixo.

> smooth 5 10
8
> smooth 9 15
12
> smooth 9 16
16
> smooth 157 248
243
> smooth 2001 2013
2002

2

J - 16 caracteres

Usando o estilo ( início , comprimento ) do intervalo, conforme permitido pelos comentários.

(0{+/:{:@q:@+)i.

Para ser usado como um verbo diádico: o argumento esquerdo é iniciado , o direito é comprimento .

   5 (+)i. 6              NB. range
5 6 7 8 9 10
   5 (q:@+)i. 6           NB. prime factorizations
5 0 0
2 3 0
7 0 0
2 2 2
3 3 0
2 5 0
   5 ({:@q:@+)i. 6        NB. largest prime factors
5 3 7 2 3 5
   5 (+/:{:@q:@+)i. 6     NB. sort range by smallest factors
8 6 9 5 10 7
   5 (0{+/:{:@q:@+)i. 6   NB. take first entry
8
   f=:(0{+/:{:@q:@+)i.    NB. can also be named
   2001 f 13
2002

Uma solução ( início , fim ) tem +2 caracteres e exclui o fim; incluindo o final é +2 a mais. Mas pelo lado positivo, parece muito bom, pois combinamos todos os {chaves}.

(0{}./:{:@q:@}.)i.    NB. excluding
(0{}./:{:@q:@}.)1+i.  NB. including

2

Sério, 8 * 14/7 = 16 (não competitivo)

,x;`yM`M;m@í@E

O Seriously foi criado após esse desafio, mas eu queria postar essa resposta, pois exemplifica o tipo de desafio em que o Seriously é bom.

Experimente online!

Explicação:

,x;`yM`M;m@í@E
,x;             make two copies of range(a,b) (a,b = input())
   `  `M;       make two copies of the result of the map:
    yM            push maximum prime factor
         m@í    push index of minimum element from prime factors
            @E  push element from range with given index

2

Pitão , 7 bytes

.mePbrF

Experimente aqui!

[uma,b)[uma,b]}r

.mePbrF – Full program with arguments a and b.
     rF – Fold by half-inclusive range. Yields the integers in [a, b).
.m      – Values b in that list which give minimal results when applied f.
  ePb   – function / block f. 
   Pb   – Prime factors of b.
  e     – Last element. This is guaranteed to yield the largest, as they're sorted.

1

Cobra - 150

def f(r as vari int)
    x,y=r
    c,o=y,0
    for n in x:y,for m in n:0:-1
        p=1
        for l in 2:m,if m%l<1,p=0
        if n%m<=0<p
            if m<c,c,o=m,n
            break
    print o

Nem mesmo sei por que me incomodei, a cobra simplesmente não pode competir aqui.


11
O Cobra parece idêntico ao python ... Quais são as diferenças?
Beta Decay

@BetaDecay Cobra é o que acontece quando você fornece ao C # a sintaxe do Python. O site Cobra
Οurous

1

Ruby - 113 caracteres

Usando o stdlib. Retorna um resultado. Testado em rubi 2.1.2.

require 'prime'
def smooth_range(a,b)
  (a...b).sort_by{|e|e.prime_division.flat_map{|f,p|[f]*p}.uniq.max}[0]
end

11
Bem-vindo à Programação de quebra-cabeças e troca de código da pilha de golfe. Obrigado por postar seu resultado. Como esta é uma pergunta sobre código-golfe, inclua sua contagem de caracteres em sua resposta. Você pode usar uma ferramenta como esta: javascriptkit.com/script/script2/charcount.shtml
isaacg

1

Perl (5.10+), 83

for(<>..<>){$n=$_;$p=2;$_%$p&&$p++or$_/=$p while$_>1;$m=$p,$r=$n if$p<$m||!$m}
say$r

(a quebra de linha pode ser removida). Toma dois pontos finais de um intervalo inclusivo em duas linhas de stdin (porque <>é mais barato do que acessar ARGV) e gera o resultado mais suave para stdout. Se houver um empate para o mais suave, imprima o menor. Pode imprimir o maior com o custo de um caractere.

O algoritmo é basicamente a maneira de Isaac encontrar o maior fator primo, embora o tenhamos escolhido de forma independente. Essa parte se resume a uma única declaração em perl, o resto tem mais despesas do que eu gostaria.

Deve ser executado sob perl -Eou com um use 5.012preâmbulo. Se você não pode fazer isso, substitua say$rpor print$r,$/.


1

Python 2 (84)

f=lambda n,p=2:n>1and f(n/p**(n%p<1),p+(n%p>0))or p
print min(range(*input()),key=f)

A solução de @ isaacg , mas com uma mintecla de função by no lugar da localização min explícita e uma função recursiva desempenhando o papel da iteração.

Execute no Python sem pilha para evitar limites de recursão.

Parece um desperdício usar a condição parênteses (n%p<1), depois repita sua negação também entre parênteses (n%p>0), mas foi o melhor que obtive. Eu tentei várias coisas, mas elas ficaram piores.

f(n/p**(n%p<1),p+(n%p>0))     # Current for comparison
f(*[n/p,n,p,p+1][n%p>0::2])
n%p and f(n,p+1)or f(n/p,p)
f(*n%p and[n,p+1]or[n/p,p])

Congratulo-me com todas as melhorias que você pode pensar.


1

Java 8 - 422 454 caracteres

Estou aprendendo Java 8 e queria dar uma chance a isso em relação ao Java (ou mesmo aos fluxos Java 8).

Comparado a outros idiomas, este é brutal, mas é um exercício interessante.

Golfe:

import java.util.stream.*;import java.math.*;
class F{int v;int i;public int getV() { return v; }
F(int i){this.i = i;v=IntStream.range(2,i+1).map(j->((i%j==0)&&new BigInteger(""+j).isProbablePrime(1))?j:0).max().getAsInt();}}
public class T{
int s(int a, int b){return IntStream.range(a,b+1).boxed().map(F::new).sorted(java.util.Comparator.comparingInt(F::getV)).collect(java.util.stream.Collectors.toList()).get(0).i;}}

Ungolfed:

import java.util.stream.*;
import java.math.*;

class F {
    int v;
    int i;
    public int getV() { return v; }
    F (int i) { 
        this.i = i;
        v = IntStream.range(2,i+1)
                     .map( j -> ((i%j==0) && 
                           new BigInteger(""+j).isProbablePrime(1))?j:0)
                     .max()
                     .getAsInt();
    }
}

public class T {
    int s(int a, int b) {
        return IntStream.range(a,b+1)
                    .boxed()
                    .map(F::new)
                    .sorted(java.util.Comparator.comparingInt(F::getV))
                    .collect(java.util.stream.Collectors.toList())
                    .get(0).i;
    }
}

exemplo, execute usando:

public static void main(String[] s) {
    System.out.println(new T().s(157,249));
}

192

1

MATL ( não competitivo ), 20 bytes

Esta linguagem foi projetada após o desafio

O alcance é inclusivo nas duas extremidades. Os números são tomados como duas entradas separadas.

2$:t[]w"@YfX>v]4#X<)

Experimente online!

Explicação

2$:          % implicitly input two numbers. Inclusive range
t            % duplicate                      
[]           % empty array
w            % swap elements in stack         
"            % for each                  
  @          %   push loop variable
  Yf         %   prime factors                  
  X>         %   maximum value
  v          %   vertical concatenation         
]            % end for each                         
4#X<         % arg min 
)            % index with this arg min into initial range of numbers

Eu acho que hoje isso seria 17 bytes &:[]y"@YfX>h]&X<)ou talvez 16 :[]y"@YfX>h]&X<). A &verdade era uma grande idéia (e eu estou supondo que ynão estava disponível naquela época?).
Sundar

E parece que a transmissão Yfcom 1 prefixado também seria útil aqui, mas isso provavelmente não é suficiente para decidir que é uma boa ideia em geral. :)
sundar

Sim, este foi o começo, então não you &. Agradeço a Suever pela semântica muito útil desta última (minha idéia inicial foi fazer com que ela significasse "uma entrada a mais que o padrão"). Se virmos mais casos em que Yfadicionar outros seria útil, pode realmente valer a pena adicionar esse recurso. O problema é que, há cerca de 34 respostas que usam Yf(de acordo com o script ), por isso é difícil dizer
Luis Mendo

1

Gelatina , 7 bytes, pontuação = 7 × 7 × 8 = 8, desafio pós-datas no idioma

rÆfṀ$ÐṂ

Experimente online!

Toma os pontos de extremidade inferior e superior como dois argumentos separados. Produz uma lista de todos os números mais suaves do intervalo. (Isso pode ser visto como uma função; nesse caso, a saída é uma lista Jelly, ou como um programa completo; nesse caso, a saída usa a mesma representação de lista que o JSON).

Explicação

Aqueles momentos em que seu programa Jelly é apenas uma tradução literal das especificações…

rÆfṀ$ÐṂ
r        Range from {first argument} to {second argument}
     ÐṂ  Return the elements which have the minimum
   Ṁ$      largest
 Æf          prime factor
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.