Skip to content

Commit

Permalink
feat: add LeetCode problem 65
Browse files Browse the repository at this point in the history
Solution for valid number
  • Loading branch information
MustafaAamir committed Nov 8, 2024
1 parent e5dad3f commit b376f32
Showing 1 changed file with 83 additions and 0 deletions.
83 changes: 83 additions & 0 deletions leetcode/src/65.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* Returns a boolean value of true if the input string is a valid number.
* Heavily optimized solution that utilizes branch prediction builtin's provided by
* GCC and clang.
* Uses a 4-bit bitset to track state of the program.
*
* Copyright (C) Mustafa Aamir <[email protected]>
* */


/* Defining branch prediction and inline macros */
#if defined(__GNUC__) || defined(__clang__)
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
#define _force_inline __attribute__((always_inline)) static inline
#else
#define likely(x) x
#define unlikely(x) x
#define _force_inline static inline
#endif

/* stdbool compatibility */
#ifndef __STDBOOL_H
#define bool int
#define true 1
#define false 0
#endif


/* Bitset to track the state of the program
* Going from MSB to LSB, a high value for each bit represents the following values:
* 1. decimal: '.' used
* 2. sign '+' or '-' seen
* 3. exponential 'E' or 'e' seen
* 4. Integer value {0..9} seen
*/
typedef struct {
unsigned flag : 4;
} state_t;

_force_inline bool isDigit(const char c) {
return (unsigned char)(c - '0') < 10;
}

_force_inline bool isNumber(const char *s) {
// initializing state bitset
state_t state = {0};

// performing checks on the first char of the input
if (unlikely(*s == '\0')) {
return false;
} else if (likely(isDigit(*s))) {
state.flag |= 0x1;
} else if (likely(*s == '+' || *s == '-')) {
state.flag |= 0x4;
} else if (*s == '.') {
state.flag |= 0x8;
} else {
return false;
}

// iterating over subsequent characters of the input string
while (likely(*++s != '\0')) {
if (likely(isDigit(*s))) {
state.flag |= 1;
continue;
}
switch (*s) {
case 'E': case 'e':
if (state.flag & 2 || !(state.flag & 1)) return false;
state.flag = 2; break;
case '+': case '-':
if (state.flag & 13) return false; // check for exp?
state.flag |= 4; break;
case '.':
if (unlikely(state.flag & 10)) return false;
state.flag |= 8; break;
default:
return false;
}
}
return state.flag & 1;
}

0 comments on commit b376f32

Please sign in to comment.