Jump to content

Ahhhh... que maldade a nossa! :)


fredericopissarra

Recommended Posts

Num forum, um daqueles usuários com nomes esquisitos, estudante, que mal sabe escrever um "hello, world", pergunta ao povo para resolver um problema que o professor passou... Fico de saco cheio com esse tipo de canalha que não quer aprender porra nenhuma. Eis o problema:

Gerar 6 números aleatórios entre 1 e 49, sem repetições.

Daí, de sacanagem, um outro usuário e eu estamos trocando códigos que fazem isso, sem comentários. Eis um deles:

// tickets.c
//
//   Compile with:
//      cc -O2 -march=native -o tickets tickets.c
//
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <fcntl.h>
#include <time.h>

#if defined(__x86_64) || defined(__i386)
#ifdef __GNUC__
  #include <immintrin.h>
#endif

#ifdef __RDRND__
  #include <cpuid.h>

  static unsigned int RAND_( void )
  {
    unsigned int r, retries;

    retries = 10;
    while ( retries-- )
      if ( _rdrand32_step( &r ) )
        return r;

    fputs( "\e[1;31mERROR\e[m: RDRAND failure!\n", stderr );
    exit(EXIT_FAILURE);
  }

  static void do_nothing(void) {}
#endif
#endif

static void SRAND_(void) 
{ 
  int fd;
  unsigned int rnd;
  ssize_t size;

  if ( ( fd = open( "/dev/urandom", O_RDONLY ) ) < 0 )
  {
    perror("open");
    goto fallback;
  }

  if ( ( size = read( fd, &rnd, sizeof rnd ) ) != sizeof rnd )
  {
    if ( size < 0 )
      perror("read");
    close( fd );
    goto fallback;
  }

  close(fd);

  srand( rnd );

  return;

fallback:
  srand( time( NULL ) );
}

static unsigned int (*RAND)(void) = (unsigned int (*)(void))rand;
static void (*SRAND)(void) = SRAND_;

#define HIGH_NUM     49
#define TICKET_SIZE  6
#define NUM_TICKETS  20

uint64_t generate_ticket( unsigned int count )
{
  uint64_t mask, ticket = 0;

  while ( count-- )
  {
    do
      mask = 1ULL << ( RAND() % HIGH_NUM );
    while ( ticket & mask );

    ticket |= mask;
  }

  return ticket;
}

void print_ticket( uint64_t ticket )
{
  unsigned int count, i;

  for ( i = 0, count = HIGH_NUM; count--; i++ )
    if ( ticket & ( 1ULL << i ) )
      printf( "%2u ", i + 1 );
  putchar( '\n' );
}

void print_highlighted_matches( uint64_t ticket, uint64_t draw )
{
  uint64_t mask, matches = ticket & draw;
  unsigned int i, cnt = 0;

  for ( i = 0; i < HIGH_NUM; ++i )
  {
    mask = 1ULL << i;

    if ( ticket & mask )
    {
      if ( matches & mask )
      {
        fputs( "\033[1;36m", stdout );
        ++cnt;
      }

      printf( "%2u ", i + 1 );

      if ( matches & mask )
        fputs( "\033[m", stdout );
    }
  }

  printf( "  [ %u ]\n", cnt );
}

int main( void )
{
  unsigned int i;
  uint64_t draw, tickets[NUM_TICKETS];

  #ifdef __RDRND__
    int a, b, c, d;

    __cpuid( 1, a, b, c, d );
    if ( c & bit_RDRND )
    {
      RAND = RAND_;
      SRAND = do_nothing;
    }
  #endif

  SRAND();

  for ( i = 0; i < NUM_TICKETS; ++i )
    tickets[i] = generate_ticket( TICKET_SIZE );

  draw = generate_ticket( TICKET_SIZE );
  puts( "Draw:" );
  print_ticket( draw );
  putchar( '\n' );

  puts( "Tickets:" );

  for ( i = 0; i < NUM_TICKETS; ++i )
    print_highlighted_matches( tickets[i], draw );

  return 0;
}

Claro, só funciona direito em "unixes"... A não ser que o sujeito tenha o bom senso de retirar os ANSI codes nas strings...

Eis o bicho executado:

image.png.eae9008817a48daa65547d8e436d49c2.png

[]s
Fred

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...