Encontre um múltiplo de um determinado número cuja representação decimal pareça binária


34

Encontrei uma pergunta no site Code Review que parece interessante. Eu acho que OP está fazendo errado, mas não posso ter certeza ... Então, vamos resolver isso para ele! (escreva um programa, não uma função / procedimento)

Entrada (stdin ou similar):

Um número inteiro xem notação decimal. É maior que 1 e menor que 2 ^ 31.

Saída (saída padrão ou similar):

Um número inteiro yem notação decimal. O produto x * yna representação decimal deve conter apenas os dígitos 0 e 1. Ele deve ser o número mínimo mínimo maior que 0.

Nota: a saída não é limitada - se o mínimo yé em torno de 10 ^ 100, seu programa deve produzir todos os seus 100 dígitos (não sei se existe um limite razoável, como 2 ^ 64, ativado y- não o resolveu )

Seu programa deve terminar em um tempo razoável (1 segundo? 1 hora? - algo assim) para todos os que xestiverem ao alcance.

Bônus:

Se o seu programa não tiver um limite no tamanho da entrada (exceto RAM) e tiver complexidade polinomial, multiplique a contagem de bytes do seu programa 0.8e arredonde para baixo.


Exemplo: Entrada 2; saída 5, porque 2 * 5 = 10

Exemplo: Entrada 21; saída 481, porque 21 * 481 = 10101


Isenção de responsabilidade: Eu não sou responsável pela pergunta no site de Revisão de código. Em caso de qualquer discrepância, apenas a descrição acima deve ser considerada como especificação adequada.

OEIS A079339


6
Deve sempre ser solucionável. Claramente deve existir pelo menos um q tal que exista um número infinito de n tal que 10 ^ n mod x = q. Tome x tais valores de n e some os respectivos poderes 10 ^ n.
feersum

1
Múltiplos de 9 parecem produzir resultados extraordinariamente altos.
SuperJedi224

1
Problema projeto relacionado Euler , para qualquer pessoa que pensei que esta questão parecia familiar
SP3000

1
Por complexidade polinomial, você quer dizer polinômio no número de dígitos da entrada ou polinômio no valor da entrada?
Reto Koradi

3
@anatolyg mine não é força bruta
aditsu 16/10

Respostas:


8

Pitão, 9 bytes

f!-`*TQ10

Demonstração

Para cada múltiplo, converta em uma sequência, subtraia os dígitos 10(usando o int útil de Pyth para transmitir neste caso) e, em seguida, negue logicamente o resultado, encerrando a pesquisa somente quando o múltiplo correto for encontrado.

Solução de bônus, 10 bytes:

f.xi`*TQ2Z

Esta solução realmente verifica se a representação de string do número pode ser tratada como um número binário ( i ... 2) e termina quando um erro não é gerado nesta tentativa.


18

Python 2, solução eficiente, 99

n=input()
d={n:0}
k=1
while min(d):[d.setdefault((x+k)%n,d[x]+k)for x in set(d)];k*=10
print d[0]/n

Obrigado Sp3000 por algumas dicas de golfe.

Desafio todo mundo a postar (em suas próprias respostas) quanto tempo leva para obter o resultado para entrada 72ou 99:) Se esses forem realmente rápidos, tente algo como o 79992próximo (ainda <1 segundo aqui).

Explicação:

Eu pensei que isso não era necessário (já que o código é bastante legível), mas recebi uma solicitação, então aqui vai:

A primeira idéia é que um número de aparência binária é uma soma de 1 ou mais potências diferentes de 10. Portanto, podemos tentar adicionar várias potências de 10 de maneiras diferentes até obter o restante 0.

Se fizermos isso de forma ingênua, será o mesmo que gerar todos os números binários e testá-los. Mas muitos remanescentes serão os mesmos. Uma maneira melhor é gravar apenas o menor número que forneceu um determinado restante e adicionar sucessivamente maiores potências de 10 aos números que registramos. É isso que o programa faz.

dé um dicionário / mapa em que as chaves são remanescentes e os valores são números binários com esse restante. A inicial n:0é um caso especial: é suposto 0:0que possamos começar a adicionar poderes a ela, mas o algoritmo para ao encontrar a chave 0, então usei o nque é garantido que tem o mesmo efeito e não interfere nos outros valores.

Começamos a adicionar potências de 10 (armazenadas em k) a todos os números existentes e a gravar os demais. Adicionamos kao restante: (x+k)%ne ao número: d[x]+ke o registramos apenas se for um novo restante:, em d.setdefault(…)seguida, passamos à próxima potência: k*=10e repetimos até obtermos a tecla 0:while min(d)

No final, d[0]fornece o número de aparência binária que possui o restante 0 mod n, então dividimos npara obter a solução.

Nota: o programa pode ser mais eficiente evitando grandes números (registrando expoentes em vez de potências de 10 e calculando restos de potências a partir de valores anteriores), mas é código de golfe, então ...

De fato, aqui, escrevi uma versão mais rápida:

n=input()
d={n:0}
k=1
b=0
while 0not in d:
 for x in list(d):d.setdefault((x+k)%n,b)
 k=(k*10)%n;b+=1
x=10**d[0]
while x%n:x+=10**d[n-x%n]
print x/n

1
Minha resposta também não está. xD "Porra, Java, amaldiçoe a sua escolha de Integer.MAX_VALUE ao usar o BigInteger por padrão!" - Todo programador Java de todos os tempos
Addison Crump

@VTCAKAVSMoACE por que você não usa Long?
Aditsu 16/10/2015

Hmm. É um byte extra, mas ... vale a pena. Obrigado!
Addison Crump

Ou não. Isso realmente reduz a sério. Obrigado!
Addison Crump

1
Horários para resolver 99: aditsu: 0.001 segundos; xnor: mais de 5 horas e ainda não foi concluído.
user193661

13

Python 2, 47 bytes

n=a=input()
while'1'<max(str(a)):a+=n
print a/n

Rastreia o número de entrada ne o múltiplo atual a. Quando aparecer binário, produza a proporção a/n. Para verificar se um número é constituído por 0's' e 1's, comparamos o caractere máximo em sua representação de string com '1'.

Usa em str(a)vez de `a`evitar que os longos terminem em L. Infelizmente, 'L'é maior que '1'.


12

Perl, 27 bytes

#!perl -p
1while($_*++$\)=~/[2-9]/}{

Contando o shebang como um, a entrada é obtida de stdin.

Uso da amostra

$ echo 2 | perl dec-bin.pl
5

$ echo 21 | perl dec-bin.pl
481

$ echo 98 | perl dec-bin.pl
112245

Perl, 25 bytes

#!perl -p
eval'0b'.++$\*$_||redo}{

Uma melhoria de dois bytes por @skmrx .

Em vez de verificar em relação a uma regex, isso tenta avaliar o produto como um literal binário. Em caso de falha, ele passa para o próximo. Normalmente, a octfunção seria usada para esse fim, mas apara silenciosamente dígitos inválidos, o que não é útil nesse desafio.


Perl, 40 bytes

#!perl -p
1while($b=sprintf"%b",++$i)%$_;$_=$b/$_

Uma solução muito mais eficiente. Nós iteramos sobre representações binárias, as interpretamos como base 10 e, em seguida, verificamos a divisibilidade. Os tempos de execução para todos os valores abaixo de 100 são insignificantes.

Uso da amostra

$ echo 72|perl dec-bin.pl
1543209875

$ echo 99|perl dec-bin.pl
1122334455667789

2
Bom :) Aprendi algumas coisas novas do seu post hoje! Ao ler seu código, encontrei uma maneira de remover alguns bytes do primeiro código:eval"0b".$_*++$\||redo}{
svsd

Mas acho que precisaremos incluir use bigintpara dar suporte aos grandes números que o OP determinou para serem suportados :(
svsd

1
@skmrn Isso é brilhante. Eu tentei oct'0b'.++$\*$_, mas silenciosamente apara dígitos inválidos. Não pensei em usar eval.
Primo

11

Javascript, 43 bytes

Isso acabou muito mais curto do que eu pensava. Basicamente, aumenta y1 até y * (input number) = (binary-looking number). Obviamente, bastante ineficiente.

for(x=prompt(y=0);!+('0b'+x*++y););alert(y)


Javascript (solução mais eficiente), 53 bytes

Este incrementa yem binário até y / (input number) = (number without a remainder). Então ele sai (number without a remainder).

for(x=prompt(y=1);(z=y.toString(2))%x;y++);alert(z/x)


Javascript (solução ainda mais eficiente), 76 bytes

Este combina os dois métodos anteriores descritos acima. Ele verifica os incrementos yaté y * (input number) = (binary-looking number)( ou seja, a saída é y) OU y / (input number) = (number without a remainder)( ou seja, a saída é (number without a remainder)).

for(x=prompt(y=a=0);!a;a=+('0b'+x*++y)?y:(z=y.toString(2))%x?0:z/x);alert(a)


Deve dar 1 quando possível (entrada de exemplo: 1)
edc65

@ edc65 Corrigido - sem alterações na contagem de bytes!
Mama Fun rolo

Isso trava o Safari 9.0. Jussayin '. :)
Addison Crump

1
Mas é limitado a pequenos números na saída. Números JavaScript 17 dígitos de precisão, OP está pedindo algo maior (e isso pode ser feito usando a aritmética modular)
edc65

Protip: não tente digitar 72. O Firefox 41 congela por 15 minutos e depois trava. Eu descobri isso da maneira mais difícil.
ETHproductions

9

Haskell, 72 70 64 60 58 bytes

main=do x<-readLn;print$[y|y<-[1..],all(<'2')$show$x*y]!!0

Edit: @Jan Dvorak me ajudou a economizar 4 bytes.

Edit: @BlackCap salvou 2 bytes mudando para donotação. Obrigado!


main=print.f=<<readLn
John Dvorak

Você pode salvar um byte, inlining f:main=readLn>>= \x->print$[y|y<-[1..],all(<'2')$show$x*y]!!0
BlackCap 25/10

2 na verdademain=do x<-readLn;print$[y|y<-[1..],all(<'2')$show$x*y]!!0
BlackCap 25/10

@BlackCap: Nice! Muito obrigado!
nimi

7

Python 2, 67 65 63 60 bytes

a=input();b=1
while set(`a*b`)&set('23456789'):b+=1
print b

Graças ao status por 2 bytes e Shebang por 5 bytes!


1
Eu acho que você deve inicializarb=1
anatolyg

2
Você pode raspar 2 bytes fazendoany(c in`a*b`for c in'23456789')
Status

1
Não tenho certeza disso, mas not c in`a*b`for c in'10'funcionaria?
cole

2
Você pode salvar 6 bytes alterando sua condição while para set('a*b')&set('23456789').
Kade

2
`produz um Lpara longs e 'L'>'1'.
user193661

6

JavaScript (ES6) 222 250

Usando matemática de precisão arbitrária (operando em cadeias de dígitos decimais)

Isso pode ser jogado um pouco mais (feito), mas eu gosto do fato de que não se limita aos números padrão JS (17 dígitos decimais de precisão) e que é rápido.

Teste a execução do snippet abaixo em um navegador compatível com EcmaScript 6. O tempo é aceitável até 9998 - não tente 9999 e seja paciente com 999.

// As a complete program with I/O via popup  
for(n=+prompt(a=[0],q=[t=1]);t;){for(c=1,t=i=0;i<a.length;i++)a[i]=a[i]&c?0:a[i]|c?(c=0,t+=q[i],1):c=0;c&&(a[i]=c,t+=q[i]=q[i-1]*10%n);t%=n}a.reverse().map(a=>(z+=[a],d=z/n|0,z%=n,r||d?r+=d:0),r='',z=0);alert([r,a.join``])

// As a testable function
f=n=>{
  for(a=[0],q=[t=1];t;)
  {
    for(c=1,t=i=0;i<a.length;i++)
      a[i]=a[i]&c?0:a[i]|c?(c=0,t+=q[i],1):c=0
    c&&(a[i]=c,t+=q[i]=q[i-1]*10%n);
    t%=n
  }  
  a.reverse().map(a=>(z+=[a],d=z/n|0,z%=n,r||d?r+=d:0),r='',z=0)
  return [r,a.join``]
}

// Test and timing
out = x => O.innerHTML += x + '\n'

setTimeout(_=>{
;[1,2,10, 21, 23, 98, 72, 9, 99, 999]
.forEach((test,i) => { 
  var t0 = ~new Date  
  var result = f(test)
  out('n='+test+' '+result+' time(ms) ' + (t0-~new Date))
})},100)  
<pre id=O>Timing test cases ...
</pre>

Mais legível

Esta é a primeira versão, com módulo e divisão longa como funções separadas.

// function M - Modulus with arbitrary precision - a is a string of decimal digits
M = (a, b, q = 1, t = 0, j = a.length) => {
  while (j--) + a[j] ? t += q : 0, q = (q * 10) % b;
  return t % b
}

// function D - Long division with arbitrary precision - a is a string of decimal digits
D = (a, b, r = '', z = 0) => [...a].map(a => (z += a, d = z / b | 0, z %= b, r || d ? r += d : 0)) && r

// Testable function 
f = n => {
  for (i = 0; ++i < 1e7 && (z = M(v = i.toString(2), n)););
  return z ? ['big'] : [D(v, n), v]
}

Eu consegui que funcionasse no Firefox, mas não parece lidar com números maiores, por exemplo, 999
aditsu 17/10/2015

Eu tenho uma nova versão que pode lidar com 999 em 36 segundos, mas não há esperança de chegar a 9999 com o tempo limite do javascript (cada '9' adicionado requer 2 ^ 9 (~ 500) vezes o tempo para concluir)
edc65

@aditsu é o melhor que posso fazer em JavaScript (mas em C # é exatamente o mesmo). Eaherly à espera de uma explicação do que você incrível algoritmo
edc65

Eu adicionei uma explicação agora
aditsu 17/10/2015



4

PHP, 50 bytes

while(preg_match('/[^01]/',$argv[1]*++$y));echo$y;

Alguns casos de teste

1 > 1
2 > 5
12 > 925
21 > 481

1
Ia fazer algo como isso, este é ainda um pouco mais curto do que eu tinha em mente
Martijn

4

CJam, 19 17 16 bytes

li:V!{)_V*sAs-}g

Experimente online

Solução de força bruta, tentando valores seqüencialmente até encontrar uma condição.

A versão mais recente economiza 2 bytes graças ao uso em Asvez de "01"para criar uma string contendo 0e 1, como sugerido pelo @aditsu. A solução completa proposta no comentário salva outro byte, mas parece bastante diferente do meu, portanto, não queria publicá-la em meu nome.

E mais 1 byte salvo por @Dennis.

Explicação:

li      Get input and convert to int.
:V      Save it in variable V.
!       Negate the value. Since we saved it in V, we don't need it on the stack anymore.
        But we need 0 on the stack as the start value for y. This conveniently
        accomplishes both with a single operator, since the input is guaranteed to be
        larger than 0.
{       Loop over y.
  )       Increment y.
  _       Copy it.
  V*      Multiply with input in variable V.
  s       Convert to string.
  As      Push the string "10", as the number 10 converted to a string .
  -       Remove 0 and 1 digits. This will result in an empty list if there were only
          0 and 1 digits. The empty list is falsy, and will terminate the loop.
}g      End loop.

3
16:li0{1$+_sAs-}g\/
aditsu 16/10

Obrigado, @aditsu. Eu realmente não queria copiar sua solução completa em meu nome. Eu peguei o Aspara construir a string, já que é uma mudança muito local, que em retrospectiva (que é sempre muito mais fácil ...) eu deveria ter pensado.
Reto Koradi 17/10/2015

1
@RetoKoradi 16 bytes, menos modificações: li:V!{)_V*sAs-}gAlém disso, 0{)_easi*sAs-}g(15 bytes) funciona com o interpretador Java e os argumentos da linha de comando.
Dennis

4

Python 3 2, 101 76 bytes

-25 bytes graças a @aditsu

quase tão eficiente quanto a solução da @ aditsu

99 -> 0.436 Seconds
72 -> 0.007 Seconds
b,m,n=1,1,input()
while b%n:
 b=int("{0:b}".format(m))
 m+=1
print b/n

Em vez de tentar percorrer os múltiplos em ordem crescente, estou tentando percorrer os produtos, que estou gerando na forma 'binária'.


Não é ruim :) E quanto a 9999?
Aditsu 17/10/2015

2
Algumas dicas de golfe: use python 2 ( n=input()), while b%n:(inicialize bpara 1), sem recuo
aditsu

@aditsu Thanks! 9999 hmmm, parece que vai levar um par de dias, bem de volta à prancheta de desenho -_-
Rnet

1
bin(m)[2:]deve ser menor que a string de formato. A atribuição dupla ativada b=m=1deve economizar alguns também.
Primo

4

Java, 213 bytes

import java.math.*;class P{public static void main(String[]a){BigInteger b=new java.util.Scanner(System.in).nextBigInteger(),c,d=c=b.ONE;while(!(b.multiply(c)+"").matches("[01]+"))c=c.add(d);System.out.print(c);}}

Usa BigIntegers e, como tal, tem (para todos os propósitos e propósitos razoáveis) tamanho de entrada ilimitado. Não tenho certeza sobre a complexidade, porém, isso depende da taxa de crescimento de nossa função aqui.

Obrigado a geobits e ypnypn por salvar um punhado de bytes.


Oi, como você chamaria isso no seu método principal, por favor? Tentando, mas não conseguindo
Yassin Hajaj

Você precisaria adicionar o staticmodificador ao método.
SuperJedi224

1
A pergunta diz que a solução deve ser um programa completo, não apenas uma função.
raznagul 16/10/2015

Você pode cortar 15 com b.ONEe !(b.multiply(c)+"")(em vez de toString()).
Geobits

@raznagul: Fixed.
SuperJedi224

4

C, 3675 bytes

Tanto tempo para o Code Golf ...

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <assert.h>

#define min_n 1
#define max_n 10000

unsigned *mod_list; // list of mods to check
unsigned mod_list_length; // number of mods to check
char *graph; // for each mod, the power of 10 that gives it

void BuildGraph(unsigned n)
{
    unsigned mod10 = 10 % n;
    int pow = 1;

    memset(graph, 0, n);
    if (n == 1)
        return;
    mod_list[0] = 0; // mod 0 - no path coming to it yet
    mod_list[1] = 1; // mod 1 - 10^0 coming to it
    mod_list_length = 2;
    while (graph[0] == 0)
    {
        // We are going to change mod_list_length by adding new nodes.
        // This should not affect the set of nodes we check, so save its old value.
        unsigned mod_list_limit = mod_list_length;
        for (unsigned i = 0; i < mod_list_limit; ++i)
        {
            unsigned mod = mod_list[i] + mod10;
            if (mod >= n)
                mod -= n;
            if (graph[mod] == 0 && mod != 1) // new node?
            {
                graph[mod] = pow; // record the power of 10 with which we come to this node
                mod_list[mod_list_length++] = mod; // add it to the list of nodes
                if (mod == 0) // found the path to 0?
                    return; // stop calculating
            }
        }
        mod10 = (unsigned long long)mod10 * 10 % n; // go to next power of 10
        ++pow;
    }
}

void PrintPath(unsigned n, char *out)
{
    // Going to output powers of 10 in descending order
    unsigned mod = 0; // start at node 0
    int prev_pow = graph[mod] + 1; // happens to be an acceptable initialization
    do {
        int pow = graph[mod];
        while (--prev_pow > pow) // output the proper number of 0-digits
            *out++ = '0';
        *out++ = '1'; // output the digit 1, corresponding to current power of 10
        if (pow == 0)
            break;
        unsigned mod10 = 1;
        for (int p = 0; p < pow; ++p)
            mod10 = (unsigned long long)mod10 * 10 % n;
        mod = (mod + n - mod10 % n) % n; // go to the preceding node
    } while (mod != 0);
    while (--prev_pow >= 0) // output the proper number of 0-digits
        *out++ = '0';
    *out++ = 0;
}

// The long division algorithm
void DivideAndPrint(char *product, unsigned n, FILE* file)
{
    unsigned long long temp = 0;
    int print = 0;
    while (*product != '\0')
    {
        temp = temp * 10 + *product++ - '0';
        if (temp >= n)
            print = 1;
        if (print)
        {
            unsigned quotient = (unsigned)(temp / n);
            unsigned remainder = temp % n;
            fputc('0' + quotient, file);
            temp = remainder;
        }
    }
    fputc('\n', file);
    assert(temp == 0); // if not divisible, there is a bug somewhere
}

void Calc(unsigned n, FILE* file)
{
    char result[99];
    BuildGraph(n);
    PrintPath(n, result);
    DivideAndPrint(result, n, file);
}

int main(int argc, char* argv[])
{
    unsigned n;

    if (argv[1])
    {
        FILE* file = fopen(argv[1], "wt");
        mod_list = calloc(max_n, sizeof(int));
        graph = calloc(max_n, 1);
        clock_t before = clock();
        for (n = min_n; n <= max_n; ++n)
        {
            Calc(n, file);
        }
        clock_t after = clock();
        fprintf(stderr, "Time: %f\n", (after - before) / (double)CLOCKS_PER_SEC);
    }
    else
    {
        scanf("%u", &n);
        mod_list = calloc(n, sizeof(int));
        graph = calloc(n, 1);
        Calc(n, stdout);
    }
}

Executado sem parâmetros de linha de comando - ele recebe nde stdine envia o resultado para stdout. Execute com um nome de arquivo - ele grava os resultados n = 1...10000nesse arquivo e mede o tempo.

Desempenho para 1 ... 10000: 140 ms

Este código usa o algoritmo proposto por aditsu , implementado em C para velocidade. Não fiz nenhum esforço para jogar golfe, para que o código fosse mais fácil de ler.

Eu o implementei primeiro em C ++ usando std::mappara registrar os resultados da pesquisa, e foi bastante lento. No entanto, as chaves do mapsão números inteiros consecutivos (eu os chamo de mods, porque representam números módulo n), por isso é natural usar uma matriz - então eu a reescrevi em C.

Uma otimização adicional diz respeito aos valores do mapeamento - para evitar o armazenamento de um número inteiro grande para cada um mod, eu armazeno apenas a maior potência de 10 lá - são apenas informações suficientes para ir para o anterior mod. Portanto, o array é realmente uma árvore / gráfico de pesquisa. Quando a pesquisa chega mod = 0, o rastreamento dos nós da árvore de volta à raiz fornece os poderes de 10 em ordem decrescente.

Como a pesquisa geralmente para rapidamente, com apenas uma pequena fração de nós visitados, preciso de uma lista de nós ativos. É implementado como uma matriz mod_listcom comprimento mod_list_length.

Algumas estatísticas de tempo de execução (em uma máquina com 16 GB de RAM, o que parece ser importante para grandes empresas n, porque o programa aloca 5nbytes de memória):

  • Entrada 99999999 - 2 segundos
  • Entrada 999999999- 27 segundos (o resultado é 111111111222222222333333333444444444555555555666666666777777777888888889- provavelmente o maior resultado possível para números inteiros de 32 bits)
  • Entrada 2147483647- 26 segundos (o resultado é 4661316525084584315813)
  • Entrada 1999999998- 52 segundos (provavelmente o maior tempo de execução possível para números inteiros de 32 bits)

2
Entendo que você está atrás da recompensa, mas mesmo assim essa é uma questão de código-golfe , e as regras do site exigem que você faça algum esforço para aplicar seu código no golfe.
Peter Taylor

Seu programa possui 3546 bytes.
Aditsu 27/10/2015

@aditsu Avaliei a contagem de bytes no Windows, que usa o estilo CR / LF
anatolyg

4

C ++ 11, muitos bytes, muito rápido, uau (1,5 s em 1999999998, 0,2 s em 1… 10000)

(Versão do Golfed Python abaixo.)

Começamos com um conceito um pouco semelhante à solução do aditsu, onde construímos indutivamente uma coleção de restos modulares alcançáveis ​​em n etapas. Mas, em vez de esperar até encontrarmos o restante 0, verificamos dois restos encontrados aeb de modo que a · 10 ^ n + b = 0. Essa abordagem de encontro ao meio reduz pela metade a profundidade da árvore de pesquisa, por isso é muito mais rápido em entradas grandes e usa muito menos memória.

Alguns benchmarks:

$ echo 99999999 | \time ./decbin
1111111122222222333333334444444455555555666666667777777788888889
0.18user 0.01system 0:00.20elapsed 99%CPU (0avgtext+0avgdata 69360maxresident)k
0inputs+0outputs (0major+16276minor)pagefaults 0swaps
$ echo 999999999 | \time ./decbin
111111111222222222333333333444444444555555555666666666777777777888888889
1.22user 0.04system 0:01.27elapsed 100%CPU (0avgtext+0avgdata 434776maxresident)k
0inputs+0outputs (0major+37308minor)pagefaults 0swaps
$ echo 2147483647 | \time ./decbin
4661316525084584315813
0.00user 0.00system 0:00.01elapsed 72%CPU (0avgtext+0avgdata 5960maxresident)k
0inputs+0outputs (0major+1084minor)pagefaults 0swaps
$ echo 1999999998 | \time ./decbin
555555556111111111666666667222222222777777778333333333888888889444444445
1.42user 0.08system 0:01.50elapsed 100%CPU (0avgtext+0avgdata 544140maxresident)k
0inputs+0outputs (0major+38379minor)pagefaults 0swaps
$ \time ./decbin 10000.out
0.19user 0.00system 0:00.20elapsed 100%CPU (0avgtext+0avgdata 3324maxresident)k
0inputs+264outputs (0major+160minor)pagefaults 0swaps

Código:

#include <algorithm>
#include <boost/iterator/transform_iterator.hpp>
#include <fstream>
#include <list>
#include <iostream>
#include <string>
#include <utility>
#include <vector>

using namespace boost;
using namespace std;

static inline bool cmp_first_partnered(pair<int, pair<int, int>> a,
                                       pair<int, pair<int, int>> b) {
  return a.first < b.first;
}
static inline bool eq_first_partnered(pair<int, pair<int, int>> a,
                                      pair<int, pair<int, int>> b) {
  return a.first == b.first;
}

static pair<int, int> retrace(int modulus, int place, pair<int, int> state,
                              list<vector<int>>::iterator i,
                              list<vector<int>>::iterator j, string &ret) {
  if (i == j)
    return state;
  state = retrace(modulus, (place * 10LL) % modulus, state, next(i), j, ret);
  int remainder = state.first;
  long long k = state.second * 10LL;
  if (!binary_search(i->cbegin(), i->cend(), remainder)) {
    remainder = ((long long)remainder + modulus - place) % modulus;
    k += 1;
  }
  int digit = k / modulus;
  if (digit != 0 || ret.size())
    ret += '0' + digit;
  return make_pair(remainder, k % modulus);
}

static void mult(int modulus, int x, int y,
                 vector<pair<int, pair<int, int>>>::iterator i,
                 vector<pair<int, pair<int, int>>>::iterator j) {
  if (y - x == 1) {
    for (auto k = i; k != j; k++)
      k->first = (k->first * 10LL) % modulus;
    return;
  }

  int z = (x + y) / 2;
  vector<pair<int, pair<int, int>>>::iterator k = lower_bound(
      i, j, make_pair(int(((long long)modulus * z + 9) / 10), make_pair(0, 0)));
  mult(modulus, x, z, i, k);
  mult(modulus, z, y, k, j);
  inplace_merge(i, k, j,
                [](pair<int, pair<int, int>> a, pair<int, pair<int, int>> b) {
                  return make_pair(a.first, a.second.second) <
                         make_pair(b.first, b.second.second);
                });
}

static string go(int modulus) {
  if (modulus == 1)
    return "1";

  int sequence = 1;
  list<vector<int>> v = {{0}};
  vector<pair<int, pair<int, int>>> partnered;
  int place = 1;
  while (true) {
    v.emplace_back(v.rbegin()->size() * 2);
    vector<int> &previous = *next(v.rbegin()), &current = *v.rbegin();

    auto offset = [modulus, place, sequence](int a) {
      return (a + (long long)place) % modulus;
    };
    auto old_mid =
        lower_bound(previous.cbegin(), previous.cend(), modulus - place),
         new_mid = lower_bound(previous.cbegin(), previous.cend(), place);
    current.resize(
        set_union(new_mid, previous.cend(),
                  make_transform_iterator(previous.cbegin(), offset),
                  make_transform_iterator(old_mid, offset),
                  set_union(previous.cbegin(), new_mid,
                            make_transform_iterator(old_mid, offset),
                            make_transform_iterator(previous.cend(), offset),
                            current.begin())) -
        current.begin());

    int place2 = modulus - (long long)place * place % modulus;
    auto offset_partnered = [modulus, place, place2,
                             sequence](pair<int, pair<int, int>> a) {
      return make_pair((a.first + (long long)place2) % modulus,
                       make_pair((a.second.first + (long long)place) % modulus,
                                 sequence + a.second.second));
    };
    auto old_mid_partnered =
        lower_bound(partnered.cbegin(), partnered.cend(),
                    make_pair(modulus - place2, make_pair(0, 0))),
         new_mid_partnered = lower_bound(partnered.cbegin(), partnered.cend(),
                                         make_pair(place2, make_pair(0, 0)));
    vector<pair<int, pair<int, int>>> next_partnered(partnered.size() * 2 + 1);
    auto i =
        set_union(partnered.cbegin(), new_mid_partnered,
                  make_transform_iterator(old_mid_partnered, offset_partnered),
                  make_transform_iterator(partnered.cend(), offset_partnered),
                  next_partnered.begin(), cmp_first_partnered);
    if (new_mid_partnered == partnered.cend() ||
        new_mid_partnered->first != place2)
      *i++ = make_pair(place2, make_pair(place, sequence));
    next_partnered.resize(
        set_union(new_mid_partnered, partnered.cend(),
                  make_transform_iterator(partnered.cbegin(), offset_partnered),
                  make_transform_iterator(old_mid_partnered, offset_partnered),
                  i, cmp_first_partnered) -
        next_partnered.begin());
    partnered.swap(next_partnered);

    sequence += previous.size();

    place = (place * 10LL) % modulus;

    mult(modulus, 0, 10, partnered.begin(), partnered.end());
    partnered.resize(
        unique(partnered.begin(), partnered.end(), eq_first_partnered) -
        partnered.begin());

    auto with_first = [](int a) { return make_pair(a, make_pair(a, 0)); };

    vector<pair<int, pair<int, int>>> hits;
    set_intersection(partnered.cbegin(), partnered.cend(),
                     make_transform_iterator(current.cbegin(), with_first),
                     make_transform_iterator(current.cend(), with_first),
                     back_inserter(hits), cmp_first_partnered);

    if (hits.size()) {
      pair<int, pair<int, int>> best = *min_element(
          hits.begin(), hits.end(),
          [](pair<int, pair<int, int>> a, pair<int, pair<int, int>> b) {
            return a.second.second < b.second.second;
          });
      string ret = "";
      pair<int, int> state =
          retrace(modulus, 1, make_pair(best.second.first, 0), v.begin(),
                  prev(v.end()), ret);
      retrace(modulus, 1, make_pair(best.first, state.second), v.begin(),
              prev(v.end()), ret);
      return ret;
    }
  }
}

int main(int argc, const char *argv[]) {
  ios_base::sync_with_stdio(false);
  if (argc >= 2) {
    ofstream ofs(argv[1]);
    for (int modulus = 1; modulus <= 10000; modulus++)
      ofs << go(modulus) << '\n';
  } else {
    int modulus;
    cin >> modulus;
    cout << go(modulus) << '\n';
  }
  return 0;
}

Python, 280 bytes (8,6 segundos em 1999999998 com PyPy)

n=input()
if n<2:print 1;exit()
d={0:0}
l=[]
k=1
b=x=y=0
while 1:
 for a in[0]+l:
  m=(a+k)%n
  if m not in d:l.append(m);d[m]=b
 k=(k*10)%n;b+=1
 for a in l:
  if(-k*a)%n in d:
   while(a-x)%n:x+=10**d[(a-x)%n]
   while(-y-k*a)%n:y+=10**d[(-y-k*a)%n]
   print(10**b*x+y)/n;exit()

2
Entendo que você está atrás da recompensa, mas mesmo assim essa é uma questão de código-golfe , e as regras do site exigem que você faça algum esforço para aplicar seu código no golfe.
22615 Peter Taylor

1
@ PeterTaylor, muito bem, eu adicionei uma versão em golfe no Python.
Anders Kaseorg 25/10/2015

3

Mathematica 115 bytes

p=Drop[Union[FromDigits/@Flatten[Table[Tuples[{0,1},{k}],{k,2,12}],1]],2];
i=Input[];FirstCase[p,x_/;Divisible[x,i]]

3

Java 156 bytes

public class P{public static void main(String[]a){long x=Long.valueOf(a[0]),y;for(y=2;!(""+x*y).replaceAll("1|0","").isEmpty();y++);System.out.println(y);}}

Agradecimentos maciços a aditsu :)


Você não precisa de um espaço depois [], ypode ser longtambém, você esqueceu o x*y+""truque no 2º programa, use isEmptyem vez de verificar o comprimento, use ;em vez de{}
aditsu

De qualquer forma, bem-vindo ao golfe código :)
aditsu

Devo dizer, estou impressionado, mas fazendo y longnão iria tornar o código mais curto
Joba

Sim, seria:long x=…,y;
aditsu 27/10/2015

ydeve começar a partir de 1, você pode inicializar-lo na declaração, sua classe não precisa ser público, e você pode mover y++para a x*yparte ( x*y++)
aditsu

2

Pitão - 12 11 bytes

Usa filtro com arg numérico para obter o primeiro número natural que atende ao predicado; o padrão é 1, que é o que queremos. Diferença setwise para verificar se apenas zeros e uns.

f!-j*QT10U2

Conjunto de Teste .


Converta em string e remova "01. Salva um caractere.
Jakube 16/10

2

R, 45 bytes

x=scan();y=2;while(grepl("[2-9]",x*y))y=y+1;y

Uso:

> x=scan();y=2;while(grepl("[2-9]",x*y))y=y+1;y
1: 2
2: 
Read 1 item
[1] 5
> x=scan();y=2;while(grepl("[2-9]",x*y))y=y+1;y
1: 21
2: 
Read 1 item
[1] 481
> x=scan();y=2;while(grepl("[2-9]",x*y))y=y+1;y
1: 42
2: 
Read 1 item
[1] 2405

2

Java, 198 193 181 bytes

Agradecemos ao @aditsu por reduzir 5 bytes E aumentar o intervalo de números testáveis!

Observe que alguns valores fazem um loop negativo devido à maneira como o Java analisa números inteiros. Isso poderia ser contornado pelo BigInteger, mas o bônus era simplesmente menos valioso.

Sei que não vou ganhar, mas espero que isso inspire outras respostas mais curtas.

classe A {public static void main (String [] a) {for (long i = 1 ;; i ++) {try {long b = Long.parseLong (a [0]); if (b * i <0) quebra; Long.parseLong (b * i + "", 2); System.out.println (i);} catch (Exceção e) {}}}}

Ungofled:

classe A {
   public static void main (String [] a) {
      for (long i = 1 ;; i ++) {// loop infinito começando em 1
         try {// se um erro for gerado ao tentar analisar como binário, reinicie enquanto adiciona 1 a i
            long b = Long.parseLong (a [0]); // Para mais tarde - foi mais curto declarar do que usar duas vezes
            se (b * i <0) quebrar; // Interrompa o programa se tivermos feito um loop.
            Long.parseLong (b * i + "", 2); // Multiplique e veja se é passável como um número binário; caso contrário, gere erro e volte ao topo do loop
            System.out.println (b); // Imprima isso
         } catch (Exceção e) {} // não faz nada no catch
      }
   }
}

2
É engraçado que Longé menor do que Integer:)
anatolyg

3
A ironia mais literal que existe.
Addison Crump

2

C, 107 101 bytes ( 105 99 bytes para 32 bits)

Existe uma distinta falta de respostas em C no código de golfe. De fato, C não é a melhor opção para escrever o menor programa possível, mas não é tão ruim assim:

main(d,b){char s[9];gets(s);for(b=atoi(s);sprintf(s,"%d",b*d),strspn(s,"01")[s];d++);printf("%d",d);}

Você pode ficar sem as #includes, mas todas as definições de funções estarão implícitas. A principal desvantagem é que isso causa a suposição de que todas as funções retornam ints. Esse é um problema nas máquinas de 64 bits para funções que realmente retornam um ponteiro. Se você estiver em uma máquina de 32 bits, poderá remover 2 bytes a solução acima:

main(d,b){char s[9];for(b=atoi(gets(s));sprintf(s,"%d",b*d),strspn(s,"01")[s];d++);printf("%d",d);}

Versão um pouco mais legível:

int main()
{
  char s[9];
  gets(s);
  int d = 1;
  int b = atoi(s);
  for (; sprintf(s, "%d", b * d), strspn(s, "01")[s]; d++);
  printf("%d", d);
}

2

Tempo de C # próximo a 5 segundos (1 a 10000)

Conforme solicitado, aqui está um programa C # para golfe que responde ao desafio original. Entrada como argumento da linha de comando, saída para o console.

using System;using System.Collections.Generic;using System.Numerics;using System.Linq;
class P{static void Main(string[] a){int m,n=int.Parse(a[0]);var d=new Dictionary<int,long>();long b;int h;
for(d[n]=0,b=h=1;;b*=2,h=(h*10)%n)foreach(int k in d.Keys.Reverse())if(!d.ContainsKey(m=(h+k)%n)){
var w=d[k]|b;if(m==0){Console.Write(BigInteger.Parse(Convert.ToString(w,2))/n);return;}d.Add(m,w);}}}

Então, quanto à recompensa: a recompensa deve ir para o aditsu, pois acho que seu algoritmo não pode ser derrotado em termos de desempenho. Mas a auto-resposta de anatolyg também é incrível.

Aqui está minha rápida implementação em C #. Suponho que em C ++ poderia ser mais rápido (talvez 2x). Compilado e testado com o Visual Studio 2010, .NET framework 4, 64 bits, redirecionando a saída para nul. Hora: 00: 00: 05.2604315

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Numerics;
using System.Diagnostics;

class Program
{
   static BigInteger Find(int n)
   {
      var d = new Dictionary<int, long>();
      long kb;
      int km;
      d[n] = 0;
      for (kb = km = 1; ; kb *= 2, km = (km * 10) % n)
      {
         foreach (int key in d.Keys.Reverse())
         {
            int m = (km + key) % n;
            if (!d.ContainsKey(m))
            {
               long w = d[key] | kb;
               if (m == 0)
               {
                  return BigInteger.Parse(Convert.ToString(w, 2));
               }
               d.Add(m, w);
            }
         }
      }
   }

   static void Exec(int n, out string sq, out string sa)
   {
      var v = Find(n);
      sq = (v/n).ToString();
      sa = v.ToString();
   }  

   static void Main(string[] args)
   {
      // string n = Console.ReadLine();
      int limit = int.Parse(args[0]);
      string q ="", a = "";
      Stopwatch x = new Stopwatch();
      x.Start();
      for (int n = 1; n <= limit; n++)
      {
         Exec(n, out q, out a);
         Console.WriteLine("{0} {1} {2}", n, q, a);
      }
      x.Stop();
      Console.Error.WriteLine("{0}", x.Elapsed);
   }
}

Times 4.1s. Eu errei na recompensa. Com a versão mais recente do PyPy, a versão mais rápida do aditsu dura aproximadamente 8s, então isso é duas vezes mais rápido.
Primo

Entendo que você está atrás da recompensa, mas mesmo assim essa é uma questão de código-golfe , e as regras do site exigem que você faça algum esforço para aplicar seu código no golfe.
Peter Taylor

Não estou atrás da recompensa, é apenas um exemplo de implementação. Mas você está certo, vou adicionar uma versão em golfe.
Edc65

@PeterTaylor poderia ir agora?
Edc65 22/10

A propósito, por quê Keys.Reverse? A ordem é importante? Se é apenas para evitar problemas de concorrência, ToListé mais curto.
Peter Taylor

2

C com GMP (621 bytes, rápido)

Eu tentei ser rápido e curto, mas favoreci rápido. Esta implementação usa uma versão ligeiramente aprimorada da aceleração teórica dos números que mencionei em um comentário na resposta do aditsu .

Salvar como pseudobinary.ce compilar com gcc pseudobinary.c -lgmp -o pseudobinary. Observe que isso aloca tanta memória para entradas grandes que você precisará compilá-la para uma plataforma de 64 bits.

#include <gmp.h>
int main(int y,char*z[]){int i,n,b,c,e,f,m,*j,*k,*l,*r,*h;char *d,*s;mpz_t
B,I,Q;i=atoi(z[1]);n=i;for(b=0;n%10<1;++b)n/=10;for(;n%2<1;++b)n/=2;for(;n%5<1;++b)n/=5;if(n<2)--b;d=calloc(n,1);j=calloc(n,sizeof(int));r=calloc(99,sizeof(int));c=2;d[1]=1;*j=r[1]=e=1;l=j+1;for(s=0;!s;++c){r[c]=e=e*10%n;k=l;for(h=j;h<k;h++){f=*h;m=(e+f)%n;if(d[m]<1){*l++=m;if(m<1){s=malloc(99);memset(s,48,99);for(f=c;f;f=d[m=(m+n-r[f])%n])s[c-f]++;s[c]=0;h=k;}d[m]=c;}}}f=strlen(s);s[f]=48;s[f+b]=0;mpz_init_set_str(B,s,10);mpz_init_set_si(I,i);mpz_init(Q);mpz_divexact(Q,B,I);d=mpz_get_str(0,10,Q);printf("%s\n",d);return 0;}

Versão de loop para temporização (751 bytes)

#include <gmp.h>
char **v;int main(){int i,n,b,c,e,f,m,*j,*k,*l,*r,*h;char *d,*s;mpz_t
B,I,Q;v=calloc(10001,sizeof(char*));v[1]=s=malloc(99);memset(s,48,99);*s=49;s[1]=0;for(i=0;++i<10001;){n=i;for(b=0;n%10<1;++b)n/=10;for(;n%2<1;++b)n/=2;for(;n%5<1;++b)n/=5;d=calloc(n,1);j=calloc(n,sizeof(int));r=calloc(99,sizeof(int));c=2;d[1]=1;*j=r[1]=e=1;l=j+1;for(;!v[n];++c){r[c]=e=e*10%n;k=l;for(h=j;h<k;h++){f=*h;m=(e+f)%n;if(d[m]<1){*l++=m;if(m<1){v[n]=s=malloc(99);memset(s,48,99);for(f=c;f;f=d[m=(m+n-r[f])%n])s[c-f]++;s[c]=0;h=k;}d[m]=c;}}}free(d);free(j);free(r);s=v[n];f=strlen(s);s[f]=48;s[f+b]=0;mpz_init_set_str(B,s,10);mpz_init_set_si(I,i);mpz_init(Q);mpz_divexact(Q,B,I);d=mpz_get_str(0,10,Q);printf("%s\n",d);free(d);s[f+b]=48;s[f]=0;}return 0;}

Versão ungolfed loop

#include <gmp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char **cache;

int main() {
    int i,n,shift,_kb,km,key,m,*ks,*ksi,*nksi,*res,*ii;
    char *d,*s;
    mpz_t B,I,Q;

    cache = calloc(10001,sizeof(char*));
    if (!cache) { printf("Failed to malloc cache\n"); return 1; }
    cache[1]=s = malloc(99);
    memset(s,48,99);
    *s=49;
    s[1]=0;
    for (i=0;++i<10001;) {
        n=i;
        for(shift=0;n%10<1;++shift)n/=10;
        for(;n%2<1;++shift)n/=2;
        for(;n%5<1;++shift)n/=5;

        d = calloc(n,1);
        if (!d) { printf("Failed to malloc d\n"); return 1; }

        ks = calloc(n,sizeof(int));
        if (!ks) { printf("Failed to malloc ks\n"); return 1; }

        res = calloc(99,sizeof(int));
        if (!res) { printf("Failed to malloc res\n"); return 1; }

        _kb = 2;
        d[1] = 1;
        *ks = res[1] = km = 1;
        nksi = ks + 1;

        for(;!cache[n];++_kb) {
            res[_kb] = km = km*10%n;
            ksi = nksi;
            for (ii = ks; ii < ksi; ii++) {
                key = *ii;
                m = (km + key) % n;
                if (d[m] < 1) {
                    *nksi++ = m;
                    if (m < 1) {
                        cache[n] = s = malloc(99);
                        if (!s) { printf("Failed to malloc s\n"); return 1; }
                        memset(s,48,99);
                        for(key=_kb;key;key = d[m = (m + n - res[key]) % n])s[_kb-key]++;
                        s[_kb]=0;
                        ii = ksi; // break
                    }
                    d[m] = _kb;
                }
            }
        }

        free(d);
        free(ks);
        free(res);

        // Add shift * '0'
        s=cache[n];
        key=strlen(s);
        s[key]=48;
        s[key+shift]=0;

        // convert to big integer, divide, print
        mpz_init_set_str(B,s,10);
        mpz_init_set_si(I,i);
        mpz_init(Q);
        mpz_divexact(Q,B,I);
        d = mpz_get_str(0,10,Q);
        if (!s) { printf("Failed to malloc quotient\n"); return 1; }
        printf("%s\n", d);
        free(d);

        // Remove shift * '0'
        s[key+shift]=48;
        s[key]=0;
    }
    return 0;
}

2

C + GMP, 669

Isso é realmente rápido para números pequenos; começa a engasgar quando o resultado tem mais de 64 dígitos.

#include<gmp.h>
#define B(x)(int)((x*(long)k)%n);
int*M,*H,P[99],n,x,p,q=2,e=1,k=10,y,f,z;char*E,C[99];int b(int k,int t){int
j=E[k],a=1<<(j-2);if(j<2){C[t]=49;return 1;}x=(int)((k+n-P[j]*(long)H[k]%n)%n);if(x)b(x,t);return a+b(H[k],t-a);}int
main(){scanf("%d",&n);E=calloc(n+1,1);M=calloc(n+1,4);H=malloc(n*4);M[1]=E[1%n]=P[1]=1;while(!E[0]){P[++e]=k;p=q;for(x=0;++x<p;){y=B(M[x])if(E[n-y]){E[0]=e;H[0]=M[x];break;}}if(!E[x=0])while(++x<p){y=B(M[x])for(z=0;z<p;++z){f=y+M[z];if(f>=n)f-=n;if(!E[f]){E[f]=e;H[f]=M[x];M[q++]=f;}}}k=B(k)}memset(C,48,98);C[99]=0;x=b(0,97);mpz_t
m,r;mpz_init(r);mpz_init_set_str(m,C+98-x,10);mpz_fdiv_q_ui(r,m,n);puts(mpz_get_str(C,10,r));}

Versão com loop para 10000 (671 bytes):

#include<gmp.h>
#define B(x)(int)((x*(long)k)%n);
#define N 10001
int M[N],H[N],P[99],n=0,x,p,q,e,k,y,f,z;char E[N],C[99];int b(int k,int t){int
j=E[k],a=1<<(j-2);if(j<2){C[t]=49;return 1;}x=(int)((k+n-P[j]*(long)H[k]%n)%n);if(x)b(x,t);return a+b(H[k],t-a);}int
main(){while(++n<N){memset(E,M[0]=0,n);M[1]=E[1%n]=P[1]=e=1;q=2;k=10;while(!E[0]){P[++e]=k;p=q;for(x=0;++x<p;){y=B(M[x])if(E[n-y]){E[0]=e;H[0]=M[x];break;}}if(!E[x=0])while(++x<p){y=B(M[x])for(z=0;z<p;++z){f=y+M[z];if(f>=n)f-=n;if(!E[f]){E[f]=e;H[f]=M[x];M[q++]=f;}}}k=B(k)}memset(C,48,98);C[99]=0;x=b(0,97);mpz_t
m,r;mpz_init(r);mpz_init_set_str(m,C+98-x,10);mpz_fdiv_q_ui(r,m,n);puts(mpz_get_str(C,10,r));}}

Aqui estão alguns comandos para testar meu código e os dos concorrentes e os resultados no meu laptop:

ls -l *.c*       
-rw-r--r-- 1 aditsu aditsu  669 Oct 27 15:01 mult-aditsu-single.c
-rw-r--r-- 1 aditsu aditsu  671 Oct 27 15:01 mult-aditsu.c
-rw-r--r-- 1 aditsu aditsu 3546 Oct 27 15:01 mult-anatoly.c
-rw-r--r-- 1 aditsu aditsu 6175 Oct 27 15:01 mult-anders.cpp
-rw-r--r-- 1 aditsu aditsu  621 Oct 27 15:01 mult-peter-single.c
-rw-r--r-- 1 aditsu aditsu  751 Oct 27 15:01 mult-peter.c

gcc -w -march=native -O3 mult-aditsu-single.c -lgmp -o mult-aditsu-single
gcc -w -march=native -O3 mult-aditsu.c -lgmp -o mult-aditsu
gcc -w -march=native -O3 mult-peter-single.c -lgmp -o mult-peter-single
gcc -w -march=native -O3 mult-peter.c -lgmp -o mult-peter
gcc -w -march=native -O3 --std=c99 mult-anatoly.c -o mult-anatoly
g++ --std=c++11 -march=native -O3 mult-anders.cpp -o mult-anders

for i in {1..5}; do time ./mult-anders mult-anders.txt; done
./mult-anders mult-anders.txt  0.34s user 0.00s system 99% cpu 0.344 total
./mult-anders mult-anders.txt  0.36s user 0.00s system 99% cpu 0.358 total
./mult-anders mult-anders.txt  0.34s user 0.00s system 99% cpu 0.346 total
./mult-anders mult-anders.txt  0.35s user 0.00s system 99% cpu 0.347 total
./mult-anders mult-anders.txt  0.34s user 0.00s system 99% cpu 0.344 total

for i in {1..5}; do ./mult-anatoly mult-anatoly.txt; done
Time: 0.254416
Time: 0.253555
Time: 0.245734
Time: 0.243129
Time: 0.243345

for i in {1..5}; do time ./mult-peter > mult-peter.txt; done
./mult-peter > mult-peter.txt  0.14s user 0.00s system 99% cpu 0.137 total
./mult-peter > mult-peter.txt  0.15s user 0.00s system 97% cpu 0.153 total
./mult-peter > mult-peter.txt  0.15s user 0.00s system 99% cpu 0.149 total
./mult-peter > mult-peter.txt  0.15s user 0.00s system 99% cpu 0.150 total
./mult-peter > mult-peter.txt  0.14s user 0.00s system 99% cpu 0.138 total

for i in {1..5}; do time ./mult-aditsu > mult-aditsu.txt; done
./mult-aditsu > mult-aditsu.txt  0.06s user 0.00s system 95% cpu 0.058 total
./mult-aditsu > mult-aditsu.txt  0.05s user 0.00s system 97% cpu 0.055 total
./mult-aditsu > mult-aditsu.txt  0.06s user 0.00s system 99% cpu 0.056 total
./mult-aditsu > mult-aditsu.txt  0.05s user 0.00s system 99% cpu 0.054 total
./mult-aditsu > mult-aditsu.txt  0.05s user 0.00s system 98% cpu 0.055 total

md5sum *.txt
6eef8511d3bc5769b5d9218be2e00028  mult-aditsu.txt
6eef8511d3bc5769b5d9218be2e00028  mult-anatoly.txt
6eef8511d3bc5769b5d9218be2e00028  mult-anders.txt
6eef8511d3bc5769b5d9218be2e00028  mult-peter.txt

Uma resposta que merece uma recompensa. Interesso-me particularmente por esse problema (e sua solução inicial), porque é um caso especial do problema de soma de subconjuntos , que é conhecido por ser NP-completo (dada uma lista dos resíduos de 10ⁱ mod n , encontre o subconjunto mais antigo que soma n ).
Primo

@primo Obrigado :) Minha abordagem aqui é diferente - duplico o número de dígitos em cada etapa, em vez de apenas incrementá-lo, e também verifico primeiro (muito rapidamente) se algum dos novos números seria uma solução, antes de realmente calcular eles. E tenho certeza de que ainda há espaço para jogar golfe.
Aditsu 28/10/2015

Interessante. Quando tentei dobrar o número de dígitos em cada etapa, acabou sendo mais lento. Talvez a pré-verificação de soluções faça uma grande diferença.
27516 Peter

@ PeterTaylor isso é possível .. parece que você também está chamando calloc em um loop, o que pode atrasá-lo. De qualquer forma, gostaria de adicionar uma versão não-gasta do meu código quando encontrar algum tempo, e também tenho uma idéia de como torná-lo mais rápido para números maiores / mais desagradáveis.
Aditsu 28/10/2015

2

T-SQL, 164 156 155 154 159 bytes

(-1 byte. Obrigado Jonathan!)

(-1 mais porque porque tenho espaços à direita nas linhas? SMH)

(+5 percebi que meu golfe quebrou as coisas)

create function b(@ int)
returns int
as begin
declare @b varchar(max)='',@i int=@
while @>0SELECT @b=cast(@%2 as varchar)+@b,@/=2
return cast(@b as int)/@i
end

Não sei por que continuo voltando a essas perguntas, onde devo converter em binário ... O T-SQL não sabe como fazer isso direito.

De qualquer forma, aqui está um SQLFiddle .

Sem golfe:

create function binarySquare(@id int)
returns int 
as BEGIN

A maioria dessas coisas é necessária para escrever uma função no T-SQL, até onde eu saiba.

    declare @bin nvarchar(max) = ''

Crie uma string em branco que vamos armazenar como nosso número binário.

    declare @id2 int = @id

Salve o valor de entrada para uso no final. Parece que deve haver uma maneira de usar a entrada original, mesmo se alterarmos o valor, mas não consigo encontrar uma.

    while @id>0
      BEGIN
        SET @bin = cast(@id%2 as varchar(1)) + @bin

Então pegamos nossa entrada original, MOD com 2 para encontrar o restante, e esse será o próximo dígito menor. Por exemplo, 5% 2 = 1

        SET @id = @id/2

Então pegamos nosso número e dividimos ao meio. Como é um inttipo, ele o arredonda para o número inteiro mais próximo, então 5/2 = 2. END Em seguida, fazemos um loop até o valor ser 0. Então, terminamos com 5% 2 = 1 5/2 = 2 2 % 2 = 0 2/2 = 1 1% 2 = 1 1/2 = 0, o que nos dá o valor da sequência binária de 101.

    declare @binNum int = (SELECT cast(@bin as int))

Pegamos nossa string binária e a convertemos novamente em uma intnovamente.

    return @binNum/@id2

Retornamos nossa string binária intdividida por nosso valor original, de acordo com a origem da pergunta.

END

O espaço @>0 SELECTnão é omitível?
Jonathan Frech 22/09

Boa pegada! Nunca me lembro de quais espaços são capazes de omitir ...
phroureo

Na maioria das vezes, você pode omitir espaços entre literais e variáveis ​​/ palavras-chave, pois eles não podem começar com um dígito.
Jonathan Frech 22/09

1

Ruby, 46 bytes

Eu realmente deveria eliminar o loop while com um loop alternativo.

n,k=gets,0;$_="#{n.to_i*k+=1}"while/[^01]/;p k

Edit: Obrigado @manatwork por raspar 1 byte!

Edit2: Obrigado @histocraft pelos 9 bytes insanos!

Edit: Obrigado @manatwork novamente por raspar 7 bytes!


z!=z[/[01]+/]é mais curto. z[/[^01]/]é ainda mais curto.
manatwork

@manatwork Thanks! 1 byte a menos!
Peter Lenkefi

2
Os loops de linha única tendem a ser os mais curtos: z="#{n.to_i*k+=1}"while z[/[^01]/]
histocrat 16/10/2015

@histocrat São 9 bytes! E eu nem sabia que ruby ​​é capaz disso. Obrigado!
Peter Lenkefi

Interessante que você não alterou o teste para um conjunto de caracteres negados nem depois foi sugerido pela segunda vez. Qualquer razão?
manatwork

1

Scala, 114 bytes

val i=scala.io.StdIn.readInt;Stream.from(1).foreach{x=>if((i*x+"").map{_.asDigit}.max<2){print(x);System.exit(0)}}

Versão legível

val i=scala.io.StdIn.readInt
Stream.from(1).foreach{x => 
    if((i*x+"").map{_.asDigit}.max<2) {
        print(x)
        System.exit(0)
    }
}

1

força bruta gawk4, 28 + 2 = 30 bytes

{while(++n*$0~/[2-9]/);}$0=n

Precisa ser chamado com o -M opção de usar grandes números. É claro que isso é ridiculamente lento, o uso de grandes números diminui ainda mais, mas teoricamente a entrada não é limitada e o uso da RAM é insignificante.

Exemplo de uso (se você tiver tempo a perder ;))

echo 27 | awk -M '{while(++n*$0~/[2-9]/);}$0=n'

gawk4 otimizado, 69 + 2 = 71 bytes

{for(;!a[0];NR*=10)for(i in a)a[j=(s=a[i]+NR)%$0]?0:a[j]=s}$0=a[0]/$0

Bem, isso acabou sendo um clone da resposta do aditsu. Depois de analisar essa pergunta, eu ainda estava tentando descobrir como codificar a parte do subconjunto, quando não pude resistir a olhar para as outras respostas aqui.

No awk, os elementos da matriz têm o comportamento (estranho?) De que, se você comparar um elemento não existente com algo, ele é inicializado como vazio antes de ser comparado (admito que não tenho muita certeza do que está acontecendo lá). Então, depois de verificar !a[0]ofor(i in a) loop começa mesmo sem inicializara[$0] do 0aditsu.

Claro que o -M opção também deve ser usada para isso.

Embora seja bastante rápido, ainda é notavelmente mais lento que o Python. Para 79992isso leva cerca de 14 segundos em minha 2GHz Core2Duo. E eu não diria que funciona para entradas de até 2 ^ 31, porque, na pior das hipóteses, ele precisa criar uma matriz de grandes números (o gawk4 usa GMP para isso), que tem o tamanho do número de entrada. Como um 'bônus', grandes matrizes são muito lentas no awk ...


1

Dyalog APL , 25

Isso define um programa adequado "P" (não apenas uma função sem nome):

P←2∘{0::⍵∇⍨1+⍺⋄⍺⊣~⍎¨⍕⍺×⍵}

2∘comece com 2 como argumento à esquerda,
0::se houver algum erro ...
⍵∇⍨1+⍺chame a si mesmo com um argumento à esquerda incrementado
⍺×⍵multiplique os argumentos à esquerda e à direita
transformados em cadeia de
⍎¨caracteres
~. else ...)
⍺⊣retorna o argumento atual à esquerda.

      P 2
50
      P 21
481
      P¨⍳8    ⍝ 1 through 8
10 5 37 25 2 185 143 125
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.