Ondalık gösterimi ikili gibi görünen belirli bir sayının katını bulma


34

Kod İnceleme sitesinde ilginç görünen bir soru ile karşılaştım. Bence OP yanlış yapıyor ama emin olamıyorum ... O yüzden hadi onun için çözelim! (bir program yaz, fonksiyon / prosedür değil)

Giriş (stdin veya benzeri):

xOndalık gösterimli bir tam sayı . 1'den büyük ve 2 ^ 31'den küçük.

Çıktı (stdout veya benzeri):

yOndalık gösterimli bir tam sayı . x * yOndalık gösterimli ürün yalnızca 0 ve 1 rakamlarını içermelidir. Bu sayı 0'dan büyük en az olmalıdır.

Not: çıktı sınırlı değil - en az y10 ^ 100 civarındaysa, programınız 100 basamağın tümünü çıkarmalıdır (2 ^ 64 gibi makul bir sınır olup olmadığını bilmiyorum y- açık değil) ).

Programınız tüm menziler için makul bir sürede (1 saniye - 1 saat? - buna benzer bir şey) xbitmelidir.

Bonus:

Programınızın girişin boyutu üzerinde bir sınırı yoksa (RAM hariç) ve polinom karmaşıklığı varsa, programınızın bayt sayısını, 0.8aşağı ve yukarı çarpın .


Örnek: Giriş 2; çıktı 5, çünkü 2 * 5 = 10

Örnek: Giriş 21; çıktı 481, çünkü 21 * 481 = 10101


Feragatname: Kod İnceleme sitesindeki sorudan sorumlu değilim. Herhangi bir tutarsızlık olması durumunda, sadece yukarıdaki açıklama uygun özellik olarak kabul edilmelidir.

OEIS A079339


6
Her zaman çözülebilir olmalıdır. Açıkça, sınırsız sayıda n olacak şekilde en az bir q bulunmalıdır, öyle ki, 10 ^ n mod x = q. Bu gibi n değerlerini x alın ve ilgili güçleri 10 ^ n ekleyin.
feersum

1
9 katları alışılmadık derecede yüksek sonuçlar veriyor gibi görünüyor.
SuperJedi224

1
İlgili Proje Euler sorunu , bu sorunun tanıdık
geldiğini

1
Polinom karmaşıklığı ile girişin basamağındaki polinomu veya girişin değerindeki polinomu mu kastediyorsunuz?
Reto Koradi

3
@anatolyg mayın kaba kuvvet değil
aditsu

Yanıtlar:


8

Pyth, 9 bayt

f!-`*TQ10

gösteri

Her bir çoklu için, bir dizgeye dönüştürün, içindeki rakamları çıkarın 10(bu örnekte Pyth'in kullanışlı int komutunu kullanarak) ve daha sonra mantıksal olarak reddedin ve sadece doğru çoklu bulunduğunda susturmayı sonlandırın.

Bonus çözümü, 10 bayt:

f.xi`*TQ2Z

Bu çözüm gerçekte, sayının dize gösteriminin bir ikili sayı ( i ... 2) olarak ele alınabildiğini kontrol eder ve bu denemede bir hata atılmadığında sona erer.


18

Python 2, verimli çözüm, 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

Bazı golf ipuçları için Sp3000 teşekkürler.

Herkese, cevap vermenin ne kadar uzun sürdüğünü (kendi cevaplarıyla) göndermeleri için herkese meydan okuyorum 72ya da 99:) Eğer gerçekten hızlılarsa, bir 79992sonraki gibi bir şey deneyiniz (hala burada <1 sn).

Açıklama:

Bunun gerekli olmadığını düşündüm (kod oldukça okunaklı olduğu için), ancak bir istek aldım, işte burada:

İlk fikir, ikili görünüşlü bir sayının, 10 veya 1'den daha fazla farklı güç toplamı olmasıdır. Bu nedenle, geri kalan 0 olana kadar 10'un farklı güçlerini farklı şekillerde eklemeye çalışabiliriz.

Bunu saf bir şekilde yaparsak, tüm ikili görünüşlü sayıları oluşturmak ve bunları test etmekle aynı şeydir. Ancak birçok geri kalan aynı olacaktır. Daha iyi bir yol, yalnızca belirli bir geri kalanı veren en küçük sayıyı kaydetmektir ve art arda kaydettiğimiz sayılara 10'dan daha büyük güçler eklemektir. Programın yaptığı bu.

dAnahtarların geri kalan ve değerlerin geri kalanı ile ikili görünümlü sayılar olduğu bir sözlük / haritadır. İlki n:0özel bir durumdur: buna 0:0güçler eklemeye başlayabileceğimiz söylenebilir, ancak algoritma 0 tuşunu bulduğunda durur, ben de nbunun yerine kullandım , aynı etkiye sahip olduğu ve diğer değerleri etkilemeyeceği garanti edilir.

Daha sonra kmevcut tüm sayılara 10'luk (depolanan ) güçler eklemeye ve kalanları kaydetmeye başlarız . kKalan noktaya: (x+k)%nve sayıya:, ekleriz d[x]+kve yalnızca yeni bir kalansa: kaydederiz d.setdefault(…), sonra bir sonraki güce gideriz: k*=10ve 0 anahtarını alana kadar tekrar edin:while min(d)

Sonunda d[0], geriye kalan 0 mod olan ikili görünümlü sayıyı verir n, bu yüzden nçözümü almak için böleriz .

Not: Program, çok sayıdan kaçınarak (10'luk güçlerden ziyade üstleri kaydetme ve önceki değerlerden güçlerin kalanlarını hesaplayarak) daha verimli hale getirilebilir, ancak kod golf, yani ...

Aslında, burada daha hızlı bir sürüm yazdım:

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
Cevabım da anlamadı. xD "Dangit, Java, varsayılan olarak BigInteger kullanarak Integer.MAX_VALUE seçiminizi lanetleyin!" - Şimdiye kadarki her Java Programcısı
Addison Crump

@VTCAKAVSMoACE neden Uzun kullanmıyorsun?
aditsu

Hmm. Fazladan bir bayt ama buna değer. Teşekkürler!
Addison Crump

Ya da değil. Bu aslında onu ciddi biçimde azaltır. Teşekkürler!
Addison Crump,

1
99 çözme zamanlamaları: aditsu: 0.001 saniye; xnor: 5+ saat ve hala tamamlanmadı.
user193661

13

Python 2, 47 bayt

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

Giriş numarasını nve geçerli çoklu izlemeyi izler a. aİkili göründüğü zaman , oranın çıktısını alın a/n. Bir sayının 0's ve 1' lerden oluştuğunu kontrol etmek için , dize gösterimindeki maksimum karakteri karşılaştırırız '1'.

Kullanımları str(a) yerine `a`biten uzun ürünler önlemek için L. Ne yazık ki, 'L'daha büyük '1'.


12

Perl, 27 bayt

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

Shebang'ı bir olarak sayarak girdi stdin'den alınır.

Örnek Kullanım

$ echo 2 | perl dec-bin.pl
5

$ echo 21 | perl dec-bin.pl
481

$ echo 98 | perl dec-bin.pl
112245

Perl, 25 bayt

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

İki baytlık bir gelişme @ Skmrx .

Bir regex'e bakmak yerine, bunun yerine ürünü bir ikili hazır bilgi olarak değerlendirmeyi dener. Başarısızlık üzerine, bir sonrakine geçer. Genellikleoct işlev bu amaç için kullanılacaktır, ancak bu zorlamada kullanışlı olmayan geçersiz rakamları sessizce keser.


Perl, 40 bayt

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

Çok daha verimli bir çözüm. İkili gösterimler üzerinde yineliyoruz, 10 üssü olarak yorumluyoruz ve sonra bölünebilirliği kontrol ediyoruz. 100'ün altındaki tüm değerler için çalışma süreleri ihmal edilebilir.

Örnek Kullanım

$ echo 72|perl dec-bin.pl
1543209875

$ echo 99|perl dec-bin.pl
1122334455667789

2
Güzel :) Bugün gönderinizden birkaç yeni şey öğrendim! Kodunuzu okurken, ilk koddan birkaç eval"0b".$_*++$\||redo}{
byte'ı

Fakat use bigintOP'nin desteklenmesi için zorunlu olduğu çok sayıda kişiyi desteklemek için
eklememiz gerekecek sanırım

1
@ skmrn Bu mükemmel. Denedim oct'0b'.++$\*$_, ama geçersiz sayıları sessizce keser. Onun evalyerine kullanmayı düşünmedim .
primo

11

Javascript, 43 bayt

Bu düşündüğümden çok daha kısa sürdü. Temelde y1'e kadar artar y * (input number) = (binary-looking number). Açıkçası oldukça verimsiz.

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


Javascript (daha verimli çözüm), 53 bayt

Bu bir ykadar ikili olarak artmaktadır y / (input number) = (number without a remainder). Sonra çıktılar (number without a remainder).

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


Javascript (daha da verimli çözüm), 76 bayt

Bu, yukarıda açıklanan önceki yöntemlerin ikisini de birleştirir. yYa da y * (input number) = (binary-looking number)(çıkışın olduğu anlamına gelir y) OR y / (input number) = (number without a remainder)(çıkışın olduğu anlamına gelir ) kadar artışları kontrol eder (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)


Mümkün olduğunda 1 vermelidir (örnek giriş: 1)
edc65

@ edc65 Sabit - bayt sayısında değişiklik olmadan!
Mama Fun Roll

Bu Safari 9.0 çöküyor. Jussayin'. :)
Addison Crump

1
Ancak çıktıdaki küçük sayılarla sınırlıdır. Javascript numaraları 17 basamaklıdır, OP daha büyük bir şey istiyor (ve modüler aritmetik kullanılarak yapılabilir)
edc65

Protip: Giriş 72'yi denemeyin. Firefox 41 15 dakika donuyor ve sonra kilitleniyor. Bunu zor yoldan keşfettim.
ETHProductions 17:15

9

Haskell, 72 70 64 60 58 bayt

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

Düzenleme: @Jan Dvorak 4 bayt kaydetmeme yardımcı oldu.

Düzenleme: @BlackCap donotasyona geçerek 2 bayt kaydetti . Teşekkürler!


main=print.f=<<readLn
John Dvorak

F:main=readLn>>= \x->print$[y|y<-[1..],all(<'2')$show$x*y]!!0
BlackCap

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

@ BlackCap: Güzel! Çok teşekkürler!
nimi

7

Python 2, 67 65 63 60 bayt

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

2 baytlık Durum ve 5 baytlık Shebang için teşekkürler !


1
b=1
Başlamanız

2
Yaparak 2 bayt tıraş edebilirsinizany(c in`a*b`for c in'23456789')
Durum

1
Bundan emin değilim ama not c in`a*b`for c in'10'işe yarar mı?
cole,

2
Süre koşulunuzu değiştirerek 6 bayt tasarruf edebilirsiniz set('a*b')&set('23456789').
Kade

2
`bir Luzun süre için üretir ve 'L'>'1'.
user193661

6

JavaScript (ES6) 222 250

Keyfi hassasiyetli matematik kullanma (ondalık basamak dizelerinde çalışma)

Bu biraz daha golf olabilir (bitti), ancak JS standart numaraları (17 ondalık basamak) ile sınırlı olmaması ve hızlı olması gerçeğini seviyorum.

Aşağıdaki pasajı EcmaScript 6 uyumlu bir tarayıcıda çalıştırmayı test edin. Zaman 9998'e kadar kabul edilebilir - 9999'u denemeyin ve 999'a sabırlı olun.

// 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>

Daha okunabilir

Bu, ilk sürüm, modulus ve ayrı fonksiyonlar olarak uzun bölünme ile.

// 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]
}

Firefox'ta çalışmasını
sağladım

999'u 36 saniyede idare edebilecek yeni bir sürümüm var, ancak javascript zaman aşımı ile 9999'a ulaşma umudum yok (eklenen her '9', bitirme zamanının 2 ^ 9 (~ 500) kez yapılmasını gerektiriyor)
edc65

@aditsu, JavaScript'te yapabileceğimin en iyisidir (ancak C # ile aynıdır). Eaherly size inanılmaz bir algoritma bir açıklama için bekliyorum
edc65

Şimdi bir açıklama ekledim
aditsu



4

PHP, 50 bayt

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

Bazı test durumları

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

1
Böyle bir şey yapacak mıydı, bu benim aklımdan biraz daha kısa
Martijn

4

CJam, 19 17 16 bayt

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

Çevrimiçi deneyin

Kaba kuvvet çözümü, koşulu bulana kadar sırayla değerleri denemek.

En son sürüm içeren bir dize oluşturmak Asyerine kullanmak yerine 2 bayt kazandırır"01"0 ve 1@aditsu tarafından önerildiği gibi,. Yorumdaki önerilen çözüm, başka bir bayttan tasarruf sağlar, ancak benimkinden oldukça farklı görünüyor, bu yüzden adıma göndermek istemedim.

Ve @Dennis tarafından kaydedilen 1 bayt daha.

Açıklama:

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

Teşekkürler, @didiu. Tam çözümünüzü benim adım altında kopyalamak istemedim. Asİpin yapımını ben yaptım , çünkü bu çok yerel bir değişiklikti, çünkü (her zaman çok daha kolay olan) düşünmem gerekenlerdi.
Reto Koradi

1
@RetoKoradi 16 bayt, daha az değişiklik: li:V!{)_V*sAs-}gAyrıca, 0{)_easi*sAs-}g(15 bayt) Java yorumlayıcısı ve komut satırı argümanları ile çalışır.
Dennis,

4

Python 3 2, 101 76 Bayt

@Aditsu sayesinde -25 bayt

@ aditsu'nun çözümü kadar verimli

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

Artan sırayla katlar arasında dolaşmaya çalışmak yerine, 'ikili' formda ürettiğim ürünler arasında dolaşmaya çalışıyorum.


Fena değil :) Peki ya 9999?
aditsu 17:15

2
Bazı golf püf noktaları: python 2 ( n=input()) kullanın ( while b%n:(ilk bkullanıma 1), girinti yok
aditsu 17:15

@ditsu Teşekkürler! 9999 hmmm, birkaç gün sürecek gibi görünüyor, çizim tahtasına geri dönelim -_-
Rnet

1
bin(m)[2:]biçim dizesinden daha kısa olmalıdır. İkili atama b=m=1da birkaç kişiden tasarruf etmelidir.
primo

4

Java, 213 bayt

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);}}

Kullanımları BigInteger ve bu nedenle (tüm makul amaç ve amaçlar için) sınırlandırılmamış girdi boyutuna sahiptir. Ancak karmaşıklığından emin değiliz, buradaki işlevimizin büyüme hızına bağlı.

Bir avuç bayt tasarrufu için geobits ve ypnypn'a teşekkürler.


Merhaba, bunu ana yönteminizde nasıl çağırırsınız?
Deniyor

staticDeğiştiriciyi yönteme eklemeniz gerekir .
SuperJedi224

1
Soru, çözümün sadece bir işlev değil, eksiksiz bir program olması gerektiğini söylüyor.
raznagul

15 b.ONEve ile !(b.multiply(c)+"")(yerine toString()) kesebilir .
Geobits

@raznagul: Sabit.
SuperJedi224 16:15

4

C, 3675 bayt

Code Golf için çok uzun ...

#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);
    }
}

Hiçbir komut satırı parametreleri ile çalıştırın - bu gets ngelen stdinve sonucu çıkarır stdout. Bir dosya adı ile çalıştır - sonuçları için yazarn = 1...10000 o dosyaya ve zamanı ölçer.

1 ... 10000: 140 ms için performans

Bu kod, hız için C'de uygulanan aditsu tarafından önerilen algoritmayı kullanır . Golf oynamak için hiç çaba sarf etmedim, bu yüzden kodun okunması daha kolay olurdu.

İlk önce C ++ kullanarak std::maparamanın sonuçlarını kaydetmek için kullandım ve oldukça yavaştı. Ancak, tuşları mapardışık tamsayılardır (onları mods olarak adlandırıyorum, çünkü bunlar modulo sayılarını temsil ediyorlar).n ), bu yüzden bir dizi kullanmak doğaldır - bu yüzden C'yi yeniden yazdım.

Ek bir optimizasyon, haritalamanın değerleriyle ilgilidir - her biri için büyük bir tamsayı depolamaktan kaçınmak için mod, orada yalnızca 10 olan en büyük gücü saklıyorum - bir öncekine gitmek için yeterli bilgi mod. Yani dizi gerçekten bir arama ağacı / grafiğidir. Arama geldiğinde mod = 0, ağacın düğümlerini köke geri izlemek, azalan sırayla 10'un gücünü verir.

Arama genellikle hızlı bir şekilde durduğundan, yalnızca küçük bir düğüm kesimi ziyaret edildiğinde, aktif düğümlerin bir listesine ihtiyacım var. mod_listUzunluğu olan bir dizi olarak uygulanır mod_list_length.

Bazı çalışma zamanı istatistikleri (16 by RAM RAM olan bir makinede, bunlar büyük bellek için önemlidir n, çünkü program 5nbellek bayt ayırır):

  • Giriş 99999999- 2 saniye
  • Giriş 999999999- 27 saniye (sonuç111111111222222222333333333444444444555555555666666666777777777888888889 - muhtemelen 32-bit tamsayılar için mümkün olan en büyük sonuç)
  • Giriş 2147483647- 26 saniye (sonuç 4661316525084584315813)
  • Giriş 1999999998- 52 saniye (32 bit tam sayılar için muhtemelen mümkün olan en uzun çalışma süresi)

2
Ödülün peşinde olduğunuzu anlıyorum, ancak bu bile bir kod golf sorusu ve site kuralları kodunuzu golf oynamak için biraz çaba göstermenizi gerektiriyor .
Peter Taylor

Programınız 3546 bayt var.
aditsu

@aditsu CR / LF stilini kullanan Windows'taki bayt sayısını
ölçtüm

4

C ++ 11, çok sayıda bayt, çok hızlı, vay (1999999998'de 1.5 s, 1… 10000'de 0.2 s)

(Aşağıdaki Golf Python versiyonu.)

Aditsu'nun çözümüne biraz benzeyen bir konseptle başlıyoruz, burada n adımlarla ulaşılabilen modüler kalıntı koleksiyonu oluşturduk. Ancak, kalan 0'ı bulana kadar beklemek yerine, a ve b'de bulunan iki ve kalan 2 a'yı kontrol ederiz. · 10 ^ n + b = 0 olur. büyük girişlerde çok daha hızlı ve daha az bellek kullanıyor.

Bazı kriterler:

$ 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

Kod:

#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 bayt (1999999998'de PyPy ile 8.6 saniye içinde)

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
Ödülün peşinde olduğunuzu anlıyorum, ancak bu bile bir kod golf sorusu ve site kuralları kodunuzu golf oynamak için biraz çaba göstermenizi gerektiriyor .
Peter Taylor

1
@PeterTaylor, çok iyi, Python'da golf versiyonunu ekledim.
Anders Kaseorg

3

Mathematica 115 bayt

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 bayt

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);}}

Aditsu'ya çok teşekkürler :)


You don't need a space after [], y can be long too, you forgot the x*y+"" trick in the 2nd program, use isEmpty instead of checking the length, use ; instead of {}
aditsu

Anyway, welcome to code golf :)
aditsu

I must say, I am impressed, but making y long wouldn't make the code shorter
Joba

Yes it would: long x=…,y;
aditsu

y must start from 1, you can initialize it in the declaration, your class doesn't need to be public, and you can move y++ to the x*y part (x*y++)
aditsu

2

Pyth - 12 11 bytes

Uses filter with numeric arg to get first natural number that fulfills predicate, default is 1 which is what we want. Setwise diff to check if only zeros and ones.

f!-j*QT10U2

Test Suite.


Convert to string and remove "01. Saves one char.
Jakube

2

R, 45 bytes

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

Usage:

> 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

Thanks to @aditsu for shaving off 5 bytes AND increasing the range of testable numbers!

Note that some values loop negatively due to how Java parses integers. This could be circumvented by BigInteger, but the bonus was simply less valuable.

I know that I'm not going to win, but I hope this inspires other, shorter, answers.

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

Ungofled:

class A {
   public static void main(String[] a){
      for(long i=1;;i++){ // infinite loop starting at 1
         try{ // if an error is thrown by attempting to parse as binary, restart while adding 1 to i
            long b=Long.parseLong(a[0]); // For later - it was shorter to declare than use twice
            if(b*i<0)break; // Break out of the program if we have looped.
            Long.parseLong(b*i+"",2); // Multiply out and see if it's passable as a binary number, otherwise, throw error and go back to the top of the loop
            System.out.println(b); // print it out
         } catch (Exception e) {} // do nothing on catch
      }
   }
}

2
It's funny that Long is shorter than Integer :)
anatolyg

3
The most literal irony there is.
Addison Crump

2

C, 107 101 bytes (105 99 bytes for 32-bits)

There is a distinct lack of answers in C on code golf. Indeed, C is not the best choice for writing the smallest possible program, but it's not that bad:

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);}

You can do without the #includes, but then all the function definitions will be implicit. The main drawback is that this causes the assumption that all functions return ints. This is a problem on 64-bit machines for functions that actually return a pointer. If you are on a 32-bit machine, 2 bytes can be shaved off the above solution:

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

Somewhat more readable version:

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

C# time near 5 seconds (1 to 10000)

As requested, here is a golfed C# program answering the original challenge. Input as command line argument, output to 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);}}}

Then, as for the bounty: the bounty should go to aditsu, as I think his algorithm cannot be beaten in terms of perfomance. But anatolyg self-answer is amazing too.

Here is my fast implementation in C#. I suppose that in C++ it could be faster (maybe 2x). Compiled and tested with Visual Studio 2010, .NET framework 4, 64 bits, redirecting output to nul. Time : 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. I misspoke in the bounty. With the latest version of PyPy, aditsu's faster version times approximately 8s, so this is twice as fast.
primo

I understand that you're after the bounty, but even so this is a code-golf question, and the site rules require you to make some effort to golf your code.
Peter Taylor

I'm not after the bounty, it's just an example of implementation. But you're right, I'll add a golfed version.
edc65

@PeterTaylor could it go now?
edc65

By the way, why Keys.Reverse? Is the order important? If it's just to avoid concurrency issues, ToList is shorter.
Peter Taylor

2

C with GMP (621 bytes, fast)

I've tried to be fast and short, but favoured fast. This implementation uses a slightly improved version of the number-theoretic speedup I mentioned in a comment on aditsu's answer.

Save as pseudobinary.c and compile with gcc pseudobinary.c -lgmp -o pseudobinary. Note that this allocates so much memory for large inputs that you will need to compile it for a 64-bit platform.

#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;}

Loop version for timing (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;}

Ungolfed loop version

#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

This is really fast for smallish numbers; it starts to choke when the result has more than 64 digits.

#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));}

Version that loops to 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));}}

Here are some commands for testing my code as well as my competitors', and the results on my 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

An answer well-deserving of a bounty. I take particular interest in this problem (and your initial solution), because it is a special case of the subset sum problem, which is known to be NP-complete (given a list of the residues of 10ⁱ mod n, find the earliest subset which sums to n).
primo

@primo Thank you :) My approach here is different - I double the number of digits at each step rather than just incrementing it, and I also check first (very quickly) if any of the new numbers would be a solution, before actually calculating them. And I'm sure there's still room for golfing.
aditsu

Interesting. When I tried doubling the number of digits at each step it ended up being slower. Maybe the pre-check for solutions makes a big difference.
Peter Taylor

@PeterTaylor that's possible.. it seems that you're also calling calloc in a loop, which might slow it down. Anyway, I'd like to add an ungolfed version of my code when I find some time, and I also have an idea how to make it faster for bigger/nastier numbers.
aditsu

2

T-SQL, 164 156 155 154 159 bytes

(-1 byte. Thanks Jonathan!)

(-1 more because why do I have trailing spaces on lines? SMH)

(+5 realized my golfing broke things)

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

I don't know why I keep coming back to these questions where I'm supposed to convert to Binary... T-SQL doesn't know how to do that right.

In any case, here's a SQLFiddle.

Un-golfed:

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

Most of this stuff is required to write a function in T-SQL, as far as I'm aware.

    declare @bin nvarchar(max) = ''

Create a blank string that we're going to store as our binary number.

    declare @id2 int = @id

Save the input value for use at the end. It seems like there should be a way to use the original input even if we change the value, but I can't find one.

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

So we take our original input, MOD it with 2 to find the remainder, and that's going to be our next smallest digit. For example, 5%2 = 1

        SET @id = @id/2

Then we take our number, and divide it in half. Because it's an int type, it rounds it down to the nearest whole number, so 5/2 = 2. END We then loop through this until the value is 0. So we end up with 5%2 = 1 5/2 = 2 2%2 = 0 2/2 = 1 1%2 = 1 1/2 = 0 which gives us our binary string value of 101.

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

We take our binary string and convert it back to an int again.

    return @binNum/@id2

We return our binary string int divided by our original value, per the origin of the question.

END

Is the space in @>0 SELECT not omittable?
Jonathan Frech

Nice catch! I can never remember what spaces are omit-able...
phroureo

Most of the time you can omit spaces in between literals and variables / keywords, as they cannot begin with a digit.
Jonathan Frech

1

Ruby, 46 bytes

I should really eliminate the while loop with an alternative loop.

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

Edit: Thanks @manatwork for shaving off 1 byte!

Edit2: Thanks @histocraft for the insane 9 bytes!

Edit: Thanks @manatwork again for shaving off 7 bytes!


z!=z[/[01]+/] is shorter. z[/[^01]/] is even more shorter.
manatwork

@manatwork Thanks! 1 byte less!
Peter Lenkefi

2
Single-line while loops tend to be the shortest: z="#{n.to_i*k+=1}"while z[/[^01]/]
histocrat

@histocrat That's 9 bytes! And I didn't even know that ruby is capable of this. Thanks!
Peter Lenkefi

Interesting that you not changed the test to negated character set neither after was suggested 2nd time. Any reason?
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)}}

Readable version

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

1

gawk4 brute force, 28+2 = 30 bytes

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

Needs to be called with the -M option for using big numbers. Of course this is ridiculously slow, using big numbers slows it down even more, but theoretically the input is not limited, and RAM usage is negligible.

Usage example ( if you got time to waste ;))

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

gawk4 optimized, 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

Well, this ended up being a clone of aditsu's answer. After looking at this question I was still figuring out how to code the subset-sum part, when I couldn't resist looking at the other answers here.

In awk array elements have the (strange ?) behaviour that if you compare a non-existing element to something it is somehow initialized as empty before being compared (I'll admit that I'm not quite sure about what is happening there). So after checking !a[0] the for(i in a) loop starts even without initializing a[$0] to 0 as aditsu did.

Of course the -M option has to be used for this too.

Though it is rather fast it is still remarkably slower than Python. For 79992 this takes around 14 seconds on my 2GHz Core2Duo. And I wouldn't say it works for inputs up to 2^31, because in the worst case it has to build an array of big numbers (gawk4 uses GMP for this), which has the size of the input number. As a 'bonus' large arrays are very very slow in awk...


1

Dyalog APL, 25

This defines a proper program "P" (not just an unnamed function):

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

2∘ begin with 2 as left argument
0:: if there is any error...
⍵∇⍨1+⍺ call itself with an incremented left argument
⍺×⍵ multiply left and right arguments
make into string
⍎¨ make each character into a number
~ attempt logical NOT (if it fails, go to error-handling above, else...)
⍺⊣ return the current left argument.

      P 2
50
      P 21
481
      P¨⍳8    ⍝ 1 through 8
10 5 37 25 2 185 143 125
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.