Periksa apakah angka adalah produk dari angka integer berurutan

18

Beberapa angka seperti: 6, 12, 20, 30, 42, 56, 60, 90, 120 dan seterusnya seperti yang dapat dinyatakan sebagai produk angka integer berurutan seperti yang ditunjukkan di bawah ini.

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

Tulis program atau fungsi yang menampilkan daftar bilangan bulat berturut-turut yang produknya sama dengan angka yang ditentukan.

Contoh angka yang tidak cocok untuk logika ini adalah:

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)

Harap perhatikan bahwa untuk kasus 2 = 2 * 1, kami tidak menganggapnya sebagai hasil yang valid, karena bilangan bulat dikalikan dengan 1 memberikan hasil yang sama. Untuk pertanyaan ini, kami hanya akan mempertimbangkan bilangan bulat> = 2 dalam produk.

Memasukkan

Integer positif 32-bit yang valid. Dapat dari input standar, argumen fungsi, dll.

Keluaran

Daftar angka integer berurutan> = 2 (dalam urutan naik atau turun). Jika ada beberapa kombinasi bilangan bulat berturut-turut, cukup berikan satu contoh yang akan dilakukan. Jika Anda memberikan lebih banyak, tidak apa-apa.

Batasan

Kode harus mengambil jumlah waktu yang wajar (<5 menit) untuk dijalankan pada komputer standar untuk semua input yang valid (bilangan bulat 32-bit positif). Jika ada produk integer berturut-turut, kode harus menampilkan satu atau lebih dalam batas waktu. Selain itu, kode harus berakhir tanpa output dalam batas waktu.

Ini adalah kode golf, jadi kode terpendek dalam byte menang.

Suraz
sumber
1
Teka-teki ini, seperti yang disebutkan, tidak cocok untuk format situs ini. Situs ini untuk kontes di mana ada cara yang baik untuk menentukan pemenang (misalnya, kode terpendek, kode tercepat, sebagian besar upvotes, dll.). Anda belum menyediakan cara seperti itu.
Chris Jester-Young
2
Saya sarankan Anda membuat ini kode-golf (kode terpendek.) Anda perlu memberi batasan padanya. Misalnya angka 0 hingga 10.00000, waktu eksekusi maks 10 detik, dll.
Level River St
Mencoba mengeditnya untuk menyelamatkan pertanyaan ini. Tapi saya belum mengajukan pertanyaan sebelumnya, jadi jika Anda melihat sesuatu, silakan lakukan edit.
Vektor
@ Bitpwner Selain beberapa kesalahan ketik, sepertinya tidak masalah bagi saya. Memilih untuk membuka kembali.
seequ
5
Saya pikir maksud Anda 30=5*6.
Kyle Kanos

Jawaban:

8

Jawa - 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;}

Mulai dari 2, ini loop sampai angka awal> akar kuadrat dari target (atau target tercapai dengan tepat). Jika produk rendah, itu dikalikan dengan jumlah tinggi dan menambahnya. Jika tinggi, itu dibagi dengan angka awal dan menambahnya.

Misalnya, untuk 30, ia akan memeriksa:

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!)

Menghasilkan serangkaian faktor yang dipisahkan ruang dalam urutan menaik.

Dengan jeda baris:

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;
}
Geobit
sumber
7

Python - 104 97 95 92 cobalah

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

Jika n, misalnya, diatur ke 120 sebelumnya, program mengeluarkan dua solusi:

[2, 3, 4, 5]
[4, 5, 6]
Falko
sumber
Maaf, saya lupa mendefinisikan beberapa input.
Falko
1
ganti c = c + 1, i = i +1 dengan c + = 1, i + = 1
Gerrat
1
Oh ya, tidak memikirkan +=. Tapi aku rindu ++dengan Python ...
Falko
1
if s>=ndan if s/nsetara, sehingga Anda dapat memberikan semua solusi dalam jumlah karakter yang sama.
isaacg
1
Anda dapat menyimpan tiga karakter dengan mengubah s=s*(i+c)ke s*=i+c.
El'endia Starman
4

Clojure - 127 109 byte

(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)))

Contoh:

(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)

Penjelasan:

Ini adalah pendekatan fungsional dasar, yang cukup tidak dioptimalkan. Saya membuat daftar malas dari semua kemungkinan menggunakan loop sederhana di atasnya (tidak melewati semua kombinasi yang akan memberikan angka terlalu besar, mencegah overflow) dan mengambil yang pertama. Jika tidak ada kemungkinan, ia mengembalikan nihil.

Paling mudah untuk menguji di http://tryclj.com/ .


Saya juga sekarang memperhatikan bahwa saya dapat mengembalikan semua kemungkinan: 120 byte 102 byte , tetapi memberikan hasil dalam daftar bersarang.

(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))

Contoh:

(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)) () () () ())
seequ
sumber
3

CJam, 31 byte

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

Ini adalah pendekatan brute-force, tetapi waktu eksekusi hanya beberapa detik menggunakan penerjemah resmi Java .

Jika Anda ingin menguji kodenya menggunakan penerjemah online , Anda harus menjaga inputnya tetap rendah. Apa pun yang kurang dari 26 masih berfungsi di mesin saya.

Contohnya

$ 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

Bagaimana itu bekerja

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.                                             ";
Dennis
sumber
2

Jawa, 162

mengembalikan array bilangan bulat, atau nulljika tidak ada angka berurutan yang ada.

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;
}
Qwix
sumber
2

C 105 110 mencobanya

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 dengan bonus: yang ini berulang melalui setiap nomor dan menemukan produk yang cocok

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);}}
bebe
sumber
Bagus, sangat sederhana dan elegan! Pasti bekerja untuk beberapa angka yang lebih kecil yang saya berikan. Kemudian saya memberikannya 50815512 (7128 x 7129) dan ia pergi ke loop yang tak terbatas. Apakah meluap ketika mencoba menghitung 7128 x 7129 x 7130 = 362314600560?
Todd Lehman
Terima kasih! rupanya kondisinya k < nterlalu tinggi karena k *= l++. saya bisa menambahkan lama yang tidak ditandatangani pada awal tapi ... itu akan merusak kehidupan
bebe
2

PHP 258 karakter, 201 tidak termasuk fungsi faktorial.

Cara paling sederhana untuk mengekspresikan secara matematis "faktor-faktor berurutan yang sama dengan angka" adalah X!/Y!Di mana Xadalah angka tertinggi dan Yterendah minus. Sayangnya saya berhenti mengambil kalkulus sebelum saya belajar untuk menyelesaikannya Z = X!/Y!, jadi saya harus sedikit memaksa.

Versi berantakan dan tidak diserami:

<?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);}

Contoh output:

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

Golf:

<? 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';}

Keluaran:

[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

Saya tidak mengharapkan waktu lari secepat ini!

Sammitch
sumber
ide ini datang ke pikiran saya juga dan itu terlihat sangat manjur tetapi saya ragu itu dapat dipersingkat cukup "untuk memenuhi syarat".
bebe
1
@ bbebe 258 karakter, tidak terlalu buruk untuk PHP. Jika saya tidak begitu malas dan keras kepala saya akan melakukannya dalam bahasa nyata . : P
Sammitch
X! / Y! adalah produk bilangan bulat N sehingga Y <N <= X. Apakah itu membantu?
trichoplax
2

Pyth , 35

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

Catatan: Kode saya benar-benar menemukan representasi input terpendek sebagai representasi bilangan bulat berurutan> = 2, sehingga pada input yang tidak valid akan mencetak daftar elemen 1, mungkin setelah waktu yang sangat lama. Karena pernyataan masalah mengatakan input akan valid, saya menganggap ini OK.

Penjelasan singkat:

Pada dasarnya, program menyimpan batas atas dan bawah rentang, menghitung produk dari angka dalam rentang menggunakan pengurangan, menyesuaikan titik akhir yang diperlukan, dan mengulangi hingga produk sama dengan input.

Penjelasan panjang:

Untuk setiap potongan kode, saya akan memberikan python yang setara, serta penjelasan dan alasan yang lebih rinci.

Jvw => J=eval(input())

Cara standar untuk mengambil input dalam Pyth.

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

Inilah bagian aneh pertama: Alih-alih menyimpan titik akhir sebagai variabel terpisah, saya menyimpannya sebagai elemen daftar. Alasannya akan segera jelas. Selain itu, alih-alih melakukan tugas sederhana, yang dalam Pyth akan K[2 3), saya menggunakan rentang untuk menyimpan karakter.

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

Pada titik ini, Anda mungkin bertanya, "Apa itu Z? Anda belum mendefinisikannya." Dalam Pyth, semua variabel sudah ditentukan sebelumnya. Z akan dimulai sebagai 0. Namun, Z akan ditetapkan ke nilai produk nanti, jadi pemeriksaan ini akan berfungsi untuk mengakhiri loop sementara setelah daftar berada pada nilai yang benar.

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

Inilah mengapa saya menyimpan nilai dalam daftar, bukan dalam variabel terpisah: Saya ingin menambah satu dari dua titik akhir, tergantung pada apakah produk saat ini terlalu tinggi atau terlalu rendah. Itu akan menjadi syarat yang agak panjang jika titik akhir adalah variabel yang terpisah, tetapi dengan keajaiban pengindeksan daftar, itu menjadi pendek. Juga, fakta bahwa pemeriksaan ini datang sebelum produk, dan fakta bahwa Z diinisialisasi ke 0, memastikan bahwa K akan[2,4] pada saat kami pertama kali mengambil produk, yang merupakan titik akhir yang tepat.

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

Sekarang, saya perlu daftar aktual bahwa produk akan diambil alih, dan itu akan dicetak jika kita berhasil. Jelas, kami akan menggunakan fungsi rentang. Trickiness terletak pada mendapatkan input ke fungsi rentang. Cara yang jelas untuk melakukan ini, dengan mengindeks daftar, adalah =Yr'K@K1. Namun, dengan menggunakan fungsi pengurangan pada daftar dua elemen ini, kita dapat mempersingkatnya dengan karakter.

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

Dan sekarang, untuk seluruh titik urusan ini, operasi pengurangan untuk menemukan produk dari daftar.

) => Akhiri sementara

Y => print(Y)

Jika berhasil, cetak daftar.

Contoh dijalankan:

$ 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]
isaacg
sumber
1

Jawa - 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);}

Sedikit kurang 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);
}
Ypnypn
sumber
Eh, Anda membuat fungsi dan mencetak nilai kembali. Belum pernah melihat yang dilakukan di sini sebelumnya.
seequ
Aku tidak bisa mendapatkannya untuk mencetak apa-apa ... Tapi apakah itu akan memberi saya beberapa output, Anda dapat golf System.out.printlnke System.out.printdan titik koma pada akhir for(int k=1,x=j;(x*=j+k)<i;k++)tidak hanya perlu tetapi juga menyebabkan kesalahan.
Qwix
Ini tidak berhasil untuk saya. x, j, kBerada di luar ruang lingkup dalam terakhir if/forblok karena ;. Jika saya menghapus ;, itu tidak mencetak apa pun.
Geobits
1
@Qwix Mengubah ke printberarti dia harus menambahkan karakter spasi untuk menghindari angka berjalan bersama.
Geobits
1
@Geobits Poin bagus! Saya mungkin akan melihat bahwa jika itu memberi saya beberapa output.
Qwix
1

Matlab (88)

Kode mengharapkan nomor untuk disimpan xdan dikeluarkan 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

Karena 13! > 2^32kode ini hanya mencari produk dengan panjang 2 hingga 12. Kode ini memiliki runtime konstan sekitar 0,001s.

cacat
sumber
1

Scala - 86

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

Kode ini sangat tidak efisien tetapi mengoptimalkannya hanya akan menambah beberapa karakter. Ini menggunakan pendekatan fungsional untuk memeriksa produk dari semua kemungkinan urutan berturut-turut. (urutan bilangan bulat berturut-turut direpresentasikan sebagai objek Range di Scala)

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
}
SpiderPig
sumber
1

CJam saat ini tidak berfungsi untuk jumlah besar karena waktu perhitungan yang lama

Ini adalah kode CJam terpendek saya. Tes di http://cjam.aditsu.net/ . Ini bekerja dengan: mendefinisikan input sebagai A; membuat array semua angka dari 0 hingga A-1; Menendang 0; menendang angka terkecil hingga mengalikan semua angka dalam array tidak lebih besar dari A; memeriksa apakah lebih besar dari A; jika tidak, membuat array dari 0 hingga A-2; dan ulangi sampai jawabannya ditemukan. Jika tidak ada yang ditemukan, pengecualian dilemparkan. Saya tidak mempertimbangkan bahwa spasi antara angka diperlukan sehingga mereka termasuk dalam kode kedua yang panjangnya 32 karakter.

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

ri:A,{)\;,1{;(;_{*}*_A>}gA<}g" "*
kaine
sumber
Saya pikir jawaban Anda terlalu lambat untuk valid. Ingat, itu harus selesai dalam waktu tidak lebih dari 5 menit pada integer 32 bit mana pun yang valid. Berapa lama waktu yang diperlukan untuk 3600060000 == 60000 * 60001?
isaacg
titik adil, saya akan mengolahnya kembali dan memposting jika pendek
kaine
Jika Anda akan memperbaikinya, harap hapus jawaban ini sampai saat itu, atau jika tidak ada yang menunjukkan bahwa saat ini tidak valid.
isaacg
1

Dart - 102 karakter

Ini adalah implementasi yang lambat. Itu dapat dibuat lebih cepat tetapi itu membutuhkan lebih banyak karakter (seperti melakukan loop hanya sampai 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 tanpa jeda baris dan ruang terkemuka).

Untuk menggunakannya, lakukan sesuatu seperti:

main() {
  print(f(123456789*123456790));
}
Tuan
sumber
0

Javascript, 88

Kode golf:

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)}}

Lebih mudah membaca kode (spasi baik):

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);
    }
}

Untuk setiap angka dari 2 ke nomor input, ia menemukan produk bilangan bulat berturut-turut dari angka saat ini kembali ke 2. Jika produk ini sama dengan nomor input, maka seri angka berurutan, bersama dengan nomor input asli, adalah output .

Ini mengeluarkan nomor input diikuti oleh bilangan bulat berturut-turut yang produknya adalah nomor input.

Misalnya f (120) menghasilkan peringatan dengan teks "120,5,4,3,2" dan kemudian peringatan kedua dengan teks "120,6,5,4".

Rhubarb Custard
sumber