Combinazione matematica


11

Scrivi un programma che accetta un input come:

n,k

che quindi calcola:

Combinazione di n e k.  (C (n, k))

e quindi stampa il risultato.


Un esempio numerico:

Ingresso:

5,2

Calcolo interno:

(5!) / (3! X2!)

Uscita stampata:

10

Mi piacerebbe vedere una risposta che batte la mia soluzione Python di 65 caratteri, ma ovviamente tutte le lingue sono benvenute.

Ecco la mia soluzione:

n,k=input();f=lambda x:+(x<2)or x*f(x-1);print f(n)/(f(k)*f(n-k))

Modificare:

Ammetto che questa domanda proviene dal puzzle di combinazione matematica del sito Web codegolf . So che la mia risposta potrebbe sembrare che non si possano fare molti progressi, ma i leader di questo enigma l'hanno risolto in quasi la metà dei personaggi.

I conteggi dei caratteri più bassi correnti per lingua sono:

Perl: 35

Rubino: 36 anni

Python: 39

PHP: 62


Funzione o programma completo? La descrizione indica una funzione che restituisce il risultato corretto, ma il tuo esempio è un programma completo che lo stampa.
Ventero,

@Ventero Hai ragione intendevo programma. Mi dispiace per quello.
backus,

3
In generale, i concetti matematici di base non sono grandi domande sul golf perché J, APL, Maple, Mathematica e molti altri li avranno integrati. Inoltre, essere un po 'più specifico sul formato di input e output e fornire risultati di esempio - Non posso dì se intendi 5 scegli 2 o 2 scegli 5 qui.
Jesse Millikan,

@Jesse Ho ricevuto questa sfida da un altro sito Web che consente solo i principali linguaggi di scripting, ricorderò questa linea guida in futuro. Ho modificato la mia domanda per cercare di chiarire i requisiti della sfida, fatemi sapere se è abbastanza chiaro o no.
backus,

Sono nuovo, quindi siamo nella stessa barca. Tuttavia, non riassumere i risultati; saranno solo obsoleti. Basta votare e (se appropriato) accettare le risposte. (Inoltre, renderai le persone infelici se ignori le risposte di J e GolfScript senza un motivo.)
Jesse Millikan

Risposte:


11

APL, 3 byte

⎕!⎕

O per coloro il cui browser non esegue il rendering di quanto sopra, in un rendering ASCII:

{Quad}!{Quad}

3
Per essere completamente conforme n,kall'input, dovresti farlo !/⌽⎕.
Marin il


10

C 96

Con I / O (che richiede circa 34 caratteri). Aggiunti un paio di nuove righe per renderlo leggibile.

main(a,b,c,d){scanf("%d,%d",&a,&b);
d=a-b;for(c=1;a>b;){c*=a--;}for(;d;)
{c/=d--;}printf("%d",c);}

Ora, se mi scusi, ho un ASCII n scelgo k missile da catturare.

    d;main(a
   ,         b
  ,           c
 )  int        a
 ;   {scanf    (
 (   "%d %d"   )
 ,   &a,  &b   )
 ;   d    =a   -
 b   +     b   -
 b   *     1   ;
 a             -
 a  ;for    (  c
 =  1;a>   b   ;
 )  {c=   c    *
 (  (a-- )     )
 ;  }for(      b
 =  b + 1      ;
 d  ;    )     {
 c  =     c    /
 (  d--    )   ;
  }           {
  }           {
   }         (
  printf("%d",c)
 )      ;       }
/*     *  *   * *\
 * * X   * 8 * * |
|     *      *    \
*/    //       *  */

7

GolfScript, 17 caratteri

Questa soluzione gestisce correttamente casi come k = 0 o k = 1.

~>.,,]{1\{)*}/}//

La parte fattoriale si basa su una risposta precedente .


6

GolfScript 21

~~)>.,,]{{)}%{*}*}%~/

Non particolarmente breve, GolfScript non ha una vera funzione fattoriale, tuttavia questa deve essere la manipolazione dei dati più malvagia che io abbia mai fatto, questo richiede una traccia dello stack:

"5,2" Dati nello stack dall'input.
~Il comando Eval, si noti, è un operatore che trasforma un numero in un array.
[0 1 2 3 4] 2
~Binario no.
[0 1 2 3 4] -3
)Incremento.
[0 1 2 3 4] -2
>Prendi la fine dell'array, -2 come parametro per ottenere gli ultimi 2 elementi.
[3 4]
.Elemento duplicato.
[3 4] [3 4]
,Lunghezza della matrice.
[3 4] 2
,Ruotare il numero in serie.
[3 4] [0 1]
]Crea array.
[[3 4] [0 1]]
{{)}%{*}*}Blocco di codice.
[[3 4] [0 1]] {{)}% {*} *}
%Esegue il blocco una volta per ogni elemento dell'array. La parte seguente mostra solo il primo ciclo.
[3 4]
{)}%Incrementa ciascun elemento dell'array.
[4 5]
{*}Blocco contenente un comando moltiplica.
[4 5] {*}
*"Piega" l'array usando il comando block, ovvero in questo caso crea il prodotto di tutti gli elementi.
20
Al termine del ciclo grande, restituisce un array con i risultati.
[20 2]
~Decostruisci l'array.
20 2
/Division.
10


6

Ruby 1.9, 52 46 (42) caratteri

eval"A,B="+gets;i=0;p eval"(A-B+i+=1)/i*"*B+?1

Se stderr viene ignorato:

eval"A,B=I="+gets;p eval"I/(A-I-=1)*"*B+?1

Ruby 1.8, 43 caratteri, nessun output aggiuntivo per stderr:

eval"a,b=i="+gets;p eval"i/(a-i-=1)*"*b+"1"

modifiche:

  • (52 -> 48) Trovato un modo più breve per analizzare l'input
  • (48 -> 46) Meno loop, più valutazione.

4

Python (56)

f=lambda n,k:k<1and 1or f(n-1,k-1)*n/k;print f(*input())

Codice non golfato e alcune spiegazioni di una scorciatoia per il calcolo del coefficiente binomiale. (Nota: c'è qualche intuizione che non ho ancora capito per arrivare alla versione 39 caratteri; non credo che questo approccio ti porterà lì.)

# Since choose(n,k) =
#
#     n!/((n-k)!k!)
#
#          [n(n-1)...(n-k+1)][(n-k)...(1)]
#        = -------------------------------
#            [(n-k)...(1)][k(k-1)...(1)]
#
# We can cancel the terms:
#
#     [(n-k)...(1)]
#
# as they appear both on top and bottom, leaving:
#
#    n (n-1)     (n-k+1)
#    - ----- ... -------
#    k (k-1)       (1)
#
# which we might write as:
#
#      choose(n,k) = 1,                      if k = 0
#                  = (n/k)*choose(n-1, k-1), otherwise
#
def choose(n,k):
    if k < 1:
        return 1
    else:
        return choose(n-1, k-1) * n/k

# input() evaluates the string it reads from stdin, so "5,2" becomes
# (5,2) with no further action required on our part.
#
# In the golfed version, we make use of the `*` unpacking operator, 
# to unpack the tuple returned by input() directly into the arguments
# of f(), without the need for intermediate variables n, k at all.
#
n, k = input()

# This line is left as an exercise to the reader.
print choose(n, k)

Potresti fornire un esempio non golfato della tua sceneggiatura?
backus,

Possiamo usare *per l'analisi degli input del modulo 4545 78?
Chisciotte

Sfortunatamente no, ma non è *questo il problema. 4545 78non è un'espressione Python valida, quindi input()solleverà a SyntaxError. Questo trucco dipende interamente dal problema richiesto x,y. Se avessi una funzione che leggesse x ye restituisse una tupla, allora potresti usarla *bene.


3

Windows PowerShell, 57

$a,$b=iex $input
$p=1
for($a-=$b;$a-ge1){$p*=1+$b/$a--}$p

3

J, 33 36

(":!~/".;._1}:toJ',',1!:1(3))1!:2(4)

Sono immessi, analizzati e stampati 35 caratteri. L'altro personaggio, !n è scegliere k.

Non ho Windows in giro per testarlo al momento, ma credo che dovrebbe funzionare lì.


3

Q, 32 caratteri

{f:{1*/1.+(!)x};f[x]%f[y]*f x-y}

2

Perl 6 (55)

my ($a,$b)=lines;$_=1;for 1..$a-$b {$_+=$_*$b/$^a};.say

2

RPL (22)

(non utilizzando la funzione COMB integrata)

→ n k 'n!/(k!*(n-k)!)'

2

Q ( 50 45)

 f:{(prd 1.+til x)%((prd 1.+til y)*prd 1.+til x-y)}

Puoi eliminare alcuni caratteri da quanto sopra rimuovendo le parentesi ridondanti e usando 1 * / invece di prd.

f:{(1*/1.+til x)%(1*/1.+til y)*1*/1.+til x-y}

2

Mathematica 12

Semplice, funzione integrata.

n~Binomial~k

2

Perl 6 , 25 16 byte

-9 byte grazie a nwellnhof

+*o&combinations

Provalo online!

Funzione anonima che accetta due numeri e restituisce un int. Questo utilizza il built-in combinationse converte l'elenco restituito in un int.



@nwellnhof Ah, non mi ero reso conto che combinationspotesse prendere un numero anziché un elenco
Jo King l'

1

PHP (71 79 )

<?$a=fgetcsv(STDIN);$x=1;while($a[1]-$i)$x=$x*($a[0]-++$i+1)/$i;echo$x;

<?php $a=fgetcsv(STDIN);$x=1;while(++$i<=$a[1])$x=$x*($a[0]-$i+1)/$i;echo $x?>


1

Python (54)

f=lambda n,k:k<1or f(n-1,k-1)*n/k;print 1*f(*input())

Essenzialmente uguale a quello di Python sopra, ma mi rado quattro byte rilasciando il

and 1

dalla definizione della funzione. Tuttavia, ciò comporta che la funzione restituisca True anziché 1 se k = 0, ma ciò può essere risolto moltiplicando per 1 prima della stampa, poiché 1 * True = 1, aggiungendo quindi due byte.


1

J, 11 caratteri

!~/".1!:1[1

Riceve input dalla tastiera.

    !~/".1!:1[1
5,2
10

0

Haskell (80)

f(_,0)=1
f(n,k)=n/k*f(n-1,k-1)
main=getLine>>=putStr.show.f.read.(++")").('(':)

Ma, se x yè consentito l'input nel formato anziché nel formato x,y, è 74 caratteri:

f[_,0]=1
f[n,k]=n/k*f[n-1,k-1]
main=interact$show.f.map read.take 2.words


0

Python (52)

 f=lambda n,k:k<1or f(n-1,k-1)*n/k;print+f(*input())

Migliorato dagli altri due utilizzando print+per convertire il risultato fda booleana intin caso k==0.

Non ho ancora idea di come ridurlo a 39, mi chiedo se stiano usando lambda.


0

(L'OP ha solo vagamente specificato il metodo / formato di input e output, quindi quanto segue sembra accettabile.)

Sage Notebook ( 39 41 40)

Nella cella corrente,

f=lambda n,k:k<1or f(n-1,k-1)*n/k;+f(*_)

dove n,kviene immesso e valutato l'input nel modulo nella cella precedente. Questo simula "input da riga di comando" assegnandolo a _(simile agli argomenti della riga di comando).

Sage Notebook ( 42 44 43)

In alternativa, utilizzando "input in-source" (con solo i x=caratteri e newline che si aggiungono alla partitura), ad es.

x=5,2
f=lambda n,k:k<1or f(n-1,k-1)*n/k;+f(*x)

Entrambi questi approcci sono ovviamente derivati ​​da precedenti risposte di altri.



0

Javascript, 27 byte

Innanzitutto le mie soluzioni a 35 byte:

f=(n,k)=>n-k&&k?f(--n,k)+f(n,k-1):1

Oppure, in alternativa,

f=(n,k,i=k)=>i?f(n-1,k-1,i-1)*n/k:1

Il primo funziona in modo ricorsivo, con la semplice (n,k) = (n-1,k) + (n-1,k-1)regola. Il secondo lo usa (n,k) = (n-1,k-1) * n/k.

MODIFICARE

Ho appena notato la soluzione di Arnould in un duplicato di questo:

f=(n,k)=>k?n*f(n-1,k-1)/k:1

Che è un enorme 8 byte in meno (27 byte)


0

TI-BASIC, 16 caratteri (8 byte)

Ans(1) nCr Ans(2

L'input è un elenco di lunghezza 2 pollici Ans.
L'output è il risultato della formula qui definita .

Se la soluzione precedente non è sufficiente, funziona anche la seguente soluzione di 35 caratteri (24 byte) :

Ans(2)!⁻¹(Ans(1)-Ans(2))!⁻¹Ans(1)!

Nota: TI-BASIC è un linguaggio tokenizzato. Il conteggio dei caratteri non equivale al conteggio dei byte.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.