Bir sayının ardışık tamsayı sayılarının bir ürünü olup olmadığını kontrol edin


18

Aşağıdaki gibi bazı sayılar: 6, 12, 20, 30, 42, 56, 60, 90, 120 ve benzerleri, aşağıda gösterildiği gibi ardışık tam sayıların bir ürünü olarak ifade edilebilir.

6   = 2 * 3  
12  = 3 * 4  
30  = 5 * 6
60  = 3 * 4 * 5  
90  = 9 * 10  
120 = 4 * 5 * 6  

Ürünün belirtilen sayıya eşit olduğu ardışık tamsayıların bir listesini çıkaran bir program veya işlev yazın.

Bu mantık için uygun olmayan sayılara örnekler:

99  = 9 * 11  (Product of non-consecutive numbers)
121 = 11 * 11 (Same numbers)
2   = 1 * 2   (Product of itself and 1)
13  = 13      (Product of only one number)

Lütfen 2 = 2 * 1, 1 ile çarpılan bir tamsayı aynı sonucu verdiğinden, geçerli bir sonuç olarak değerlendirmediğimizi unutmayın . Bu soru için, üründe yalnızca> = 2 tamsayısını dikkate alacağız.

Giriş

Geçerli bir 32 bit pozitif tam sayı. Standart girdi, bir işlev bağımsız değişkeni vb. Olabilir.

Çıktı

Ardışık tam sayıların listesi> = 2 (artan veya azalan sırada). Ardışık tamsayıların birkaç kombinasyonu varsa, sadece bir örneğin yapmasını sağlayın . Daha fazlasını sağlarsanız, para cezası.

Kısıtlamalar

Kodun standart bir bilgisayarda çalışması makul bir süre (<5 dakika) sürmelidir tüm geçerli girişler (pozitif 32 bit tamsayılar) için . Ardışık bir tamsayı ürün varsa, kod zaman sınırı içinde bir veya daha fazla çıktı almalıdır. Aksi takdirde, kod zaman sınırı içinde çıktı olmadan sonlandırılmalıdır.

Bu kod golf, yani bayt içindeki en kısa kod kazanır.


1
Bu bulmaca, belirtildiği gibi, bu sitenin biçimi için uygun değildir. Bu site, bir kazanana karar vermenin iyi bir yolunun olduğu yarışmalar içindir (örneğin, en kısa kod, en hızlı kod, çoğu oy, vb.). Böyle bir yol göstermediniz.
Chris Jester-Young

2
Bunu bir kod-golf (en kısa kod.) Yapmanızı tavsiye ederim, ancak üzerine bazı sınırlar koymanız gerekir. Örneğin 0 ile 1000000 arasındaki sayılar, maksimum yürütme süresi 10 sn, vb.
Level River St

Bu soruyu kurtarmak için düzenlemeyi denedim. Ama daha önce hiç soru sormadım, bu yüzden bir şey görürseniz, lütfen düzenleme yapın.
Vectörize

@ bitpwner Birkaç yazım hatası dışında, bana iyi geliyor. Oy verildi reopen.
seequ

5
Bence demek istiyorsun 30=5*6.
Kyle Kanos

Yanıtlar:


8

Java - 124

String f(int t){int s=2,h=3,p=s,i;String o="";for(;p!=t&&s*s<t;p=p<t?p*h++:p/s++);if(p==t)for(i=s;i<h;o+++=i+" ");return o;}

2'den başlayarak, başlangıç ​​numarası hedefin karekökü olana (veya hedefe tam olarak ulaşılana) kadar bu döngü gerçekleşir. Ürün düşükse, yüksek sayı ile çarpar ve arttırır. Yüksekse, başlangıç ​​numarasına böler ve artırır.

Örneğin, 30 yaşında şunları kontrol eder:

2*3     = 6 (too low, multiply)
2*3*4   = 24 (too low, multiply)
2*3*4*5 = 120 (too high, divide)
3*4*5   = 60 (too high, divide)
4*5     = 20 (too low, multiply)
4*5*6   = 120 (too high, divide)
5*6     = 30 (bingo!)

Boşlukla ayrılmış bir faktör dizesini artan sırada çıkarır.

Satır kesmeleri ile:

String p(int t){
    int s=2,h=3,p=s,i;
    String o="";
    for(;p!=t&&s*s<t;p=p<t?p*h++:p/s++);
    if(p==t)
        for(i=s;i<h;o+=i+" ");
    return o;
}

7

Python - 104 97 95 92 dene

n=input()
s=i=2
c=1
while s<n:
 s*=i+c;c+=1
 if s==n:print range(i,i+c)
 if s/n:i+=1;s,c=i,1

Eğer nkadar, mesela, daha önce 120 ayarı, program iki çözüm üretir:

[2, 3, 4, 5]
[4, 5, 6]

Üzgünüm, bazı girdileri tanımlamayı unuttum.
Falko

1
c = c + 1, i = i + 1 yerine c + = 1, i + = 1
Gerrat

1
Oh evet, düşünmedim +=. Ama ++Python'da özlüyorum ...
Falko

1
if s>=nve if s/neşdeğerdir, böylece tüm çözümleri aynı sayıda karakterle sağlayabilirsiniz.
isaacg

1
Sen değiştirerek üç karakter kaydedebilirsiniz s=s*(i+c)için s*=i+c.
El'endia Starman

4

Clojure - 127 109 bayt

(defn f[x](first(for[r[range]y(r 2 x)v[(take-while #(<=(apply * %(r y %))x)(r y x))]:when(=(apply * v)x)]v)))

Misal:

(map f [6 12 30 60 90 120 1404816 99 121 2 13])
=> ((2 3) (3 4) (5 6) (3 4 5) (9 10) (2 3 4 5) (111 112 113) nil nil nil nil)

Açıklama:

Bu temel, oldukça optimize edilmemiş fonksiyonel yaklaşımdır. Tüm olasılıkların üzerinde basit bir döngü kullanarak tembel bir liste oluşturuyorum (çok büyük sayılar verecek, taşmayı önleyen tüm kombinasyonları atlıyor) ve ilkini alıyor. Hiçbir olasılık yoksa sıfır döndürür.

Test etmek en kolay http://tryclj.com/ .


Şimdi de tüm olasılıkları döndürebileceğimi fark ettim: 120 bayt 102 bayt , ancak iç içe bir listede sonuç verir.

(defn f[x](for[r[range]y(r 2 x)v[(take-while #(<=(apply * %(r y %))x)(r y x))]:when(=(apply * v)x)]v))

Misal:

(map f [6 12 30 60 90 120 1404816 99 121 2 13])
=> (((2 3)) ((3 4)) ((5 6)) ((3 4 5)) ((9 10)) ((2 3 4 5) (4 5 6)) ((111 112 113)) () () () ())

3

CJam, 31 bayt

q~:Qmq,A,m*{2f+~,f+_:*Q={p}*}%;

Bu kaba-kuvvet yaklaşımıdır, ancak resmi Java yorumlayıcısı kullanılarak yürütme süresi sadece birkaç saniyedir .

Çevrimiçi yorumlayıcıyı kullanarak kodu test etmek istiyorsanız , girişi makul düzeyde düşük tutmalısınız. Makinemde 2 26'dan az herhangi bir şey hala çalışıyor.

Örnekler

$ TIME="%e s"
$ time cjam product.cjam <<< 2
0.12 s
$ time cjam product.cjam <<< 6
[2 3]
0.10 s
$ time cjam product.cjam <<< 120
[2 3 4 5]
[4 5 6]
0.12 s
$ time cjam product.cjam <<< 479001600
[2 3 4 5 6 7 8 9 10 11 12]
0.68 s
$ time cjam product.cjam <<< 4294901760
[65535 65536]
1.48 s
$ time cjam product.cjam <<< 4294967295
1.40 s

Nasıl çalışır

q~:Q      " Read from STDIN, interpret the input and save the result in variable “Q”.     ";
mq,       " Push the array [ 0 1 2 … (Q ** 0.5 - 1) ].                                    ";
A,m*      " Push the array [ 0 1 2 … 9 ] and take the Cartesian product.                  ";
{         " For each pair in the Cartesian product:                                       ";
  2f+     " Add 2 to each component.                                                      ";
  ~       " Dump the array's elements on the stack.                                       ";
  ,       " Push the array [ 0 1 2 … n ], where “n” is the topmost integer on the stack.  ";
  f+      " Add “m” to each element, where “m” is the integer below the array.            ";
  _:*     " Duplicate the resulting array and push the product of its elements.           ";
  Q={p}*  " If the product is equal to “Q”, print.                                        ";
}%        " Collect the remaining results into an array.                                  ";
;         " Discard the array from the stack.                                             ";

2

Java, 162

bir tamsayı dizisi döndürür veya nullvar olan ardışık sayılar yoksa.

int[] e(int n){for(int i=1;i<n;i++){int h=i+1,c=1,s=i;while(s<n){c++;s*=h++;}if(s==n){int[] o=new int[c];for(int j=0;j<c;j++){o[j]=h-j-1;}return o;}}return null;}

ungolfed:

int[] execute(int input){
    for(int i=1; i<input; i++){
        int highest = i+1, count = 1, sum = i;
        while(sum < input){
            count++;
            sum *= highest++;
        }
        if(sum == input){
            int[] numbers = new int[count];
            for(int j=0; j<count; j++){
                numbers[j] = highest-j-1;
            }
            return numbers;
        }
    }
    return null;
}

2

C 105 110 deneyin

n,k,l;main(i){for(scanf("%d",&n);++i<n;)for(k=1,l=i;k<n;)if(k*=l++,k==n)for(l=n;l/=i;)printf("%d ",i++);}

144 bonus ile: bu her sayı boyunca yinelenir ve eşleşen ürünleri bulur

main(i,j,k,l,m){for(scanf("%d",&m);++i<13;)for(j=0;++j<46341-i;){for(l=k=1;k<=i;)l*=j+k++;if(l==m)for(puts(""),k=0;k<i;)printf("%d ",j+k+++1);}}

Güzel, çok basit ve zarif! Kesinlikle ben attı küçük sayıların bazıları için çalıştı. Sonra 50815512 (7128 x 7129) verdim ve sonsuz bir döngüye girdi. 7128 x 7129 x 7130 = 362314600560 hesaplamaya çalıştığında taşan mı?
Todd Lehman

Teşekkürler! görünüşe göre k < ndurum çok yüksek oluyor k *= l++. başından beri uzun süre imzasız ekleyebilirim ama ... hayatlarını mahveder
bebe

2

PHP 258 karakter, 201 faktöriyel fonksiyon saymıyor.

Matematiksel olarak "Bir sayısına eşit ardışık faktörleri" ifade etmek en basit yoldur X!/Y!nerede Xen yüksek sayıdır ve Yen düşük eksi biridir. Ne yazık ki çözmeyi öğrenmeden önce kalkülüs almayı bıraktım Z = X!/Y!, bu yüzden biraz kaba kuvvetlendirmek zorunda kaldım.

Dağınık, çözülmemiş versiyon:

<?php
// PHP does not define a factorial function, so I've kludged one in.
function fact($n) {
    $r = 1;
    for($i=$n; $i>1; $i--) {
        $r *= $i;
    }
    return $r;
}

$input = intval($argv[1]);

if( $input < 2 ) { die('invalid input'); }

printf("input: %s\n", $input);

$max=min(ceil(sqrt($input)),170); // integer breakdown for > 170!
$grid = array();
for( $x=1;$x<$max;$x++ ) {
    for( $y=$max;$y>=1;$y-- ) {
        if( $y >= $x ) { continue; } // Skip results that would be < 1
        $cur = fact($x)/fact($y);
        if( $cur > $input ) { // too large!
            echo "\n"; continue 2;
        }
        if( $cur == $input ) { //just right
            printf("%7d\n\nFound %s == %s\n", $cur, implode(' * ', range($y+1, $x)), $cur);
            break 2;
        }
        printf("%7d ", $cur);
    }
    echo "\n";
}
if($cur!=$input){printf("No consecutive factors produce %d\n", $input);}

Örnek çıktı:

input: 518918400

  2
  3       6
  4      12      24
  5      20      60     120
  6      30     120     360     720
  7      42     210     840    2520    5040
  8      56     336    1680    6720   20160   40320
  9      72     504    3024   15120   60480  181440  362880
 10      90     720    5040   30240  151200  604800 1814400 3628800
 11     110     990    7920   55440  332640 1663200 6652800 19958400 39916800
 12     132    1320   11880   95040  665280 3991680 19958400 79833600 239500800 479001600
 13     156    1716   17160  154440 1235520 8648640 51891840 259459200
 14     182    2184   24024  240240 2162160 17297280 121080960
 15     210    2730   32760  360360 3603600 32432400 259459200
 16     240    3360   43680  524160 5765760 57657600 518918400

Found 9 * 10 * 11 * 12 * 13 * 14 * 15 * 16 == 518918400

golfed:

<? function f($n){$r=1;for($i=$n;$i>1;$i--)$r*=$i;return $r;}$i=$argv[1];$m=min(ceil(sqrt($i)),170);for($x=1;$x<$m;$x++){for($y=$m;$y>0;$y--){if($y>=$x)continue;$c=f($x)/f($y);if($c>$i)continue 2;if($c==$i){$y++;echo "$y $x";break 2;}}}if($c!=$i){echo 'No';}

Çıktı:

[sammitch@vm ~/golf] time php consecutive_golf.php 518918400
9 16
real 0m0.019s
user 0m0.011s
sys  0m0.009s
[sammitch@vm ~/golf] time php consecutive_golf.php 518918401
No
real 0m0.027s
user 0m0.017s
sys  0m0.011s

Çalışma süresi oldukça hızlı olmasını beklemiyordum!


Bu fikir de aklıma geldi ve çok verimli görünüyor ama "nitelikli olmak" için kısaltılabilir şüpheliyim.
bebe

1
@bebe 258 karakter, PHP için çok kötü değil. Eğer çok tembel ve inatçı olmasaydım bunu gerçek bir dilde yapardım . : P
Sammitch

X! / Y! "Y" N = X olacak şekilde N tamsayılarının çarpımıdır. Bu hiç yardımcı oluyor mu?
trichoplax

2

Pyth , 35

JvwKr2 4W-ZJ~@KgJZ1=YurGHK=Zu*NTY)Y

Not: Kodum aslında girişin en kısa temsilini> = 2 ardışık tamsayıların bir temsili olarak bulur, bu nedenle geçersiz girişte, muhtemelen çok uzun bir süre sonra 1 elemanlı bir liste yazdırır. Sorun ifadesi girişin geçerli olacağını söylediğinden, bunun iyi olduğunu varsayıyorum.

Kısa açıklama:

Esasen, program bir aralığın üst ve alt sınırlarını depolar, aralıktaki sayıların çarpımını kullanarak ürününü hesaplar, uç noktaları gerektiği gibi ayarlar ve ürün girişe eşit olana kadar tekrar eder.

Uzun açıklama:

Her kod snippet'i için, daha ayrıntılı bir açıklama ve akıl yürütmenin yanı sıra eşdeğer python vereceğim.

Jvw => J=eval(input())

Pyth'te girdi almanın standart yolu.

Kr2 4=> K=range(2,4)=>K=[2,3]

İşte ilk garip kısım: Uç noktaları ayrı değişkenler olarak saklamak yerine, onları bir listenin öğeleri olarak saklıyorum. Nedeni yakında belli olacak. Ayrıca, Pyth'teki basit bir ödev yapmak yerine, K[2 3)bir karakteri kaydetmek için bir aralık kullanıyorum.

W-ZJ=> while Z-J=>while Z!=J

Bu noktada, "Z nedir? Onu tanımlamadınız" diye sorabilirsiniz. Pyth'te tüm değişkenler önceden tanımlanmıştır. Z 0 olarak başlar. Ancak Z daha sonra ürünün değerine ayarlanır, bu nedenle liste doğru değere ulaştığında bu kontrol while döngüsünü sonlandırır.

~@K>JZ1 => K[J>Z] += 1

İşte neden değerleri ayrı değişkenlerde değil, bir listede saklıyorum: Ürünün şu anda çok yüksek veya çok düşük olmasına bağlı olarak, iki uç noktadan birini artırmak istiyorum. Uç noktalar ayrı değişkenler olsaydı bu oldukça uzun bir koşul olurdu, ancak liste indeksleme büyüsü ile kısalır. Ayrıca, bu kontrolün üründen önce gelmesi ve Z'nin 0 olarak başlatılması gerçeği, K'nın [2,4]ürünü ilk aldığımız zamana kadar, uygun son noktalar olmasını sağlayacaktır.

=YurGHK=> Y=reduce(lambda G,H: range(G,H),K)=>Y=range(K[0],K[1])

Şimdi, ürünün devralınacağı ve başarılı olursak basılacak olan gerçek listeye ihtiyacım var. Açıkçası, bir aralık fonksiyonu kullanacağız. Düzenbazlık, aralık işlevinin girdilerinin elde edilmesinde yatmaktadır. Bunu yapmanın bariz yolu, listeyi indeksleyerek olacaktır =Yr'K@K1. Ancak, bu iki öğe listesinde bir azaltma işlevi kullanarak, bunu bir karakterle kısaltabiliriz.

=Zu*NTY => Z=reduce(lambda N,T: N*T,Y)

Ve şimdi, bu meselenin tüm noktası için, listenin ürününü bulmak için işlemi azaltın.

) => Bitiş tarihi

Y => print(Y)

Başarılı olduğunuzda listeyi yazdırın.

Örnek çalışma:

$ cat seq_prod 
JvwKr2 4W-ZJ~@K>JZ1=YurGHK=Zu*NTY)Y

$ cat seq_prod | python3 pyth.py
<debug stuff>
==================================================
[9, 10, 11, 12, 13, 14, 15, 16]

1

Java - 115

void f(int i){for(int j=2;j<i;j++)for(int k=1,x=j;(x*=j+k)<i;k++);if(x==i)for(i=j;i<j+k;i++)System.out.println(i);}

Biraz daha az golf:

void f(int i) {
 for(int j=2; j<i; j++)
  for(int k=1, x=j; (x*=j+k) < i; k++);
   if(x == i)
    for(i=j; i<j+k; i++)
     System.out.println(i);
}

Eh, bir işlev oluşturdunuz ve dönüş değerini yazdırdınız. Daha önce burada yapıldığını görmedim.
seequ

Ben bir şey yazdırmak için alamıyorum ... Ama bana bir çıktı verirse, System.out.printlnaşağı golf olabilir System.out.printve sonunda noktalı virgül for(int k=1,x=j;(x*=j+k)<i;k++)sadece gereksiz değil aynı zamanda hatalara neden olur.
Qwix

Bu benim için işe yaramıyor. x, j, kSonuncu kapsamı dışındadır if/forçünkü blokları ;. Ben kaldırırsanız ;, hiçbir şey yazmıyor.
Geobits

1
@Qwix olarak değiştirmek, printsayıların birlikte çalışmasını önlemek için bir boşluk karakteri eklemesi gerektiği anlamına gelir.
Geobits

1
@Geobits İyi bir nokta! Muhtemelen bana bir çıktı verseydi görecektim.
Qwix

1

Matlab (88)

Kod, içinde depolanacak xve çıktı alınacak sayıyı bekler l.

for n=2:12
r=ceil(x^(1/n))
for s=-3*n:n
l=r-s+(1:n)
if prod(l)==x
return 
end;end;l=x;end

Bu yana 13! > 2^32, yalnızca 12. kadar uzunluğu 2 ürünleri için bu kod aramaları bu kod etrafında 0.001s sabit bir çalışma zamanı vardır.


1

Scala - 86

def p(n:Int)=(2 to n).flatMap(i=>(i to n).map(i to _-1).find(_.product==n)).headOption

Bu kod çok verimsiz ama optimize etmek sadece birkaç karakter daha ekleyecek. Tüm olası ardışık dizilerin ürünlerini kontrol etmek için fonksiyonel bir yaklaşım kullanır. (ardışık bir tamsayı dizisi Scala'da bir Range nesnesi olarak temsil edilir)

ungolfed:

def product(n: Int): Option[Range] = {
  def productStartingAt(start: Int): Option[Range] =
    (start to n-1).map(start to _).find(_.product == n)

  (2 to n).flatMap(i => productStartingAt(i)).headOption
}

1

CJam uzun hesaplama süresi nedeniyle şu anda çok sayıda çalışmaz

Bu benim en kısa CJam kodum. Http://cjam.aditsu.net/ adresinde test edin . Şununla çalışır: girişi A olarak tanımlamak; 0 ila A-1 arasındaki tüm sayıların bir dizisinin oluşturulması; Tekme 0; dizideki tüm sayıları çarpıncaya kadar en küçük sayılara tekme A'dan büyük değildir; A'dan büyük olup olmadığını kontrol etmek; değilse, 0 ile A-2 arasında bir dizi oluşturma; ve cevap bulunana kadar tekrarlayın. Hiçbiri bulunmazsa, bir istisna atılır. Sayılar arasındaki boşlukların gerekli olduğunu düşünmedim, bu yüzden 32 karakter uzunluğundaki ikinci kodda yer aldılar.

ri:A,{)\;,1{;(;_{*}*_A>}gA<}g

ri:A,{)\;,1{;(;_{*}*_A>}gA<}g" "*

Bence cevabınız geçerli olamayacak kadar yavaş. Unutmayın, geçerli 32 bit tamsayıda en fazla 5 dakika içinde tamamlanmalıdır. 3600060000 == 60000 * 60001 ne kadar sürer?
isaacg

adil bir nokta, yeniden çalışacağım ve kısa ise göndereceğim
göndereceğim

Yeniden çalışacaksanız, lütfen o zamana kadar bu cevabı silin veya bir şekilde şu anda geçerli olmadığını belirtin.
isaacg

1

Dart - 102 karakter

Bu yavaş bir uygulama. Daha hızlı yapılabilir, ancak daha fazla karakter gerektirir (yalnızca döngüyü yalnızca şu ana kadar yapmak gibi i*i<n)

f(n,[i=2]){
  t(j,p,a)=>p<n?t(++j,p*j,a..add(j)):p>n?f(n,i+1):a;
  for(;i<n;i++)if(n%i<1)return t(i,i,[i]);
}

(102 karakter, satır kesmeleri ve önde gelen boşluklar olmadan).

Kullanmak için şöyle bir şey yapın:

main() {
  print(f(123456789*123456790));
}

0

Javascript, 88

Golf kodu:

function f(a){for(i=2;i<a;i++){b=[1];for(j=i;j>1;j--)if((b[0]*=b[i-j+1]=j)==a)alert(b)}}

Daha kolay okunan (güzel aralıklı) kod:

function f(a){
    for(i=2;i<a;i++){
        b=[1];
        for(j=i;j>1;j--)
            if((b[0]*=b[i-j+1]=j)==a)
                alert(b);
    }
}

2'den giriş numarasına kadar her sayı için, geçerli sayıdan 2'ye kadar ardışık tamsayıların ürününü bulur. Bu ürün giriş numarasına eşitse, orijinal giriş numarasıyla birlikte ardışık sayı serileri çıkarılır .

Önce girdi numarasını, ardından ürünü girdi numarası olan ardışık tamsayıları çıkarır.

Örneğin f (120), "120,5,4,3,2" metniyle bir uyarı ve daha sonra "120,6,5,4" metniyle ikinci bir uyarı verir.

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.