#include <iostream>
#include <chrono>
#include <unordered_map>
#include <algorithm>
#include <random>
using namespace std;
int hextoint1 ( char number)
{
if ( number == '0' )
return 0 ;
if ( number == '1' )
return 1 ;
if ( number == '2' )
return 2 ;
if ( number == '3' )
return 3 ;
if ( number == '4' )
return 4 ;
if ( number == '5' )
return 5 ;
if ( number == '6' )
return 6 ;
if ( number == '7' )
return 7 ;
if ( number == '8' )
return 8 ;
if ( number == '9' )
return 9 ;
if ( number == 'a' )
return 10 ;
if ( number == 'b' )
return 11 ;
if ( number == 'c' )
return 12 ;
if ( number == 'd' )
return 13 ;
if ( number == 'e' )
return 14 ;
if ( number == 'f' )
return 15 ;
return - 1 ;
}
std:: unordered_map < char , int > table{
{ '0' , 0 } ,{ '1' , 1 } ,{ '2' , 2 } ,
{ '3' , 3 } ,{ '4' , 4 } ,{ '5' , 5 } ,
{ '6' , 6 } ,{ '7' , 7 } ,{ '8' , 8 } ,
{ '9' , 9 } ,{ 'a' , 10 } ,{ 'A' , 10 } ,
{ 'b' , 11 } ,{ 'B' , 11 } ,{ 'c' , 12 } ,
{ 'C' , 12 } ,{ 'd' , 13 } ,{ 'D' , 13 } ,
{ 'e' , 14 } ,{ 'E' , 14 } ,{ 'f' , 15 } ,
{ 'F' , 15 } ,{ 'x' , 0 } ,{ 'X' , 0 } } ;
int hextoint2 ( char number)
{
return table[ ( std:: size_t ) number] ;
}
int hextoint4( char number)
{
if ( number >= '0' && number <= '9' )
return number - '0' ;
else if ( number >= 'a' && number <= 'f' )
return number - 'a' + 0x0a ;
else return - 1 ;
}
struct Mytable {
int x[ 128 ] ;
Mytable( ) : x{ }
{
fill( begin( x) , end( x) , - 1 ) ;
for ( int i = '0' ; i <= '9' ; i++ )
x[ i] = i - '0' ;
for ( int i = 'A' ; i <= 'F' ; i++ )
x[ i] = x[ i- 'A' + 'a' ] = i - 'A' + 0xa ;
}
} ;
int hextoint5( char number)
{
static Mytable mytable;
return ( number < 0 || number> 128 ) ? - 1 : mytable.x [ number] ;
}
int hextoint6( char number)
{
switch ( number) {
case '0' : return 0 ;
case '1' : return 1 ;
case '2' : return 2 ;
case '3' : return 3 ;
case '4' : return 4 ;
case '5' : return 5 ;
case '6' : return 6 ;
case '7' : return 7 ;
case '8' : return 8 ;
case '9' : return 9 ;
case 'A' : case 'a' : return 0xa ;
case 'B' : case 'b' : return 0xb ;
case 'C' : case 'c' : return 0xc ;
case 'D' : case 'd' : return 0xd ;
case 'E' : case 'e' : return 0xe ;
case 'F' : case 'f' : return 0xf ;
default : return - 1 ;
}
}
const int variants = 5 ;
const long long maxloop = 10000000 ;
struct Bench {
int ( * f) ( char ) ;
char * s;
} bench[ variants] = {
hextoint1, "If chain " ,
hextoint2, "Map(no error processing)" ,
hextoint4, "Compact if " ,
hextoint5, "Table based " ,
hextoint6, "Switch " ,
} ;
int main( )
{
mt19937 generator;
std:: uniform_int_distribution < int > myrandom( 0 , 16 ) ;
const char * s = "0123456789abcdef" ;
volatile int x;
for ( int i = 0 ; i < variants; i++ ) {
cout << bench[ i] .s << " " ;
chrono:: high_resolution_clock :: time_point t1 = chrono:: high_resolution_clock :: now ( ) ;
for ( long long j = 0 ; j < maxloop; j++ ) {
char c = s[ myrandom( generator) ] ;
x = bench[ i] .f ( c) ;
}
chrono:: high_resolution_clock :: time_point t2 = chrono:: high_resolution_clock :: now ( ) ;
long dt = chrono:: duration_cast < chrono:: milliseconds > ( t2 - t1) .count ( ) ;
cout << dt << " ms for " << maxloop << " iterations = " << dt * 1000000 / maxloop << " ns/it" << endl;
}
cin .get ( ) ;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8Y2hyb25vPgojaW5jbHVkZSA8dW5vcmRlcmVkX21hcD4KI2luY2x1ZGUgPGFsZ29yaXRobT4KI2luY2x1ZGUgPHJhbmRvbT4KCnVzaW5nIG5hbWVzcGFjZSBzdGQ7IAoKaW50IGhleHRvaW50MSAoY2hhciBudW1iZXIpCnsKCWlmIChudW1iZXIgPT0gJzAnKSAKCQlyZXR1cm4gMDsKCWlmIChudW1iZXIgPT0gJzEnKQoJCXJldHVybiAxOwoJaWYgKG51bWJlciA9PSAnMicpIAoJCXJldHVybiAyOwoJaWYgKG51bWJlciA9PSAnMycpCgkJcmV0dXJuIDM7CglpZiAobnVtYmVyID09ICc0JykKCQlyZXR1cm4gNDsKCWlmIChudW1iZXIgPT0gJzUnKQoJCXJldHVybiA1OwoJaWYgKG51bWJlciA9PSAnNicpCgkJcmV0dXJuIDY7CglpZiAobnVtYmVyID09ICc3JykKCQlyZXR1cm4gNzsKCWlmIChudW1iZXIgPT0gJzgnKQoJCXJldHVybiA4OwoJaWYgKG51bWJlciA9PSAnOScpIAoJCXJldHVybiA5OwoJaWYgKG51bWJlciA9PSAnYScpIAoJCXJldHVybiAxMDsKCWlmIChudW1iZXIgPT0gJ2InKSAKCQlyZXR1cm4gMTE7CglpZiAobnVtYmVyID09ICdjJykgCgkJcmV0dXJuIDEyOwoJaWYgKG51bWJlciA9PSAnZCcpIAoJCXJldHVybiAxMzsKCWlmIChudW1iZXIgPT0gJ2UnKSAKCQlyZXR1cm4gMTQ7CglpZiAobnVtYmVyID09ICdmJykgCgkJcmV0dXJuIDE1OwoJcmV0dXJuIC0xOwp9CgpzdGQ6OnVub3JkZXJlZF9tYXA8Y2hhciwgaW50PiB0YWJsZXsKCXsgJzAnLCAwIH0seyAnMScsIDEgfSx7ICcyJywgMiB9LAoJeyAnMycsIDMgfSx7ICc0JywgNCB9LHsgJzUnLCA1IH0sCgl7ICc2JywgNiB9LHsgJzcnLCA3IH0seyAnOCcsIDggfSwKCXsgJzknLCA5IH0seyAnYScsIDEwIH0seyAnQScsIDEwIH0sCgl7ICdiJywgMTEgfSx7ICdCJywgMTEgfSx7ICdjJywgMTIgfSwKCXsgJ0MnLCAxMiB9LHsgJ2QnLCAxMyB9LHsgJ0QnLCAxMyB9LAoJeyAnZScsIDE0IH0seyAnRScsIDE0IH0seyAnZicsIDE1IH0sCgl7ICdGJywgMTUgfSx7ICd4JywgMCB9LHsgJ1gnLCAwIH0gfTsKCmludCBoZXh0b2ludDIgKGNoYXIgbnVtYmVyKQp7CglyZXR1cm4gdGFibGVbKHN0ZDo6c2l6ZV90KW51bWJlcl07Cn0KCgppbnQgaGV4dG9pbnQ0KGNoYXIgbnVtYmVyKQp7CglpZiAobnVtYmVyID49ICcwJyAmJiBudW1iZXIgPD0gJzknKQoJCXJldHVybiBudW1iZXIgLSAnMCc7CgllbHNlIGlmIChudW1iZXIgPj0gJ2EnICYmIG51bWJlciA8PSAnZicpCgkJcmV0dXJuIG51bWJlciAtICdhJyArIDB4MGE7CgllbHNlIHJldHVybiAtMTsKfQoKc3RydWN0IE15dGFibGUgewoJaW50IHhbMTI4XTsKCU15dGFibGUoKSA6IHh7fQoJewoJCWZpbGwoYmVnaW4oeCksIGVuZCh4KSwgLTEpOyAKCQlmb3IgKGludCBpID0gJzAnOyBpIDw9ICc5JzsgaSsrKQoJCQl4W2ldID0gaSAtICcwJzsgIAoJCWZvciAoaW50IGkgPSAnQSc7IGkgPD0gJ0YnOyBpKyspCgkJCXhbaV0gPSB4W2ktJ0EnKydhJ10gPSBpIC0gJ0EnKzB4YTsKCX0KfTsKCmludCBoZXh0b2ludDUoY2hhciBudW1iZXIpCnsKCXN0YXRpYyBNeXRhYmxlIG15dGFibGU7CglyZXR1cm4gIChudW1iZXIgPCAwIHx8IG51bWJlcj4xMjgpID8gLTEgOiBteXRhYmxlLnhbbnVtYmVyXTsKfQoKaW50IGhleHRvaW50NihjaGFyIG51bWJlcikKewoJc3dpdGNoIChudW1iZXIpIHsKCWNhc2UgJzAnOiByZXR1cm4gMDsKCWNhc2UgJzEnOiByZXR1cm4gMTsKCWNhc2UgJzInOiByZXR1cm4gMjsKCWNhc2UgJzMnOiByZXR1cm4gMzsKCWNhc2UgJzQnOiByZXR1cm4gNDsKCWNhc2UgJzUnOiByZXR1cm4gNTsKCWNhc2UgJzYnOiByZXR1cm4gNjsKCWNhc2UgJzcnOiByZXR1cm4gNzsKCWNhc2UgJzgnOiByZXR1cm4gODsKCWNhc2UgJzknOiByZXR1cm4gOTsKCWNhc2UgJ0EnOiBjYXNlICdhJzogcmV0dXJuIDB4YTsKCWNhc2UgJ0InOiBjYXNlICdiJzogcmV0dXJuIDB4YjsKCWNhc2UgJ0MnOiBjYXNlICdjJzogcmV0dXJuIDB4YzsKCWNhc2UgJ0QnOiBjYXNlICdkJzogcmV0dXJuIDB4ZDsKCWNhc2UgJ0UnOiBjYXNlICdlJzogcmV0dXJuIDB4ZTsKCWNhc2UgJ0YnOiBjYXNlICdmJzogcmV0dXJuIDB4ZjsKCWRlZmF1bHQ6IHJldHVybiAtIDE7Cgl9Cn0KCmNvbnN0IGludCB2YXJpYW50cyA9IDU7IApjb25zdCBsb25nIGxvbmcgbWF4bG9vcCA9IDEwMDAwMDAwOyAKc3RydWN0IEJlbmNoIHsKCWludCgqZikoY2hhcik7IAoJY2hhciAqczsgCn0gYmVuY2hbdmFyaWFudHNdID0gewoJaGV4dG9pbnQxLCAiSWYgY2hhaW4gICAgICAgICAgICAgICAgIiwKCWhleHRvaW50MiwgIk1hcChubyBlcnJvciBwcm9jZXNzaW5nKSIsCgloZXh0b2ludDQsICJDb21wYWN0IGlmICAgICAgICAgICAgICAiLAoJaGV4dG9pbnQ1LCAiVGFibGUgYmFzZWQgICAgICAgICAgICAgIiwKCWhleHRvaW50NiwgIlN3aXRjaCAgICAgICAgICAgICAgICAgICIsCn07CgppbnQgbWFpbigpCnsKCW10MTk5MzcgZ2VuZXJhdG9yOwoJc3RkOjp1bmlmb3JtX2ludF9kaXN0cmlidXRpb248aW50PiBteXJhbmRvbSgwLCAxNik7IAoJY29uc3QgY2hhciAqcyA9ICIwMTIzNDU2Nzg5YWJjZGVmIjsKCXZvbGF0aWxlIGludCB4OwoKCWZvciAoaW50IGkgPSAwOyBpIDwgdmFyaWFudHM7IGkrKykgewoJCWNvdXQgPDwgYmVuY2hbaV0uczw8IiAiOyAKCQljaHJvbm86OmhpZ2hfcmVzb2x1dGlvbl9jbG9jazo6dGltZV9wb2ludCB0MSA9IGNocm9ubzo6aGlnaF9yZXNvbHV0aW9uX2Nsb2NrOjpub3coKTsgCgkJZm9yIChsb25nIGxvbmcgaiA9IDA7IGogPCBtYXhsb29wOyBqKyspIHsKCQkJY2hhciBjID0gc1tteXJhbmRvbShnZW5lcmF0b3IpXTsKCQkJeCA9IGJlbmNoW2ldLmYoYyk7IAoJCX0KCQljaHJvbm86OmhpZ2hfcmVzb2x1dGlvbl9jbG9jazo6dGltZV9wb2ludCB0MiA9IGNocm9ubzo6aGlnaF9yZXNvbHV0aW9uX2Nsb2NrOjpub3coKTsKCQlsb25nIGR0ID0gY2hyb25vOjpkdXJhdGlvbl9jYXN0PGNocm9ubzo6bWlsbGlzZWNvbmRzPih0MiAtIHQxKS5jb3VudCgpOyAKCQljb3V0IDw8IGR0IDw8ICIgbXMgZm9yICIgPDwgbWF4bG9vcCA8PCAiIGl0ZXJhdGlvbnMgPSAiIDw8IGR0ICogMTAwMDAwMCAvIG1heGxvb3AgPDwgIiBucy9pdCIgPDwgZW5kbDsgCgl9CgljaW4uZ2V0KCk7IAp9