Sahte sahte Golf!


9

Giriş / Arka Plan

Bir de son tartışmada yer kripto sohbet Birlikte / yardım görüşmek üzere meydan Fermat asallık testi ve Carmichael numaraları. Bu test a^(p-1) mod p==1her zaman primler için geçerli olacak p, ancak her zaman kompozitler için geçerli olmayan öncüllere dayanmaktadır . Bir dizi kendisi için: Artık bir Carmichael numarası Fermat testi en büyük düşmanı temelde zorunda almak adeğil eş-asal birlikte olmak piçin a^(p-1) mod p!=1. Şimdi eğer aeş-başlı değilse , aslında önemsiz olmayan bir faktör buldunuzpve hepimizin bildiği gibi faktoring oldukça zor olabilir. Özellikle tüm faktörler yeterince büyükse. Artık Fermat testinin pratikte neden sıklıkla kullanılmadığını (daha iyi algoritmalar var) fark edebilirsiniz, çünkü bir savunma oyuncusu olarak (güvenlik açısından) benzer miktarda iş yapmak zorunda kalacaksınız. bir saldırgan (yani sayı faktörü).

Şimdi bu rakamların neden biraz büyüleyici olduğunu bildiğimize göre , bunları mümkün olan en kısa şekilde üreteceğiz, böylece herhangi bir şeye ihtiyacımız olursa, üreten kodu ezberleyebiliriz!

Carmichael sayıları OEIS'de A002997 olarak da bilinir .
Orada bir olan ilgili sorun zaten, ama boyutu aksine onlar hız için optimize edilmiştir, çünkü oradan girişleri burada rekabetçi değil. Aynı argüman ters yön için de geçerlidir, buradaki girişlerin büyüklük lehine hıza karşı değiş tokuş yapması muhtemeldir.

Şartname

Giriş

Bu bir standart ngiriş olarak pozitif veya negatif olmayan bir tam sayı alırsınız . ntercih ettiğiniz gibi 0- veya 1 dizinli olabilir (lütfen belirtin).

Çıktı

Çıktınız ya tercih ettiğiniz gibi n-th carmichael numarası veya ilk ncarmichael numaraları olacaktır (lütfen belirtiniz).

Şartname

Bir tamsayı xbir Carmichael sayısı ise ve sadece eğer xkompozit ve tüm tamsayılar için ybirlikte gcd(x,y)=1, bu tutar y^(x-1) mod x==1.

Kim kazanır?

Bu , bayttaki en kısa kod kazanır!
Standart IO ve boşluk deliği kuralları geçerlidir.

Test Durumları

İlk birkaç carmichael numarası:

 561,1105,1729,2465,2821,6601,8911,10585,15841,
 29341,41041,46657,52633,62745,63973,75361,101101,
 115921,126217,162401,172081,188461,252601,278545,
 294409,314821,334153,340561,399001,410041,449065,
 488881,512461

Yanıtlar:



6

Python 2 , 92 bayt

f=lambda j,n=1:j and f(j-([(k/n)**~-n%n for k in range(n*n)if k/n*k%n==1]<[1]*~-n),n+1)or~-n

Çevrimiçi deneyin!

1 indeksli ve pekmez gibi yavaş.

Liste kavrayışında, Dennis'in yönteminin (n'nin totatifleri ) eş zamanlı olarak tüm tamsayıları üretmek için kullanıyorum ve sonra x**~-n%nhepsini hesaplıyorum . Bu listeyi çağıralım L.

Bir Carmichael numarasını tespit etmek için, bu listeyi sözlükbilimsel olarak bir listeyle karşılaştırıyorum n-1. Bu neden işe yarıyor?

Her bir elemanı L, bir pozitif tamsayıdır: (k/n)için göreceli asal olan n, bu yüzden (k/n)**~-n, bu yüzden de (k/n)**~-n%n > 0. Dolayısıyla, bunun tek olası değerleri Lsözlükbilimsel olarak daha düşüktür [1]*(n-1) ve tamamen küçük n-1 olanlardan oluşur. ( Lİçeremez daha fazla n-1olarak, değerler nfazla olamaz n-1totatives karşılaştırmalar gibi Yani! [1,1,1,1,3] < [1,1,1,1]Dışındadır.)

İçinde n-1girişlerden daha az olup olmadığını kontrol etmek kompozit Lolmasını sağlar n. ( n-1Totatiflere sahip olmak, ilkeliğe eşdeğer bir koşuldur.) Ve sonra, bir Carmichael numarası olmanın koşulu tam olarak her öğeye Leşittir 1. Yani bu sözlükbilimsel karşılaştırma tam olarak Lilgilendiğimiz şeyleri algılar .

Bay Xcoder, yinelemeli lambda formuna geçerek bir bayt kaydetti: jbir Carmichael numarasına nher bastığımızda geri sayım ve her tekrarladığımızda geri sayım. Yani bir kez jsıfıra çarptığında n-1, original_value_of_j"Carmichael" sayısına eşittir .


5

Jöle ,  12  11 bayt

Sayesinde -1 bayt mil ve Bay Xcoder (Carmichael fonksiyonu atomu ve bunun bir golf kullanımı)

%Æc’=ÆP
⁹Ç#

nİlk nCarmichael numaralarının bir listesini alan ve döndüren monadik bir bağlantı .

Çevrimiçi deneyin!

Nasıl?

Carmichael işlevi için bir önceki gibi (aşağıda) olduğu gibi - bu güce yükseltilen giriş, tüm tamsayılar için bu tamsayı için prime prime olan bir modulo ile uyumlu olacak şekilde en küçük gücü veren yerleşiktir. Böylece yanlış pozitifleri (primerleri) daha az bayt içinde hariç tutabiliriz ve daha hızlı kodlara sahip olabiliriz!

%Æc’⁼ÆP - isCarmichael: number, n (any integer)
 Æc     - Carmicael function of n
%       - n modulo that
   ’    - decremented (0 for Carmichael numbers and primes)
     ÆP - is n prime? (1 for primes 0 otherwise)
    ⁼   - equal?

⁹Ç# - Main link: number, n
  # - count up finding the first n values satisfying:
 Ç  - ...condition: call the last link as a monad
⁹   - ...starting with a value of: literal 256

Önceki 12 bayt :

Ṗ*%⁼Ṗ_ÆP
⁹Ç#

Çevrimiçi deneyin! (Evet, zaman aşımına uğradı n=3).

Nasıl?

cKompozit ise bir sayı, bir Carmichael numarasıdır ve xyükseltilmiş herhangi bir tamsayının modulo cile uyumlu olduğu doğrudur .xc

Biz sadece olumlu bu kontrol etmek gerekir xetmek kadar x=ckendisi.

Ayrıca x=ckontrol xsırasında gücüne yükseltilmiş modulo xile uyumlu olup olmadığına dikkat edin , bu doğrudur - bu yüzden bunu kontrol xetmemize xgerek yoktur (bu daha kısa kod sağlar).

Ṗ*%⁼Ṗ_ÆP - Link 1, isCarmichaelNumber: integer c (greater than 1)
Ṗ        - pop c (uses the implicit range(c)) = [1, 2, 3, ..., c-1]
 *       - raise to the power of c (vectorises) = [1^c, 2^c, 3^c, ..., (c-1)^c]
  %      - modulo by c (vectorises) = [1^c%c, 2^c%c, 3^c%c, ..., (c-1)^c%c]
    Ṗ    - pop c = [1, 2, 3, ..., c-1]
   ⁼     - equal? (non-vectorising) = 1 if so, 0 if not
      ÆP - isPrime?(c) = 1 if so, 0 if not
     _   - subtract = 1 if Carmichael 0 if not
         -     (Note the caveat that c must be an integer greater than 1, this is because
         -      popping 1 yields [] thus the equality check will hold; same for 0,-1,...)

⁹Ç# - Main link: number, n
  # - count up finding the first n values satisfying:
 Ç  - ...condition: call the last link as a monad
⁹   - ...starting with a value of: literal 256

Ayrıca 12 bayt, ancak ilk 33'ü bir dakikadan kısa bir sürede Carmichael atomunu kullanarak hesaplar.
mil

Dahili Carmichael işlevini kullanarak 11 bayt .
Bay Xcoder

@ Mr.Xcoder Ayrı ayrı gönderilen milleri önerecektim, sonra seninkini gördükten sonra yorumunu gördüm ve sildim. Dv, birinin bunun milden daha fazla yorum yaptığına benzediğini düşünüyor olabilir, ancak aynı şeyi bağımsız olarak bulamadığınızı düşünmek için hiçbir sebep olmadığından, bu bile garip bir sebep olduğunu düşünüyorum (biliyorum bu tür şeyleri defalarca yaptık). İsterseniz 11'inizi gönderirim, ancak siz veya millerin kredi alması gerektiğine inanıyorum.
Jonathan Allan

@miles too ... ^
Jonathan Allan

@JonathanAllan Sadece kendin gönder. Millerden ve
katkımdan bahsetmiştim ve millerin de

2

ECMAScript Regex, 86 89 bayt

Uyarı: Sizin için şımarık bir tek normal regex sihri istemiyorsanız bunu okumayın. Bu büyüyü kendiniz anlamaya çalışmak istiyorsanız, ECMAScript regex'teki bazı sorunları çözerek başlamanızı şiddetle tavsiye ederim: sırayla spoiler etiketli önerilen sorunların birer birer çözülmesi için bu önceki gönderiye bakın .

^(?!(x(x+))(?!\2*$)\1*(?=\1$)(?!(xx+)\3+$))((?=(xx+?)\5*$)(?=(x+)(\6+$))\7(?!\5*$)){2,}x$

Çevrimiçi deneyin!

# Match Carmichael numbers in the domain ^x*$ using Korselt's criterion
# N = input number (initial value of tail)
^
(?!
    # Iterate through factors \1, with \2 = \1-1, for which \2 does not divide into N-1
    (x(x+))
    (?!\2*$)           # Assert N-1 is not divisible by \2
    \1*(?=\1$)         # Assert N is divisible by \1; tail = \1
    # If the factor \1, which already passed the aboved tests, is prime, then fail the
    # outside negative lookahead, because N is not a Carmichael number.
    (?!(xx+)\3+$)
)
# Assert that N has at least 2 unique prime factors, and that all of its prime factors
# are of exactly single multiplicity (i.e. that N is square-free).
(
    (?=(xx+?)\5*$)     # \5 = smallest prime factor of tail
    (?=(x+)(\6+$))     # \6 = tail / \5 (implicitly); \7 = tool to make tail = \6
    \7                 # tail = \6
    (?!\5*$)           # Assert that tail is no longer divisible by \5, i.e. that that
                       # prime factor was of exactly single multiplicity.
){2,}
x$

Bu normal ifadenin ana büyüsü, N'nin asal faktörlerinin tamamının tek bir çoklukta olduğunu ileri süren kısımdır. Uzunluğu dördüncü bir güç olan ve En Yumuşak Numarayı Bul regexes: Maç dizeleri tarafından kullanılanla aynı hile : en küçük asal faktör tarafından tekrarlanan örtük bölüm.

N'nin mükemmel kare faktörleri olmadığını (N'nin kare içermediğini) doğrudan test etmek de mümkündür. Bu, bir sayının mükemmel bir kare olup olmadığını test etmek için bol miktarda regex postumun bir paragrafında kısaca açıklanan çarpma algoritmasının bir varyantını kullanır . Bu bir spoiler . Yani bazı gelişmiş tekli regex sihirli sizin için şımarık istemiyorsanız başka okumaz . Bu büyüyü kendiniz anlamaya çalışmak istiyorsanız, bu önceki yazıda arka arkaya spoiler etiketli önerilen problemler listesinde bazı problemleri çözerek ve matematiksel kavrayışları bağımsız olarak bulmaya başlamanızı şiddetle tavsiye ederim .

Ancak, bu algoritmanın bu sorun üzerinde kullanılması herhangi bir fayda sağlamaz. Daha büyük boyutta 97 bayt ile daha yavaş bir normal ifadeyle sonuçlanır. Asal çokluk testi olmadan (bir döngüde hem en az 2 asal faktörün olduğunu hem de her birinin tek çokluk olduğunu varsayar), N'nin bileşik olduğunu ayrı ayrı iddia etmeliyiz.

^(?!(x(x+))(?!\2*$)\1*(?=\1$)(?!(xx+)\3+$)|((xx+)\5*(?=\5$))?(x(x*))(?=(\6*)\7+$)\6*$\8)(xx+)\9+$

Çevrimiçi deneyin!


 ^
 (?!
     # Iterate through factors \1, with \2 = \1-1, for which \2 does not divide into N-1
     (x(x+))
     (?!\2*$)           # Assert N-1 is not divisible by \2
     \1*(?=\1$)         # Assert N is divisible by \1; tail = \1
     # If the factor \1, which already passed the aboved tests, is prime, then fail the
     # outside negative lookahead, because N is not a Carmichael number.
     (?!(xx+)\3+$)
 |
 # Assert that N is square-free, i.e. has no divisor >1 that is a perfect square.
     ((xx+)\5*(?=\5$))?  # cycle tail through all of the divisors of N, including N itself
     # Match iff tail is a perfect square
     (x(x*))             # \6 = potential square root; \7 = \6 - 1
     (?=
         (\6*)\7+$       # iff \6 * \6 == our number, then the first match here must result in \8 == 0
     )
     \6*$\8              # test for divisibility by \6 and for \8 == 0 simultaneously
 )
 (xx+)\9+$               # Assert that N is composite
 


2
(Açıkçası, bu bir decision-problemcevaptır, ancak zorluk bir sequencemeydan okumadır.) Muhtemelen daha güçlü bir regex varyantında kare bölücüler için daha doğrudan bir test olurdu?
Neil

@Neil Haklısın, doğrudan kare bölenleri test ederek golf oynayabilirim. ECMA'da ekstra özelliklere gerek yoktur. Ama bu çok daha yavaş yapacak (ve ayrıca bir spoiler etiketi altında gizlemek isteyeceğim). Her iki sürümü de eklemek isteyeceğim.
Deadcode

Evet, daha önce yazdığım regex'ler için, doğru tipte bir meydan okuma olmayan sorular bulmak çok can sıkıcı bir durum. Cevabımı silmeli miyim?
Deadcode

@Neil İşte. Algoritmanızı fikrinizi kullanarak uyguladım. Muhtemelen bu yüzden bunu kendi başıma sürdürmeyi düşünmedim; aslında daha uzun bir normal ifade ile sonuçlanır, çünkü bir is-kompozit test gereklidir.
Deadcode

(Site kurallarına göre cevabınızı silmelisiniz, evet.) Benim fikrim, Retina regex'lerinin ekstra özelliklerini kullanarak, onu ^(?!(x(x+))(?!\2*$)\1*(?=\1$)(?!(xx+)\3+$)|((^x|xx\5){2,})\4*$)(xx+)\6+$72 bayttan daha da aşağıya veya belki de daha az olabilir.
Neil


1

Retina , 94 bayt

\d*$
x
"$+"}/^(?!(x(x+))(?!\2*$)\1*(?=\1$)(?!(xx+)\3+$)|((^x|xx\5){2,})\4*$)(xx+)\6+$/^+`$
x
x

Çevrimiçi deneyin! 1 endeksli. Hızlı değil, bu yüzden n>5TIO için zaman aşımına uğrayacak . Açıklama:

\d*$
x

Geçerli değeri artırın. İlk geçişte bu n, çıkış arabelleğinden de silinir (ancak $+yine de erişebilir).

/^(?!(x(x+))(?!\2*$)\1*(?=\1$)(?!(xx+)\3+$)|((^x|xx\5){2,})\4*$)(xx+)\6+$/

Mevcut değerin bir Carmichael numarası olup olmadığını test edin. .NET / Perl / PCRE normal ifadesi kullanılarak yazıldığında kare algılama daha kısa olduğundan @ Deadcode'un alternatif algoritmasını kullanır.

^+`

Mevcut değer bir Carmichael numarası olana kadar tekrarlayın.

$
x

Geçerli değeri artırın.

"$+"}

İlk artışı ve döngü nsürelerini tekrarlayın.

x

Sonucu ondalığa dönüştürün.


0

Haskell , 95 bayt

s=filter
c n=s(\x->let l=s((1==).gcd x)f;f=[1..x-1]in l/=f&&all(\y->y^(x-1)`mod`x==1)l)[1..]!!n

Çevrimiçi deneyin!

Degolfed:

-- function to filter out Carmichael numbers
filterFunction x = 
    let coprimes = filter ((1 ==) . gcd x) lesserNumbers
        lesserNumbers = [1 .. x - 1]
    in
        -- the number x is Carmichael if it is not prime
        lesserNumbers /= coprimes && 
            -- and all of its coprimes satisfy the equation
            all (\y -> y ^ (x - 1) `mod` x == 1) coprimes

-- get n'th Carmichael number (zero-based)
c n = filter filterFunction [1..] !! n
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.