Cod sursa(job #2823998)

Utilizator mircea_007Mircea Rebengiuc mircea_007 Data 30 decembrie 2021 15:28:44
Problema Radix Sort Scor 30
Compilator c-64 Status done
Runda Arhiva educationala Marime 2.79 kb
// This program was written on 30.12.2021
// for problem radixsort
// by Mircea Rebengiuc

#include <stdio.h>
#include <ctype.h>

#ifdef PROFILER
#include <sys/time.h>
#define DEBUG_TIME(start, end) printf("(!) [DEBUG] time spent is %fs\n", ((double)end - start) / 1000000)
#endif

#define MAXN 10000000
#define OUTSTEP 10
#define SIGMA 65536 // vom lua numerele in baza 16
#define LSIGMA 16 // log2(sigma)
#define NUMSTEP 2
#define NIL -1
#define MAXNCF 10

#define MAXBUF (128 * 1024)

#ifdef PROFILER
inline long long getTime() {
  struct timeval tv;

  gettimeofday(&tv, NULL);
  return tv.tv_sec * 1000000LL + tv.tv_usec;
}
#endif

int v[MAXN];
int ord[MAXN];

int list[SIGMA];
int next[MAXN];

FILE *fin, *fout;

char wbuf[MAXBUF];
int wbp = 0;

static inline void bputc( int ch ){
  wbuf[wbp] = ch;
  if( (wbp = ( (wbp + 1) & (MAXBUF - 1) )) == 0 )
    fwrite(wbuf, sizeof(char), MAXBUF, fout);
}

static inline void bflush(){
  fwrite(wbuf, sizeof(char), wbp, fout); 
}

static inline void fputint( int n ){
  char out[MAXNCF + 2] = "0000000000 ";
  int i = MAXNCF;
  
  if( n == 0 )
    i--;
  
  while( n ){
    out[--i] += (n % 10);
    n /= 10;
  }
  
  for( ; i <= MAXNCF ; i++ )
    bputc(out[i]);
}

int main(){
  fin  = fopen("radixsort.in",  "r");
  fout = fopen("radixsort.out", "w");
  
  int n, i, b, c, step, mask;
  long long a;// ca sa se faca automat conversia la 64 de fiecare data
  
  #ifdef PROFILER
  long long t0, t1, t2, t3, t4, t5;
  #endif
  int num_iterations;
  
  fscanf(fin, "%d%lld%d%d", &n, &a, &b, &c);
  
  v[0] = b;
  ord[0] = 0;
  for( i = 1 ; i < n ; i++ ){
    v[i] = (a * v[i - 1] + b) % c;
    ord[i] = i;
  }
  
  mask = (1 << LSIGMA) - 1;
  for( step = 0 ; step < NUMSTEP ; step++ ){
    #ifdef PROFILER
    printf("@step = %d\n", step);
    t0 = getTime();
    #endif
    for( c = 0 ; c < SIGMA ; c++ )
      list[c] = NIL;
  
    for( i = 0 ; i < n ; i++ ){
      c = ((v[ord[i]] & mask) >> (step * LSIGMA));
      next[ord[i]] = list[c];
      list[c] = ord[i];
    }

    #ifdef PROFILER
    t1 = getTime();
    #endif

    // sortare stabila (bucket sort)    
    a = n;
    for( c = SIGMA ; c-- ; ){
      #ifdef PROFILER
      t4 = getTime();
      #endif
      num_iterations = 0;
      i = list[c];
      while( i != NIL ){
        ord[--a] = i;
        i = next[i];
        #ifdef PROFILER
        num_iterations++;
        #endif
      }
      #ifdef PROFILER
      DEBUG_TIME(t4, getTime());
      printf("looped %d times\n", num_iterations);
      #endif
    }
    
    #ifdef PROFILER
    t2 = getTime();
    printf("----------------------\n");
    DEBUG_TIME(t0, t1);
    DEBUG_TIME(t1, t2);
    DEBUG_TIME(t0, t2);
    #endif

    mask <<= LSIGMA;
  }
  
  for( i = 0 ; i < n ; i += OUTSTEP )
    fputint(v[ord[i]]);
  bputc('\n');
  
  bflush();
  fclose(fin);
  fclose(fout);
  return 0;
}