Yarı kurak bir faktörü ortaya çıkaran en küçük çarpan


16

Bir yarı-yarı N verildiğinde , N'nin iki faktörünün ikili temsili N * m'nin ikili gösteriminde bulunabilecek şekilde en küçük pozitif tamsayı m'yi bulun .

Misal

En yarıasal düşünelim N = 9799 .

1'den başlayarak farklı m değerleri deneriz :

 m |  N * m |   N * m in binary
---+--------+------------------
 1 |   9799 |    10011001000111
 2 |  19598 |   100110010001110
 3 |  29397 |   111001011010101
 4 |  39196 |  1001100100011100
 5 |  48995 |  1011111101100011
 6 |  58794 |  1110010110101010
 7 |  68593 | 10000101111110001
 8 |  78392 | 10011001000111000
 9 |  88191 | 10101100001111111
10 |  97990 | 10111111011000110
11 | 107789 | 11010010100001101

Geçen ürünün ikili gösterimi içerdiğinden burada durdurmak 101001ikili temsilidir ki 41 , iki faktörlerden biri 9799 (diğeri varlık 239 ).

misal

Yani cevap 11 olur .

Kurallar ve notlar

  • M değerlerini bile denemek anlamsızdır. Yukarıdaki örnekte tamlık uğruna gösterilmiştir.
  • Programınız herhangi desteklemelidir N kendisi için Nm dilinizin bilgi işlem yetenekleri dahilindedir.
  • Sen çarpanlarına izin verilen N ikili gösterimi her olası alt dize çalışırken daha önceden yerine N * m o bir faktör olarak çıkıyor olmadığını görmek için N .
  • MitchellSpector tarafından kanıtlandığı gibi , m her zaman vardır.
  • Bu kod golf, bu yüzden bayttaki en kısa cevap kazanır. Standart boşluklar yasaktır.

Test senaryoları

İlk sütun girdi. İkinci sütun beklenen çıktıdır.

         N |    m |         N * m |                              N * m in binary | Factor
-----------+------+---------------+----------------------------------------------+-------
         9 |    3 |            27 |                                      [11]011 |      3
        15 |    1 |            15 |                                       [11]11 |      3
        49 |    5 |           245 |                                   [111]10101 |      7
        91 |    1 |            91 |                                    10[1101]1 |     13
       961 |   17 |         16337 |                             [11111]111010001 |     31
      1829 |    5 |          9145 |                             1000[111011]1001 |     59
      9799 |   11 |        107789 |                          1[101001]0100001101 |     41
     19951 |   41 |        817991 |                       1[1000111]101101000111 |     71
    120797 |   27 |       3261519 |                     11000[1110001]0001001111 |    113
   1720861 |  121 |     208224181 |               11000110100[100111111101]10101 |   2557
 444309323 |  743 |  330121826989 |    100110011011100110010[1101010010101011]01 |  54443
 840000701 | 4515 | 3792603165015 | 11011100110000[1000110000111011]000101010111 |  35899
1468255967 |   55 |   80754078185 |      1001011001101010100010[1110001111]01001 |    911

Hmm, Blackjack dizisi mücadelesinde kullandıklarımıza benzer bir algoritma kokusu alıyorum ...
ETHproductions

@ETHproductions Hmm, gerçekten mi? Dürüst olmak gerekirse tamamen ilgisiz olmaları gerekiyor.
Arnauld

Aslında, her bir bitişik alt dizeyi belirli bir özellik için kontrol etmeniz gerektiğinden temel olarak benzerler. Bunun dışında gerçekten çok ilgisizler.
ETHproductions

"ve muhtemelen cesaretlendirildi" - Üzgünüm. Kodumuzun hızını umursamıyoruz.
John Dvorak

@JanDvorak Yeterince adil. Kaldırıldı.
Arnauld

Yanıtlar:


6

Pyth, 13 bayt

ff}.BY.B*TQPQ

gösteri

Açıklama:

ff}.BY.B*TQPQ
f                Find the first integer >= to 1 where the following is true
 f         PQ    Filter the prime factors of the input
        *TQ      Multiply the input by the outer integer
      .B         Convert to a binary string
   .BY           Convert the prime factor to a binary string
  }              Check whether the factor string is in the multiple string.

6

05AB1E , 18 16 15 bayt

Riley sayesinde -2 bayt!

Emigna sayesinde -1 bayt!

[N¹*b¹Ñ¦¨båOiNq

Açıklama:

[                   # Infinite loop start
 N                  # Push the amount of times we have iterated
  ¹*               # Multiplied by input
    b              # Convert to binary
     ¹Ñ¦¨b         # Calculate the proper divisors of the input in binary excluding one
          åO       # Check if a substring of N * m in binary is in the divisors
            iNq    # If so, print how many times we have iterated and terminate the program

Çevrimiçi deneyin!


¹Ñ¦¨båOher bir alt dizeyi kontrol etmek yerine çalışmalıdır.
Riley

@Riley bunu tespit ettiğiniz için teşekkürler!
Okx

2
Değiştirerek ¼ve ¾ile başka bir bayt kaydedebilirsiniz N.
Emigna

@Emigna Bu numarayı bilmiyordum, teşekkürler!
Okx

4

JavaScript (ES6), 96 95 80 bayt

n=>F=m=>(k=p=>p&&(q=1,g=x=>1<x&&x<n&n%x<1|g(x>>1,q*=2))(p)|k(p-q))(n*m)?m:F(-~m)

Özyinelemeli işlev kullanan özyinelemeli işlev kullanan özyinelemeli işlev döndüren işlev. Gerçekten .toString(2)rotanın daha kısa olup olmayacağını merak etmeye başlıyorum ...

Bir değişkene atayın f=n=>...ve fazladan bir çift paren ile çağırın f(9)(). Buna izin verilmiyorsa ( meta yayın + 6 / -2'de), bu 83 baytlık sürümü standart çağırma ile kullanabilirsiniz:

f=(n,m)=>(k=p=>p&&(q=1,g=x=>1<x&&x<n&n%x<1|g(x>>1,q*=2))(p)|k(p-q))(n*m)?m:f(n,-~m)

Her iki versiyon da son üç test durumu hariç hepsi için çalışır. Sen değiştirerek de bu test durumları deneyebilirsiniz x>>1için (x-x%2)/2.


Bu konuda gerçekten bir fikir birliği olup olmadığından emin değilim (kayıt sırasında + 6 / -2'deyiz), ancak endişelendiğim kadarıyla, ilk giriş formatı iyi.
Arnauld

3

Bash + Unix yardımcı programları, 85 84 bayt

for((;;m++)){ dc -e2o$[$1*m]n|egrep -q $(dc "-e2o`factor $1`nBEPn")&&break;}
echo $m

Çevrimiçi deneyin!


Ayrıca, m'nin her yarı yarıda n her zaman var olduğunu da göstereceğim. İşte nedeni:

N = pq yazın, burada p ve q asaldır ve p <= q olur.

B n-1'in ikili gösterimindeki hane sayısını alalım. Daha sonra, 0 ve n-1 dahil olmak üzere herhangi bir k için, ikilikteki p * (2 ^ b) + k, p'nin ikili gösteriminden sonra k temsil eden b ek bitlerden oluşur.

Bu nedenle, 0 <= k <= n-1 için p * (2 ^ b) + k sayıları, ikili olarak yazıldığında, tümü p'nin ikili gösterimi ile başlar. Ancak bunlar ardışık n sayılarıdır, bu nedenle bunlardan biri n'nin katı olmalıdır.

Sonuç olarak, ikili temsili p'nin ikili temsili ile başlayan bir çoklu mn'ye sahibiz.

Buna dayanarak, biri 2 m2 (n) m için bir üst sınır ortaya çıkabilir. (Muhtemelen bundan daha sıkı bir üst sınır elde edilebilir.)


2

Haskell, 161 bayt

import Data.List
(!)=mod
a#b|a!b==0=b|0<1=a#(b+1)
g 0=[]
g n=g(n`div`2)++show(n!2)
(a%b)c|g b`isInfixOf`g(a*c)=c|0<1=a%b$c+1
f n=min(n%(n#2)$1)$n%(n`div`(n#2))$1

Kolay kontrol. Önce faktör, ardından 1'den başlayarak doğrusal olarak arama yapın ve her iki faktör için minimum değeri alın.

Geçen testcase için birkaç saniye sürer ( 1468255967), ghciraporlar (15.34 secs, 18,610,214,160 bytes)Laptop'ıma.


2

Mathematica, 83 bayt

1//.x_/;FreeQ[Fold[#+##&]/@Subsequences@IntegerDigits[x#,2],d_/;1<d<#&&d∣#]:>x+1&

2

Brachylog (2), 14 bayt

ḋḃᵐD∧?:.×ḃs∈D∧

Çevrimiçi deneyin!

Bunu Brachylog'da 14 baytta yazmanın birden fazla yolu var, bu yüzden en verimli şekilde gittim. Brachylog gönderimlerinde yaygın olduğu gibi, bu bir işlev gönderimidir; girdisi yarı çarpı, çıktı çarpanıdır.

açıklama

ḋḃᵐD∧?:.×ḃs∈D∧
ḋ               Prime decomposition (finds the two prime factors)
 ḃᵐ             Convert each factor to binary
   D            Name this value as D
    ∧?          Restart with the user input
      :.×       The output is something that can be multiplied by it
         ḃ      to produce a number which, when expressed in binary
          s     has a substring
           ∈D   that is an element of D
             ∧  (suppress an implicit constraint that D is the output; it isn't)

Prolog ve Brachylog'un değerlendirme sırası, girişten hemen çıkarılamayan ilk kısıtlama tarafından belirlenir. Bu programda, bu çarpma işleminin sonucu üzerinde bir kısıtlama olduğundan, yorumlayıcı çarpmanın işlenenlerini mümkün olduğunca 0'a yakın tutmayı amaçlayacaktır. İşlenenlerden birini biliyoruz ve diğeri çıktı, bu yüzden yapabileceğimiz en küçük çıktıyı buluyoruz, bu tam olarak istediğimiz şey.


1

PowerShell , 136 bayt

param($n)$a=2..($n-1)|?{!($n%$_)}|%{[convert]::ToString($_,2)};for(){$b=[convert]::toString(++$m*$n,2);if($a|?{$b-like"*$_*"}){$m;exit}}

Çevrimiçi deneyin!

PowerShell'de ikiliye dönüşümün çalışması nedeniyle çok uzun. : - /

Giriş alır $nyoluyla, döngüler 2için $n-1faktörlere üzerinden çeker !($n%$_). Bunları bir döngüye gönderir |%{...}ve converther birini bir ikili (temel 2) dizeye gönderir . Bu ikili dizeleri içine saklar $a.

Sonra sonsuz bir for(){...}döngüye giriyoruz . Her yineleme, biz artırır ++$m, çarpma tarafından o $nve convertbir ikili dizeye, depolanmış olduğu içine $b. Sonra, ifbu dize regex -likeherhangi bir dizeleri $a, biz çıktı $mve exit.


0

Perl 6 , 66 bayt

->\n{first {(n*$_).base(2)~~/@(grep(n%%*,2..^n)».base(2))/},^∞}

Regex tabanlı.

Süper yavaş, çünkü denenen her sayının her normal ifade eşleştirme konumunda n faktörlerini tekrar tekrar zorlar .

Faktörleri sadece bir kez hesaplamak performansı artırır, ancak 72 bayt yapar:

->\n{my @f=grep(n%%*,2..^n)».base(2);first {(n*$_).base(2)~~/@f/},^∞}
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.