I have two bytes that are made up of two 4-bit numbers packed together. I need to know if either of the two numbers from the first byte matches either of the numbers from the second byte. Zero is considered null and shouldn't match itself.
Obviously, I can do this by unpacking the numbers and comparing them one by one:
a = 0b10100101;
b = 0b01011111; // should have a match because 0101 is in both
a1 = a>>4; a2 = a&15;
b1 = b>>4; b2 = b&15;
return (a1 != 0 && (a1 == b1 || a1 == b2)) || (a2 != 0 && (a2 == b1 || a2 == b2));
// ( true && ( false || false )) || ( true && ( true || false ))
// ( true && false ) || ( true && true )
// false || true
// TRUE
However I'm just wondering if anyone knows of a cleaner way to do this?
Precompute the answer and store it in a lookup table. The key to your table is 16 bits ((a<<8)+b). It need only be 1 bit output (uses 8K), but you could use 8 bits for simplicity (uses 64K).
A cleaner way would be to get rid of that hard-to-parse expression and make the code more readable.
def sameNybble (a, b):
# Get high and low nybbles.
ahi = (a >> 4) & 15 ; alo = a & 15;
bhi = (b >> 4) & 15 ; blo = b & 15;
# Only check ahi if non-zero, then check against bhi/blo
if ahi != 0:
if ahi == bhi or ahi == blo:
return true
# Only check alo if non-zero, then check against bhi/blo
if alo != 0:
if alo == bhi or alo == blo:
return true
# No match
return false
Any decent optimising compiler will basically give you the same underlying code so it's sometimes better to optimise for readability.
Here is a solution in C++ that is more concise and 1.6 times faster. It generates code that is friendlier for high end microprocessors with deep pipelines and complex branch prediction logic. It generates true/false with no comparison/branches and no table lookup (no data cache miss).
A nibble has 4 bits and therefore holds one of 16 values, I map the two nibbles in each of the inputs to an unsigned value (which has at least 16 bits) with bits set in the corresponding bit positions indicating both nibble values present in the input. I then AND the two bitsets, thus computing the intersection of the sets. The last AND discards any matches with nibble 0.
inline unsigned set( unsigned char X ) {
return (1 << (X & 15)) | (1 << (X >> 4));
}
// Return true if a nibble in 'A' matches a non-null nibble in 'B'
inline bool match( unsigned char A, unsigned char B ) {
return set( A ) & set( B ) & ~set( 0 );
}
I've timed it on an Intel Xeon X5570 # 2.93GHz and it is 1.6x faster than the original in the question. Here's the code I used to time it:
#include <time.h>
#include <iostream>
bool original( unsigned char A, unsigned char B ) {
unsigned char a1 = A >> 4;
unsigned char a2 = A & 15;
unsigned char b1 = B >> 4;
unsigned char b2 = B & 15;
return (a1 != 0 && (a1 == b1 || a1 == b2)) || (a2 != 0 && (a2 == b1 || a2 == b2));
}
static inline unsigned set( unsigned char X ) {
return (1 << (X & 15)) | (1 << ((X >> 4)&15));
}
bool faster( unsigned char A, unsigned char B ) {
return set( A ) & set( B ) & ~set( 0 );
}
class Timer {
size_t _time;
size_t & _elapsed;
size_t nsec() {
timespec ts;
clock_gettime( CLOCK_REALTIME, &ts );
return ts.tv_sec * 1000 * 1000 * 1000 + ts.tv_nsec;
}
public:
Timer(size_t & elapsed) : _time(nsec()), _elapsed(elapsed) {}
~Timer() { _elapsed = nsec() - _time; }
};
int main()
{
size_t original_nsec, faster_nsec;
const size_t iterations = 200000000ULL;
size_t count = 0;
{ Timer t(original_nsec);
for(size_t i=0; i < iterations; ++i) {
count += original( 0xA5 , i & 0xFF );
}
}
{ Timer t(faster_nsec);
for(size_t i=0; i < iterations; ++i) {
count += faster( 0xA5 , i & 0xFF );
}
}
std::cout << double(original_nsec) / double(faster_nsec)
<< "x faster" << std::endl;
return count > 0 ? 0 : 1;
}
Here's the output:
$ g++ -o match -O3 match.cpp -lrt && ./match
1.61564x faster
$
Related
I tried to use Frama-c to prove the occurrence of true value in an array that is the same as a integer which used to record the number of true values. But the prove failed if I want to change some values false to true.
Is there any method to solve this problem?
(Frama-c 25.0 / Alt-Ergo 2.4.2 / CVC4 1.8 / Z3 4.8.6)
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define SIZE 150
bool table[SIZE] = {true};
int true_counter;
/*#
logic integer count_true(integer idx) =
idx<=0 ? 0 :
(table[idx-1]==true ? count_true(idx-1) + 1 : count_true(idx-1));
*/
/*#
requires table[0] == false;
requires true_counter == count_true(SIZE);
assigns table[0], true_counter;
ensures table[0] == true;
ensures true_counter == \old(true_counter) + 1;
*/
void ATEST(void) {
int countBF = 0;
int countAF = 0;
/*#
loop invariant 0 <= idx <= SIZE;
loop invariant 0 <= countBF == count_true(idx) <= idx;
loop assigns idx, countBF;
loop variant SIZE - idx;
*/
for(int idx=0; idx<SIZE; idx++) {
if(table[idx] == true) countBF += 1;
}
//# assert true_counter == countBF;
table[0] = true;
true_counter += 1;
/*#
loop invariant 0 <= idx <= SIZE;
loop invariant 0 <= countAF == count_true(idx) <= idx;
loop assigns idx, countAF;
loop variant SIZE - idx;
*/
for(int idx=0; idx<SIZE; idx++) {
if(table[idx] == true) countAF += 1;
}
//# assert true_counter == countAF;
//# assert countAF == countBF + 1;
}
[kernel] Parsing test.c (with preprocessing)
[rte:annot] annotating function ATEST
[wp] 33 goals scheduled
[wp] [Failed] Goal typed_ATEST_assert_2
Z3 4.8.6: Unknown (Qed:8ms) (cached)
CVC4 1.8: Timeout (Qed:8ms) (10s) (cached)
Alt-Ergo 2.4.2: Timeout (Qed:8ms) (10s) (cached)
[wp] [Cache] found:17
[wp] Proved goals: 32 / 33
Qed: 26 (0.84ms-7ms-24ms)
Alt-Ergo 2.4.2: 6 (7ms-13ms-27ms) (629) (interrupted: 1) (cached: 7)
CVC4 1.8: 4 (20ms-28ms-30ms) (11375) (interrupted: 1) (cached: 5)
Z3 4.8.6: 4 (10ms-20ms) (46252) (unknown: 1) (cached: 5)
The problem is that such a reasoning is not that direct. Here is what happen: when we write cell 0, WP creates a new memory whose properties are directly related to the old memory. The loop invariant of the first loop gives to the solver some information about the original memory, the loop invariant of the second loop gives information about the new memory. But for establishing the link between the two we need to learn something like "since only on value has changed, the remaining part has the same number of occurrences". Which is not possible with most SMT solvers.
For this particular example, we can be brutal and directly push the information in the invariant of the second loop:
/*#
loop invariant 0 <= idx <= SIZE;
loop invariant 0 <= countAF == count_true(idx) <= idx;
// added:
loop invariant idx >= 1 ==> countAF == 1 + count_true{Pre}(idx) <= idx;
loop assigns idx, countAF;
loop variant SIZE - idx;
*/
for(int idx=0; idx<SIZE; idx++) {
if(table[idx] == true) countAF += 1;
}
Which allows to create the link between the number of occurrences in the pre-state with the current number of occurrences. A more elegant solution is to dedicate a bit of ghost code so that it applies to any location:
/*#
requires 0 <= loc < SIZE ;
requires table[loc] == false;
requires true_counter == count_true(SIZE);
assigns table[loc], true_counter;
ensures table[loc] == true;
ensures true_counter == \old(true_counter) + 1;
*/
void ATEST(int loc) {
int countBF = 0;
int countAF = 0;
/*#
loop invariant 0 <= idx <= SIZE;
loop invariant 0 <= countBF == count_true(idx) <= idx;
loop assigns idx, countBF;
loop variant SIZE - idx;
*/
for(int idx=0; idx<SIZE; idx++) {
if(table[idx] == true) countBF += 1;
}
//# assert true_counter == countBF;
table[loc] = true;
true_counter += 1;
/*# ghost
/# loop invariant 0 <= i <= loc ;
loop invariant count_true(i) == count_true{Pre}(i);
loop assigns i;
loop variant loc - i ;
#/
for(int i = 0 ; i < loc ; i++);
/# loop invariant loc < i <= SIZE ;
loop invariant count_true(i) == 1 + count_true{Pre}(i);
loop assigns i;
loop variant SIZE - i ;
#/
for(int i = loc+1 ; i < SIZE ; i++);
*/
/*#
loop invariant 0 <= idx <= SIZE;
loop invariant 0 <= countAF == count_true(idx) <= idx;
loop assigns idx, countAF;
loop variant SIZE - idx;
*/
for(int idx=0; idx<SIZE; idx++) {
if(table[idx] == true) countAF += 1;
}
}
On can also express lemmas to handle the problem. For example the following lemmas can provide enough information to solvers so that they can finish the proof:
/*# lemma same_count{L1,L2}:
\forall integer size; 0<= size < SIZE ==>
(\forall integer i; 0 <= i < size ==> \at(table[i], L1) == \at(table[i],L2)) ==>
count_true{L1}(size) == count_true{L2}(size);
*/
/*# lemma same_but_one{L1,L2}:
\forall integer size; 0 <= size < SIZE ==>
\forall integer i_diff; 0 <= i_diff < size ==>
(\forall integer i; 0 <= i < size && i != i_diff ==> \at(table[i],L1) == \at(table[i],L2))
&& \at(table[i_diff],L1) == false && \at(table[i_diff],L2) == true
==>
count_true{L1}(size) + 1 == count_true{L2}(size);
*/
The first lemma states that an unchanged memory region keeps the same number of occurrences as before. The second states that when in a state a cell has true while in another it is false and all remaining cells are the same, the number of occurrences changes by one. These two lemmas can be verified via the induction tactic (see for example https://stackoverflow.com/a/73796135/4628125).
These two lemmas can be used directly by the solvers to get a proof for any location.
I am learning programming on my own at home. I'm interested in C right now and so, this is my first question. I have been trying to figure out why my code is not printing the right answer but I'm not sure what is wrong. I will attach the question and my code below. If some could help me figure out what I am doing wrong I'd be really grateful.
"Write a program that takes a string and displays it, replacing each of its
letters by the letter 13 spaces ahead in alphabetical order.
'z' becomes 'm' and 'Z' becomes 'M'. Case remains unaffected.
The output will be followed by a newline.
If the number of arguments is not 1, the program displays a newline."
I'm using command line arguments to read in a string "My horse is Amazing." and the expected output should be "Zl ubefr vf Nznmvat." but I am getting this as my output "Zå ubeÇr vÇ Nznçvat."
This is my code:
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv[]){
char ch, str[100], newStr[100];
int i, len;
if(argc != 2){
printf("\n");
return (-1);
}
strcpy(str, argv[1]);
len = strlen(str);
printf("%s %d\n\n", str, len);
for (i = 0; i < len; i++)
{
ch = str[i];
if ((ch >= 65) && (ch <= 90)){
ch = ch + 13;
if(ch > 90){
ch = ch - 90;
ch = ch + 64;
}
}else if ((ch >= 97) && (ch <= 122)){
ch = ch + 13;
if(ch > 122){
ch = ch - 122;
ch = ch + 96;
}
}
newStr[i] = ch;
}
printf("%s \n", newStr);
return 0;
}
ch is a signed 1-byte variable, meaning it can only represent values between -128 and 127. Adding 13 to y results in a value outside of that range.
I am having a QString :
QString str = "1000140035";
I want to extract each byte from above string like this :--
Unsigned char a = 0x10
Unsigned char b = 0x00
Unsigned char c = 0x14
Unsigned char d = 0x00
Unsigned char e = 0x35
Please suggest how to do this ... tried but failed many times.
QByteArray::fromHex + QString::toLatin1()
const QString str = "1000140035";
const QByteArray data = QByteArray::fromHex( str.toLatin1() );
unsigned char a = data[0];
unsigned char b = data[1];
unsigned char c = data[2];
unsigned char d = data[3];
unsigned char e = data[4];
You can use QString::toInt and set the base to 16 to convert a hex-string to int (or QString::toUInt).
QString str = "1000140035";
while(!str.isEmpty())
{
unsigned char byte = str.left(2).toInt(0, 16);
// do something with byte, store it somewhere or whatever...
str.remove(0, 2);
}
Perhaps this is what you're looking for? The code will parse an arbitrary length hexadecimal string and return an array of 2-digit hexadecimal numbers along with their count. It allocates memory for the result, so it is your responsibility to release it afterwards. The number of extracted numbers is returned through the third argument.
#include <QString>
#include <cmath>
unsigned HexToNum(char c)
{
if(c >= '0' && c <= '9')
return c - '0';
if(c >= 'A' && c <= 'F')
return 15 + c - 'A';
if(c >= 'a' && c <= 'f')
return 15 + c - 'a';
//Non hex char passed, return 0
return 0;
}
void ExtractBytes(const QString& hexString, unsigned char*& result, int& resultNumbersCount)
{
resultNumbersCount = static_cast<int>(ceil(hexString.length() / 2));
result = new unsigned char[resultNumbersCount];
int i, j = -1;
for(i = 0; i < resultNumbersCount; ++i)
result[i] = 0;
for(i = 0; i < hexString.length(); ++i)
{
if(i % 2 == 0)
++j;
result[j] = result[j] * 16 + HexToNum(hexString.at(i).toLatin1());
}
}
Please see the following Question recently posted on HackerRank
Adam is standing at point (a,b) in an infinite 2D grid. He wants to know if he can reach point (x,y) or not. The only operation he can do is to move to point (a+b,b), (a,a+b), (a-b,b), or (a,a-b) from some point (a,b). It is given that he can move to any point on this 2D grid,i.e., the points having positive or negative X(or Y) co-ordinates.Tell Adam whether he can reach (x,y) or not.
https://www.hackerrank.com/contests/infinitum-jun14/challenges/possible-path
I realized that both x and y must be a sum of some multiple of a and b...
So x%(a+b) OR x%(a-b) should be divisible by either a or b
and similarly for y...
But the following does not work ...
long long int xb,yb,xa,ya;
xb = x % b;
xa = x % a;
yb = y % b;
ya = y % a;
// for x
bool cxbaplusb = a+b==0 ? xb == 0: (xb%(a+b))==0;
bool cxbaminb = a-b==0 ? xb == 0: (xb%(a-b))==0;
// for y
bool cybaplusb = a+b==0 ? yb == 0: (yb%(a+b))==0;
bool cybaminb = a-b==0 ? yb == 0: (yb%(a-b))==0;
// for x
bool cxaaplusb = a+b==0 ? xa == 0: (xa%(a+b))==0;
bool cxaaminb = a-b==0 ? xa == 0: (xa%(a-b))==0;
// for y
bool cyaaplusb = a+b==0 ? ya == 0: (ya%(a+b))==0;
bool cyaaminb = a-b==0 ? ya == 0: (ya%(a-b))==0;
if ( (cxbaplusb || cxbaminb || cxaaplusb || cxaaminb) && (cybaplusb || cybaminb || cyaaplusb || cyaaminb) )
std::cout << "YES" << std::endl;
else
std::cout << "NO" << std::endl;
But this is not working ... Am I missing any conditions ? Any suggestions ??
The following mathematical explanation may help you achieve your goal.
Source: https://hr-filepicker.s3.amazonaws.com/infinitum-jun14/editorials/2372-possible-path.pdf
Please check the input size
1 ≤ a,b,x,y ≤ 10^18
https://www.hackerrank.com/challenges/possible-path
CPP won't support this much size, it will throw garbage value resulting in wrong answer
def gcd(a, b):
if(b == 0):
return a
return gcd(b, a%b)
t=input()
for i in range(t):
a = map(int, raw_input().split())
if(gcd(a[0],a[1]) == gcd(a[2],a[3])):
print "YES"
else:
print "NO"
#include<iostream>
using namespace std;
int gcd(int a, int b){
return b ? gcd(b, a%b) : a;
}
int main(){
int t;
cin >> t;
while (t--){
int a, b, x, y;
cin >> a >> b >> x >> y;
if (gcd(abs(a), abs(b)) == gcd(abs(x), abs(y)))
cout << "YES" << endl;
else
cout << "NO" << endl;
}
return 0;
}
Initially I had same doubt as you , but its not " x and y must be a sum of some multiple of a and b " because we can move from (a,b) to any point in (a+b,b), (a-b,b),(a,b+a),(a,b-a) in case if you move (a+b,b) now a=a+b,b=b so for this value of a,b ( not the given one here a is updated to a+b) only you can do the above operation so its not that x and y always must be sum of some multiple of a,b . so that you have to go with gcd method
public class Solution {
public static void main(String[] args) {
int a,b,x,y;
if(gcd(x,y)=gcd(a,b))
System.out.println("Adam can reach")
else
System.out.println("Adam cannot reach")
}
}
How do I convert an int, n, to a string so that when I send it over the serial, it is sent as a string?
This is what I have so far:
int ledPin=13;
int testerPin=8;
int n=1;
char buf[10];
void setup()
{
pinMode(ledPin, OUTPUT);
pinMode(testerPin, OUTPUT);
Serial.begin(115200);
}
void loop()
{
digitalWrite(ledPin, HIGH);
sprintf(buf, "Hello!%d", n);
Serial.println(buf);
delay(500);
digitalWrite(ledPin, LOW);
delay(500);
n++;
}
Use like this:
String myString = String(n);
You can find more examples here.
use the itoa() function included in stdlib.h
char buffer[7]; //the ASCII of the integer will be stored in this char array
itoa(-31596,buffer,10); //(integer, yourBuffer, base)
You can simply do:
Serial.println(n);
which will convert n to an ASCII string automatically. See the documentation for Serial.println().
You just need to wrap it around a String object like this:
String numberString = String(n);
You can also do:
String stringOne = "Hello String"; // using a constant String
String stringOne = String('a'); // converting a constant char into a String
String stringTwo = String("This is a string"); // converting a constant string into a String object
String stringOne = String(stringTwo + " with more"); // concatenating two strings
String stringOne = String(13); // using a constant integer
String stringOne = String(analogRead(0), DEC); // using an int and a base
String stringOne = String(45, HEX); // using an int and a base (hexadecimal)
String stringOne = String(255, BIN); // using an int and a base (binary)
String stringOne = String(millis(), DEC); // using a long and a base
This is speed-optimized solution for converting int (signed 16-bit integer) into string.
This implementation avoids using division since 8-bit AVR used for Arduino has no hardware DIV instruction, the compiler translate division into time-consuming repetitive subtractions. Thus the fastest solution is using conditional branches to build the string.
A fixed 7 bytes buffer prepared from beginning in RAM to avoid dynamic allocation. Since it's only 7 bytes, the cost of fixed RAM usage is considered minimum. To assist compiler, we add register modifier into variable declaration to speed-up execution.
char _int2str[7];
char* int2str( register int i ) {
register unsigned char L = 1;
register char c;
register boolean m = false;
register char b; // lower-byte of i
// negative
if ( i < 0 ) {
_int2str[ 0 ] = '-';
i = -i;
}
else L = 0;
// ten-thousands
if( i > 9999 ) {
c = i < 20000 ? 1
: i < 30000 ? 2
: 3;
_int2str[ L++ ] = c + 48;
i -= c * 10000;
m = true;
}
// thousands
if( i > 999 ) {
c = i < 5000
? ( i < 3000
? ( i < 2000 ? 1 : 2 )
: i < 4000 ? 3 : 4
)
: i < 8000
? ( i < 6000
? 5
: i < 7000 ? 6 : 7
)
: i < 9000 ? 8 : 9;
_int2str[ L++ ] = c + 48;
i -= c * 1000;
m = true;
}
else if( m ) _int2str[ L++ ] = '0';
// hundreds
if( i > 99 ) {
c = i < 500
? ( i < 300
? ( i < 200 ? 1 : 2 )
: i < 400 ? 3 : 4
)
: i < 800
? ( i < 600
? 5
: i < 700 ? 6 : 7
)
: i < 900 ? 8 : 9;
_int2str[ L++ ] = c + 48;
i -= c * 100;
m = true;
}
else if( m ) _int2str[ L++ ] = '0';
// decades (check on lower byte to optimize code)
b = char( i );
if( b > 9 ) {
c = b < 50
? ( b < 30
? ( b < 20 ? 1 : 2 )
: b < 40 ? 3 : 4
)
: b < 80
? ( i < 60
? 5
: i < 70 ? 6 : 7
)
: i < 90 ? 8 : 9;
_int2str[ L++ ] = c + 48;
b -= c * 10;
m = true;
}
else if( m ) _int2str[ L++ ] = '0';
// last digit
_int2str[ L++ ] = b + 48;
// null terminator
_int2str[ L ] = 0;
return _int2str;
}
// Usage example:
int i = -12345;
char* s;
void setup() {
s = int2str( i );
}
void loop() {}
This sketch is compiled to 1,082 bytes of code using avr-gcc which bundled with Arduino v1.0.5 (size of int2str function itself is 594 bytes). Compared with solution using String object which compiled into 2,398 bytes, this implementation can reduce your code size by 1.2 Kb (assumed that you need no other String's object method, and your number is strict to signed int type).
This function can be optimized further by writing it in proper assembler code.
The solution is much too big. Try this simple one. Please provide a 7+ character buffer, no check made.
char *i2str(int i, char *buf){
byte l=0;
if(i<0) buf[l++]='-';
boolean leadingZ=true;
for(int div=10000, mod=0; div>0; div/=10){
mod=i%div;
i/=div;
if(!leadingZ || i!=0){
leadingZ=false;
buf[l++]=i+'0';
}
i=mod;
}
buf[l]=0;
return buf;
}
Can be easily modified to give back end of buffer, if you discard index 'l' and increment the buffer directly.
This simply work for me:
int bpm = 60;
char text[256];
sprintf(text, "Pulso: %d ", bpm);
//now use text as string
In Arduino, using the String keyword creates an object of the String class which has multiple versions of its constructor. If an integer is passed as an argument while instantiating, it contains the ASCII representation of the numbers.
int num = 12;
String intString = String(num);
// The value of intString should be "12"
Please check out the arduino String reference.
Here below is a self composed myitoa() which is by far smaller in code, and reserves a FIXED array of 7 (including terminating 0) in char *mystring, which is often desirable. It is obvious that one can build the code with character-shift instead, if one need a variable-length output-string.
void myitoa(int number, char *mystring) {
boolean negative = number>0;
mystring[0] = number<0? '-' : '+';
number = number<0 ? -number : number;
for (int n=5; n>0; n--) {
mystring[n] = ' ';
if(number > 0) mystring[n] = number%10 + 48;
number /= 10;
}
mystring[6]=0;
}
Serial.println(val)
Serial.println(val, format)
for more you can visit to the site of arduino
https://www.arduino.cc/en/Serial/Println
wish this will help you.
thanks!