Spaß mit Permutationen


17

Wer liebt Permutationen nicht unbedingt, oder? Ich weiß, sie sind unglaublich - so viel Spaß!

Warum nicht diesen Spaß nehmen und ihn lustiger machen ?

Hier ist die Herausforderung:

Bei einer Eingabe in der genauen Form:, nPrwobei nder Pool entnommen wird und rdie Anzahl der Auswahlen aus diesem Pool (und nund rganze Zahlen), wird die genaue Anzahl der Permutationen ausgegeben / zurückgegeben. Für diejenigen von euch, die ein bisschen verrostet sind mit der Terminologie: Permutation, def. 2a .

Hier kommt jedoch die Herausforderung ins Spiel (macht es nicht zu einfach):

Sie dürfen keine eingebaute Bibliothek, Framework oder Methode für Ihre Permutationsfunktion verwenden. Sie dürfen keine Fakultätsmethode, Permutationsmethode oder ähnliches verwenden. du musst alles selbst schreiben.

Wenn weitere Klarstellungen erforderlich sind, zögern Sie bitte nicht, mich in den Kommentaren darauf hinzuweisen, und ich werde umgehend entsprechend handeln.


Hier ist ein E / A-Beispiel:

Beispielfunktion ist permute(String) -> int

Eingang:

permute("3P2")

Ausgabe:

6

Das ist Code-Golf, also gewinnt der kürzeste Code!


2
Aww. Ich dachte, dass diese Herausforderung Permutationsgruppen betreffen würde . Cooles Zeug. Dies ist auch cool und eng mit Permutationsgruppen verbunden. Liebe die Herausforderung.
Justin

Wenn Sie keine eingebauten Methoden oder Bibliotheksmethoden angeben, meinen Sie dies für Permutationen oder für irgendetwas? Kann ich den eingebauten benutzen split, um den Eingang am aufzuteilen P? Was ist mit einer Funktion, die eine Zeichenfolge in eine Zahl umwandelt?
Xnor

3
Können Antworten das annehmen 0 <= r <= n?
Peter Taylor

1
@Dopapp Meinst du, dass r nicht größer als n ist ?
Dennis

1
@RetoKoradi - Ich nehme an, dass Sie keine Fakultäts- oder Permutationsmethoden / -funktionen verwenden dürfen, um die meisten Poster nicht zu zwingen, ihre Antworten zu wiederholen.
Daniel

Antworten:


4

CJam, 15 bis 14 Bytes

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

Probieren Sie es online im CJam-Interpreter aus .

Wie es funktioniert

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 Bytes

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

Zählt man den Shebang als 4, wird die Eingabe von stdin übernommen.


Beispielnutzung

$ echo 3P2 | perl npr.pl
6

$ echo 7P4 | perl npr.pl
840

Was für eine Option ist das l61?
Feersum

@feersum wird $\auf 1(char 49, octal 61) gesetzt.
Primo

3

Haskell, 71 66 Bytes

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

Ziemlich unkompliziertes Zeug: Teilen Sie am 'P' auf und nehmen Sie dann das Produkt zwischen (n-k + 1) und n.

Danke an nimi für die Idee, Pattern Guards anstelle von a zu verwenden where Klausel zu verwenden, konnten 5 Bytes eingespart werden.


2

Minkolang 0,11 , 13 25 19 Bytes

Vielen Dank an Sp3000 für diesen Vorschlag!

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

Probieren Sie es hier aus.

Erläuterung

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

Dies verwendet den gleichen Algorithmus wie Alex: n P k= n(n-1)(n-2)...(n-k+1).


2

Julia, 63 58 48 Bytes

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

Dadurch wird eine unbenannte Funktion erstellt, die eine Zeichenfolge akzeptiert und eine Ganzzahl zurückgibt. Um es zu nennen, geben Sie ihm einen Namen, z f=s->....

Ungolfed:

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

Dies nutzt die Tatsache , dass die Anzahl der Permutationen ist n ( n - 1) ( n - 2) ... ( n - k + 1).

10 Bytes gespart dank Glen O!


Keine Notwendigkeit Int, so können Sie einfach verwenden map(parse,...).
Glen O

@ GlenO Mein Verstand wurde geblasen. Ich wusste nicht, dass Intes in dieser Situation notwendig war. Vielen Dank!
Alex A.

2

Bash + Linux-Utils, 33

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

joterzeugt die Folge von rganzen Zahlen beginnend mit n-r+1und trennt sie mit *. Dieser Ausdruck wird bczur arithmetischen Auswertung weitergeleitet.


1

MATLAB, 54 Bytes

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

Versuchte es kleiner zu machen, aber eines der Dinge, in denen MATLAB wirklich schlecht ist, ist das Erhalten von Eingaben. Es dauert 32 Zeichen, nur um die beiden Zahlen aus der Eingabezeichenfolge zu erhalten!

Ziemlich selbsterklärender Code. Ruft die Eingabe in der Form ab, %dP%din der% d eine Ganzzahl ist. Teilen Sie das in nund auf r. Zeigen Sie dann das Produkt jeder ganzen Zahl im Bereich n-r+1bis an n. Interessanterweise funktioniert dies sogar xP0, wenn die richtige Antwort 1 lautet. Dies liegt daran, dass die prod()Funktion in MATLAB 1 zurückgibt, wenn Sie versuchen, das Produkt eines leeren Arrays zu erstellen. Immer wenn rNull ist, wird der Bereich ein leeres Array sein, also bekommen wir 1.


Dies funktioniert auch perfekt mit Octave . Sie können es hier online ausprobieren .


1

Javascript, 59 57 Bytes

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 Bytes

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

Eine anonyme Funktion. Beispiel:

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

Erläuterung:

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

Die Stope-Funktion, die ich verwendet habe, kann als eingebaut gelten ... Sie liegt irgendwo zwischen der Allgemeinheit des Multiplikationsoperators und der Spezifität des Fakultätsoperators.


1

APL, 23

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

Nimmt den String als Argument. Erläuterung:

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

Welche APL ist das? Ich erhalte einen Fehler mit meiner Kopie von Dyalog.
Lirtosiast

1
@ThomasKwa ⎕ML←3In Dyalog verwenden.
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

Ziemlich einfach. Verarbeitet die Zahleneingabe als a,b. Hält ein laufendes Produkt als P, das mit den ersten bGliedern von multipliziert wird a, a-1, a-2, ....


2
Ich verstehe nicht, wie input()es nicht zu einem Fehler kommen konnte.
Feersum

@feersum Ich habe es versucht und es wird in der Tat ein Syntaxfehler ausgelöst.
Alex A.

Ich habe Eingaben mit Anführungszeichen vorgenommen "3P2", die meiner Meinung nach normalerweise zulässig sind, aber hier lautet die Aufforderung "eine Eingabe in der exakten Form", und ich ändere sie in eine Funktion, die eine Zeichenfolge annimmt.
8.

1

TI-BASIC, 52 Bytes

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 verfügt über eine "Produkt einer Liste" -Funktion, so dass es nicht allzu schwierig ist, die Einschränkungen für integrierte Funktionen zu umgehen. TI-BASIC unterstützt jedoch keine leeren Listen - wir müssen es also tun

Um die beiden Zahlen zu extrahieren, extrahiere ich die erste Zahl als Teilzeichenfolge. Das ist teuer ; es nimmt die ganze zweite Zeile ein. Um zu vermeiden, dass dies für die zweite Nummer erneut ausgeführt werden muss, setze ich die Variable P auf diese Nummer und bewerte die gesamte Zeichenfolge mitexpr( bewerte und dividiere dann durch P².

Schließlich nehme ich eine zufällige Permutation der Liste zwischen den beiden Zahlen (wobei ich darauf achte, eine zur zweiten Zahl hinzuzufügen) und nehme das Produkt.


1

Ouroboros , 47 45 Bytes

Einiges davon ist ziemlich hässlich - ich würde mir vorstellen, dass man weiter Golf spielen könnte.

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

Jede Codezeile in Ouroboros stellt eine Schlange dar, die ihren Schwanz frisst.

Schlange 1

Swechselt zum gemeinsamen Stack. r.rliest eine Zahl, dupliziert sie und liest eine andere. (Nicht-numerische Zeichen wie Pwerden übersprungen.) -Subtrahiert die beiden. Ist der Eingang war 7P2, haben wir jetzt 7, 5auf dem gemeinsamen Stapel. Zum Schluss 1(isst der letzte Charakter der Schlange. Da dies das Zeichen ist, auf dem sich der Befehlszeiger befindet, stirbt die Schlange.

Schlange 2

)s tut nichts beim ersten mal durch. .!+dupliziert die Oberseite des Stapels von Schlange 2, prüft, ob er Null ist, und fügt in diesem Fall 1 hinzu. Bei der ersten Iteration ist der Stapel leer und wird so behandelt, als ob er unendliche Nullen enthielte1 . Bei späteren Iterationen enthält der Stapel einen Wert ungleich Null. Dies hat keine Auswirkung.

Als nächstes Sschaltet auf den freigegebenen Stapel, wo wir die Nummer haben nund einen Zähler für die Berechnung des Produkts. 1+erhöht den Zähler. .@@.@\<!dupliziert beide Zahlen und drückt 1, wenn nder Zähler noch größer oder gleich ist, andernfalls 0. @@*YDann multipliziert man den Zähler mit dieser Zahl und wirft eine Kopie auf den Stapel von Schlange 2.

s.!+Wechselt zurück zum Stapel von Snake 2 und verwendet denselben Code wie zuvor, um die oberste Zahl in 1 umzuwandeln, wenn sie 0 war, und ansonsten beizubehalten. Dann *multipliziert man das Ergebnis mit dem Teilprodukt, das auf diesem Stapel lag.

Wir kehren jetzt zum gemeinsamen Stapel ( S) zurück, duplizieren den Zähler-oder-Null-Zähler ( .) und negieren ihn zweimal ( !!), um einen Zähler ungleich Null in eine 1 zu verwandeln. 4*.(Multipliziert dies mit 4, dupliziert und frisst so viele Zeichen aus dem Ende der Schlange.

  • Wenn wir die Haltebedingung nicht erreicht haben, haben wir eine 4 auf dem Stapel. Die vier Zeichen nach dem (werden gegessen, und die Steuerung springt zum Anfang des Codes. Hier werden )vier Zeichen swieder auferlegt, zum Stapel von Snake 2 zurückgeschaltet und die Ausführung fortgesetzt.
  • Wenn der Zähler abgelaufen ist n, haben wir eine 0 auf dem Stapel, und es wird nichts gegessen. snwechselt zum Stapel von Schlange 2 und gibt den Höchstwert als Zahl aus; dann 1(isst das letzte Zeichen und stirbt.

Das Ergebnis ist, dass das Produkt (r+1)*(r+2)*...*nberechnet und ausgegeben wird.

Versuch es

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.