Bu numara bir faktör mü?


38

Görev

Girdi olarak doğal bir sayı verildiğinde, göreviniz, girdinin herhangi bir doğal sayının faktörü olup olmamasına bağlı olarak bir hakikat veya falsey değeri vermektir. Giriş numarasının her zaman dilinizin desteklediği numaralar aralığında olacağını varsayabilirsiniz, ancak sorunu önemsizleştirmek için yerel numara türlerini kötüye kullanmamalısınız .

Standart Loopholes uygulanır.


Giriş

Size doğal bir numara verilecek (tür Integerveya benzeri).

Önceden tanımlanmış bir değişkende olduğunu varsaymak dışında girişi istediğiniz şekilde alabilirsiniz. Dosyadan, konsoldan, iletişim kutusundan ( prompt), giriş kutusundan vb. Okumaya izin verilir. Fonksiyon argümanı olarak girdiye de izin verilir!


Çıktı

Programınız, giriş numarasının herhangi bir doğal sayının faktörü olup olmamasına bağlı olarak bir gerçek veya yanlış değer vermelidir.

Truthy / falsey değerlerinin tüm girişler için tutarlı olduğundan emin olun, yani sırasıyla truthy ve falsey değerlerini belirtmek için 1 ve 0 çifti kullanıyorsanız, programınız için truthy değerleri ve 0 falsey değerine sahip olması gereken tüm girdiler.

Bir değişkene yazmak dışında istediğiniz şekilde çıktı alabilirsiniz. Dosyaya, konsola, ekrana vs. yazılabilir. İşleve returnde izin verilir!

Programınız herhangi bir giriş için hata üretmemelidir!


Test Kılıfları

Input     Output

1         Truthy (0! or 1!)
2         Truthy (2!)
3         Falsey
4         Falsey
5         Falsey
6         Truthy (3!)
7         Falsey
8         Falsey
24        Truthy (4!)
120       Truthy (5!)

Kazanan Kriter

Bu , yani bayttaki en kısa kod kazanır!


2
Dil yalnızca {0,1} aralığında sayıları destekliyorsa, girişin her zaman olmasını bekleyebilir miyim 1?
eush77


1
4! bir gerçeği?
tuskiomi

Soru: Neden G / Ç varsayılanlarını kullanmıyorsunuz?
Hesap MakinesiFeline

Yanıtlar:


37

Brachylog , 1 bayt

Çevrimiçi deneyin!

açıklama

aşağıdaki ilişkiyi ortaya koyan bir yerleşiktir: çıktısı, girişinin faktörüdür. Basit bir şekilde set çıkışı veriyoruz ve değişken girişe uyup uymadığını görüyoruz.


6
@BetaDecay Prolog'da basılmasının nedeni budur ( true.bunun bir ifade trueolup olmadığı ile
ilgisi vardır

6
Önemsiz bir çözüm, ancak prolog çalışma biçimi nedeniyle zekice.
Esolanging Meyve


17
Önce özel diller, sonra özel kodlamalar ... kod golf öldü. Bu eğlenceli sorunların tüm noktasını ilk etapta tamamen yıktık
Alexander

13
@Alexander Özel kodlamalar, neden bahsettiğiniz herhangi bir sorunla ilgili değildir. Bunun yerine herhangi bir "mevcut" kodlamayı kullanabilirdim ve yine de 1 bayt olacaktı. Sadece daha az okunabilir olurdu.
17'de


19

Jöle , 4 bayt

Œ?IE

En kısa Jelly cevabı değil, ama oldukça verimli.

Çevrimiçi deneyin!

Nasıl çalışır

Œ?IE  Main link. Argument: n

Œ?    Yield the n-th permutation of the positive integers, without the sorted tail.
      For 120, this yields [5, 4, 3, 2, 1], the tail being [6, 7, 8, ...].
  I   Increments; compute all forward differences.
      For 120, this yields [-1, -1, -1, -1].
   E  Check if all differences are equal.

2
Çünkü biz kod golfçüler verimliliği önemsiyoruz.
Okx,

12
Bir bayt pahasına çarpıcı bir karmaşıklık gelişimidir ve eğer kendim söylersem akıllıca kullanımı akıllıcadır. ¯ \ _ (ツ) _ / ¯
Dennis,

İlginçtir, bu 0 için geçerlidir, @ LeakyNun 3 byte cevabı genel olarak çok daha yavaş olsa da, 0 için doğru olarak yanlış döndürür. Etkili bir yürütme zamanı cevabında 0 için false döndürmek için fazladan bayt gerekir mi?
Deadcode

@Deadcode 0 için kontrol etmek için iki ekstra bayt gerekir. OP'nin "doğal sayılar" tanımının 0 içerip içermediğinden emin değilseniz. Test vakaları ...
Dennis

17

ECMAScript Regex, 733+ 690+ 158 119 118 (117🐌) bayt

Regex'e olan ilgim 4½ yıldan fazla bir süredir kullanılmadığı zaman yenilenen canlılığa neden oldu. Böylece, ECMAScript düzenli regex'lerle eşleşecek daha doğal sayı kümeleri ve işlevleri aramaya başladım, regex motorumu geliştirmeye devam ettim ve PCRE'yi de geliştirmeye başladım.

ECMAScript regex'te matematiksel fonksiyonlar oluşturma konusundaki sıkıntıdan etkilendim. Sorunlara tamamen farklı bir perspektiften yaklaşılmalıdır ve kilit bir iç görü gelişine kadar, çözülebilir olup olmadıkları bilinmemektedir. Belirli bir problemi çözülebilir hale getirmek için hangi matematiksel özelliklerin kullanılabileceğini bulmakta çok daha geniş bir ağ yaratmaya zorlar.

Faktör sayıları eşleştirmek, 2014'te uğraşmayı bile düşünmediğim bir problemdi - ya da eğer öyleysem, ancak bir an için mümkün olamayacak kadar azdı. Ancak geçen ay yapılabileceğini anladım.

Diğer ECMA regex yayınlarımda olduğu gibi, bir uyarı vereceğim : ECMAScript regex'teki sıradışı matematiksel problemlerin nasıl çözüleceğini öğrenmenizi tavsiye ederim. Benim için büyüleyici bir yolculuk oldu ve bunu denemek isteyebilecek herhangi biri için, özellikle de sayı teorisine ilgi duyanlar için onu mahvetmek istemiyorum. Birbiri ardına çözmek için art arda spoiler etiketli önerilen sorunların bir listesi için bu önceki yazıya bakın .

Bu yüzden , sizin için şımarık bazı düzensiz regex sihrini istemiyorsanız, daha fazla okumayın . Bu sihri kendiniz bulmaya bir göz atmak istiyorsanız, yukarıda belirtilen bağlantıda belirtildiği gibi ECMAScript regex'teki bazı sorunları çözerek başlamanızı şiddetle tavsiye ederim.

Bu benim fikrimdi:

Bu sayı kümesini eşleştirmedeki sorun, diğerlerinin çoğunda olduğu gibi, ECMA'da genellikle iki değişen sayıyı bir döngüde takip etmenin mümkün olmamasıdır. Bazen çoğaltılabilirler (örneğin, aynı tabanın güçleri açık bir şekilde birbirine eklenebilir), ancak özelliklerine bağlıdır. Bu yüzden giriş numarasıyla yeni başlayamadım ve 1'e ulaşana kadar artan şekilde artan bir temettü ile bölemedim (ya da en azından düşündüm).

Sonra, asal faktörlerin çokluğunu faktör sayıları üzerinde araştırdım ve bunun için bir formül olduğunu öğrendim - ve muhtemelen bir ECMA regex'inde uygulayabileceğim bir tane!

Bir süre üzerine bastırdıktan ve diğer bazı regex'leri yaptıktan sonra, faktoring regex'i yazma görevini üstlendim. Birkaç saat sürdü, ancak iyi çalıştı. Ek bir avantaj olarak, algoritma ters faktörü eşleşme olarak geri getirebilir. Bundan kaçınmak bile yoktu; ECMA'da nasıl uygulanması gerektiğine bağlı olarak, başka bir şey yapmadan önce ters faktörün ne olduğunu tahmin etmek gerekir.

Dezavantajı, bu algoritmanın çok uzun bir regex için yapılmış olmasıydı ... ama 651 bayt çarpım regex'imde kullanılan bir teknik gerektirdiği için memnun oldum (artık bitmiş olan, çünkü 50 bayt regex). Bu numarayı gerektiren bir problemin ortaya çıkacağını umuyordum: Aynı bazın her ikisinin de gücü olan iki sayı üzerinde, bir döngü içinde, her birini bir arada ekleyerek ve bunları birbirinden ayırarak çalıştırarak.

Ancak bu algoritmanın zorluğundan ve uzunluğundan dolayı, onu uygulamak için moleküler bakış açıları (formun (?*...)) kullandım. Bu, ECMAScript'te veya diğer ana akım regex motorlarında değil, motorumda uyguladığım özelliktir . Moleküler bir görünüşün içinde herhangi bir yakalama olmadan, işlevsel olarak atomik bir görünüşe eşdeğerdir, ancak yakalamalarla çok güçlü olabilir. Motor, geriye doğru geriye doğru ilerler ve bu, girişin karakterlerini tüketmeden tüm olasılıkları (daha sonra test etmek için) dolaşan bir değeri tahmin etmek için kullanılabilir. Bunları kullanmak daha temiz bir uygulama için yapabilir. (Değişken uzunluklu gözbebeği, moleküler gözle güç bakımından en az eşittir, ancak ikincisi daha basit ve zarif uygulamalar yapmaya meyillidir.)

Dolayısıyla, 733 ve 690 bayt uzunlukları aslında çözümün ECMAScript uyumlu enkarnasyonlarını temsil etmiyor - bu nedenle onlardan sonra "+"; Bu algoritmayı saf ECMAScript'e (uzunluğunu biraz artıracaktır) taşımak elbette mümkün ama ben bunu çözemedim ... çünkü çok daha basit ve daha kompakt bir algoritma düşündüm! Moleküler bakış açıları olmadan kolayca uygulanabilir. Aynı zamanda önemli ölçüde daha hızlı.

Bu yeni olan, önceki gibi, ters faktörü tahmin etmek, tüm olasılıklar arasında dolaşmak ve onları bir eşleşme için test etmek zorundadır. Yapması gereken işe yer açmak için N'yi 2'ye böler ve daha sonra girişi tekrar tekrar 3'te başlayan ve her seferinde artan bir bölen ile böleceği bir döngü oluşturur. (Dolayısıyla, 1! Ve 2! Ana algoritma ile eşleştirilemez ve ayrı olarak ele alınmalıdır.) Bölen, çalışmakta olan bölüme eklenerek takip edilir; Bu iki sayı açıkça ayrılabilir, çünkü M! == N, çalışan bölüm M'ye eşit olana kadar M tarafından bölünebilir olmaya devam edecek

Bu regex, döngünün en iç kısmında bir değişkene bölünür. Bölünme algoritması benim diğer regex'lerimdekiyle aynıdır (ve çarpma algoritmasına benzemektedir): A≤B, A * B = C için, yalnızca eğer C% A = 0 ve B ise B≤C'yi sağlayan en büyük sayıysa ve C% B = 0 ve (CB- (A-1))% (B-1) = 0, burada C, temettü, A, bölen, ve B, bölümdür. (A≥B'nin durumu için benzer bir algoritma kullanılabilir ve A'nın B ile karşılaştırıldığı bilinmiyorsa, gereken tek ekstra bölünebilirlik testi gerekir.)

Sorunun benim golf optimize daha az karmaşıklık indirgenemez başardı seviyorum Yani Fibonacci regex , ama benim çoğullama-güçler--aynı-baz tekniği başka sorun için beklemek zorunda olacağı hayal kırıklığı ile iç çekiyorum yok Bu aslında onu gerektirir, çünkü buna gerek yok. 651 bayt çarpım algoritmamın öyküsü, 50 baytlık bir sayı ile tekrar tekrar destekleniyor!

Düzenleme: Grimy tarafından bulunan ve bölümün bölenden büyük veya eşit olması garanti edildiğinde bölünmeyi daha da kısaltabilecek bir hile kullanarak 1 baytı (119 → 118) bırakmayı başardım .

Daha fazla uzatmadan, işte regex:

Doğru / yanlış sürüm (118 bayt):

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

Çevrimiçi deneyin!

Faktör veya eşleşmeyen ters dön (124 bayt):

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

Çevrimiçi deneyin!

ECMAScript + 'de\K (120 bayt) ters faktoringi veya eşleşmeyen değeri döndür :

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

Ve yorum içeren serbest aralıklı sürüm:

  ^
  (?=                           # Remove this lookahead and the \3 following it, while
                                # preserving its contents unchanged, to get a 119 byte
                                # regex that only returns match / no-match.
    ((x*)x*)(?=\1$)             # Assert that tail is even; \1 = tail / 2;
                                # \2 = (conjectured N for which tail == N!)-3; tail = \1
    (?=(xxx\2)+$)               # \3 = \2+3 == N; Assert that tail is divisible by \3
    # The loop is seeded: X = \1; I = 3; tail = X + I-3
    (
      (?=\2\3*(x(?!\3)xx(x*)))  # \5 = I; \6 = I-3; Assert that \5 <= \3
      \6                        # tail = X
      (?=\5+$)                  # Assert that tail is divisible by \5
      (?=
        (                       # \7 = tail / \5
          (x*)                  # \8 = \7-1
          (?=\5(\8*$))          # \9 = tool for making tail = \5\8
          x
        )
        \7*$
      )
      x\9                       # Prepare the next iteration of the loop: X = \7; I += 1;
                                # tail = X + I-3
      (?=x\6\3+$)               # Assert that \7 is divisible by \3
    )*
    \2\3$
  )
  \3                            # Return N, the inverse factorial, as a match
|
  ^xx?$                         # Match 1 and 2, which the main algorithm can't handle

Bu regex'lerin golf optimizasyonlarının tam tarihi github'da:

faktörel sayıları eşleştirmek için regex - çokluklu karşılaştırma yöntemi, moleküler lookahead.txt ile eşleştirilen faktorel sayıları.txt ile
regex (yukarıda gösterilen)

((x*)x*)((x*)+)((x+)+)n=3!\233=0

.NET regex motoru, ECMAScript modunda bu davranışı öykünmez ve bu nedenle 117 bayt regex çalışır:

Çevrimiçi deneyin! (üstel yavaşlama sürümü, .NET regex engine + ECMAScript öykünmesi ile)


14

JavaScript (ES6), 30 29 28 bayt

Olumlu bir tamsayı bekliyor. İade -1falsy için ve -2truthy için.

f=(n,k=2)=>n>1?f(n/k,k+1):~n

console.log(1,  '-->',f(1))   // Truthy (0! or 1!)
console.log(2,  '-->',f(2))   // Truthy (2!)
console.log(3,  '-->',f(3))   // Falsey
console.log(4,  '-->',f(4))   // Falsey
console.log(5,  '-->',f(5))   // Falsey
console.log(6,  '-->',f(6))   // Truthy (3!)
console.log(7,  '-->',f(7))   // Falsey
console.log(8,  '-->',f(8))   // Falsey
console.log(24, '-->',f(24))  // Truthy (4!)
console.log(120,'-->',f(120)) // Truthy (5!)

Not : Bu işlev oldukça büyük girişleri destekler (şunu okumalısınız: 'JS için oldukça büyük'). 2 53 - 1'e kadar güvenle çalışmalıdır . N = 121,645,100,408,831,992'den başlayarak kesin olarak başarısız olur , bu girdi 19'a yuvarlanır ! = 121,645,100,408,832,000 , IEEE-754 kodlaması nedeniyle. Orada olabilir önce diğer yanlış pozitif sonuçlar olmak 121,645,100,408,831,991 çünkü yuvarlama hataları, ama emin değiliz.


Güzel - ~sonunda kullanımı gibi gerçekten .
Steve Bennett

Düzenlememeyi reddedebilir miyim? (Neden reddettiğimi bilmek istiyorsanız, bu sorunun olağandışı G / Ç kurallarını unuttuğumdan dolayı.)
CalculatorFeline

@Arnauld Oyuna Devam Etmedi.
Hesap MakinesiFeline

11

Python 3 , 39 38 bayt

f=lambda n,i=1:n>1and f(n/i,i+1)or n<1

Bir yinelemeli fonksiyon, bir tam sayı alarak n, sonucunu temsil inversley bir Boole değeri dönen (truthy: False, Falsey: True)

Çevrimiçi deneyin!

Tekrar tekrar bölme nile ibir başlangıç değeri ile, 1ve geri kalanı daha az eşit ya da daha olana kadar 1bu kalan daha az ise, o zaman testler 1, sadece faktöriyel bir geri kalan kısmı ile sona erecek e eşit 1ve <daha büyük bir bayt kısadır ==.


@ovs, iki tutarlı çıktı ile sınırlandırıldık. Maalesef, iade 1ettiği durumlar dışında tüm faktörler 1için geri döner True.
Jonathan Allan

11

Java 8, 46 bayt

i->{int j=1,c=0;for(;j<i;j*=++c);return j==i;}

Bu, Roman Gräf'in bir düzine kadar baytını çalmayı başarabildiğim girişine dayanıyor. Orada önerebilirdim ama henüz yorum yapacak kadar itibarım yok! Değiştirilmiş test koşucu kodum:

import java.util.function.Function;
import java.util.stream.IntStream;

public class IsFactorial {
    public static Function<Integer, Boolean> isFactorial = i->{int j=1,c=0;for(;j<i;j*=++c);return j==i;};
    public static int[] truthyCases = {1,2,6,24,120};
    public static int[] falsyCases = {3,4,5,7,8};
    public static void main(String[] args){
        System.out.println(
            IntStream.of(truthyCases).allMatch(i->isFactorial.apply(i)) &&
            IntStream.of(falsyCases).allMatch(i->!isFactorial.apply(i)));
    }
}

9

Retina , 50 38 bayt

@Neil sayesinde döngüyü kısaltmayı birleştirerek ve ;

.+
1¶$&$*
+`^(1+)¶(\1)+$
1$1¶$#2$*
¶.$

Çevrimiçi deneyin!

1Doğru ve 0yanlış çıktılar .

.+ tüm numarayla eşleşiyor

1¶$&$*1Bunu bir yenisiyle takip eder ve eşleşmeyi unary'e çevirir.

Kalan program, alt satırdaki tekli sayıyı art arda üst sıradaki izini sürdüğü pozitif tamsayıları artırarak bölüştürür.

+` dize aynı kalana kadar döngü

  • ^(1+)¶(\1)+$alt satırdaki birçok 1s ve birçoğunun 1alt çizgisini eşleştirin ve

  • 1$1¶$#2$*üst çizgi birçok 1başka s ile 1, yani, üst çizgiyle gösterilen sayıyı 1 ile, ardından yeni çizgiyi ve alt çizgideki en üst çizginin eşleşme sayısını (yani, ikinci yakalama grubunun eşleşme sayısını) takip eder. ) birçok 1s, yani, alt sayıyı üst sayıya bölme

Bir kez artık yapmak mümkün olmadığında,

¶.$yani bu regex'in eşleşme sayısını verin. 1Alt satırda yalnız bir sayı var mı, ancak sayı faktör ise


Eğer hakikat / sahte değerler yerine çarpışma / çökmeye izin verilmezse 36 34 bayt alabilirim .

^
1¶
{`.+$
$*
^(1+)¶(\1)+$
1$1¶$#2

Bu aynı yaklaşımla gider, ancak $*üçüncü ve dördüncü sıralarda birleştirir. Üçüncü çizgi ileriye aynı döngünün bir parçası olduğu, {kısaltmasıdır +(burada (gruplar döngüye geri kalan satırlar. Faktoriyaller programın döngüsünden kopmasına neden olurken, Factorial olmayanlar sonsuza dek döngü içinde sıkışıp kalırken, Retina son değiştirme işleminin başarısız olmasına bağlı olarak bir OverflowException atıyor, bu nedenle de alt kısımları ondalık basamağı yerine tekdüze olacak ve döngünün ilk değişimi alt satırı ondalıktan birliğe dönüştürür, böylece hızlı bir şekilde patlar.


Değiştirme işleminin sonunda olduğu 1gibi olduğu gibi kaldırarak bir bayt kaydedin $*.
Neil,

Daha da iyisi, $*diğer iki çizgiyle birleştir .
Neil,


3
Şartlı olarak Retina'yı çökertmenin bir yolunu bulman çok etkilendim :)
Martin Ender

2
Bir açıklama ekleyebilir misiniz?
Hesap MakinesiFeline

8

05AB1E , 4 bayt

L!QO

Çevrimiçi deneyin!

açıklama

L      # range [1 ... input]
 !     # calculate factorial of each
  Q    # compare with input for equality
   O   # sum

1
Girdiyi çıkardığı için önce girişi kopyalamanıza gerek yok Lmu? Ayrıca, Å!girdiye eşit veya daha az olan bir faktoring listesi verir.
Neil A.,

@NeilA. Neyse ki bir işlem için yığında yeterli argüman yoksa giriş tekrar açılır, bu yüzden Dburada ihtiyacım yok. İyi yakala Å!. Liste komutlarını hep unutuyorum. Herhangi bir bayt kurtarmaz, ancak kesin olarak daha verimlidir.
Emigna

Girdilerin tekrar patlatıldığını bilmiyordum ... çok fazla bayt kurtarabilirdi.
Neil A.,

@NeilA. Bu oldukça yeni bir özellik. Sanırım bir aydan daha az eklendi.
Emigna

8

C ++, 102 100 92 Bayt

#include<cmath>
int a(int n){int i=n,j=0;for(;i;)j|=lround(exp(lgamma(i--+1)))==n;return j;}

Faktörün ila arasındaki tüm değerleri 0değiştirip nhesaplar ve eşit olup olmadığını kontrol eder n.

Teşekkürler Christoph! (8 bayt kaydedildi)


Selam! PPCG'ye Hoşgeldiniz! Güzel ilk cevap! Gelecek için iyi şanslar!
Arjun

Güzel ilk cevap! Böyle birkaç byte kaydedebilirsiniz: int a(int n){int i=n,j=0;for(;i;)j|=lround(exp(lgamma(i--+1)))==n;return j;}. lroundve lgammazaten C ++ 11 vardır, bu yüzden basitçe #include<cmath>. Belki önerilerimi daha da geliştirebilirsin :)
Christoph

7

Haskell , 43 26 bayt

f n=elem n$scanl1(*)[1..n]

Çevrimiçi deneyin!

  • Laikoni sayesinde 17 bayt kaydedildi

2
f n=elem n$scanl1(*)[1..n]saçma verimsiz ama daha kısa.
Laikoni

Kod verimliliği ile ilgili bazı kurallar yok mu?
sudee

1
Hiçbiri farkında değilim. code-golf , verimlilik beyanı olmadan mümkün olduğu kadar az baytlık bir çözüm istiyor. Ayrıca makinemde bu fonksiyon 40430belirgin bir gecikme olmadan çalışır .
Laikoni

"Çözüm makul bir zaman diliminde sona ermeli" hattı boyunca bir şey ifade ediyordum, ancak şartlara her iki şekilde de uygun olduğunu düşünüyorum. Teşekkürler!
sudee

1
Güzel ve basit. Ben, bölünme-sözü söyleyen daha iyisini yapabileceğimi düşündüm divModtarafından [1..]1 (faktöriyel) bir bölüm ya da sıfırdan farklı kalanı (non-faktöryel) ile sıfır kalanını ulaşana kadar arka arkaya, ama doğru bir yaklaşım olarak görünmemektedir. Bu sevimli 46 karakterlik çözümü buldum f|let x%n=mod n x==0&&(x+1)%div n x||n==1=(1%).
Jon Purdy

6

Haskell , 38 bayt

m#n=n<2||mod n m<1&&(m+1)#div n m
(2#)

Çevrimiçi deneyin! Örnek kullanımı: (2#) 24. TrueVeya döndürür False.

Bu hala çok verimli olurken alabileceğim en kısa şey. En büyük rakamlar için bile

145183092028285869634070784086308284983740379224208358846781574688061991349156420080065207861248000000000000000000

sonuç hemen verilir. Çözelti giriş bölünmesi ile çalışır nile m = 2,3,4,5,...ya sonucu bir ya kadar nbölünebilen değildir m.

Factorial olmayan n!girişleri hesaplayan daha kısa ama inanılmaz verimsiz 26 baytlık çözüm için buraya bakınız .



5

Fourier , 40 39 bayt

I~Q1~N(i^~i*N~N{Q}{1~Xo}N>Q{1}{1~X0o}X)

FourIDE'da dene!

Temel olarak, N sayısını girişe eşit olan (çıkış 1) veya (çıkış 0) 'dan büyük olana kadar N sayısını arttırır.

Açıklama Sözde kodu:

Q = Input
N = 1
While X != 1
    i += 1
    N = N*i
    If N = Q Then
        Print 1
        X = 1
    End If
    If N > Q Then
        Print 0
        X = 1
    End If
End While

5

Japt , 8 6 bayt

ol x¥U

Çevrimiçi deneyin!

Bu, false için 0, true için 1 verir.

açıklama

 ol x¥ U
Uol x==U
Uo       # Create the range [0 ... input]
  l      # Replace each element by its factorial
     ==U # Compare each element to the input (yielding 1 if equal and 0 otherwise)
    x    # And sum the result

1
Gerçekten "yerleşik" bir eklenti eklemeliyim: P
ETHproductions

1
Selam, değiştirmek olabilir aU ¦Jiçin x¥U(her harita Xiçin X==Uolsa TIO üzerinde çalışma yapmayacak ve toplamı).
ETHproductions

2Becuase için başarısızlık osadece sana verecek [0,1]. İşte 1 bayt tasarruf ile bir düzeltme .
Shaggy

4

Perl 5, 31 bayt

$a=<>;$a/=++$i while$a>1;exit$a

Giriş STDIN üzerinden alınır, çıkış çıkış kodu ile verilir (faktoring için 1, faktoring dışı için 0).

Girdi, 1 veya bir kesirden küçük olana kadar art arda tamsayılarla bölünür ve sonuç kesilir.



4

Perl 6 , 29 bayt

{($_,{$_/++$}...2>*).tail==1}

Dene

Expanded:

{   # bare block lambda with implicit parameter 「$_」

  (              # generate a sequence

    $_,          # starting with the input

    {
      $_ / ++$   # divide previous element by an ever increasing number
                 # 1,2,3,4,5,6,7,8 ... *
    }

    ...          # keep generating until

    2 > *        # 2 is greater than what was generated
                 # ( 1 or a fractional number )

  ).tail == 1    # check if it ended at 1
}

17 bayt: {$_∈[\*] 1..$_}. Bir başka ilginç yaklaşım da 2>*.polymod(1..*).sum.
nwellnhof

4

setlX , 32 bayt

f:=n|=>exists(x in{0..n}|n==x!);

fPotansiyel faktörlüğünüzü parametre olarak kullandığınız bir fonksiyon yaratır .

Keyfi tamsayı büyüklüğü ile çalışır, ancak oldukça verimsiz.

(bu arada: bu benim bir programlama bulmacasına ilk katılımım)




4

C # (.NET Core) , 68 bayt

bool f(System.Numerics.BigInteger n,int k=2)=>n<2||n%k<1&f(n/k,k+1);

Çevrimiçi deneyin!

En kısa çözüm değil, ancak gerçekten büyük sayılarla çalışır. TIO bağlantısı ile bir örnek içerir 10000!.

İşte intmaksimum 2147483647 değerinde olan daha kısa bir sürüm .

C # (.NET Çekirdeği) , 45 bayt

bool f(int n,int k=2)=>n<2||n%k<1&f(n/k,k+1);

Çevrimiçi deneyin!

Her iki cevaptan toplamda 3 baytlık golf oynamak için @KevinCruijssen'e kredi verin!


2
Oyun &&golf oynayabilir &ve parkur ;lambda fonksiyonları için sayılmak zorunda değildir. Ayrıca, olamaz ulong k=2olmak uint k=2için 50 bayt yanıtında?
Kevin Cruijssen

1
&Vs iyi yakalamak &&. Bir yığın taşma aldığımı sanıyordum, ama daha sonra çalışıyor gibi görünüyor. ulong32 ise 64 bit. uintBaşkalarının kullanıyor gibi görünüyor, intbu yüzden belki sadece kısa versiyonu için kullanacağım. İzlemeyle ilgili olarak ;, bunlar tam işlevlerdir, lambda değil, bu yüzden onları eklememe ihtiyacım var?
Dana,

Yani .NET çözülmesini sağlayabilir gerçekten garip /ve %aralarında ulongve uintancak ulongve int. Bunu bilmiyordum :)
dana

1
@Oliver - Bir doublenoktada yuvarlama görmeye başladığınızda - örneğin, 24! ve 120! başarısız. System.Numerics.BigIntegerEn hassas olmasına rağmen , en intkısa cevabı :)
dana

1
@Deadcode - Haklısın 0'da :) :) Mücadeledeki örneklere dayanarak, "doğal sayıları" 1,2 olarak yorumladım, ... Gerçek dünyada kısa devre &&operatörünü kullanmanın daha iyi olacağı konusunda . Ama bu kod golf;) Örnekten memnun oldum 10000!!
Dana

4

C ++ (clang), 51 bayt

Reküreme, golf oynamaya kadar kazanır.

51 bayt, sıfır doğrudur:

int f(int n,int i=2){return n<2?!n:n%i|f(n/i,i+1);}

Bu, 1 baytlık tasarruf için oldukça fazla hız feda eder. Mantıksal OR'un kısa devre değerlendirmesi nedeniyle, bunu hızlı yapmak için |ile değiştirin ||.

Çevrimiçi deneyin! (51 byte slow version)
Çevrimiçi deneyin! (52 byte hızlı versiyon)

Ungolfed yavaş versiyonu:

int isFactorial(int n, int i=2)
// returns 0 for true, and nonzero for false
{
    if (n < 2) // same as "if (n==0 || n==1)" in our natural number input domain
    {
        if (n==0)
            return 1; // not factorial
        else // n==1
            return 0; // is factorial (could be either 0! or 1!)
    }

    // Because any nonzero value represents "false", using "|" here is equivalent
    // to "||", provided that the chain of recursion always eventually ends. And
    // it does always end, because whether or not "n" is factorial, the "n / i"
    // repeated division will eventually give the value of zero or one, satisfying
    // the above condition of termination.
    return (n % i) | isFactorial(n / i, i+1);
}

Ungolfed hızlı versiyonu:

int isFactorial(int n, int i=2)
// returns 0 for true, and nonzero for false
{
    if (n < 2) // same as "if (n==0 || n==1)" in our natural number input domain
    {
        if (n==0)
            return 1; // not factorial
        else // n==1
            return 0; // is factorial (could be either 0! or 1!)
    }

    if (n % i != 0)
        return 1; // not factorial
    else
        return isFactorial(n / i, i+1);
}

Bunu yeniden düzenlemenin birçok yolu var.

52 bayt, sıfır olmayan doğru:

int f(int n,int i=2){return n<2?n:n%i?0:f(n/i,i+1);}

Çevrimiçi deneyin!

52 bayt, sıfır doğru:

int f(int n,int i=2){return!n?1:n%i?n-1:f(n/i,i+1);}

Çevrimiçi deneyin!

Özyinelemeye başvurmadan önce bazı yinelemeli sürümler yapmaya çalıştım ve yaklaşdılar.

54 bayt, sıfır olmayan doğru:

int f(int n){for(int i=2;n>1;)n=n%i?0:n/i++;return n;}

Çevrimiçi deneyin!

54 bayt, sıfır doğrudur ( Roman Gräf's Java 8 gönderimine göre ):

int f(int n){int a=1,i=0;for(;a<n;a*=++i);return a-n;}

Çevrimiçi deneyin!

Şimdi, namlunun dibi için, özyinelemesiz sürümleri n==0kullanmadan (bunları geçersiz buluyorum, çünkü 0 doğal bir sayıdır ve çok sınırlı kullanımda "doğal sayılar" için yapılmadığı herhangi bir tanımdır). Aşağıdaki sürümlerde, sonsuz yineleme f(0), yığının taşması nedeniyle ya da yinelemeye en iyi duruma getiren derleyiciler ile bir döngü kaybına neden olur;

48 bayt, sıfır doğru:

int f(int n,int i=2){return n%i?n-1:f(n/i,i+1);}

Çevrimiçi deneyin!

48 bayt, sıfır doğrudur ( Hagen von Eitzen'in 33 bayt C (gcc) gönderimine dayanarak ):

int f(int n,int e=0){return n%++e?n-1:f(n/e,e);}

Çevrimiçi deneyin!


50 EDIT: 49 , özyineleme olmadan.
Grimmy

48 için özyinelemeye geri dönün . Muhtemelen bundan hoşlanmayacaksınız ama 44 global var kullanarak.
Grimmy

3

Mathematica, 20 bayt

!FreeQ[Range[#]!,#]&

büyük sayıları test etmek için diğer sürüm (yorumları görün)

Range[10^3]!~MemberQ~#&

1000'e kadar test eder!


2
Anladığım kadarıyla, eğer Mathematica 1001 alabiliyorsa! bir giriş olarak bu şartnameye uygun değil.
Peter Taylor

2
Tüm girişler için geçerli kılarken üç bayt bile kaydedebilirsiniz. Sadece 10 ^ 3 yerine #; Range @ #
Julien Kluge 'nin

1243234 için @Julien Klugethen sonsuza dek sürecek ...
J42161217

1
Sana değiştirerek başka byte kurtarabilir miyiz Range[#]ile Range@#:)
numbermaniac

3
Bir başka baytı infix sözdizimi ile kaydedebilirsiniz !Range@#!~FreeQ~#&.
numbermaniac

3

Cubix , 24 bayt

U0O@1I1>-?1u>*w;W;@Orq)p

Çevrimiçi deneyin

Cubified

    U 0
    O @
1 I 1 > - ? 1 u
> * w ; W ; @ O
    r q
    ) p

Biz iterek başlamak 1, I, girilen 1yığının üzerine. Bunlar sırasıyla endeksimiz, hedefimiz ve akümülatörümüz olacaktır.

Daha sonra döngü yapıyoruz. Her yinelemede, akümülatörü girdiden çıkartırız. Sonuç 0 ise 1, Obittiğimiz için, bastırır , çıkarır ve çıkarız. Sonuç negatif olursa biz itmek böylece biz, çok ileri gittin 0, Oıkış ve çıkış. Aksi halde görürüz

;p)*rq;
;         Pop the difference off the stack.
 p)       Move the index to the top of the stack and increment it.
   *      Multiply the accumulator by the index to get the next factorial.
    rq;   Put the stack back in the right order.

3

Neim , 8 bayt

𝐈Γ𝐈𝐩₁𝔼)𝐠

Açıklama:

Example input: 6
𝐈         Inclusive range [1 .. input]
          [1, 2, 3, 4, 5, 6]
 Γ        For each...
  𝐈         Inclusive range [1 .. element]
            [[[1], [1, 2], [1, 2, 3], [1, 2, 3, 4], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5, 6]]
   𝐩        Product
            [1, 2, 6, 24, 120, 720]
     𝔼      Check for equality with
    ₁       the first line of input
            [[0, 0, 1, 0, 0, 0]]
      )   End for each
       𝐠  Select largest element
          [1]

Dene!

Neim , 3 bayt (rekabet etmeyen)

Zorlama yapıldıktan sonra içerilen belirteç ve faktör belirteç olarak rekabet etmeyenler eklendi.

𝐈𝐓𝕚

Açıklama:

Example input: 6
𝐈     Inclusive range [1 .. input]
      [[1, 2, 3, 4, 5, 6]
 𝐓    Factorial each
      [[1, 2, 6, 24, 120, 720]]
  𝕚   Check that the [cycled] input is in the list
      [1]

Dene!


3

> <> , 24 22 bayt

@Aaron sayesinde -2 bayt

Yeni bir dil deniyorum (Mathematica lisansımın süresi dolmuş olduğundan ...)

01\{=n;
?!\$1+:@*:{:}(

Çevrimiçi olarak veya balık oyun alanında deneyin

Giriş numarasının zaten yığında olduğunu ve 0 veya 1 değerini döndürdüğünü varsayar. İlk n sayısını girdiden daha az olana kadar ilk olarak çarparak çalışır ve ardından girişe eşitse 1, sonra değilse 0 t.


Seni v>\n<^dönüştürebilirsin \\n/; buraya bakın
Aaron

@Aaron, bu harika, teşekkür ederim!
Ağaç değil

3

APL (Dyalog Unicode) , 5 6 7 bayt

Değiştirerek byte golfed ×/için !Erik Outgolfer sayesinde

⊢∊!∘⍳

Çevrimiçi deneyin!

açıklama

                          Range of numbers from 1 to argument, 1 2 3 4 .. n
   !                       Factorial; 1! 2! 3! 4! .. n!
⊢∊                         Is the right argument a member of this list?

Birikimli toplam?
Sızdıran Rahibe

@LeakyNun Sabit
Kritixi Lithos

GNU APL 1.2'de bir ilave bayt daha var. N∊×\⍳N←⎕Bu nasıl bir tartışmaya girer? Hiçbir nyerde göremiyorum . Bu Dyalog'a özgü bir şey mi?
Arc676

2
@ Arc676 Benim çözümüm bir tren ve buna (⊢∊(×/⍳)) right_argumentşöyle diyorsunuz : TIO bağlantısında gördüğünüz gibi. Ve doğru argüman ifade eder.
Kritixi Lithos,

Notlar: AGL size bir bayt kazandırır; ⊢∊×\ä⍳. "Doğru" (ancak daha uzun) çözüm 0=1|!⍣¯1; "Ters faktörlü bir tamsayı mı?"
Adám

2

JavaScript (ES6), 71 bayt

Bu, fonksiyon argümanı olarak girdiyi alır ve alertçıktıdır. Çıkışlar 0Falsey için ve1 truthy için.

f=n=>n?n*f(n-1):1;g=(n,r=0,i=0)=>{while(i<=n){r=f(i)==n|r;i++}alert(r)}

açıklama

Program iki fonksiyondan oluşmaktadır fve g. fözyinelemeli bir faktörel hesaplama işlevidir ve gprogramın ana işlevidir. tek bir argüman g olduğunu varsayarn . r0 değerine sahip varsayılan bir argümanı ve değerine sahip başka bir varsayılan argümanı tanımlar 0. Daha sonra, tüm Tamsayıları 0'dan ntekrar eder ve her bir yinelemede, füzerine uygulanan işlevin i(geçerli dizin) eşit nolup olmadığını, yani nbir faktörlü olup olmadığını denetler i. Bu durumda, rdeğeri 1 olarak ayarlanır. İşlev sonunda r, alerted.

Test Parçacığı

( Not: Snippet console.log(), bu sinir bozucu alert()s'den çok kimse gibi kullanılmayacak şekilde çıktı . )

f=n=>n?n*f(n-1):1;g=(n,r=0,i=0)=>{while(i<=n){r=f(i)==n|r;i++}console.log(r)}

g(1)
g(2)
g(3)
g(4)
g(5)
g(6)
g(7)
g(8)
g(24)
g(120)


Değerlendirme bir kod bloğu kullanmaktan daha kısa olabilir.
Downgoat

@Downgoat Bunu nasıl yapmalıyım? Çok açıksa üzgünüm! : P
Arjun,

2

QBIC , 21 19 bayt

[:|q=q*a~q=b|_x1}?0

açıklama

[:|     Start a FOR loop from 1 to n
q=q*a   q starts as 1 and is multiplied by the FOR loop counter
        consecutively: q=1*1, *2, *3, *4 ... *n
~q=b|   If that product equals n
_x1     Then quit, printing a 1
}       Close the IF and the FOR
?0      If we're here, we didn't quit early and didn't find a factorial, print 0

Önceden

[:|q=q*a┘c=c+(q=b)}?c

Açıklama:

[:|         Start a FOR loop from 1 to n
q=q*a       q starts as 1 and is multiplied by the FOR loop counter
            consecutively: q=1*1, *2, *3, *4 ... *n
┘           Syntactic line break
c=c+        c starts out at 0 and then keeps track of 
    (q=b)       how often our running total == n
}           Closes the FOR-loop
?c          Print c, which is 0 fir non-factorials and -1 otherwise.

2

Java 8, 59 bayt

i->{for(int j=1,c=0;j<=i;j*=++c)if(j==i)return 1;return 0;}

deneme kodunda

import java.util.function.IntFunction;
import java.util.stream.IntStream;

public class IsFactorial
{
    public static IntFunction<Integer> isFactorial = i->
    {
        for(int j=1,c=0;j<=i;j*=++c)
            if(j==i)return 1;return 0;
    };

    public static int[] truthyCases = {1,2,6,24,120};
    public static int[] falsyCases = {3,4,5,7,8};

    public static void main(String[] args)
    {
        System.out.println
        (
            IntStream.of(truthyCases)
                .allMatch(i->isFactorial.apply(i)==1)
            && IntStream.of(falsyCases)
                .allMatch(i->isFactorial.apply(i)==0)
        );
    }
}
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.