Tuesday, 23 July 2019

Fastest way to read input from stdin C++

Method 1 :

A noob's way :

#include <iostream>
using namespace std;
int main(){
   int nb,a;
   cin >> nb;
   for (int i=0; i < nb; ++i){
      cin >> a;
      // do some stuff
   }
   return 0;
}

Method 2 :

A classic way :

#include <iostream>
using namespace std;
int main(){
   ios::sync_with_stdio(false);
   cin.tie(nullptr);
   int nb,a;
   cin >> nb;
   for (int i=0; i < nb; ++i){
      cin >> a;
      // do some stuff
   }
   return 0;
}

Method 3 :

The C way :

#include <cstdio>
int main(){
   int nb,a;
   scanf("%d",&nb);
   for (int i=0; i < nb; ++i){
      scanf("%d",&a);
      // do something
   }
   return 0;
}

Method 4 :

The getchar way :

#include <stdio.h>
#include <stdlib.h>
int fastscan(){
   int c;
   bool negative = false;
   int a = 0;
   c = getchar();
   if (c=='-'){
      negative = true;
      c = getchar();
   }
   while(c>47 and c<58){
      a = a*10 + c - 48;
      c = getchar();
   }
   if(negative){
      a = -a;
   }
   return a;
}
int main(){
   int nb;
   scanf("%d",&nb);
   for (int i=nb; ~i; --i){
      fastscan();
      // do something
   }
   return 0;
}

Method 5 :

The optimised getchar_unlocked method :

#include <stdio.h>
#include <stdlib.h>
inline int fastscan(){
   int c;
   bool negative = false;
   int a = 0;
   c = getchar_unlocked();
   if (c=='-'){
      negative = true;
      c = getchar_unlocked();
   }
   while(c>47 and c<58){
      a = (a<<1) + (a<<3) + (c - 48);
      c = getchar_unlocked();
   }
   if(negative){
      a = -a;
   }
   return a;
}
int main(){
   int nb;
   scanf("%d",&nb);
   for (int i=nb; ~i; --i){
      fastscan();
      // do some stuff
   }
   return 0;
}

Method 6 :

The inserter's way :

#include <iostream>
#include <vector>
#include <iterator>
#pragma GCC optimize ("O3")
using namespace std;
int main(){
   setvbuf(stdin, (char*)NULL, _IOFBF, 0);
   ios::sync_with_stdio(false);
   cout.tie(nullptr);
   cin.tie(nullptr);
   int nb;
   cin >> nb;
   vector<int> v;
   copy(istream_iterator<int>(cin), istream_iterator<int>(),back_inserter(v));
   for (auto& i:v) // do some operations
   return 0;
}

Method 7 :

The bufferer's way :

#include <iostream>
#define BUFSIZE 1024*900*64
int main(){
   int n, number=0,numbers;
   scanf("%d",&n);
   char buf[BUFSIZE+1] = {0};
   while ((numbers = fread(buf, 1, BUFSIZE, stdin)) > 0){
     bool neg=false;
      for (int i=0; i < numbers; i++){
      if (buf[i] == '-') neg=true;
      else if (buf[i] != '\n'){
         number = buf[i] - '0' + 10*number;
      } 
      else{
         n--;
         if (neg) number = -number;
         // do something
         number = 0;
         neg = false; 
      }      
     }
     if (!n)  break;
   }
}

Method 8 :

The ultimate way :

#include <cstdint>
#include <cstdlib>
#include <cstdio>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
inline char* stdin_ptr(){
    struct stat sb;
    (void)fstat( STDIN_FILENO, &sb );
    return (char*)mmap (0, sb.st_size, PROT_READ, MAP_SHARED | MAP_POPULATE, STDIN_FILENO, 0);
}
inline int atoi(char*& data){
    int val = 0;
    bool neg=false;
    if (*data == '-'){
       neg = true;
       data++;
    }
    do{
        val = val*10 + *data++ - '0';
    } while(*data & (1<<4));
    if (neg) val = -val;
    ++data;
    return val;
}
int main(){
    char* ptr = stdin_ptr();
    int n = atoi(ptr);
    while (*ptr) // do something
}

If you have a better method please share !

Sunday, 30 June 2019

Facebook Hacker Cup - Qualification Round 2019

The 48h qualification round consisits of 4 algorithmic problems to do on the facebook interface. You shall do 1 question to advance in Round 1.

The first two questions were the easisiest ones. The solution is just some simple implementations, most people were able to do them. The 30th July will start Round 1 !

Now, is the time for Round 1 ! Good Luck to all !

Sunday, 7 April 2019

Google Code Jam 2019 - Qualification Round

This weekend, I have participated at the Google Code Jam contest. You only needed to get 30 pts to attend the next round !

For the first question : Because each number always has a the number 4 in it, we can just :

create (initialise) string A and string B
for each digit in the number :
     if the digit is a 4 :
          put '1' in string B
          put '3' in string A
     else :
          put the digit in string A

For the second question : It is a pretty easy question. The idea is just to replace 'E' by 'S' and 'S' by 'E':

read the string s
for each character c in s :
     if c == 'E' :
         print 'S'
     else :
         print 'E'

For the third question : just use Euclid's gcd !

Have a look at the official editorial for question 3 and 4 :

https://codejam.withgoogle.com/2018/challenges/0000000000051705/analysis/000000000008830b
https://codejam.withgoogle.com/2018/challenges/0000000000051705/analysis/00000000000881de

Here is my youtube video (doing A and B) : https://youtu.be/0k4q1SMSYSo

std::next_permutation(arr.begin(),arr.end());

What is next_permutation(a.begin(),a.end()) ? Next permutation is like what its name says, finds the next permutation of a and assigns ...