Encontre o menor número que não divide N


50

Este desafio é suficiente simples que é basicamente tudo no título: você é dado um número inteiro positivo N e você deve retornar o menor inteiro positivo que não é um divisor de N .

Um exemplo: os divisores de N = 24 são 1, 2, 3, 4, 6, 8, 12, 24. O menor número inteiro positivo que não está nessa lista é 5 , então esse é o resultado que sua solução deve encontrar.

Esta é a sequência OEIS A007978 .

Regras

Você pode escrever um programa ou uma função e usar qualquer um dos nossos métodos padrão de recebimento de entrada e saída.

Você pode usar qualquer linguagem de programação , mas observe que essas brechas são proibidas por padrão.

Isso é , então a resposta mais curta e válida - medida em bytes - vence.

Casos de teste

Os 100 primeiros termos são:

2, 3, 2, 3, 2, 4, 2, 3, 2, 3, 2, 5, 2, 3, 2, 3, 2, 4, 2, 3, 2, 3, 2, 5, 2, 
3, 2, 3, 2, 4, 2, 3, 2, 3, 2, 5, 2, 3, 2, 3, 2, 4, 2, 3, 2, 3, 2, 5, 2, 3, 
2, 3, 2, 4, 2, 3, 2, 3, 2, 7, 2, 3, 2, 3, 2, 4, 2, 3, 2, 3, 2, 5, 2, 3, 2, 
3, 2, 4, 2, 3, 2, 3, 2, 5, 2, 3, 2, 3, 2, 4, 2, 3, 2, 3, 2, 5, 2, 3, 2, 3

Em particular, verifique se sua resposta funciona para as entradas 1 e 2; nesse caso, o resultado é maior que a entrada.

E para alguns casos de teste maiores:

N          f(N)
1234567    2
12252240   19
232792560  23

Transformei a sequência de saída de amostra em um vetor de números e percebi que se você a formatar com 24 colunas, é extremamente repetitiva, exceto pelo desvio ímpar.
Carcigenicate

Isso faz sentido, 24 é 0 mod 2, 3 e 4, portanto, as únicas diferenças estariam nas colunas em que os números são> 4. É ainda mais repetitivo na largura 120.
CalculatorFeline

Respostas:


18

Mathematica, 19 bytes (codificação UTF-8)

1//.x_/;x∣#:>x+1&

Função sem nome, usando um argumento inteiro diferente de zero e retornando um número inteiro positivo. A barra vertical na metade do caminho é, na verdade, o caractere de três bytes U + 2223, que denota a relação de divisibilidade no Mathematica. Explicação:

1                   Starting with 1,
 //.                apply the following rule until it stops mattering:
    x_                if you see a number x
      /;x∣#           such that x divides the function argument,
           :>x+1      replace it with x+1.
                &   Cool, that's a function.

Editado para adicionar: ngenisis indica que //., por padrão, itera no máximo 65536 vezes. Portanto, essa implementação funciona para todos os números de entrada menores que o múltiplo menos comum dos números inteiros, de 1 a 65538 (em particular, em todos os números com no máximo 28436 dígitos), mas tecnicamente não para todos os números. Pode-se substituir x//.ypor ReplaceRepeated[x,y,MaxIterations->∞]para corrigir essa falha, mas obviamente ao custo de 34 bytes adicionais.


Maneira muito interessante para fazer um loop sem usar For, Whileetc
ngenisis

5
Eu aprendi com este site! Definitivamente, estou gostando de aprender mais sobre o Mathematica por estar aqui (posso justificar isso no meu quadro de horários ...?).
Greg Martin

3
Isso não parece mathematica O_o
Mama Fun Roll

2
não deixe que a falta de letras maiúsculas e suportes enganar ya;)
Greg Martin


14

Pitão, 3 bytes

f%Q

Basicamente, faz um floop do código até que %QT( Q % Tonde Testá a variável de iteração) seja verdadeira.

Experimente online aqui.


2
Viu o problema, fez esta resposta, veio aqui para postá-lo, encontrou o seu. Bem feito!
Isaacg

Eu escrevi isso e me senti incrível sobre mim: .V1In%Qb0bBvi sua resposta e não me sinto mais tão incrível.
John Red

@JohnRed Lol, acho que você só precisa se familiarizar com os built-ins em Pyth.
precisa saber é

14

JavaScript (ES6), 25 23 bytes

f=(n,k)=>n%k?k:f(n,-~k)

Nota: Uma coisa interessante aqui é que o kparâmetro é inicializado ex nihilo na primeira iteração. Isso funciona porque n % undefinedé NaN(falso conforme o esperado) e -~undefinedé igual 1. Nas próximas iterações, -~ké essencialmente equivalente a k+1.

Teste


Exatamente o que eu consegui. Eu ficaria surpreso se alguma coisa mais curto possível
ETHproductions

@ETHproductions Pensando bem, há uma mais curta. :-)
Arnauld

5
Hum. Isso é ... uau.
ETHproductions

13

Python, 43 36 35 bytes

f=lambda n,d=2:d*(n%d>0)or f(n,d+1)


11

R, 28 bytes

Bem direto, nada extravagante. Pega a entrada de stdin, incrementa o valor Taté que o imódulo Tseja diferente de zero.

i=scan()
while(!i%%T)T=T+1
T

Se você quiser algo um pouco mais sofisticado, há o seguinte para 29 bytes :

i=scan()
match(0,!i%%1:(i+1))

Explicado:

i=scan(): Leia ide stdin.

1:(i+1): Gere todos os números inteiros de 1até i+1(a +1contabilização dos casos de 1e 2).

i%%1:(i+1) : Module a entrada de cada número em nossa lista.

!i%%1:(i+1): Negue a lista resultante; isso implicitamente o converte em um tipo lógico, tal que 0é FALSEe diferente de zero TRUE. Depois de negar, os TRUEvalores se tornam FALSEe vice-versa. Agora, todos os valores originalmente diferentes de zero são codificados como FALSE.

match(0,!i%%1:(i+1)): Retorna o índice da primeira instância de 0em nossa lista. 0é FALSE, portanto, isso retorna o índice do primeiro FALSEda lista, que é o primeiro valor diferente de zero da operação do módulo. Desde que nossa lista original começou em 1, o índice é igual ao valor do menor não divisor.


Bom, só queria sugerir o uso which.min, mas depois vi a edição e parece que matchfaz um trabalho semelhante.
JAD

2
Além disso, bom truque usando T, economizando a necessidade de defini-lo antes do whileloop.
JAD

@JarkoDubbeldam Thanks! Não consigo encontrar uma maneira de a abordagem vetorizada ser mais curta que a whileabordagem, o que é bom, pois consome muita memória para N. grande. O Ttruque é um daqueles truques que são ótimos para o golfe, mas absolutamente horríveis para a programação real. (E, claro, você pode usar Ftambém quando você precisa de um 0.)
rturnbull

Você pode salvar dois bytes usando 0: i + 1 em vez de 1: (i + 1), embora não tenha certeza de como ele é executado com o operador %%.
Antoine-sac

@ antoine-sac Infelizmente, %%tem precedência sobre +, então parens ainda são necessários:, (0:i+1)com o mesmo número de bytes que 1:(i+1). Na verdade, eu tinha o primeiro originalmente, mas mudei para o último, pois é mais fácil de ler.
rturnbull

10

Haskell, 26 bytes

f n=until((>0).mod n)(+1)1

Todo mundo esquece until!


9

Braquilog , 10 bytes

~{=#>:A'*}

Experimente online!

Isso saiu muito semelhante à (mas menor que) a solução original da Fatalize. Desde então, o Fatalize mudou para um algoritmo diferente que se vincula a este por meio de um método diferente, então terei que explicar eu mesmo:

~{=#>:A'*}
~{       }    inverse of the following function:
  =           try possible values for the input, if it's unbound
   #>         the input is a positive integer
     :A'*     there is no A for which the input times A is the output

Quando invertemos a função, trocando "input" e "output", obtemos um algoritmo razoavelmente razoável (apenas expresso de uma maneira estranha): "tente possíveis números inteiros positivos, em sua ordem natural (ou seja, 1 para cima), até encontrar um que não pode ser multiplicado por nada para produzir a entrada ". O Brachylog não faz cálculos de ponto flutuante, a menos que todas as entradas sejam conhecidas, portanto, ele considera apenas o número A.


11
Nunca pensei em fazer isso, isso é legal!
Fatalize


8

VACA, 174 bytes

oomMOOMMMmoOmoOmoOMMMmOomOoMoOMMMmoOmoOmoOMMMmOoMOOmoO
MOomoOMoOmOoMOOmoOmoomoOMOOmOoMoOmoOMOomoomOomOoMOOmOo
moomoOMOomoomoOmoOMOOmOomOomOomOoOOMOOOMOomOOmoomOomOo
mOomOomOomoo

Experimente online!

Esse código é apenas parcialmente meu - implementa um algoritmo de módulo que eu carregava do cérebro. O restante do código é meu. No entanto, como não escrevi o algoritmo de módulo, não investiguei verdadeiramente como ele funciona e não posso documentar essa parte do código. Em vez disso, darei meu detalhamento habitual, seguido de uma explicação mais aprofundada sobre por que o código funciona.

Repartição do código

oom                          ;Read input into [0].
MOO                          ;Loop while [0].  We never change [0], so the program only terminates forcibly after a print.
  MMMmoOmoOmoOMMMmOomOo      ; Copy [0] to [3] and navigate to [1].
  MoOMMMmoOmoOmoOMMM         ; Increment [1], and copy it to [4]
  mOo                        ; Navigate back to [3].
  MOO                        ; Modulus algorithm.  Direct port of brainfuck algorithm.
    moOMOomoOMoOmOo
    MOO
      moO
    moo
    moO
    MOO
      mOoMoOmoOMOo
    moo
    mOomOo
    MOO
      mOo
    moo
    moOMOo
  moo                        ; End modulus algorithm.
  moOmoO                     ; Navigate to [5].  This contains our modulus.
  MOO                        ; Only perform these operations if [5] is non-zero -- i.e. [0] % [1] != 0
    mOomOomOomOoOOMOOOMOomOO ;  Navigate to [1], print its contents, then error out.
  moo                        ; End condition
  mOomOomOomOomOo            ; Since we're still running, [0] % [1] == 0, so navigate back to [0] and try again.
moo                          ;End main loop.

Explicação

O código primeiro lê o número inteiro em [0]. Cada iteração do loop principal (linhas 2 a 26) é incrementada [1] e, em seguida, copia tudo o que é necessário para o algoritmo de módulo, que expõe seu resultado em [5]. Se [5] contiver algum valor, [1] será o número que precisamos imprimir. Nós o imprimimos e, em seguida, forçamos o encerramento do programa.

Como o COW é um derivado do cérebro, ele funciona relativamente semelhante ao modo como o cérebro funciona - faixa infinita de fita, você pode mover para a esquerda ou direita, aumentar ou diminuir e "girar" enquanto o valor atual da fita é diferente de zero. Além do brainfuck, o COW vem com alguns recursos úteis.

(0) moo -- Equivalent to ]
(1) mOo -- Equivalent to <
(2) moO -- Equivalent to >
(3) mOO -- No equivalent.  Evaluate current tape value as instruction from this list.
(4) Moo -- If tape is 0, equivalent to ,; if tape is non-zero, equivalent to .
(5) MOo -- Equivalent to -
(6) MoO -- Equivalent to +
(7) MOO -- Equivalent to [
(8) OOO -- No equivalent.  Set tape (positive or negative) to 0
(9) MMM -- No equivalent.  If register is empty, copy tape to register.  If register is non-empty, paste register to tape and clear register.
(10) OOM -- No equivalent.  Print an integer from tape to STDOUT
(11) oom -- No equivalent.  Read an integer from STDIN and store it on tape

O verdadeiro ponto de interesse aqui é a instrução 3 mOO,. O intérprete lê o valor atual da fita e executa uma instrução com base nesse valor. Se o valor for menor que 0, maior que 11 ou igual a 3, o intérprete encerrará o programa. Podemos usar isso como uma força rápida e suja para sair do loop principal (e do programa inteiramente) depois de encontrarmos nosso não-divisor. Tudo o que precisamos fazer é imprimir nosso número, limpar [1] (com OOO), diminuí-lo para -1 com MOoe executar a instrução -1 através da mOOqual termina o programa.

A própria fita para este programa funciona da seguinte maneira:

[0]  -- Read-in integer from STDIN.
[1]  -- Current divisor to test
[2]  -- Placeholder for modulus algorithm
[3]  -- Temporary copy of [0] for use for modulus algorithm
[4]  -- Temporary copy of [1] for use for modulus algorithm
[5]  -- Placeholder for modulus algorithm.  Location of remainder at end of loop.
[6]  -- Placeholder for modulus algorithm
[7]  -- Placeholder for modulus algorithm

O algoritmo do módulo limpa naturalmente [2], [3], [6] e [7] no final da operação. O conteúdo de [4] é sobrescrito com a pasta de registro na linha 4 e [5] é zero quando [0] é divisível por [1], portanto não precisamos limpá-lo. Se [5] for diferente de zero, forçamos o encerramento na linha 23 para não precisarmos nos preocupar com isso.


7

05AB1E , 7 bytes

Xµ¹NÖ_½

Experimente online!

Explicação

Xµ       # run until counter is 1
  ¹      # push input
   N     # push iteration counter
    Ö_   # push input % iteration counter != 0
      ½  # if true, increase counter
         # output last iteration

Bom, eu queria saber como você faria isso iterativamente em 05AB1E.
Magic Octopus Urn

7

Gelatina , 5 bytes

1%@#Ḣ

Experimente online!

Explicação:

1%@#Ḣ
1  #      Find the first … numbers, counting up from 1, such that
 %@       dividing those numbers into … gives a truthy remainder
    Ḣ     then return the first

Este é um abuso horrendo de #; Existem muitos operadores neste programa, mas há muitos operandos ausentes. #realmente quer 1que seja dado explicitamente por algum motivo (caso contrário, ele tenta usar como padrão a entrada); no entanto, tudo o mais que não está especificado no programa é padronizado para a entrada do programa. (Então, por exemplo, se você fornecer 24 como entrada, este programa encontrará os primeiros 24 números que não dividem 24 e depois retorna o primeiro; meio desperdício, mas funciona.)


Maldita geléia! Pitão vence você hoje! : D
John Red

Somente ASCII:2%@1#
Erik the Outgolfer

7

C, 32 bytes 35

i;f(x){for(i=1;x%++i<1;);return i;}

Editar: adicionado i=1no loop

Uso

main(c,v)char**v;{printf("%d",f(atoi(*++v)));}

Versão completa do programa, 64 bytes:

main(c,v)char**v;{*++v;for(c=1;atoi(*v)%++c<1;);printf("%d",c);}

6

C #, 39 37 bytes

n=>{int i=0;while(n%++i<1);return i;}

Economizou dois bytes graças a Martin!


Eu gosto de while (! (N% ++ i)); melhor, mas é claro, isso é código de golfe e 1 byte é 1 byte.
John Hamilton

Isso funciona? Eu não sabia que a 0 avaliado como false automaticamente
Alfie Goodacre

Ah, eu tentei em C ++, sim, não funciona com C #.
John Hamilton

6

Perl, 19 bytes

18 bytes de código + -psinalizador.

$_=$_%++$.?$.:redo

Para executá-lo:

perl -pE '$_=$_%++$.?$.:redo' <<< 12252240

Explicações não muito detalhadas :
- $.é uma variável especial cujo valor padrão é o número da linha atual do último manipulador de arquivos acessado (stdin aqui); portanto, depois de ler a primeira linha de entrada, ele é definido como 1.
- $_mantém a entrada e é impresso implicitamente no final (graças à -pbandeira).
- redo(nesse contexto) considera que o programa está em loop e refaz a iteração atual (somente $.será diferente desde que tenha sido incrementada).
- Então, se encontrarmos o menor número (armazenado em $.) que não se divide $_, então o definiremos $_, caso contrário, tentaremos o próximo número (graças a redo).


6

Oitava / MATLAB, 26 24 bytes

@(n)find(mod(n,1:n+1),1)

find(...,1)retorna o índice ( 1com base) do primeiro elemento diferente de zero do vetor no primeiro argumento. O primeiro argumento é [n mod 1, n mod 2, n mod 3, n mod 4,...,n mod (n+1)]Isso significa que precisamos adicionar +1ao índice, pois começamos a testar em 1. Obrigado @ Giuseppe por -2 bytes.

Experimente online!


@(n)find(mod(n,1:n+1),1)é mais curto, não é?
Giuseppe

de fato, obrigado!
flawr

5

Gelatina , 6 bytes

%R;‘TḢ

Experimente online!

Explicação:

                                               Assume 24 is our N
 R      Generate all numbers from 1 to N         [1, 2, 3, 4 .., 24]
  ;‘    Attach N+1 to that list (for cases 1,2)  [1, 2, 3, 4 .., 25]
%       And modulo-divide our input by it
        Yields a list with the remainder         [0, 0, 0, 0, 4 ...]
    T   Return all thruthy indexes               [5, 7, ...]
     Ḣ  Takes the first element of that list -->  5

Não conheço Jelly, mas você poderia salvar um byte aumentando N antes de gerar o intervalo?
Emigna

@ Emigna Também não conheço Jelly;) Não vejo como: incrementá-lo anteriormente também faz o teste do módulo contra N + 1 ou aumenta os demais [1, 1, 1, 1, 5, ...].
steenbergh

Ah entendo. Eu pensei que seria possível fazer o intervalo de N% (1, N + 1), mas se aumentar o N em ambos os casos, isso não é bom.
Emigna

5

Perl 6 , 17 bytes

{first $_%*,1..*}

Tente

Expandido:

{  # bare block lambda with implicit parameter 「$_」

  # return the first value
  first

  # where the block's argument 「$_」 modulus the current value 「*」
  # doesn't return 0 ( WhateverCode lambda )
  $_ % *,
  # ( 「$_ !%% *」 would be the right way to write it )

  # from 1 to Whatever
  1 .. *
}

5

05AB1E , 6 bytes

ÌL¹ÑK¬

Experimente online!

Além disso, soletra "LINK!" ... Meio ...

ÌL     # Push [1..n+2]
  ¹Ñ   # Push divisors of n.
    K¬ # Push a without characters of b, and take first item.

O @ Zgarb perdeu essa parte, o incremento inicial de 2 corrige o problema.
Magic Octopus Urn

11
Agradável! Eu sempre esqueço que 05ab1e tem uma função de divisor :)
Emigna

5

Gelatina , 5 bytes

‘ḍ€i0

Experimente online!

Como funciona

‘ḍ€i0  Main link. Argument: n

‘      Increment; yield n+1.
 ḍ€    Divisible each; test 1, ..., n+1 for divisibility by n.
   i0  Find the first index of 0.

4

Python 2.7.9, 32 bytes

f=lambda n,d=1:n%d>0or-~f(n,d+1)

Teste em Ideona

Recursivamente conta potenciais não-divisores d. É mais curto para incrementar recursivamente o resultado do que produzir d. Um deslocamento de 1é obtido pelo booleano de True, que é igual 1, mas como d==1sempre é um divisor, a saída é sempre convertida em um número.

Python 2.7.9 é usado para permitir allow 0or. As versões iniciadas no 2.7.10 tentarão analisar 0orcomo o início de um número octal e receberão um erro de sintaxe. Veja isso na Ideone .


3

Na verdade , 7 bytes

;÷@uR-m

Experimente online! (nota: esta é uma solução muito lenta e levará muito tempo para grandes casos de teste)

Explicação:

;÷@uR-m
;÷       duplicate N, divisors
  @uR    range(1, N+2)
     -   set difference (values in [1, N+1] that are not divisors of N)
      m  minimum

3

Haskell , 29 bytes

f n=[k|k<-[2..],mod n k>0]!!0

A expressão [k|k<-[2..]]apenas cria uma lista infinita [2,3,4,5,...]. Com a condição mod n k>0, permitimos apenas aqueles kna lista que não se dividem n. Acrescentar !!0apenas retorna a primeira entrada (a entrada no índice 0) dessa lista.

Experimente online!


3

Dyalog APL , 8 bytes

1⍳⍨0≠⍳|⊢

1⍳⍨ posição da primeira True em

0≠ os valores diferentes de zero de

⍳|os remanescentes da divisão de 1 ... N quando divididos por

N

TryAPL online!

Nota: isso funciona para 1 e 2 porque 1⍳⍨retorna 1 + o comprimento do argumento, se nenhum for encontrado.


3

julia, 28 bytes

N->findfirst(x->N%x>0,1:N+2)

Nota: como 1:N+2não aloca memória, não há problemas de memória para Ns grandes
- @flawr N+2salva alguns bytes para mim
- a sugestão de @Martin salvou 1 bytes


3

QBIC , 14 bytes

:[a+1|~a%b|_Xb

Explicação:

:      Read the first cmd line param as a number, called 'a'
[a+1|  FOR (b=1 ; b <= a+1; b++) <-- a+1 for cases a = 1 or 2
~a%b   IF A modulo B ( == 0, implicit)
|_Xb   THEN exit the program, printing b
       [IF and FOR implicitly closed by QBIC]

3

PHP, 30 bytes

for(;$argv[1]%++$i<1;);echo$i;

se executado a partir do console com a -ropção (thx a @ ais523)

php -r 'for(;$argv[1]%++$i<1;);echo$i;' 232792560

32 bytes

<?for(;$argv[1]%++$i<1;);echo$i;

graças a @manatwork por remover 1 byte

33 bytes (original)

<?for(;$argv[1]%++$i==0;);echo$i;

3
IIRC, <?ele não precisa fazer parte da sua contagem de bytes (porque o PHP possui um modo de linha de comando que não exige).

3
O velho truque: compare contra em <1vez de ==0.
manatwork

Dang. Eu cheguei a for(;!($argv[1]%$i);$i++);echo$i;. A sua é a evolução natural minha. Isso tem o meu voto positivo!
Ismael Miguel

3

Cubix , 14 12 bytes

I2/L/);?%<@O

Economizou 2 bytes graças ao MickyT.

Tente

Explicação

No formato de cubo, o código é:

    I 2
    / L
/ ) ; ? % < @ O
. . . . . . . .
    . .
    . .

Basicamente, isso apenas recebe a entrada e inicia um contador. Em seguida, ele verifica cada valor sucessivo do contador até encontrar um que não seja um fator da entrada.


I2/L/);?%<@Opor alguns bytes a menos. Processo mesmo general, apenas caminho diferente
MickyT

2

> <> , 15 +3 = 18 bytes

1\n;
?\1+:{:}$%

A entrada deve estar na pilha no início do programa, portanto, +3 bytes para o -vsinalizador. Experimente online!


2

Água-viva , 12 10 bytes

p\~~|1
 >i

Leva a entrada de STDIN e sai para STDOUT. Experimente online!

Martin Ender economizou 2 bytes, obrigado!

Explicação

 \~~|
 >i

Esta parte é uma função que usa o valor de entrada em sua definição.

   ~|

Essa ~célula recebe uma função e, portanto, vira seus argumentos: ela produz a função binária "left argument modulo ( |) right argument". A função módulo interna do Jellyfish leva seus argumentos na ordem inversa.

  ~~|
  i

Essa ~célula recebe um valor e uma função, portanto aplica parcialmente: produz a função binária "input ( i) modulo right argument". Vamos chamar essa função de f .

 \~~|
 >i

A \célula-recebe duas funções, por isso executa a iteração: produz a função unária "increment ( >) até que a função f aplicada aos valores anteriores e atuais forneça um resultado verdadeiro (diferente de zero) e retorne o valor atual". Isso significa que o argumento é incrementado até não dividir a entrada.

p\~~|1
 >i

Finalmente, aplicamos essa função ao valor inicial 1e imprimimos o resultado com p.

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.