Bersenang-senang dengan Permutasi

17

Siapa yang tidak benar-benar menyukai permutasi, bukan? Saya tahu, mereka luar biasa –– sangat menyenangkan!

Nah, mengapa tidak bersenang-senang ini dan membuatnya lebih lucu ?

Inilah tantangannya:

Diberikan input dalam bentuk yang tepat:, di nPrmana npool diambil dari dan rjumlah seleksi dari pool itu ( ndan radalah bilangan bulat), output / kembalikan jumlah permutasi yang tepat. Bagi Anda yang agak berkarat dengan terminologi: Permutasi, def. 2a .

Namun, di sinilah tantangannya bermain (membuatnya tidak terlalu mudah):

Anda tidak dapat menggunakan pustaka, kerangka kerja, atau metode bawaan apa pun untuk fungsi permutasi Anda. Anda tidak boleh menggunakan metode faktorial, metode permutasi, atau semacamnya; Anda harus menulis semuanya sendiri.

Jika diperlukan klarifikasi lebih lanjut, jangan ragu untuk memberi tahu saya di komentar dan saya akan segera bertindak sesuai.


Berikut ini adalah contoh I / O:

Fungsi sampel adalah permute(String) -> int

Memasukkan:

permute("3P2")

Keluaran:

6

Ini kode-golf, jadi kode terpendek menang!

Daniel
sumber
2
Aww. Saya pikir tantangan ini ada pada kelompok permutasi . Hal yang keren. Ini keren juga, dan terkait erat dengan kelompok permutasi. Suka tantangannya.
Justin
Ketika Anda mengatakan tidak ada built-in atau metode perpustakaan, apakah maksud Anda untuk permutasi, atau untuk apa pun? Dapatkah saya menggunakan built-in splituntuk membagi input di P? Bagaimana dengan fungsi yang mengubah string menjadi angka?
xnor
3
Bisakah jawaban menganggap itu 0 <= r <= n?
Peter Taylor
1
@Dappapp Maksud Anda r tidak lebih besar dari n ?
Dennis
1
@RetoKoradi - Saya kira bahwa dalam upaya untuk tidak memaksa sebagian besar poster untuk mengulang jawaban mereka, Anda tidak diperbolehkan menggunakan metode / fungsi faktorial atau permutasi apa pun.
Daniel

Jawaban:

4

CJam, 15 14 byte

r~\;~\),>UXt:*

Cobalah online di juru bahasa CJam .

Bagaimana itu bekerja

r              e# Read a token ("nPr") from STDIN.
 ~             e# Evaluate. This pushes the numbers n, Pi and r on the stack.
  \;           e# Discard Pi.
    ~          e# Take the bitwise NOT of r. Pushes -(r+1).
     \)        e# Increment n.    
       ,       e# Turn n+1 into [0 ... n].
        >      e# Keep only the last r+1 elements.
         UXt   e# Replace the first element with 1.
               e# This avoid dealing with the egde case nP0 separately.
            :* e# Compute their product.
Dennis
sumber
4

Perl, 27 byte

#!perl -pl61
$\*=$`-$%++for/P/..$'}{

Menghitung shebang sebagai 4, input diambil dari stdin.


Contoh Penggunaan

$ echo 3P2 | perl npr.pl
6

$ echo 7P4 | perl npr.pl
840
primo
sumber
Pilihan macam apa itu l61?
feersum
@feersum diset $\ke 1(char 49, octal 61).
primo
3

Haskell, 71 66 byte

p s|(u,_:x)<-span(/='P')s,(n,k)<-(read u,read x)=product[n-k+1..n]

Hal-hal yang cukup mudah: pisah di 'P' lalu bawa produk antara (n-k + 1) dan n.

Berkat nimi karena idenya menggunakan pengawal pola daripada whereklausa, itu mengurangi 5 byte.

arjanen
sumber
2

Minkolang 0,11 , 13 25 19 byte

Terima kasih kepada Sp3000 untuk menyarankan ini!

1nnd3&1N.[d1-]x$*N.

Coba di sini.

Penjelasan

1        Push 1
n        Take integer from input (say, n)
n        Take integer from input (say, k); ignores non-numeric characters in the way
d3&1N.   Output 1 if k is 0
[   ]    Loop k times
 d1-     Duplicate top of stack and subtract 1
x        Dump top of stack
$*       Multiply all of it together
N.       Output as integer

Ini menggunakan algoritma yang sama dengan Alex: n P k= n(n-1)(n-2)...(n-k+1).

El'endia Starman
sumber
2

Julia, 63 58 48 byte

s->((n,r)=map(parse,split(s,"P"));prod(n-r+1:n))

Ini menciptakan fungsi tanpa nama yang menerima string dan mengembalikan integer. Untuk menyebutnya, berikan nama, mis f=s->....

Tidak Disatukan:

function f(s::AbstractString)
    # Get the pool and number of selections as integers
    n, r = map(parse, split(s, "P"))

    # Return the product of each number between n-r+1 and n
    return prod(n-r+1:n)
end

Ini menggunakan fakta bahwa jumlah permutasi adalah n ( n -1) ( n -2) ... ( n - k +1).

Disimpan 10 byte berkat Glen O!

Alex A.
sumber
Tidak perlu Int, jadi Anda bisa menggunakannya map(parse,...).
Glen O
@ GlenO Pikiranku telah meledak. Saya tidak menyadari Intitu perlu dalam situasi itu. Terima kasih banyak!
Alex A.
2

Utilitas Bash + Linux, 33

jot -s\* ${1#*P} $[${1/P/-}+1]|bc

jotmenghasilkan urutan rbilangan bulat mulai dari n-r+1, dan memisahkannya dengan *. Ungkapan ini disalurkan ke bcuntuk evaluasi aritmatika.

Trauma Digital
sumber
1

MATLAB, 54 byte

[n,r]=strread(input(''),'%dP%d');disp(prod((n-r+1):n))

Mencoba membuatnya lebih kecil, tetapi salah satu hal yang benar-benar buruk dari MATLAB adalah mendapatkan input. Dibutuhkan 32 karakter hanya untuk mendapatkan dua angka dari string input!

Kode penjelasan cukup jelas. Dapatkan input dalam bentuk di %dP%dmana% d adalah bilangan bulat. Pisahkan itu menjadi ndan r. Kemudian tampilkan produk dari setiap bilangan bulat dalam kisaran n-r+1ke n. Menariknya ini bekerja bahkan untuk xP0memberikan jawaban yang benar dari 1. Ini karena dalam MATLAB prod()fungsi mengembalikan 1 jika Anda mencoba dan melakukan produk dari array kosong. Setiap kali rnol, rentang akan menjadi array kosong, jadi bingo kita dapatkan 1.


Ini juga berfungsi sempurna dengan Oktaf juga. Anda dapat mencobanya online di sini .

Tom Carpenter
sumber
1

Javascript, 59 57 byte

s=>(f=(n,k)=>k?(n- --k)*f(n,k):1,f.apply(f,s.split('P')))
Naouak
sumber
1

Java (594 - byte)

import java.util.*;import java.lang.*;public class Perm {private String a;private static int[] nr=new int[2];private static int sum=1;Scanner in=new Scanner(System.in);public String input(){a=in.nextLine();return a;}public void converter(String a){this.a=a;String b=a.substring(0,1);String c=a.substring(2);nr[0]=Integer.parseInt(b);nr[1]=Integer.parseInt(c);}public int param(){for(int counter=0; counter < nr[1]; counter++){sum=sum*nr[0]--;}return sum;}public static void main(String args[]){Perm a;a=new Perm();String k=a.input();a.converter(k);int ans=a.param();System.out.println(ans);}}
Kamalnrf
sumber
1

J, 23 byte

^!._1/@(".;._1)@('P'&,)

Fungsi anonim. Contoh:

   f =. ^!._1/@(".;._1)@('P'&,)
   f '10P4'
5040

Penjelasan:

       (  ;._1)@('P'&,)   Split over 'P', and on each slice,
        ".                read a number.
      @                   Then,
^!._1/                    fold (/) with the built-in "stope function" (^!.k) for k=1.

Fungsi stope yang saya gunakan mungkin berbatasan dengan penghitungan sebagai built-in ... Itu terletak di suatu tempat antara generalitas operator multiplikasi dan spesifisitas operator faktorial.

Lynn
sumber
1

APL, 23

{{×/⍵↑⍳-⍺}/-⍎¨⍵⊂⍨⍵≠'P'}

Mengambil string sebagai argumen. Penjelasan:

              ⍵⊂⍨⍵≠'P'  ⍝ Split by 'P'.
           -⍎¨          ⍝ Convert to numbers and negate making a vector (−n −r)
 {       }/             ⍝ Reduce it by a defined function, which
      ⍳-⍺               ⍝ makes a vector of numbers from 1 to n (⍺)
    ⍵↑                  ⍝ takes r last elements (⍵←−r)
  ×/                    ⍝ and multiplies them together.
pengguna46915
sumber
APL mana ini? Saya mendapatkan kesalahan dengan salinan Dyalog saya.
lirtosiast
1
@ThomasKwa Gunakan ⎕ML←3di Dyalog.
user46915
1

Python 2, 66

def f(s):a,b=map(int,s.split('P'));P=1;exec"P*=a;a-=1;"*b;print P

Cukup mudah. Memproses input angka sebagai a,b. Mempertahankan produk yang berjalan sebagai P, yang dikalikan dengan bpersyaratan pertama a, a-1, a-2, ....

Tidak
sumber
2
Saya tidak melihat bagaimana input()tidak dapat menghasilkan kesalahan.
feersum
@feersum Saya mencobanya dan itu memang melempar kesalahan sintaksis.
Alex A.
Saya mengambil input dengan tanda kutip seperti "3P2", yang saya pikir biasanya diperbolehkan, tetapi di sini tantangannya mengatakan "input dalam bentuk yang tepat", jadi saya mengubahnya menjadi fungsi yang membutuhkan string.
xnor
1

TI-BASIC, 52 byte

Ans→Str1
expr(sub(Ans,1,⁻1+inString(Ans,"P→P        ;n
1
If expr(Str1                               ;If n^2*r ≠ 0
prod(randIntNoRep(P,P+1-expr(Str1)/P²
Ans

TI-BASIC memiliki fungsi "produk daftar", jadi mengatasi batasan pada builtin tidak terlalu sulit. Namun, TI-BASIC tidak mendukung daftar kosong — jadi kami perlu

Untuk mengekstrak dua angka, saya mengekstrak angka pertama sebagai substring. Ini mahal ; itu mengambil seluruh baris kedua. Agar tidak perlu melakukan ini lagi untuk nomor kedua, saya mengatur variabel P ke nomor itu, dan mengevaluasi seluruh string menggunakanexpr( , kemudian bagi dengan P².

Akhirnya, saya mengambil permutasi acak daftar antara dua angka (berhati-hati untuk menambahkan satu ke nomor kedua) dan mengambil produk.

lirtosiast
sumber
1

Ouroboros , 47 45 byte

Beberapa di antaranya sangat jelek - saya membayangkan bisa bermain golf lebih jauh.

Sr.r-1(
)s.!+S1+.@@.@\<!@@*Ys.!+*S.!!4*.(sn1(

Setiap baris kode di Ouroboros mewakili ular yang memakan ekornya.

Ular 1

Sberalih ke tumpukan bersama. r.rmembaca satu angka, menduplikatnya, dan membaca yang lain. (Karakter non-numerik seperti Pdilewati.) -Kurangi keduanya. Jika input tadi 7P2, sekarang kita miliki 7, 5pada stack bersama. Akhirnya, 1(makan karakter terakhir ular. Karena ini adalah karakter tempat penunjuk instruksi aktif, ular mati.

Ular 2

)stidak melakukan apa pun pertama kali melalui. .!+menduplikasi bagian atas tumpukan ular 2, memeriksa apakah nol, dan jika demikian menambahkan 1. Pada iterasi pertama, tumpukan kosong dan diperlakukan seolah-olah mengandung nol tanpa batas, jadi ini mendorong1 ; pada iterasi selanjutnya, stack berisi nilai bukan nol dan ini tidak berpengaruh.

Selanjutnya, Sberalih ke tumpukan bersama, di mana kita memiliki nomor ndan penghitung untuk menghitung produk. 1+menambah konter. .@@.@\<!menduplikasi kedua angka dan mendorong 1 jika nmasih lebih besar atau sama dengan penghitung, 0 sebaliknya. @@*Ykemudian mengalikan penghitung dengan kuantitas ini dan menarik salinannya ke tumpukan ular 2.

s.!+beralih kembali ke tumpukan snake 2 dan menggunakan kode yang sama seperti sebelumnya untuk mengubah angka teratas menjadi 1 jika 0 dan tetap sama jika tidak. Kemudian *gandakan hasilnya dengan produk parsial yang ada di tumpukan ini.

Kami sekarang kembali ke tumpukan bersama ( S), menduplikasi penghitung-atau-nol ( .), dan meniadakannya dua kali ( !!) untuk mengubah penghitung nol ke 1. 4*.(mengalikan ini dengan 4, duplikat, dan makan yang banyak karakter dari ujung ular.

  • Jika kita belum mencapai kondisi berhenti, kita punya 4 di stack. Keempat karakter setelah (dimakan, dan kontrol loop sekitar ke awal kode. Di sini )memuntahkan empat karakter, sberalih kembali ke tumpukan 2 ular, dan eksekusi berlanjut.
  • Jika penghitung telah lewat n, kami memiliki 0 di tumpukan, dan tidak ada yang dimakan. snberalih ke tumpukan ular 2 dan menampilkan nilai teratas sebagai angka; lalu 1(makan karakter terakhir dan mati.

Hasilnya adalah produk (r+1)*(r+2)*...*ndihitung dan diproduksi.

Cobalah

DLosc
sumber