Böl ve böl ve yönet


22

Bazen, önümde beliren sayıyı çarpanlara ayırmaya çalışıyorum¹¹, bir süre sonra düşündüğümden daha kolay olduğunu anlıyorum. Al 2156örneğin: sonunda hem aklıma geliyor 21ve 56katları olan 7ve bu yüzden kesinlikle 2156 = 21 x 100 + 56de bir katıdır 7.

Göreviniz, bu tür bir tesadüf nedeniyle faktörü daha kolay olan sayıları tanımlayan bir kod yazmaktır.

Daha kesin:

nGirdi olarak pozitif bir tamsayı alan bir program veya işlev yazın ve her biri bir çarpı olmak üzere iki pozitif tamsayı elde etmek için ikiye bölünebilecek bir bölen d(daha büyük 1) varsa bir gerçek değer döndürür ; değilse yanlış bir değer döndürür.nd

  • "İkiye kesilmiş", ne düşündüğünüzü ifade eder: niki ana üs-10 tamsayı üretmek için bir noktada bir ön yarıda ve bir arka yarıya bölünmüş olağan taban-10 temsili . İkinci tamsayı (bu pozitif bir tamsayı olması gerektiğini ancak not bölme böylece lider sıfır varsa Tamam 1230içine 123ve 0geçerli değildir).
  • Gerçeği ve sahte değerler, girdiye bağlı olabilir. Örneğin, sıfırdan farklı bir tamsayı seçtiğiniz dilde kaba ise, böleni dveya bu konu için "parçalarından" birini n(veya nkendisinin) geri gönderebilirsiniz .
  • Örneğin, sette en az iki rakam olan herhangi bir çift sayı {2, 4, 6, 8}bir gerçeğe uygun değer sağlar: sadece ilk çift basamaktan sonra ayırın. Ayrıca, örneğin, herhangi bir asal sayı n, herhangi bir tek basamaklı sayı gibi, sahte bir değer verecektir.
  • Asal bölenleri dikkate almanın yeterli olduğunu unutmayın d.
  • Girişin geçerli olduğunu varsayabilirsiniz (yani, pozitif bir tamsayı).

Bu , yani bayt cinsinden en kısa kod kazanır. Ancak tüm dillerde çözümler açıktır, bu nedenle genel olarak en kısa kod değil, her dilde en kısa kod için çaba gösterebiliriz.

Test durumları

(Yalnızca bir truthy veya sahte değer vermeniz gerekir; aşağıdaki açıklamalar sadece açıklama yoluyla verilir.) Truthy değerleri veren bazı girdiler:

39  (3 divides both 3 and 9)
64  (2 divides both 6 and 4)
497  (7 divides both 49 and 7)
990  (splitting into 99 and 0 is invalid; but 9 divides both 9 and 90)
2233  (11 divides both 22 and 33)
9156  (3 divides both 9 and 156; or, 7 divides both 91 and 56)
11791  (13 divides both 117 and 91)
91015  (5 divides both 910 and 15)
1912496621  (23 divides both 1912496 and 621; some splittings are multiples of 7 as well)
9372679892  (2473 divides both 937267 and 9892; some splittings are multiples of 2 as well)

Sahte değerler veren bazı girdiler:

52
61
130  (note that 13 and 0 is not a valid splitting)
691
899
2397
9029
26315
77300  (neither 7730 and 0 nor 773 and 00 are valid splittings)
2242593803

¹ evet bunu gerçekten yapıyorum

Yanıtlar:


7

Retina , 31 29 bayt


,$';$`
\d+
$*
;(11+)\1*,\1+;

Çevrimiçi deneyin!

Geçerli girdiler için pozitif bir tamsayı, geçersiz olanlar için sıfır.

Daha büyük test vakalarını beklemenizi tavsiye etmem ...

açıklama


,$';$`

Girişin her yerine virgül, daha sonra bu konumdan önceki her şeyi, sonra noktalı virgül, sonra bu konumdan sonraki her şeyi ekleyin. Bu ne işe yarıyor? Bize bir sayının olası bütün parçalarını verir (bölünerek ,, bölünerek ;) ve sonra tekrar giriş. Böylece girdi 123olur

,123;1,23;12,3;123,;123
     ^     ^     ^

Orijinal giriş karakterlerini işaretledim (işaretli olmayanlar bizim eklediklerimizdir). Bunun, gerçek bölmeler olmayan geçersiz bölmeler yarattığını ve izleyen bileşenin tamamen sıfır olup olmadığını da umursamadığını, ancak daha sonra kabul etmekten kaçınacağımızı unutmayın. Geçersiz bölmeleri yaratmanın faydası, geçerli her bölmenin bir ;önünde ve sonrasında olduğunu bilmemizdir , böylece kelime sınırlarında iki bayt tasarruf edebiliriz.

\d+
$*

Her sayıyı birliğe dönüştürün.

;(11+)\1*,\1+;

Her iki yarıyı da en az 2 olan bir sayının katları olarak eşleştirerek bölmeyi eşleştirin.


Retina hakkında hızlı soru: Önde gelen newline ne yapar?
HyperNeutrino

@HyperNeutrino İlk satır, eşleştiğimiz ilk regex ve değiştirmeyi karakterler arasındaki her bir pozisyona yerleştirmek için boş regex ile eşleştirmek istiyoruz.
Martin Ender

Tamam. Teşekkürler! Muhtemelen Retina'ya biraz daha bakmalıyım; Büyük ölçüde regex tabanlı göründüğü için kolmogorov-karmaşıklık problemleri için iyi olabilir .
HyperNeutrino

Son satır olabilir mi;(11+)+,\1+;
Riley

@Riley, ilk segmentin aynı faktörün bir katı olduğunu garanti etmiyor.
Martin Ender

6

Brachylog (2), 8 bayt

~c₂ḋᵐ∋ᵐ=

Çevrimiçi deneyin!

açıklama

~c₂ḋᵐ∋ᵐ=
~c₂       Split the input into two pieces
    ᵐ ᵐ   On each of those pieces:
   ḋ ∋      Choose a prime factor
       =  such that both the chosen factors are equal

Açıkça, aynı sayı (1'den büyük) her iki parçayı bölerse, aynı asal sayı her ikisini de böler. Faktörün asal olması şartı, düzgün bir şekilde faktör 1'e izin vermez. Ayrıca, değişmezin 0sayının bir kesimi olarak seçilmesini de önler (çünkü 0asal çarpanlaştırmaya sahip değildir ve başarısızlığa neden olur).

İç sıfırları eşleştirmeye karşı kontrol etmeye gerek yoktur; Bir bölünmüş eğer xve 0ygeçerlidir, x0ve ysadece de çalışacaktır (ve eğer başka bir yol gidiyor x0ve yeserleri, o zaman ne olursa olsun bir çalışma çözümümüz var xve 0yçalışmak veya olmaz).

Brachylog dolu bir program, bunun gibi, bir Boole döndürür; true.hatasız çalıştırmanın bir yolu varsa (yani, hiçbir hatanın oluşmayacağı seçimler yapmak için), false.tüm yollar başarısızlığa yol açarsa. Tam olarak burada istediğimiz şey bu.


4

Jelly , 14 12 11 10 bayt

ŒṖḌo1g/€P>

1 byte'lık golf için @JonathanAllan'a teşekkürler!

Çevrimiçi deneyin!

Nasıl çalışır

ŒṖḌo1g/€P>  Main link. Argument: n

ŒṖ          Compute all partitions of n's decimal digits.
  Ḍ         Undecimal; convert each array in each partition back to integer.
   o1       OR 1; replace disallowed zeroes with ones.
     g/€    Reduce (/) each (€) partition by GCD (g).
            The last GCD corresponds to the singleton partition and will always be
            equal to n. For a falsy input, all other GCDs will be 1.
        P   Take the product of all GCDs.
         >  Compare the product with n.

Bence , yürürlükte olduğu Dgibi bırakabilirsiniz . make_digitsŒṖ
Jonathan Allan

Nedense bunun bir aralık yaratacağını varsaydım ... Teşekkürler!
Dennis,

3

Mathematica, 63 62 bayt

(Greg Martin'e 1 bayt teşekkürler)

1<Max@@GCD@@@Table[1~Max~#&/@Floor@{Mod[#,t=10^n],#/t},{n,#}]&

Bu giriş ve getiri olarak bir tamsayı alan bir fonksiyondur Trueya False. Çok sayıda test ediyorsanız, beklerken okumak için bir kitap getirin.

Açıklama:

  • Floor@{Mod[#,t=10^n],#/t}aritmetik olarak girişi son nhanelere ve kalan m-nhanelere ayırır ( mtoplam basamak sayısı).
  • Table[1~Max~#&/@...,{n,#}]Bunu ngiriş numarasına kadar her şey için yapar . (Bu çok büyük bir şey. Bunu sadece girişin basamak sayısına kadar yapmamız gerekiyor , ancak bu yol baytları kurtarıyor ve hala doğru sonucu veriyor.) 1~Max~#&/@Bit sıfırdan kurtulur, sayılar 130 -> {13,0}sayılmaz olarak True.
  • 1<Max@@GCD@@@... bu çiftlerin her birinin en büyük ortak bölenini bulur ve bu bölenlerden herhangi birinin 1'den fazla olup olmadığını kontrol eder. Öyleyse, sayıyı bölerek çarpanlara ayırmanın bir yolunu bulduk.

1
Güzel cevap! Bir bayt'ı {#~Mod~10^n,#/10^n}veya ile kaydedebilirsiniz {Mod[#,t=10^n],#/t}.
Greg Martin

Denedim #~Mod~10^n, ama bunun Mod[#,10]^nyerine parantez içinde görünüyor Mod[#,10^n]. Yine de ikinci önerin hakkında hiç düşünmedim!
Bir ağaç değil

fuar konusu hakkındaMod[#,10]^n
Greg Martin


2

C, 145 142 139 138 135 bayt

i,a,b;f(){char s[99];scanf("%s",s);for(char*p=s;*p++;)for(b=atoi(p),i=*p,*p=0,a=atoi(s),*p=i,i=1;i++<b;)*s=a%i-b%i|b%i?*s:0;return!*s;}

2

JavaScript (ES6), 74 71 70 bayt

f=(s,t='',u)=>u?s%t?f(t,s%t,1):t:s&&f(t+=s[0],s=s.slice(1),1)>1|f(s,t)
<input oninput=o.textContent=f(this.value)><span id=o>

Parçacığı için kullanışlı bir dize olarak giriş alır. Düzenleme: @ user81655 sayesinde 3 bayt kaydedildi.


İki bayt kaydeder: (c,i)-> c, i+1-> ++i, t=''-> i=t=''Bu hile size 1 tabanlı endeksi kullanmak ve başlaması için bir yerde olması gereken herhangi bir zaman yararlıdır iiçin 0.
user81655

Ayrıca t=''olabileceğine inanıyorum t=0, çünkü czaten onu bir dizgiye zorluyor.
user81655

@ user81655 Bu, aslında başlangıçta ve arasında dilimleme yaptığım için oldu i, bu yüzden 1 tabanlı endekslere ihtiyacım olmadı, ama sonra ilk dilimi attı t+=c.
Neil

Ah tamam. Ayrıca son bir şey, ben bu aynı zamanda bir özyinelemeli fonksiyon olarak daha kısa olabileceğini düşünüyorum: f=(x,y,z)=>z?x%y?g(y,x%y):y:x?f(x,y,1)>1||f(x.slice(1),~~y+x[0]):0. GCD işlevinizi de birlikte fkullandım. Muhtemelen daha da golf oynayabilirdi. Son öneri, söz veriyorum! : P
kullanıcı81655

@ user81655 Ne yazık ki aşırı basitleştirilmiş gcdfonksiyonum ne zaman işe yaramadı x=0, ve onunla uğraşırken yazım tipiniz beni 72 byte'a çıkardı, bu yüzden 2 byte golf oynayabildiğim için şanslıydım.
Neil

2

Python 3, 133 118 117 bayt

i,j=int,input()
from fractions import*
print(any(i(j[k:])*i(j[:k])*~-gcd(i(j[k:]),i(j[:k]))for k in range(1,len(j))))

Kesinlikle en kısa değil, muhtemelen biraz kısaltılabilir. O(n)Zamanında çalışır . Giriş biçiminde alınır \d+ve çıkış (True|False)varsayılan Python boolean değerine göre biçiminde verilir
- Dead Bayum sayesinde -3 bayt) - Bu Guy sayesinde
ovs
-1 bayt sayesinde 15 bayt


from fractions import*3 byte kazandıracak
Dead Possum

900 için True döndürür. Sanırım, bu yanlış. Eğer iç değişmelidir MB anyiçin all? Bu durumda, tüm bu kısımları i(j[k:])and i(j[:k])hepsini 125 bayta getirecek şekilde değiştirebilirsiniz . İşte düzeltmeler
Dead Possum

Ve ve hepsini çarpımla değiştirebilirsiniz:any(i(j[k:])*i(j[:k])*~-gcd(i(j[k:]),i(j[:k]))for k in range(1,len(j)))
ovs 24/17

@DeadPossum Ah doğru, bunu yapmalıydım. Ve evet, şu anki metodumun içinde çok sayıda golf sahası var ama ovs'nin önerilerini takip edeceğim. Bunu işaret ettiğin için teşekkürler! (gerçekten kendim
denemeliydim


1

QBIC , 91 90 bayt

;_LA|[a-1|B=left$(A,b)┘C=right$(A,a-b)┘x=!B!┘y=!C![2,x|~(x>1)*(y>1)*(x%c=0)*(y%c=0)|_Xq}?0

Açıklama:

;               Get A$ from the command prompt
_LA|            Get the length of A$ and place it in a% (num var)
[a-1|           for b%=1; b% <= a%-1; b%++
B=left$(A,b)    break A$ in two components on index b%
C=right$(A,a-b)
x=!B!┘y=!C!     Convert both parts from string to num, assign to x% and y%
[2,x|           FOR c% = 2; c% <= x%; c%++

This next IF (~ in QBIC) is a bit ... iffy. It consists of a set of comparators.
Each comparator yields a -1 or a 0. We take the product of these. At any failed
comparison this will yield 0. When successful, it yields 1, which is seen as true by QBasic.

~(x>1)*(y>1)        IF X>1 and Y>1 --> this stops '00' and '1' splits.
*(x%c=0)*(y%c=0)    Trial divide the splits on loop counter c%.

|_Xq            Success? THEN END, and PRINT q (which is set to 1 in QBIC)
}               Close all language constructs (2 FOR loops and an IF)
?0              We didn't quit on match, so print 0


1

Perl 5 , 46 bayt

-pBayrak için 43 bayt kod + 3 bayt .

s~~$\|=grep!($`%$_|$'%$_),2..$`if$`*$'~ge}{

Çevrimiçi deneyin! veya birden fazla girişe izin veren bu değiştirilmiş sürümü deneyin .
Muhtemelen bunu en uzun süre denemek istemezsiniz, çünkü çok uzun sürebilir.

Açıklamalar:
Biz birlikte kelimede her pozisyonda yinelemenize s~~~gile, $`daha önce numaraları ve ihtiva $'sonra sayıları. Eğer $`*$'(o hiçbiri boş anlamına gelir ve hiçbiri doğrudur 0), o zaman 2 arasında bir sayı olmadığını kontrol $`böler her ikisi ile ( grep!(...),2..$`). Öyleyse, bayrak sayesinde sonunda yazdırılan sıfır olmayan bir değere $\|=..ayarlanır .$\-p


2
$<backquote>SE markdown nasıl yapılır bilen varsa , bana nasıl olduğunu söylerseniz minnettar olurum.
Dada

1
Sen açık kullanarak yoluyla bunu yapabilir <code>... </code>(ziyade `... `), sonra da backquotes kaçan \`. Ayrıca, bu yorum yazmak acı vericiydi, çünkü iki kez kaçmak zorunda kaldı (ve iki kaçış kuralı kümesi farklı!).

@ ais523 Harika, çok teşekkür ederim! :)
Dada

0

Python 2,69 bayt

f=lambda n,d=10,k=2:k<d<n and(n/d%k+n%d%k<1<n%d)|f(n,d,k+1)|f(n,10*d)

GCD yerleşikleri yerine özyineleme kullanır.

Çevrimiçi deneyin!

Nasıl çalışır

Tüm f (bir ila üç bağımsız değişken olarak adlandırılır d varsayılan olarak , 10 , k için 2 ifadesinin, ilk kontrol değeri) k<d<n. Eşitsizlikler k <d ve d <n'nin her ikisi de tutarsa, aşağıdaki ifade andyürütülür ve değeri döndürülür; Aksi takdirde, f yalnızca False döndürür .

Eski durumda, ifadeyi değerlendirerek başlarız. n/d%k+n%d%k<1<n%d .

d her zaman onluk bir güç olacaktır, n/dve n'ninn%d onlu hanesini iki dilime ayırın. Bu dilimler hem k ile bölünebilir, hem de sadece 0 ile değerlendirilirse sonuç 1 ile karşılaştırılarak test edilir.n/d%k+n%d%k .

Gereksinimlerin bir kısmı, her iki dilimin de pozitif tamsayıları temsil etmesi gerektiği için, değeri n%dde 1 ile karşılaştırılır . O Not 1 hiçbir asal bölenler vardır, bu yüzden daha pahalı karşılaştırma 0 gerekmemektedir. Ayrıca, d <n'nin zaten bunu sağladığını unutmayın .n/d olumlu bir tamsayı olarak değerlendirilmesini .

Nihayetinde yinelemeli olarak f(n,d,k+1)(bir sonraki potansiyel ortak bölenciyi f(n,10*d)denemek ) ve (bölmeyi denemek) tüm üç sonucun mantıksal VEYA değerini döndürür. Bu, eğer k , n / d ve n% d' nin ortak bir böleniyse veya aynısı daha büyük bir k ve / veya on d' nin daha yüksek bir gücü için geçerliyse f , True değerini döndürür .

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.