Vui vẻ với hoán vị


17

Ai không hoàn toàn thích hoán vị, phải không? Tôi biết, họ rất tuyệt vời.

Chà, tại sao không lấy niềm vui này và làm cho nó vui hơn ?

Đây là thách thức:

Đưa ra một đầu vào ở dạng chính xác : nPr, nnhóm được lấy từ đâu và rlà số lượng lựa chọn từ nhóm đó ( nrlà số nguyên), xuất / trả lại số lượng hoán vị chính xác. Đối với những bạn hơi thô lỗ với thuật ngữ: Hoán vị, def. 2a .

Tuy nhiên, đây là lúc thử thách diễn ra (làm cho nó không quá dễ dàng):

Bạn không được sử dụng bất kỳ thư viện, khung hoặc phương thức tích hợp nào cho hàm hoán vị của mình. Bạn không được sử dụng phương pháp giai thừa, phương pháp hoán vị hoặc bất cứ thứ gì thuộc loại này; bạn phải tự viết mọi thứ

Nếu cần làm rõ thêm, xin vui lòng, đừng ngần ngại cho tôi biết trong các ý kiến ​​và tôi sẽ nhanh chóng hành động phù hợp.


Đây là một ví dụ I / O:

Hàm mẫu là permute(String) -> int

Đầu vào:

permute("3P2")

Đầu ra:

6

Đây là mã golf, vì vậy mã ngắn nhất sẽ thắng!


2
À. Tôi nghĩ rằng thử thách này sẽ thuộc về các nhóm hoán vị . Công cụ mát mẻ. Điều này cũng tuyệt, và liên quan chặt chẽ đến các nhóm hoán vị. Yêu những thử thách.
Justin

Khi bạn nói không có phương thức tích hợp hoặc thư viện, bạn có nghĩa là cho hoán vị, hoặc cho bất cứ điều gì? Tôi có thể sử dụng tích hợp splitđể phân chia đầu vào tại Pkhông? Điều gì về một hàm chuyển đổi một chuỗi thành một số?
xnor

3
Có thể câu trả lời cho rằng 0 <= r <= n?
Peter Taylor

1
@Dopapp Bạn có nghĩa là r không lớn hơn n ?
Dennis

1
@RetoKoradi - Tôi cho rằng trong nỗ lực không buộc hầu hết các áp phích làm lại câu trả lời của họ, bạn không được phép sử dụng bất kỳ phương pháp / chức năng nhân tố hoặc hoán vị nào.
Daniel

Câu trả lời:


4

CJam, 15 14 byte

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

Hãy thử trực tuyến trong trình thông dịch CJam .

Làm thế nào nó hoạt động

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.

4

Perl, 27 byte

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

Đếm shebang là 4, đầu vào được lấy từ stdin.


Sử dụng mẫu

$ echo 3P2 | perl npr.pl
6

$ echo 7P4 | perl npr.pl
840

Loại tùy chọn là l61gì?
frageum

@feersum nó đặt $\thành 1(char 49, bát phân 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]

Công cụ khá đơn giản: phân chia tại 'P', sau đó lấy sản phẩm giữa (n-k + 1) và n.

Nhờ nimi cho ý tưởng của họ để sử dụng các mẫu bảo vệ chứ không phải là một wheremệnh đề, nó đã loại bỏ 5 byte.


2

Minkolang 0.11 , 13 25 19 byte

Cảm ơn Sp3000 đã gợi ý điều này!

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

Hãy thử nó ở đây.

Giải trình

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

Điều này sử dụng thuật toán tương tự như của Alex: n P k= n(n-1)(n-2)...(n-k+1).


2

Julia, 63 58 48 byte

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

Điều này tạo ra một hàm không tên chấp nhận một chuỗi và trả về một số nguyên. Để gọi nó, đặt tên cho nó, vd f=s->....

Ung dung:

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

Điều này sử dụng thực tế là số lượng hoán vị là n ( n -1) ( n -2) ... ( n - k +1).

Đã lưu 10 byte nhờ Glen O!


Không cần Int, vì vậy bạn chỉ có thể sử dụng map(parse,...).
Glen O

@GlenO Tâm trí tôi đã bị thổi bay. Tôi đã không nhận ra Intlà cần thiết trong tình huống đó. Cám ơn rất nhiều!
Alex A.

2

Đồ dùng Bash + Linux, 33

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

jottạo ra chuỗi các rsố nguyên bắt đầu từ n-r+1và phân tách chúng với *. Biểu thức này được dẫn đến bcđể đánh giá số học.


1

MATLAB, 54 byte

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

Đã cố gắng làm cho nó nhỏ hơn, nhưng một trong những điều MATLAB thực sự tệ là nhận đầu vào. Phải mất 32 ký tự chỉ để có được hai số từ chuỗi đầu vào!

Khá tự giải thích mã. Lấy đầu vào ở dạng %dP%d% d là số nguyên. Chia nó thành nr. Sau đó hiển thị sản phẩm của mọi số nguyên trong phạm vi n-r+1tới n. Điều thú vị là điều này hoạt động ngay cả khi xP0đưa ra câu trả lời đúng là 1. Điều này là do trong MATLAB, prod()hàm trả về 1 nếu bạn thử và thực hiện sản phẩm của một mảng trống. Bất cứ khi nào rbằng 0, phạm vi sẽ là một mảng trống, vì vậy bingo chúng tôi nhận được 1.


Điều này cũng hoạt động hoàn hảo với Octave là tốt. Bạn có thể thử nó trực tuyến ở đây .


1

Javascript, 59 57 byte

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

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

1

J, 23 byte

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

Một chức năng ẩn danh. Thí dụ:

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

Giải trình:

       (  ;._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.

Hàm stope mà tôi đã sử dụng có thể được tính là tích hợp ... Nó nằm ở đâu đó giữa tính tổng quát của toán tử nhân và tính đặc hiệu của toán tử nhân tử.


1

APL, 23

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

Lấy chuỗi làm đối số. Giải trình:

              ⍵⊂⍨⍵≠'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.

APL nào đây? Tôi nhận được một lỗi với bản sao Dyalog của tôi.
lirtosiast

1
@ThomasKwa Sử dụng ⎕ML←3trong Dyalog.
dùng46915

1

Con trăn 2, 66

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

Khá đơn giản. Xử lý đầu vào số như a,b. Giữ một sản phẩm đang chạy P, được nhân với các bđiều khoản đầu tiên của a, a-1, a-2, ....


2
Tôi không thấy làm thế nào input()không thể dẫn đến một lỗi.
frageum

@feersum Tôi đã thử nó và nó thực sự ném một lỗi cú pháp.
Alex A.

Tôi đã lấy đầu vào với các trích dẫn như "3P2", điều mà tôi nghĩ thường được cho phép, nhưng ở đây thách thức nói "đầu vào ở dạng chính xác", vì vậy tôi thay đổi nó thành một hàm có một chuỗi.
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 có chức năng "sản phẩm của danh sách", do đó, việc khắc phục các hạn chế đối với nội dung không quá khó. Tuy nhiên, TI-BASIC không hỗ trợ danh sách trống, vì vậy chúng tôi cần phải

Để trích xuất hai số, tôi trích xuất số đầu tiên dưới dạng chuỗi con. Đây là đắt tiền ; nó chiếm toàn bộ dòng thứ hai. Để tránh phải làm điều này một lần nữa cho số thứ hai, tôi đặt biến P thành số đó và đánh giá toàn bộ chuỗi bằng cách sử dụng expr(, sau đó chia cho P².

Cuối cùng, tôi lấy một hoán vị ngẫu nhiên của danh sách giữa hai số (chú ý thêm một vào số thứ hai) và lấy sản phẩm.


1

Ouroboros , 47 45 byte

Một số thứ này khá xấu - tôi tưởng tượng nó có thể được đánh gôn hơn nữa.

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

Mỗi dòng mã trong Ouroboros đại diện cho một con rắn ăn đuôi của nó.

Rắn 1

Schuyển sang ngăn xếp chia sẻ. r.rđọc một số, sao chép nó và đọc một số khác. (Các ký tự Pkhông phải là số không được bỏ qua.) Trừ -hai. Nếu đầu vào là 7P2, bây giờ chúng ta có 7, 5trên ngăn xếp được chia sẻ. Cuối cùng, 1(ăn nhân vật cuối cùng của con rắn. Vì đây là ký tự mà con trỏ chỉ dẫn bật, con rắn chết.

Rắn 2

)skhông có gì lần đầu tiên thông qua. .!+nhân đôi đỉnh của con rắn 2, kiểm tra xem nó có bằng không không và nếu có thêm 1. Ở lần lặp đầu tiên, ngăn xếp trống và được xử lý như thể nó chứa các số không vô hạn, vì vậy điều này đẩy 1; ở các lần lặp lại sau, ngăn xếp chứa giá trị khác 0 và điều này không có hiệu lực.

Tiếp theo, Schuyển sang ngăn xếp được chia sẻ, nơi chúng tôi có số nvà bộ đếm để tính toán sản phẩm. 1+tăng bộ đếm. .@@.@\<!nhân đôi cả hai số và đẩy 1 nếu nvẫn lớn hơn hoặc bằng bộ đếm, 0 nếu không. @@*Ysau đó nhân số đếm với số lượng này và đưa một bản sao lên ngăn xếp của rắn 2.

s.!+chuyển trở lại ngăn xếp của rắn 2 và sử dụng cùng mã như trước đó để chuyển đổi số trên cùng thành 1 nếu nó bằng 0 và giữ nguyên như vậy. Sau đó *nhân kết quả với sản phẩm một phần đang ngồi trên ngăn xếp này.

Bây giờ chúng ta quay trở lại ngăn xếp được chia sẻ ( S), sao chép bộ đếm ngược hoặc không ( .) và phủ định nó hai lần ( !!) để biến bộ đếm khác không thành 1. 4*.(nhân số này với 4, nhân đôi và ăn nhiều ký tự từ cuối con rắn.

  • Nếu chúng tôi chưa đạt đến điều kiện tạm dừng, chúng tôi đã có 4 trên ngăn xếp. Bốn ký tự sau khi (được ăn và các vòng điều khiển xung quanh đến đầu mã. Tại đây, )hồi sinh bốn nhân vật, schuyển trở lại ngăn xếp của rắn 2 và tiếp tục thực hiện.
  • Nếu bộ đếm đã qua n, chúng tôi có 0 trên ngăn xếp và không có gì được ăn. snchuyển sang ngăn xếp của rắn 2 và xuất giá trị hàng đầu dưới dạng số; sau đó 1(ăn nhân vật cuối cùng và chết.

Kết quả là sản phẩm (r+1)*(r+2)*...*nđược tính toán và đầu ra.

Dùng thử

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.