순열과 재미


17

누가 순열을 절대 좋아하지 않습니까? 나는 그들이 놀랍다 – 너무 재미있다!

그럼, 왜이 재미를 가지고 그것을하지 funner ?

도전은 다음과 같습니다.

정확한 형태의 입력을 감안 : nPr여기서이 n풀이에서 촬영되고 r그 풀에서 선택의 개수 (및 nr정수) 출력 / 순열의 정확한 수를 반환한다. 용어에 약간 녹슨 사용자에게는 Permutation, def. 2a .

그러나 여기서 도전이 시작됩니다 (너무 쉽지는 않습니다).

순열 함수에 내장 라이브러리, 프레임 워크 또는 메소드를 사용할 수 없습니다. 계승 법, 순열 법 등을 사용할 수 없습니다. 모든 것을 직접 작성해야합니다.

더 자세한 설명이 필요한 경우, 의견을 주저하지 말고 즉시 조치하겠습니다.


다음은 I / O 예제입니다.

샘플 기능은 permute(String) -> int

입력:

permute("3P2")

산출:

6

이것은 코드 골프이므로 가장 짧은 코드가 승리합니다!


2
앗 나는이 도전이 순열 그룹 에 있다고 생각했다 . 멋진 것. 이것은 시원하며 순열 그룹과 밀접한 관련이 있습니다. 도전을 사랑하십시오.
저스틴

내장 또는 라이브러리 방법이 없다고 말하면 순열이나 다른 것을 의미합니까? 내장을 사용하여 split입력을 P? 문자열을 숫자로 변환하는 함수는 어떻습니까?
xnor

3
대답은 0 <= r <= n?
피터 테일러

1
@Dopapp r n 보다 크지 않다는 것을 의미 합니까?
Dennis

1
@RetoKoradi-대부분의 포스터가 답을 다시 쓰도록 강요하지 않으려는 경우 계승 또는 순열 방법 / 함수를 사용할 수 없습니다.
Daniel

답변:


4

CJam, 15 14 바이트

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

CJam 통역사 에서 온라인으로 사용해보십시오 .

작동 원리

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

펄, 27 바이트

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

shebang을 4로 세면 입력은 stdin에서 가져옵니다.


샘플 사용법

$ echo 3P2 | perl npr.pl
6

$ echo 7P4 | perl npr.pl
840

어떤 종류의 옵션이 l61있습니까?
feersum

@feersum $\1(char 49, octal 61)로 설정됩니다.
primo

3

하스켈, 71 66 바이트

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

매우 간단한 것 : 'P'에서 분할 한 다음 (n-k + 1)과 n 사이에서 제품을 가져옵니다.

where절 대신 패턴 가드를 사용하려는 아이디어 덕분에 nimi 덕분에 5 바이트가 줄었습니다.


2

Minkolang 0.11 , 13 25 19 바이트

이것을 제안 해 주신 Sp3000 에게 감사합니다 !

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

여기에서 시도하십시오.

설명

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

이것은 Alex와 같은 알고리즘을 사용합니다 : n P k= n(n-1)(n-2)...(n-k+1).


2

줄리아, 63 58 48 바이트

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

문자열을 받아들이고 정수를 반환하는 명명되지 않은 함수를 만듭니다. 호출하려면 이름을 지정하십시오 (예 :) f=s->....

언 골프 드 :

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

이것은 순열 수가 n ( n -1) ( n- 2) ... ( n - k +1) .

Glen O 덕분에 10 바이트를 절약했습니다!


필요가 Int없으므로 사용할 수 있습니다 map(parse,...).
Glen O

@GlenO 내 마음이 날아 갔다. 나는 Int그 상황에서 필요 하다는 것을 몰랐다 . 정말 고마워!
Alex A.

2

배쉬 + 리눅스 유틸리티, 33

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

jotr에서 시작 하는 정수 시퀀스를 생성 n-r+1하고로 분리합니다 *. 이 표현식은 bc산술 평가 를 위해 파이프됩니다 .


1

MATLAB, 54 바이트

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

더 작게 만들려고했지만 MATLAB이 실제로 나쁜 점 중 하나는 입력을받는 것입니다. 입력 문자열에서 두 숫자를 얻으려면 32 문자가 필요합니다!

공정한 자기 설명 코드. %dP%d% d가 정수인 형식으로 입력을 가져옵니다 . 로 그 분할 nr. 그런 다음 범위의 모든 정수의 제품을 표시 n-r+1하는 n. 흥미롭게도 이것은 xP01의 정답 을 제공하는 경우에도 작동합니다 . 이것은 MATLAB에서 prod()함수가 빈 배열의 곱을 시도하면 1을 반환 하기 때문입니다 . r0이 될 때마다 범위는 빈 배열이므로 빙고는 1입니다.


옥타브 에서도 완벽하게 작동합니다 . 여기에서 온라인으로 사용해 볼 수 있습니다 .


1

자바 스크립트, 59 57 바이트

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

1

자바 (594-바이트)

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 바이트

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

익명의 기능. 예:

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

설명:

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

채굴장 기능이 나는대로 계산에 힘 국경을 사용하는 내장 ... 그것은 곱셈 연산자의 일반 성과 계승 연산자의 특이성 중간 쯤에 달려있다.


1

APL, 23

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

문자열을 인수로 사용합니다. 설명:

              ⍵⊂⍨⍵≠'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입니까? Dyalog 사본에 오류가 있습니다.
lirtosiast

1
@ThomasKwa ⎕ML←3Dyalog에서 사용 합니다.
user46915

1

파이썬 2, 66

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

꽤 직설적 인. 숫자 입력을로 처리 a,b합니다. 실행중인 제품을로 유지하며 P의 첫 번째 b항에 곱합니다 a, a-1, a-2, ....


2
input()오류가 발생 하는 방법을 알 수 없습니다.
feersum

@feersum 나는 그것을 시도했고 실제로 구문 오류가 발생합니다.
Alex A.

나는 "3P2"일반적으로 허용되는 것 같은 따옴표로 입력을 받고 있었지만 여기서 도전은 "정확한 형식의 입력"이라고 말하므로 문자열을 취하는 함수로 변경합니다.
xnor

1

TI-BASIC, 52 바이트

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에는 "목록의 제품"기능이 있으므로 내장에 대한 제한을 극복하는 것이 그리 어렵지 않습니다. 그러나 TI-BASIC은 빈 목록을 지원하지 않으므로 다음을 수행해야합니다.

두 숫자를 추출하기 위해 첫 번째 숫자를 하위 문자열로 추출합니다. 이것은 비싸다 ; 두 번째 줄 전체를 차지합니다. 두 번째 숫자에 대해이 작업을 다시 수행하지 않아도되도록 변수 P를 해당 숫자로 설정 expr(하고을 사용하여 전체 문자열을 평가 한 다음 P²으로 나눕니다.

마지막으로 두 숫자 사이에서 목록을 임의로 순열하고 (두 번째 숫자에 1을 더하기 위해주의를 기울임) 제품을 가져옵니다.


1

우로 보로스 , 47 45 바이트

이 중 일부는 추악합니다. 골프를 더 할 수있을 것 같아요.

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

Ouroboros의 각 코드 줄은 꼬리를 먹는 뱀을 나타냅니다.

뱀 1

S공유 스택으로 전환합니다. r.r하나의 숫자를 읽고, 복제하고 다른 숫자를 읽습니다. (숫자가 아닌 문자 P는 건너 뜁니다.) -둘을 뺍니다. 입력이 있었다면 7P2, 우리는 지금이 7, 5공유 스택에. 마지막으로 1(뱀의 마지막 캐릭터를 먹는다. 이것은 명령 포인터가있는 문자이므로 뱀이 죽습니다.

뱀 2

)s처음부터 아무것도하지 않습니다. .!+snake 2의 스택 상단을 복제하고, 0인지 확인하고, 1을 추가하면 1을 추가합니다. 첫 번째 반복에서 스택은 비어 있고 무한한 0을 포함하는 것처럼 처리되므로 푸시합니다 1. 나중에 반복 할 때 스택에 0이 아닌 값이 포함되며 이는 효과가 없습니다.

다음으로 S공유 스택으로 전환합니다. 여기 n에서 제품 계산을위한 번호 와 카운터가 있습니다. 1+카운터를 증가시킵니다. .@@.@\<!숫자를 모두 복제 n하고 카운터보다 크거나 같으면 1을, 그렇지 않으면 0을 누릅니다. @@*Y그런 다음 카운터에이 수량을 곱하고 뱀 2의 스택에 사본을 찍습니다.

s.!+snake 2의 스택으로 다시 전환하고 이전과 동일한 코드를 사용하여 최상위 숫자가 0이면 1로 변환하고 그렇지 않으면 동일하게 유지합니다. 그런 다음 *이 스택에있는 부분 제품에 결과를 곱합니다.

이제 공유 스택 ( S) 으로 돌아가서 카운터 또는 0 ( .)을 복제하고 두 번 무효화 !!하여 0이 아닌 카운터를 1로 4*.(바꿉니다.이 값에 4를 곱하고 중복하여 뱀의 끝.

  • 정지 조건에 도달하지 않으면 스택에 4가 표시됩니다. 다음에 나오는 4 개의 문자 (가 먹고 컨트롤이 코드의 시작 부분으로 돌아갑니다. 여기서 )4 개의 문자를 역류 s시키고 뱀 2의 스택으로 다시 전환하며 실행이 계속됩니다.
  • 카운터가 통과 n하면 스택에 0이 있고 아무것도 먹지 않습니다. snsnake 2의 스택으로 전환하고 최상위 값을 숫자로 출력합니다. 1(마지막 캐릭터 를 먹고 죽습니다.

결과는 (r+1)*(r+2)*...*n 이 계산되어 출력됩니다.

사용해보십시오

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.