[FLUG] Un salto al BAR

  • From: Simon <f.simon@xxxxxxxx>
  • To: fanolug@xxxxxxxxxxxxx
  • Date: Fri, 13 Sep 2002 20:23:16 +0200

Mailing List del Fortunae LUG
=============================

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Eh niente praticamente qualche giorno fa cercavo di pensare
ad un algoritmo breve per mischiare un mazzo di carte che
poi avrei separato in due mazzetti da 20 carte ciascuno.

Una roba figa che mi è venuta in mente di fare era non
di mischiare le carte in un mazzo unico e poi dividerle in
due mazzetti... ma invece di generare le carte in fila e
poi smistarle (a caso) in questo o in quel mazzetto.

Lo svantaggio vabbè si nota subito... anche se vengono date
a caso sono comunque diciamo "in fila"... e questo mi ha
fatto scartare l'applicabilità dell'idea.

Nonostante tutto però la particolarità di tale algoritmo
mi ha incuriosito a tal punto da farmelo realizzare comunque
anche se poi non l'avrei utilizzato.

L'algoritmo infatti doveva essere abbastanza "intelligente"
da capire che se arrivato ad un certo punto aveva ancora
5 carte da distribuire e la differenza di carte tra un mazzo
e l'altro era appunto di 5 carte avrebbe dovuto darle tutte
al mazzetto con meno carte.
Ovviamente questo caso particolare m'ha fatto subito pensare
ad una funzione che dinamicamente generasse in base alla
differenza di carte tra i mazzetti e le carte ancora da 
distribuire delle percentuali su "a chi assegnare" tale carta.
Facciamo un esempio... alla partenza entrambi i mazzetti
hanno lo stesso numero di carte (0) quindi le percentuali
sono uguali... 50% ciascuno... la carta viene assegnata al
mazzetto A. Ora la differenza di carte tra i mazzetti è 1
e le carte rimanenti sono 39... quindi bisogna sbilanciare
di poco le probabilità che la seconda carta vada al mazzetto
B... facciamo 51% e 49%. Però anche la seconda carta va
al mazzetto A... quindi sbilanciamo nuovamente le probabilità,
per esempio 56% e 44%. Etc...

Insomma mi serve una funzione che in base alle carte che
rimangono ancora da distribuire e la differenza di carte
tra i mazzetti generi delle percentuali che siano adeguate.

Casi particolari:

Parità di carte tra i mazzetti => probabilità 50%

Carte rimaste da distribuire      probabilità 100%
uguale alla differenza         => per il mazzo con
di carte tra i mazzetti           meno carte

Realizzazione:

nA: numero di carte nel mazzetto A
nB: numero di carte nel mazzetto B
i:  carta da distribuire (si parte da 1 fino a 40)

Matematicamente:

p = (nB - nA) / (40 - i)

p sarà un numero generalmente compreso tra -1 e 1 che
rappresenta lo "spartiacque" tra la probabilità del
mazzetto A e quella del mazzetto B.
(notate che 40-i praticamente è la quantità di carte
ancora da distribuire)
Ho detto che p è *generalmente* compreso tra -1 e 1
perchè quando ci si trova alla fine che le carte da
distribuire sono uguali a quelle mancanti in un
mazzetto inzia a sballare ovviamente a favore di chi
ne ha meno.

con p  =  0   50% di probabilità per entrambi
con p >=  1   100% di probabilità per il mazzetto A
con p <= -1   100% di probabilità per il mazzetto B

Ed ora la mia realizzazione in C di tale funzione e di tutto
il resto dell'algoritmo:

- ------| inizio file: shuffle1.c |------

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>

int deckA[40], deckB[40], nA = 0, nB = 0;

int
main (int argc, char *argv[])
{
  int i;
  double p, r;

  srand (time (NULL));

  /* giving and 'shuffling' cards */
  for (i = 1; i <= 40; ++i)
    {
      p = (double) (nB - nA) / (40.0 - i);
      r = (2.0 * (rand () / (RAND_MAX + 1.0))) - 1;

      if (p > r)
        deckA[nA] = i % 10, ++nA;
      else
        deckB[nB] = i % 10, ++nB;

      printf ("nA: %02i nB: %02i (last: %i %i) r: %f (A < %f < B)\n",
              nA, nB, deckA[nA - 1], deckB[nB - 1], r, p);
    }

  return 0;
}

- ------| fine file: shuffle1.c |------

Spero di essere stato chiaro.

- -- 
/* Federico 's1m0n' Simoncelli <f.simon@xxxxxxxx>
   http://www.jkcal.org/simon
*/
int main(){unsigned int g,h=0;while(++h){for(g=(h>1)?2:1;g<
h/2+1&&h%g!=0;g++);if(g==h/2+1)printf("%i\n",h);}return 0;}

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.7 (GNU/Linux)

iD8DBQE9gi0Kann7qHrKp7cRAkaPAKCQNB7VsOwl272A40xXUkC3zL7hSwCdEu8u
uOzJIBzNCPdbqfxk2tLiH6U=
=JQPJ
-----END PGP SIGNATURE-----
--
"in short: just say no to drugs and maybe you won't end up like the hurd 
people" -- Linus Torvalds

Other related posts: