1000003'e bölünebilir mi? Kolay, sadece son rakamı 300001 ile çarpın ve ekleyin!


16

Bir asalden Pdaha büyük bir değer verildiğinde 10, programınız veya fonksiyonunuz, asalın xson basamağı ile çarpıldığında ve aslının geri kalanına eklendiğinde orijinal asalın katını veren en küçük mutlak değere sahip tamsayı olarak tanımlanan bölünebilirlik kuralını bulmalıdır. önemli.

Misal

Bir giriş verildiğinde 31, son rakam 1ve geri kalan sayı 3. Böylece program tamsayı bulmak zorundadır xasgari mutlak değere sahip 1*x + 3bir katıdır 31. Bu durumda, x=-3çalışır, böylece program veya işlev dönecekti -3.

Bir giriş verildiğinde 1000003, son rakam 3ve geri kalan sayı 100000. Böylece programınız bulur x=300001çünkü 3*300001+100000 = 1000003hangisinin katıdır 1000003.

Matematiksel Altyapı

Değeri xbir bölünebilirlik testi olarak kullanılabilir. Bir numara Eğer Nbölünemeyen bir P, daha sonra ekleme xzamanları son rakamı Ngeri kalanına Nkatlarını verecektir Pancak ve ancak Nbölünemeyen Pilk etapta.

Çünkü P=11, x=-1iyi bilinen bölünebilirlik kuralına eşdeğerdir 11: bir sayı, 11basamaklarının dönüşümlü farkı ile bölünebilir 11.

kurallar

  • Çıktı, çıktının hem işaretini hem de değerini açıkça kodlayan herhangi bir biçimde olabilir.
  • Girilen asal 10 ile 2 ^ 30 arasında olacaktır.
  • Giriş bir asal değilse veya aralıkta değilse işlem yapmanız gerekmez.
  • Her iki takdirde sap gerekmez xve -xgeçerli çıkışları (olmamalı) bulunmaktadır.
  • Kaba güce izin verilir, ancak daha yaratıcı çözümler takdir edilir.
  • Bu , her dilde en kısa kod kazanır! Golf dillerindeki cevapların diğer dillerde yayın yapmanıza izin vermemesine izin vermeyin.

Test Durumları

Input   Output
11  -1
13  4
17  -5
19  2
23  7
29  3
31  -3
37  -11
41  -4
43  13
47  -14
53  16
59  6
61  -6
67  -20
71  -7
73  22
79  8
83  25
89  9
97  -29
101 -10
103 31
107 -32
109 11
113 34
127 -38
131 -13
1000003 300001
2000003 600001
2999999 300000
9999991 -999999

3
Yararlı bir basitleştirme: Girdi ile bölünebilen xmutlak değerdeki en küçük değeri arıyoruz 10*x-1.
xnor

Birisi neden bir ipucu verebilir (3 / (n % 5 * 2 - 5) * n + 1) / 10ve (n % 5 * 2 - 5^2) * n / 10 + 1böyle bir şey için minimum mutlak bir değer bulabilir mi? İlk sezgim, Euclid'in algoritması ile hesaplanan en büyük ortak böleni kullanarak en küçük ortak katlamayı hesaplamak olurdu.
David Foerster

1
@DavidFoerster Bir sayı verildiğinde, son basamağı kaldırabilir, bir sayıyla çarpabilir x, ekleyebilir ve yine de tarafından bölünebilen bir sayı alabilirsiniz n. Daha sonra yeni sayıyı 10 ile çarpar ve orijinal sayıyı çıkarırsak hala bölünebilir kalır n. xnor'ın yorumu daha sonra bazı cebirlerden gelir. Bir sonraki adım, formülü x, nx = cinsinden verecek şekilde yeniden düzenlemektir (k*n+1)/10. Biz en küçük mutlak istiyoruz xbu nedenle biz en küçük mutlak istiyoruz kve bunun hangisi biri olmalıdır -3, -1, 1veya 3(bağlı ntam bölünme yapar 'ın son basamak).
Neil

Yanıtlar:


14

JavaScript (ES6), 32 25 23 bayt

f=
n=>(3/(n%5*2-5)*n+1)/10
<input type=number min=1 oninput=o.textContent=this.value%5*(this.value%2)?f(this.value):``><pre id=o>

3/(n%5*2-5)9/n(mod -10)dengeli modulo bölümüne erişebilseydim yazılacaktı . Düzenleme: @EgorSkriptunoff sayesinde 2 bayt kaydedildi


3
n=>((n%10*2%14-3)*n+1)/10n=>(3/(n%5*2-5)*n+1)/10
Egor Skriptunoff


@KevinCruijssen Muhtemelen Java 8 için neredeyse özlenen bir çok dilli ... oh bekleyin, şimdi cevabınızı görüyorum!
Neil

@Neil Haklısın. Genellikle Java yanıtları gönderiyorum, bu yüzden cevabınızı gördüğümde zaten xnor bağlantı noktasında çalışıyordum . Her iki şekilde de sizi sıkıcı bir liman olarak yayınladı.
Kevin Cruijssen

8

Python 2 , 27 bayt

lambda n:(n%5*2-5^2)*n/10+1

Çevrimiçi deneyin!

Operasyonlar soldan sağa yapılır: (((n%5)*2)-5)^2.

Aritmetik kaba zorlayıcımı , bir tortu modunun negatif tersini aralık içine alarak, n%5*2-5^2gerçekleştirilecek ifadeyi bulmak için kullandım .{1:-1,3:3,2:-3,4:1}[k][-2..2]


Bu aritmetik kaba kuvvetlendirici bir yerde halka açık mı?
Lynn

Bulduğu tek ifade bu mu yoksa sadece belirli bir uzunlukta ilkini mi yazdırıyor? ( 3/(n%5*2-5)ile aynı uzunluktadır (n%5*2-5^2).)
Neil

@Lynn Hayır, zamanım olduğunda temizleyebilir ve gönderebilirim.
xnor

1
@Neil Sadece eşdeğer ve n%5*2-6^3. Paren içermeyen ifade ile sadece uzunluğa baktım, oysa 3/(n%5*2-5)iki karakter daha uzun, ancak öncelik nedeniyle dış parenler üzerinde tasarruf sağladım. Bu uzunluktaki ifadelerin aranması biraz zaman alabilir. Bu kullanım durumu, yalnızca belirli bir bağlamda kullanılabilecek ifadeleri, en yüksek önceliği olan, yeterince yüksek önceliğe sahip olarak bulma seçeneğini önerir.
xnor

6

Jöle ,10 8 bayt

,N⁵æiAÞḢ

Çevrimiçi deneyin!

açıklamalar

,N       Get [Input, -Input].
⁵æi      Modular inverse of 10 mod each of [Input, -Input].
AÞ       Sort by absolute value.
Ḣ        First.

+1 Asla bayt kaydeden bir Jelly başvurusu görmedim
Bay Xcoder

@ Mr.Xcoder İyi golf oynamadım çünkü.
jimmy23013




5

Japt , 16 9 bayt

@Xnor tarafından yapılan gözlem sayesinde çok fazla bayt kaydedildi

_*AÉ vU}c

Çevrimiçi test edin! Daha büyük girdilerde birkaç saniye sürebilir.

açıklama

_  *AÉ  vU}c    Implicit: U = input integer
Z{Z*A-1 vU}c    Ungolfed
Z{        }c    Loop through each integer Z in [0, -1, 1, -2, ...] and yield the first where
  Z*A             Z times 10
     -1           minus 1
        vU        is divisible by the input.
                Implicit: output result of last expression




1

Python 2 , 44 43 bayt

(44 çarpı hala 44.) Bir bayt tasarrufu için Fireflame241 sayesinde!

P=input();i=P/3
while i*10%P-1:i-=1
print i

Çevrimiçi deneyin!

Arasında tam tersi bir sayı vardır 0ve P-1bunun tersi de geçerlidir 10. Ancak bu ters udeğer daha büyük olursa P/2, o zaman (u-P)terstir ve mutlak değeri daha küçüktür u. Böylece, ve ile xarasındaki benzersiz sayıyı gerçekten arıyoruz.-P/2P/2 bunun tersi10 .

Yukarıdaki kod tam olarak bunu yapar (zeminden) P/2ve bir tersine ulaşana kadar aşağı doğru adım atar. Bu daha bazı değerinden büyük gerçekleşmesi gerekir -P/2sürece Pdaha asal büyüktür 10. Daha kesin olarak, eğer sadece Pvezne olması durumunda sona erecektir 10.

Düzenleme: Aslında ve xarasında olması garanti olduğu ortaya çıkıyor , bu nedenle mevcut sürüm başlar ve oradan aşağı iner. Etiketli bölüme bakın-P/3P/3P/3 açıklaması için Geliştirilmiş Ciltli .

Matematiksel açıklama

Bölünebilirlik testinin neden işe yaradığı hemen belli değildi. Başka birinin merak etmesi durumunda bir açıklama.

Izin Pvermek bir asal, daha büyük 10, son rakam olan b. Böylece

P = 10a + b

nerede a > 0, ve 0 <= b < 10. Aslında bya 1, 3, 7, veya 9, bir asal büyüktür çünkü10 bu rakamlardan birine mutlaka sonuna.

Şimdi varsayalım bx + a = 0 (mod P). Sonra

a = -bx (mod P)

10a + b = 10(-bx) + b (mod P)

0 = 10(-bx) + b (mod P)

0 = b(1 - 10x) (mod P)

Beri Pasal tamsayıları mod Pbir olan tamlık . Bu yüzden yab = 0 (mod P) , ya 1 - 10x = 0 (mod P).

Biliyoruz 0 <= b < 10 < P, eğer b = 0 (mod P)öyleyse b = 0. Ama dedik bya edilir 1, 3, 7veya 9, bu nedenle bu imkansızdır. Bu 1 - 10x = 0 (mod P)nedenle 10x = 1 (mod P). Başka bir deyişle , modulo'nun xtersidir10P .

Şimdi N, son basamağı olan negatif olmayan bir tam sayı olduğunu varsayalım d, bu yüzden N = 10c + d. eşdeğer ifadeler zincirimiz var:

10c + d = 0 (mod P)

<==> 10xc + dx = 0 (mod P)

<==> c + dx = 0 (mod P)

QED.

Kullanışlılığı?

Ben de (verilen bölünebilme testi olmadığını merak N = 10c + d, yerine Ngöre dx + c) aslında pratikte üretken olacaktır. Ya da en azından güvenilir Nbir değerden N(mutlak değerde) küçük bir sayı ile mi geçer?

Varsayalım N = 10c + d, nerede c >= 0ve 0 <= d < 10. Bu nedenle 10c = N - d <= N. Üçgen eşitsizliği ile,

|c + dx| <= |c| + |dx| = c + d|x| <= N/10 + d|x|

< N/10 + 10|x| <= N/10 + 10P/2 = N/10 + 5P

Böylece 5P <= 9N/10, o zaman |c + dx| < N.

Özellikle, eğer N >= 6P, o zaman |c + dx| < N. Böylece, verilen Pbiz hesaplayarak başlar 2P, 3P, ..., 6P, ile birlikte x. Sonra verilen Naz süremiz bir numara veya ulaşılması eşit olana kadar tekrar tekrar bölünebilme testi, 6Pve sonuç numaralardan herhangi olup olmadığını kontrol 0, P, 2P, ..., 6P.

(Tabii ki, negatif bir sayıya ulaştığımızda, onu mutlak değeri ile değiştiririz, bu iyidir, çünkü eğer sadece ve sadece ise qbölünebilir .)P(-q)

Geliştirilmiş Sınır

Bunun |x|/Phiç yakın olmadýđýný fark ettim 1/2. O hep az oldu gibi Aslında görünüyordu 1/3... ya yakından incelendiğinde üzerine çok yakın ya hep, 1/10ya 3/10. Şimdiye kadar olan en büyük görünüyordu 4/13( P=13ve ne zaman olur x=4). Neden böyle olsun ki?

Izin uvermek bir tamsayı ve varsayalım 10u = kP + 1bazı tamsayı k, utersi 10, modulo P. Sonra da biliyoruz knispeten asal 10beri k(-P)eşdeğerdir 1modulo 10.

Şimdi, tersidir biliyoruz 10modulo Ptüm katları farklılık Pbiz tamsayı alabilir, böylece uekleyebilir veya katları çıkarma ya Piradesiyle ve sonuç her zaman hala bir ters olacak 10modülo P. Çıkartmayı tercih varsayalım Pdan u: aldığımız

10(u - P) = 10u - 10P = kP + 1 - 10P

10(u - P) = (k - 10)P + 1

Diğer bir deyişle, azalan (sırasıyla artarak) uile P(artan) azalan tekabül kile 10. Biz Eklemek istediğiniz / bir çıkarma katları Parasından usol taraftaki mutlak değer olarak en aza kadar; ancak sol taraf tam olarak sağ taraf küçültüldüğünde en aza indirilir ve bu nedenle sağ taraf mutlak değerde en aza 10indirilene kkadar toplama / çıkarma yapmak istiyoruz .

Ama biz bu ne zaman olacağını biliyorum karasındadır -5ve 5ve bu nedenle (çünkü knispeten asal 10) Bu araçlar kya -3, -1, 1, veya 3. (Bu @ Neil'in OP altındaki yorumunun içeriğidir. Teşekkürler Neil! )

Böylece |u|en aza indirilir (yani, u=x), biz olacak x/P = u/P = k/10 + 1/(10P)burada, kya -3, -1, 1ya da 3. Bu nedenle |x|/P <= 3/10 + 1/(10P). Eşdeğer olarak |x| <= (3P + 1)/10.

Dahası, bu eşitsizlik katıdır P=11, çünkü P=11bizde x=-1ve vardır k=-1. PEşitliğin sahip olduğu en küçük şey P=13(nerede x=4ve k=3).

Bu nedenle, |x|/Pşimdiye kadar elde edilen en büyük şey 3/10 + 1/(10*13), çünkü P=13sahip olduğumuz ilk asaldır k=3ve sahip olanlar arasında k=3, 1/(10P)terim Pen küçük olduğunda (yani, at P=13) en büyüktür . Bu nedenle, herkes için Pde var |x|/P <= 3/10 + 1/130 = 4/13 < 1/3. Bu, yukarıdaki kodda i = P/3,P/2 .

Ayrıca, yukarıdaki Yararlılık bölümündeki sınırlar artık geliştirilebilir.

Lemma : N = 10c + dNerede c > 0ve olsun 0 <= d <= 9. Sonrac + d|x| < N/10 + 9(3P + 1)/10 . (Katı eşitsizliğe dikkat edin.)

Lemma kanıtı: vakalara göre. Durum I: d = 0yani N = 10c. Sonrac + d|x| = c = N/10 < N/10 + 9(3P + 1)/10 .

Durum II: 0 < d <= 9. Sonra 10c = N - d < N, bu yüzden c < N/10. bu nedenlec + d|x| < N/10 + d|x| <= N/10 + 9|x| <= N/10 + 9(3P + 1)/10 . QED.

Böylece, eğer N > 3P(ve N = 10c + dönceki gibi), o zaman

3P + 1 <= N

9(3P + 1)/10 <= 9N/10

N/10 + 9(3P + 1)/10 <= N

c + d|x| < N/10 + 9(3P + 1)/10 <= N

Eğer N > 3Pöyleyse c + d|x| < N.

Bu nedenle, sadece bulmak zorunda P, 2Pve 3Pbirlikte x. Verilen N > 0süre N > 3P, biz yerine Ngöre |c + dx|azalır, hangi N. Sonunda alacağız N <= 3P; o noktada durup olmadığını kontrol Nnumaralardan herhangi eşittir 0, P, 2P, veya 3P.

Genelden daha iyisini yapamayız 3P. Örneğin varsayalım P = 13ve N = 39bu yüzden, x = 4. Sonra değiştirilmesi Nyoluyla dx + c = 9(4) + 3yaprakları Ndeğişmeden.


Çok güzel bir açıklama! -1Parantezin dışına giderek bir bayt kaydedebilirsiniz : 43 bayt
fireflame241

@ fireflame241 Çok teşekkür ederim! 44'te bıraktığımı iddia edebilirim, böylece onu geçebilirim (bu bir yalan olsa da).
mathmandan

1

Boşluk , 92 bayt

Bu dilin sözdiziminin yalnızca boşluktan oluştuğunu unutmayın, bu nedenle her boşluk karakterinin önüne S, T veya L (sırasıyla Boşluk, Sekme ve Satır Besleme'ye karşılık gelir) eklenmiştir. Bunlar, işlevselliği kaybetmeden kaldırılabilir, ancak düzgün bir şekilde görüntülemek için buraya dahil edilirler.

S S S L
T   L
T   T   S S S L
T   T   T   S L
S S S S T   T   L
T   S S L
S L
T   S S S T S T L
T   S T T   S L
S T S S S S S S T   S T L
T   S S T   T   S T S S S S T   L
T   S S S S S S T   S T S L
T   S T S T L
S T L
L
L
.

Çevrimiçi deneyin!


1

Japt , 14 bayt

Neil'in çözümünden ilham aldı .

Ì*2%E-3 *UÄ /A

Çevrimiçi test edin!

Açıklama:

  Ì  *2%E-3 *UÄ  /A
((UgJ*2%E-3)*U+1)/A
  U                  // Implicit U = Input
   gJ                // Get the char at index -1 (last char)
     *2              // Multiply by 2
       %E            // Mod 14
         -3          // Minus 3
            *U+1     // Multiply by U+1
                 /A  // Divided by 10 


0

Excel, 27 bayt

=0.3/(MOD(A1,5)*2-5)*A1+0.1

Hücreye şu şekilde girilebilir

=.3/(MOD(A1,5)*2-5)*A1+.1

25 byte için, ancak Excel otomatik güncellemeler.


Aslında girmeniz gereken bayt sayısını talep edebileceğinizi düşünüyorum (ancak metaları kontrol etmek için çok tembelim).
Neil
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.