Say I got a byte like this: 00010001 (with 2 bits ON)
And I wish to compare it to these bytes: {0000 0110, 0000 0011, 0011 0000, 0000 1100 }
The idea is to get the bytes that that don't match; where (byteA & byteX) == 0
For the example I should get/find: {0000 0110, 0000 1100 }
This maybe easy if we write a code where we loop the array of bytes.
Here an example:
byte seek = 17;
byte[] pool = {6, 3, 48, 12 };
for(int p=0; p<pool.Length; p++)
{
if((pool[p] & seek)==0)
{
//Usefull
}
}
Now I wish to do the same without looping the array.
Say the array is huge; and I wish to compare each byte with the rest.
for(int p1=0; p1<pool.Length; p1++)
{
for(int p2=0; p2<pool.Length; p1++)
{
if((pool[p1] & pool[p2])==0)
{
//byte at p1 works with byte at p2.
}
}//for p2
}//for p1
So what are my options?
A dictionary won't help me (i think) because if I have my seek byte 0001 0001
I will wan't to find a byte like this: XXX0 XXX0
Any ideas?
Thanks a lot for your help;
I welcome C#, C++ or any pseudocode.
I am looking for an algorithm; not so much the code
Mike
Here's an entirely different idea, that may or may not work well, depending on what's in your pool.
Put the entire pool into a zero suppressed binary decision diagram. The items from pool would be sets, where the indices for which the bit is 1 are elements of that set. The ZDD is the family of all those sets.
To do a query, form an other ZDD - the family of all sets that do not include the bits which are 1 in seek (that will be a small ZDD, in terms of nodes), then enumerate all sets in the intersection of those ZDD's.
Enumerating all those sets from the intersection is an output sensitive algorithm, but calculating the intersection takes time depending on how big the ZDD's are, so whether it works well depends on whether pool is a nice ZDD (the query zdd is definitely nice). And of course you have to prepare that ZDD, so in any case it'll only help if you plan to query the same pool often.
The great thing about bytes is there are only 256 possibilities.
You could initially create a 2d array 256x256 then just do a look-up into the array with your two values.
You could create the array before hand and then store the result in your main program as a static instance.
static bool[256,256] LookUp = {
{true, true, true ... },
...
{false, false, false ...}
};
static bool IsUsefule(byte a, byte b) {
return LookUp[a][b];
}
edit *
Or use Arrays of answer Arrays
The inner array would ONLY contain the bytes that are 'Useful'.
static List<<byte[]> LookUp = new List<byte[]>(256);
static byte[] IsUseful(byte a) {
return LookUp[a];
}
If 'a' = 0 then IsUseful would return the 255 bytes that have a bit set. This would avoid your inner loop from your example.
One fairly general solution is to "bit-transpose" your data so that you have e.g. a chunk of words containing all the high-order bits of your data, a chunk of words containing all the bits one position down from there, and so on. Then for your two-bit query, you or together two such chunks of words and look for 0 bits - so if a result word is -1 you can skip over it completely. To find where all the 0 bits are in word x, look at popcnt(x ^ (x + 1)): If x = ...10111, then x + 1 = ...11000 so x ^ (x + 1) = 000..01111 - and popcnt will then tell you where the lowest order 0 is. In practice, the big win may be when most of your data does not satisfy the query and you can skip over whole words: when you have a lot of matches the cost of query under any scheme may be small compared to the cost of whatever you plan to do with the matches. In a database, this is http://en.wikipedia.org/wiki/Bitmap_index - lots of info there and pointers to source code.
There are a number of ideas for querying 0/1 data in Knuth Vol 2 section 6.5 - "Binary attributes". Most of these require you to have some idea of the distribution of your data to recognise where they are applicable. One idea from there is generally applicable - if you have any sort of tree structure or index structure, you can keep in the nodes of the tree information on the or/and of everything under it. You can then check your query against that information and you may sometimes find that nothing below that node can possibly match your query, in which case you can skip it all. This is probably most useful if there are connections between the bits, so that e.g. if you divide the pool up just by sorting it and cutting it into chunks, even bits which do not affect the division into chunks are allways set in some chunks and never set in other chunks.
The only thing I can think of is to reduce number of tests:
for(int p1=1; p1<pool.Length; p1++)
{
for(int p2=0; p2<p1; p1++)
{
if((pool[p1] & pool[p2])==0)
{
//byte at p1 works with byte at p2.
//byte at p2 works with byte at p1.
}
}
}
First of all, my english is poor but I hope you understand. Also, I know that my answer is a bit late but I think is still useful.
As someone has pointed, best solution is generate a look up table.
With this purpose, you have to hardcode every loop iteration case in
an array.
Fortunately, we are working with bytes, so it is only possible 256
cases. For instance, if we take your pattern list {3, 6, 12, 48} we
get this table:
0: { 3, 6, 12, 48 }
1: { 6, 12, 48 }
2: { 12, 48 }
3: { 12, 48 }
3: { 12, 48 }
...
252: { 3 }
253: -
254: -
255: -
We use the input byte as an index in the look up table to get a list pattern values that doesn't match with the input byte.
Implementation:
I've used Python to generate two headers files. One with a look up table
definition, an other one with desired pattern list values. Then, I include this file in a new C project an that's all!
Python Code
#! /usr/bin/env python
from copy import copy
from time import *
import getopt
import sys
class LUPattern:
__LU_SZ = 256
BASIC_TYPE_CODE = "const uint8_t"
BASIC_ID_CODE = "p"
LU_ID_CODE = "lu"
LU_HEADER_CODE = "__LUPATTERN_H__"
LU_SZ_PATTLIST_ID_CODE = "SZ"
PAT_HEADER_CODE = "__PATTERNLIST_H__"
PAT_ID_CODE = "patList"
def __init__(self, patList):
self.patList = copy(patList)
def genLU(self):
lu = []
pl = list( set(self.patList) )
pl.sort()
for i in xrange(LUPattern.__LU_SZ):
e = []
for p in pl:
if (i & p) == 0:
e.append(p)
lu.append(e)
return lu
def begCode(self):
code = "// " + asctime() + "\n\n" \
+ "#ifndef " + LUPattern.LU_HEADER_CODE + "\n" \
+ "#define " + LUPattern.LU_HEADER_CODE + "\n" \
+ "\n#include <stdint.h>\n\n" \
return code
def luCode(self):
lu = self.genLU()
pDict = {}
luSrc = LUPattern.BASIC_TYPE_CODE \
+ " * const " \
+ LUPattern.LU_ID_CODE \
+ "[%i] = { \n\t" % LUPattern.__LU_SZ
for i in xrange(LUPattern.__LU_SZ):
if lu[i]:
pId = "_%i" * len(lu[i])
pId = pId % tuple(lu[i])
pId = LUPattern.BASIC_ID_CODE + pId
pBody = "{" + "%3i, " * len(lu[i]) + " 0 }"
pBody = pBody % tuple(lu[i])
pDict[pId] = pBody
luSrc += pId
else:
luSrc += "0"
luSrc += (i & 3) == 3 and (",\n\t") or ", "
luSrc += "\n};"
pCode = ""
for pId in pDict.keys():
pCode += "static " + \
LUPattern.BASIC_TYPE_CODE + \
" " + pId + "[] = " + \
pDict[pId] + ";\n"
return (pCode, luSrc)
def genCode(self):
(pCode, luSrc) = self.luCode()
code = self.begCode() \
+ pCode + "\n\n" \
+ luSrc + "\n\n#endif\n\n"
return code
def patCode(self):
code = "// " + asctime() + "\n\n" \
+ "#ifndef " + LUPattern.PAT_HEADER_CODE + "\n" \
+ "#define " + LUPattern.PAT_HEADER_CODE + "\n" \
+ "\n#include <stdint.h>\n\n"
code += "enum { " \
+ LUPattern.LU_SZ_PATTLIST_ID_CODE \
+ " = %i, " % len(self.patList) \
+ "};\n\n"
code += "%s %s[] = { " % ( LUPattern.BASIC_TYPE_CODE,
LUPattern.PAT_ID_CODE )
for p in self.patList:
code += "%i, " % p
code += "};\n\n#endif\n\n"
return code
#########################################################
def msg():
hmsg = "Usage: "
hmsg += "%s %s %s" % (
sys.argv[0],
"-p",
"\"{pattern0, pattern1, ... , patternN}\"\n\n")
hmsg += "Options:"
fmt = "\n%5s, %" + "%is" % ( len("input pattern list") + 3 )
hmsg += fmt % ("-p", "input pattern list")
fmt = "\n%5s, %" + "%is" % ( len("output look up header file") + 3 )
hmsg += fmt % ("-l", "output look up header file")
fmt = "\n%5s, %" + "%is" % ( len("output pattern list header file") + 3 )
hmsg += fmt % ("-f", "output pattern list header file")
fmt = "\n%5s, %" + "%is" % ( len("print this message") + 3 )
hmsg += fmt % ("-h", "print this message")
print hmsg
exit(0)
def getPatternList(patStr):
pl = (patStr.strip("{}")).split(',')
return [ int(i) & 255 for i in pl ]
def parseOpt():
patList = [ 255 ] # Default pattern
luFile = sys.stdout
patFile = sys.stdout
try:
opts, args = getopt.getopt(sys.argv[1:], "hp:l:f:", ["help", "patterns="])
except getopt.GetoptError:
msg()
for op in opts:
if op[0] == '-p':
patList = getPatternList(op[1])
elif op[0] == '-l':
luFile = open(op[1], 'w')
elif op[0] == '-f':
patFile = open(op[1], 'w')
elif op[0] == '-h':
msg()
return (patList, luFile, patFile)
def main():
(patList, luFile, patFile) = parseOpt()
lug = LUPattern(patList)
print >> luFile , lug.genCode()
print >> patFile, lug.patCode()
patFile.close()
luFile.close()
if __name__ == "__main__":
main()
C Code
Now, after call above script, it'll generate two files: lu.h and pl.h. We must to include
that files on our new C project.
Here a simple C code example:
#include "pl.h"
#include "lu.h"
#include <stdio.h>
int main(void)
{
uint32_t stats[SZ + 1] = { 0 };
uint8_t b;
while( fscanf(stdin, "%c", &b) != EOF )
{
(void)lu[b];
// lu[b] has bytes that don't match with b
}
return 0;
}
Test and benchmark:
I've done some extra stuff to check and get results. There are
more code which I've used as a test case unit but I don't paste here
(If you wish I'll paste later).
I make two similar versions of a same utility. One use look up table (noloop version)
an other one use typical loop (loop version).
loop code are slightly different than noloop code but I try to minimize these differences.
noloop version:
#include "pl.h"
#include "lu.h"
#include <stdio.h>
void doStats(const uint8_t * const, uint32_t * const);
void printStats(const uint32_t * const);
int main(void)
{
uint32_t stats[SZ + 1] = { 0 };
uint8_t b;
while( fscanf(stdin, "%c", &b) != EOF )
{
/* lu[b] has pattern values that not match with input b */
doStats(lu[b], stats);
}
printStats(stats);
return 0;
}
void doStats(const uint8_t * const noBitMatch, uint32_t * const stats)
{
uint8_t i, j = 0;
if(noBitMatch)
{
for(i = 0; noBitMatch[i] != 0; i++)
for(; j < SZ; j++)
if( noBitMatch[i] == patList[j] )
{
stats[j]++;
break;
}
}
else
stats[SZ]++;
}
void printStats(const uint32_t * const stats)
{
const uint8_t * const patList = lu[0];
uint8_t i;
printf("Stats: \n");
for(i = 0; i < SZ; i++)
printf(" %3i%-3c%9i\n", patList[i], ':', stats[i]);
printf(" ---%-3c%9i\n", ':', stats[SZ]);
}
loop version:
#include "pl.h"
#include <stdio.h>
#include <stdint.h>
#include <string.h>
void getNoBitMatch(const uint8_t, uint8_t * const);
void doStats(const uint8_t * const, uint32_t * const);
void printStats(const uint32_t * const);
int main(void)
{
uint8_t b;
uint8_t noBitMatch[SZ];
uint32_t stats[SZ + 1] = { 0 };
while( fscanf(stdin, "%c", &b ) != EOF )
{
getNoBitMatch(b, noBitMatch);
doStats(noBitMatch, stats);
}
printStats(stats);
return 0;
}
void doStats(const uint8_t * const noBitMatch, uint32_t * const stats)
{
uint32_t i;
uint8_t f;
for(i = 0, f = 0; i < SZ; i++)
{
f = ( (noBitMatch[i]) ? 1 : f );
stats[i] += noBitMatch[i];
}
stats[SZ] += (f) ? 0 : 1;
}
void getNoBitMatch(const uint8_t b, uint8_t * const noBitMatch)
{
uint8_t i;
for(i = 0; i < SZ; i++)
noBitMatch[i] = ( (b & patList[i]) == 0 ) ? 1 : 0;
}
void printStats(const uint32_t * const stats)
{
uint8_t i;
printf("Stats: \n");
for(i = 0; i < SZ; i++)
printf(" %3i%-3c%9i\n", patList[i], ':', stats[i]);
printf(" ---%-3c%9i\n", ':', stats[SZ]);
}
Both code perform same action: count bytes that not match with a concrete byte of pattern list (pl.h).
Makefile for compile them:
###
CC = gcc
CFLAGS = -c -Wall
SPDUP = -O3
DEBUG = -ggdb3 -O0
EXECUTABLE = noloop
AUXEXEC = loop
LU_SCRIPT = ./lup.py
LU_HEADER = lu.h
LU_PATLIST_HEADER = pl.h
#LU_PATLIST = -p "{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }"
#LU_PATLIST = -p "{ 3, 6, 12, 15, 32, 48, 69, 254 }"
LU_PATLIST = -p "{ 3, 6, 12, 48 }"
#LU_PATLIST = -p "{ 1, 2 }"
#LU_PATLIST = -p "{ 1 }"
LU_FILE = -l $(LU_HEADER)
LU_PAT_FILE = -f $(LU_PATLIST_HEADER)
SRC= noloop.c loop.c
SOURCE = $(EXECUTABLE).c
OBJECTS = $(SOURCE:.c=.o)
AUXSRC = $(AUXEXEC).c
AUXOBJ = $(AUXSRC:.c=.o)
all: $(EXECUTABLE) $(AUXEXEC)
lookup:
$(LU_SCRIPT) $(LU_PATLIST) $(LU_FILE) $(LU_PAT_FILE)
touch $(SRC)
$(EXECUTABLE): lookup $(OBJECTS)
$(CC) $(OBJECTS) -o $#
$(AUXEXEC): $(AUXOBJ)
$(CC) $(AUXOBJ) -o $#
.c.o:
$(CC) $(CFLAGS) $(SPDUP) -c $<
debug: lookup dbg
$(CC) $(OBJECTS) -o $(EXECUTABLE)
$(CC) $(AUXOBJ) -o $(AUXEXEC)
dbg: *.c
$(CC) $(CFLAGS) $(DEBUG) -c $<
clean:
rm -f $(EXECUTABLE) $(AUXEXEC) *.o &> /dev/null
.PHONY: clean
I've use three plain texts as input stream: gpl v3 plain text, Holy Bible plain text and linux kernel sources using recursive cat tool.
Executing this code with different pattern list give me this results:
Sat Sep 24 15:03:18 CEST 2011
Test1: test/gpl.txt (size: 35147)
---------------------------------------------------
Look up table version:
------------------------
Stats:
1: 18917
2: 22014
3: 12423
4: 19015
5: 11111
6: 12647
7: 7791
8: 23498
9: 13637
10: 16032
11: 9997
12: 14059
13: 9225
14: 8609
15: 6629
16: 25610
---: 0
real 0m0.016s
user 0m0.008s
sys 0m0.016s
Loop version:
------------------------
Stats:
1: 18917
2: 22014
3: 12423
4: 19015
5: 11111
6: 12647
7: 7791
8: 23498
9: 13637
10: 16032
11: 9997
12: 14059
13: 9225
14: 8609
15: 6629
16: 25610
---: 0
real 0m0.020s
user 0m0.020s
sys 0m0.008s
Test2: test/HolyBible.txt (size: 5918239)
---------------------------------------------------
Look up table version:
------------------------
Stats:
1: 3392095
2: 3970343
3: 2325421
4: 3102869
5: 1973137
6: 2177366
7: 1434363
8: 3749010
9: 2179167
10: 2751134
11: 1709076
12: 2137823
13: 1386038
14: 1466132
15: 1072405
16: 4445367
---: 3310
real 0m1.048s
user 0m1.044s
sys 0m0.012s
Loop version:
------------------------
Stats:
1: 3392095
2: 3970343
3: 2325421
4: 3102869
5: 1973137
6: 2177366
7: 1434363
8: 3749010
9: 2179167
10: 2751134
11: 1709076
12: 2137823
13: 1386038
14: 1466132
15: 1072405
16: 4445367
---: 3310
real 0m0.926s
user 0m0.924s
sys 0m0.016s
Test3: test/linux-kernel-3.0.4 (size: 434042620)
---------------------------------------------------
Look up table version:
------------------------
Stats:
1: 222678565
2: 254789058
3: 137364784
4: 239010012
5: 133131414
6: 146334792
7: 83232971
8: 246531446
9: 145867949
10: 161728907
11: 103142808
12: 147836792
13: 93927370
14: 87122985
15: 66624721
16: 275921653
---: 16845505
real 2m22.900s
user 3m43.686s
sys 1m14.613s
Loop version:
------------------------
Stats:
1: 222678565
2: 254789058
3: 137364784
4: 239010012
5: 133131414
6: 146334792
7: 83232971
8: 246531446
9: 145867949
10: 161728907
11: 103142808
12: 147836792
13: 93927370
14: 87122985
15: 66624721
16: 275921653
---: 16845505
real 2m42.560s
user 3m56.011s
sys 1m26.037s
Test4: test/gpl.txt (size: 35147)
---------------------------------------------------
Look up table version:
------------------------
Stats:
3: 12423
6: 12647
12: 14059
15: 6629
32: 2338
48: 1730
69: 6676
254: 0
---: 11170
real 0m0.011s
user 0m0.004s
sys 0m0.016s
Loop version:
------------------------
Stats:
3: 12423
6: 12647
12: 14059
15: 6629
32: 2338
48: 1730
69: 6676
254: 0
---: 11170
real 0m0.021s
user 0m0.020s
sys 0m0.008s
Test5: test/HolyBible.txt (size: 5918239)
---------------------------------------------------
Look up table version:
------------------------
Stats:
3: 2325421
6: 2177366
12: 2137823
15: 1072405
32: 425404
48: 397564
69: 1251668
254: 0
---: 1781959
real 0m0.969s
user 0m0.936s
sys 0m0.048s
Loop version:
------------------------
Stats:
3: 2325421
6: 2177366
12: 2137823
15: 1072405
32: 425404
48: 397564
69: 1251668
254: 0
---: 1781959
real 0m1.447s
user 0m1.424s
sys 0m0.032s
Test6: test/linux-kernel-3.0.4 (size: 434042620)
---------------------------------------------------
Look up table version:
------------------------
Stats:
3: 137364784
6: 146334792
12: 147836792
15: 66624721
32: 99994388
48: 64451562
69: 89249942
254: 5712
---: 105210728
real 2m38.851s
user 3m37.510s
sys 1m26.653s
Loop version:
------------------------
Stats:
3: 137364784
6: 146334792
12: 147836792
15: 66624721
32: 99994388
48: 64451562
69: 89249942
254: 5712
---: 105210728
real 2m32.041s
user 3m36.022s
sys 1m27.393s
Test7: test/gpl.txt (size: 35147)
---------------------------------------------------
Look up table version:
------------------------
Stats:
3: 12423
6: 12647
12: 14059
48: 1730
---: 11277
real 0m0.013s
user 0m0.016s
sys 0m0.004s
Loop version:
------------------------
Stats:
3: 12423
6: 12647
12: 14059
48: 1730
---: 11277
real 0m0.014s
user 0m0.020s
sys 0m0.000s
Test8: test/HolyBible.txt (size: 5918239)
---------------------------------------------------
Look up table version:
------------------------
Stats:
3: 2325421
6: 2177366
12: 2137823
48: 397564
---: 1850018
real 0m0.933s
user 0m0.916s
sys 0m0.036s
Loop version:
------------------------
Stats:
3: 2325421
6: 2177366
12: 2137823
48: 397564
---: 1850018
real 0m0.892s
user 0m0.860s
sys 0m0.052s
Test9: test/linux-kernel-3.0.4 (size: 434042620)
---------------------------------------------------
Look up table version:
------------------------
Stats:
3: 137364784
6: 146334792
12: 147836792
48: 64451562
---: 132949214
real 2m31.187s
user 3m31.289s
sys 1m25.909s
Loop version:
------------------------
Stats:
3: 137364784
6: 146334792
12: 147836792
48: 64451562
---: 132949214
real 2m34.942s
user 3m33.081s
sys 1m24.381s
Test10: test/gpl.txt (size: 35147)
---------------------------------------------------
Look up table version:
------------------------
Stats:
1: 18917
2: 22014
---: 6639
real 0m0.014s
user 0m0.016s
sys 0m0.008s
Loop version:
------------------------
Stats:
1: 18917
2: 22014
---: 6639
real 0m0.017s
user 0m0.016s
sys 0m0.008s
Test11: test/HolyBible.txt (size: 5918239)
---------------------------------------------------
Look up table version:
------------------------
Stats:
1: 3392095
2: 3970343
---: 881222
real 0m0.861s
user 0m0.848s
sys 0m0.032s
Loop version:
------------------------
Stats:
1: 3392095
2: 3970343
---: 881222
real 0m0.781s
user 0m0.760s
sys 0m0.044s
Test12: test/linux-kernel-3.0.4 (size: 434042620)
---------------------------------------------------
Look up table version:
------------------------
Stats:
1: 222678565
2: 254789058
---: 84476465
real 2m29.894s
user 3m30.449s
sys 1m23.177s
Loop version:
------------------------
Stats:
1: 222678565
2: 254789058
---: 84476465
real 2m21.103s
user 3m22.321s
sys 1m24.001s
Test13: test/gpl.txt (size: 35147)
---------------------------------------------------
Look up table version:
------------------------
Stats:
1: 18917
---: 16230
real 0m0.015s
user 0m0.020s
sys 0m0.008s
Loop version:
------------------------
Stats:
1: 18917
---: 16230
real 0m0.016s
user 0m0.016s
sys 0m0.008s
Test14: test/HolyBible.txt (size: 5918239)
---------------------------------------------------
Look up table version:
------------------------
Stats:
1: 3392095
---: 2526144
real 0m0.811s
user 0m0.808s
sys 0m0.024s
Loop version:
------------------------
Stats:
1: 3392095
---: 2526144
real 0m0.709s
user 0m0.688s
sys 0m0.040s
Test15: test/linux-kernel-3.0.4 (size: 434042620)
---------------------------------------------------
Look up table version:
------------------------
Stats:
1: 222678565
---: 201900739
real 2m21.510s
user 3m23.009s
sys 1m23.861s
Loop version:
------------------------
Stats:
1: 222678565
---: 201900739
real 2m22.677s
user 3m26.477s
sys 1m23.385s
Sat Sep 24 15:28:28 CEST 2011
Conclusions:
In my opinion, use of a look up table improve code execution by
increasing code size, but that improvment are not too much
significant. To start to notice differences, the amount input bytes should
be huge.
Related
I'm tryna make a random username generator (or at least a prototype)
Code I'm using is This:
def Usergenerator():
word1 = {
0: 'Good',
1: 'I',
2: 'yeet',
3: 'Not',
4: 'Fishe',
5: 'Xx',
6: 'Ucan',
7: 'Ultra',
8: 'Bald',
9: 'boom',
10: 'silly'
}
word2 = {
0: 'Milk',
1: 'Cat',
2: 'Dog',
3: 'poo',
4: 'ghost',
5: 'Fire',
6: 'xX',
7: 'June',
8: 'Lunar'
}
word3 = {
0: 'Foot',
1: 'Man',
2: 'Boy',
3: 'Poop',
4: 'Cell',
5: 'Wat',
6: 'Burn'
}
numbers = {
0: '12',
1: '60',
2: '45',
3: '11',
4: '22',
5: '33',
6: '78',
7: '16',
8: '55'
}
import random
a = 0
b = len(word1)
random = random.randint(a, b)
get = word1.get(random)
import random
a = 0
b = len(word2)
random = random.randint(a, b)
get2 = word2.get(random)
import random
a = 0
b = len(word3)
random = random.randint(a, b)
get3 = word3.get(random)
import random
a = 0
b = len(numbers)
random = random.randint(a, b)
get4 = numbers.get(random)
Username1 = get + get2 + get3 + get4
print(Username1)
Usergenerator()
The dictionaries maps numbers from 0 to whatever to a word
There are multiple that have different mappings and lengths
it first imports random, then generates a random number, and maps the random number onto the word
Then it sets "get" to the result
it does this about 4 times
Then it combines all of the give variables into one, called "Username"
then just prints Username out
this is all in a module which is then ran after its created
But I get this error:
File "c:/Users/why/are/you/here/you/creep.py", line 85, in Usergenerator
Username1 = get + get2 + get3 + get4
TypeError: can only concatenate str (not "NoneType") to str"
Turns out you have to format it so I had to do this:
Username = f'{get}{get2}{get3}{get4}'
print(Username)
I just answered my own question
I'm new to scala and I wonder whether it is possible to define generic math function that works with both BigInt and Int and in the case of Int the arguments of function will be treated as primitives (without any boxing and unboxing in function body).
So, for example I can do something like
def foo[#specialized(Int) T: Numeric](a: T, b: T) = {
val n = implicitly[Numeric[T]]
import n._
//some code with the use of operators '+-*/'
a * b - a * a + b * b * b
}
//works for primitive Int
val i1 : Int = 1
val i2 : Int = 2
val i3 : Int = foo(i1, i2)
//works for BigInt
val b1 : BigInt = BigInt(1)
val b2 : BigInt = BigInt(2)
val b3 : BigInt = foo(b1, b2)
Here in foo I can use all math operators for both primitive ints and BigInts (that is what I need). However, function foo(Int, Int) compiles to the following:
public int foo$mIc$sp(int a, int b, Numeric<Object> evidence$1) {
Numeric n = (Numeric)Predef..MODULE$.implicitly(evidence$1);
return BoxesRunTime.unboxToInt((Object)n.mkNumericOps(n.mkNumericOps(n.mkNumericOps((Object)BoxesRunTime.boxToInteger((int)a)).$times((Object)BoxesRunTime.boxToInteger((int)b))).$minus(n.mkNumericOps((Object)BoxesRunTime.boxToInteger((int)a)).$times((Object)BoxesRunTime.boxToInteger((int)a)))).$plus(n.mkNumericOps(n.mkNumericOps((Object)BoxesRunTime.boxToInteger((int)b)).$times((Object)BoxesRunTime.boxToInteger((int)b))).$times((Object)BoxesRunTime.boxToInteger((int)b))));
}
instead of plain:
//this is what I really need and expect from `#specialized(Int)`
public int foo$mIc$sp(int a, int b) {
return a * b - a * a + b * b * b;
}
which makes #specialized(Int) useless because the performance is unacceptably low with all these (un)boxings and unnecessary invocations n.mkNumericOps(...).
So, is there a way to implement such generic function as foo that will compile to "just as is" code for primitive types?
The problem is that the Numeric typeclass is not specialized.
If you want to do generic math with high performance, I highly recommend the spire math library.
It has a very elaborate mathematical type class hierarchy, instead of just Numeric.
Here is how your example would look using spire:
import spire.implicits._ // typeclass instances etc.
import spire.syntax._ // syntax such as +-*/
import spire.algebra._ // typeclassses such as Field
def foo[#specialized T: Field](a: T, b: T) = {
//some code with the use of operators '+-*/'
a * b - a * a + b * b * b
}
Here you are saying that there has to be a Field instance for T. Field refers to the algebraic concept.
Spire is highly modular:
spire.algebra contains many well known algebraic concepts such as groups, fields etc, encoded as scala typeclasses
spire.syntax contains the implicit conversions to add operators and other syntax to types for which typeclass instances are available
spire.implicits contains instances for the typeclasses in spire.algebra for common types such as JVM primitives.
This is why you need the three imports.
Regarding the performance: if your code is specialized, and you are using primitives, the performance will be exactly the same as working with primitives directly.
Here is the code of the foo method when specialized for Int:
public int foo$mIc$sp(int, int, spire.algebra.Field<java.lang.Object>);
Code:
0: aload_3
1: aload_3
2: aload_3
3: iload_1
4: iload_2
5: invokeinterface #116, 3 // InterfaceMethod spire/algebra/Field.times$mcI$sp:(II)I
10: aload_3
11: iload_1
12: iload_1
13: invokeinterface #116, 3 // InterfaceMethod spire/algebra/Field.times$mcI$sp:(II)I
18: invokeinterface #119, 3 // InterfaceMethod spire/algebra/Field.minus$mcI$sp:(II)I
23: aload_3
24: aload_3
25: iload_2
26: iload_2
27: invokeinterface #116, 3 // InterfaceMethod spire/algebra/Field.times$mcI$sp:(II)I
32: iload_2
33: invokeinterface #116, 3 // InterfaceMethod spire/algebra/Field.times$mcI$sp:(II)I
38: invokeinterface #122, 3 // InterfaceMethod spire/algebra/Field.plus$mcI$sp:(II)I
43: ireturn
Note that there is no boxing, and the invokeinterface calls will be inlined by the JVM.
For n variables, there exists 2^(2^n) distinct boolean functions. For example, if n=2, then there exists 16 possible boolean functions which can be written in sum of product form, or product of sum forms. The number of possible functions increases exponentially with n.
I am looking for an algorithm which can generate all these possible boolean rules for n variables. I have tried to search at various places, but have not found anything suitable till now. Most of the algorithms are related to simplifying or reducing boolean functions to standard forms.
I know even for the number of rules become too large even for n=8 or 9, but can somebody please help me out with the relevant algorithm if it exists?
A boolean function of n variables has 2^n possible inputs. These can be enumerated by printing out the binary representation of values in the range 0 <= x < 2^n.
For each one of the those possible inputs, a boolean function can output 0 or 1. To enumerate all the possibilities (i.e. every possible truth table). List the binary values in range 0 <= x < 2^(2^n).
Here's the algorithm in Python:
from __future__ import print_function
from itertools import product # forms cartesian products
n = 3 # number of variables
print('All possible truth tables for n =', n)
inputs = list(product([0, 1], repeat=n))
for output in product([0, 1], repeat=len(inputs)):
print()
print('Truth table')
print('-----------')
for row, result in zip(inputs, output):
print(row, '-->', result)
The output looks like this:
All possible truth tables for n = 3
Truth table
-----------
(0, 0, 0) --> 0
(0, 0, 1) --> 0
(0, 1, 0) --> 0
(0, 1, 1) --> 0
(1, 0, 0) --> 0
(1, 0, 1) --> 0
(1, 1, 0) --> 0
(1, 1, 1) --> 0
Truth table
-----------
(0, 0, 0) --> 0
(0, 0, 1) --> 0
(0, 1, 0) --> 0
(0, 1, 1) --> 0
(1, 0, 0) --> 0
(1, 0, 1) --> 0
(1, 1, 0) --> 0
(1, 1, 1) --> 1
Truth table
-----------
(0, 0, 0) --> 0
(0, 0, 1) --> 0
(0, 1, 0) --> 0
(0, 1, 1) --> 0
(1, 0, 0) --> 0
(1, 0, 1) --> 0
(1, 1, 0) --> 1
(1, 1, 1) --> 0
Truth table
-----------
(0, 0, 0) --> 0
(0, 0, 1) --> 0
(0, 1, 0) --> 0
(0, 1, 1) --> 0
(1, 0, 0) --> 0
(1, 0, 1) --> 0
(1, 1, 0) --> 1
(1, 1, 1) --> 1
... and so on
If you want the output in algebraic form rather than truth tables, the algorithm is the same:
from __future__ import print_function
from itertools import product # forms cartesian products
n = 3 # number of variables
variables = 'abcdefghijklmnopqrstuvwxyz'[:n]
pairs = [('~'+var, var) for var in variables]
print('All possible algebraic expressions for n =', n)
inputs = list(product(*pairs))
for i, outputs in enumerate(product([0, 1], repeat=len(inputs))):
terms = [''.join(row) for row, output in zip(inputs, outputs) if output]
if not terms:
terms = ['False']
print('Function %d:' % i, ' or '.join(terms))
The output looks like this:
All possible algebraic expressions for n = 3
Function 0: False
Function 1: abc
Function 2: ab~c
Function 3: ab~c or abc
Function 4: a~bc
Function 5: a~bc or abc
Function 6: a~bc or ab~c
Function 7: a~bc or ab~c or abc
Function 8: a~b~c
Function 9: a~b~c or abc
Function 10: a~b~c or ab~c
Function 11: a~b~c or ab~c or abc
Function 12: a~b~c or a~bc
Function 13: a~b~c or a~bc or abc
Function 14: a~b~c or a~bc or ab~c
Function 15: a~b~c or a~bc or ab~c or abc
Function 16: ~abc
Function 17: ~abc or abc
Function 18: ~abc or ab~c
Function 19: ~abc or ab~c or abc
Function 20: ~abc or a~bc
Function 21: ~abc or a~bc or abc
Function 22: ~abc or a~bc or ab~c
Function 23: ~abc or a~bc or ab~c or abc
Function 24: ~abc or a~b~c
Function 25: ~abc or a~b~c or abc
Function 26: ~abc or a~b~c or ab~c
Function 27: ~abc or a~b~c or ab~c or abc
Function 28: ~abc or a~b~c or a~bc
Function 29: ~abc or a~b~c or a~bc or abc
Function 30: ~abc or a~b~c or a~bc or ab~c
Function 31: ~abc or a~b~c or a~bc or ab~c or abc
Function 32: ~ab~c
Function 33: ~ab~c or abc
... and so on
As mentioned in comments, there's a one-to-one relation between numbers and truth tables. For example, we can represent the truth table
0 0 0 | 1
0 0 1 | 1
0 1 0 | 0
0 1 1 | 0
1 0 0 | 1
1 0 1 | 0
1 1 0 | 1
1 1 1 | 0
by the binary number 01010011 (the topmost row is represented by the least-significant bit).
It is obviously just a matter of looping over numbers to generate these representations:
for f := 0 to 2^(2^n) - 1:
# do something with f
What can we do with f? We can evaluate it, for example. Say we want to know f(0,1,0). It's as simple as interpreting the argument as the binary number x = 010 and doing some bit-magic:
def evaluate(f, x):
return (f & (1<<x)) != 0
We can also find its disjunctive normal form by just checking which bits are 0:
def dnf(f):
for x := 0 to 2^n - 1:
if f & (1<<x) != 0:
print binary(x) + " OR "
Giving a result like 000 OR 001 OR 100 OR 110 (OR) for the function above.
I've changed the code posted by Raymond Hettinger.
Now you can:
generate all Boolean expressions up to n_ary,
pick a particular function,
perform evaluation, and
get answers in binary or True/False manner.
Code:
from itertools import product
def allBooleanFunctions(kk):
"""Finds all Boolean functions for indegree kk"""
inputs1 = list(product([0, 1], repeat=kk))
variables = 'abcdefghijklmnopqrstuvwxyz'[:kk]
pairs = [('( not '+var+' )', var) for var in variables]
inputs = list(product(*pairs))
bool_func=[]
for i, outputs in enumerate(product([0, 1], repeat=len(inputs))):
terms = [' and '.join(row) for row, output in zip(inputs, outputs) if output]
if not terms:
terms = ['False']
bool_func.append(('('+(') or ('.join(terms))+')'))
return bool_func
n_ary=2 # number of inputs; keep it n_ary<=5
boolean_function_analytical=allBooleanFunctions(n_ary)
print('All Boolean functions of indegree:'+str(n_ary)+'\n')
print(boolean_function_analytical)
print
print('A Boolean function:'+'\n')
print(boolean_function_analytical[2])
# Evaluate third boolean function:
a=1 # first input
b=0 # second input
c=0 # third input
d=0 # fourth input
print('a='+str(a)+'; b='+str(b)+'; c='+str(c)+'; d='+str(d)+'\n')
print('Evaluation in 0/1 manner:')
print(int(eval((boolean_function_analytical[2]))))
print('Evaluation in True/False manner:')
print(bool(eval((boolean_function_analytical[2]))))
Result:
All Boolean functions of indegree:2
['(False)', '(a and b)', '(a and ( not b ))', '(a and ( not b )) or (a and b)', '(( not a ) and b)', '(( not a ) and b) or (a and b)', '(( not a ) and b) or (a and ( not b ))', '(( not a ) and b) or (a and ( not b )) or (a and b)', '(( not a ) and ( not b ))', '(( not a ) and ( not b )) or (a and b)', '(( not a ) and ( not b )) or (a and ( not b ))', '(( not a ) and ( not b )) or (a and ( not b )) or (a and b)', '(( not a ) and ( not b )) or (( not a ) and b)', '(( not a ) and ( not b )) or (( not a ) and b) or (a and b)', '(( not a ) and ( not b )) or (( not a ) and b) or (a and ( not b ))', '(( not a ) and ( not b )) or (( not a ) and b) or (a and ( not b )) or (a and b)']
A Boolean function:
(a and ( not b ))
a=1; b=0; c=0; d=0
Evaluation in 0/1 manner:
1
Evaluation in True/False manner:
True
Have fun!!!
This kind of usage is common while writing loops.
I was wondering if i >=0 will need more CPU cycles as it has two conditions greater than OR equal to when compared to i > -1. Is one known to be better than the other, and if so, why?
This is not correct. The JIT will implement both tests as a single machine language instruction.
And the number of CPU clock cycles is not determined by the number of comparisons to zero or -1, because the CPU should do one comparison and set flags to indicate whether the result of the comparison is <, > or =.
It's possible that one of those instructions will be more efficient on certain processors, but this kind of micro-optimization is almost always not worth doing. (It's also possible that the JIT - or javac - will actually generate the same instructions for both tests.)
On the contrary, comparsions (including non-strict) with zero takes one CPU instruction less. x86 architecture supports conditional jumps after any arithmetic or loading operation. It is reflected in Java bytecode instruction set, there is a group of instructions to compare the value on the top of the stack and jump: ifeq/ifgt/ifge/iflt/ifle/ifne. (See the full list). Comparsion with -1 requires additional iconst_m1 operation (loading -1 constant onto the stack).
The are two loops with different comparsions:
#GenerateMicroBenchmark
public int loopZeroCond() {
int s = 0;
for (int i = 1000; i >= 0; i--) {
s += i;
}
return s;
}
#GenerateMicroBenchmark
public int loopM1Cond() {
int s = 0;
for (int i = 1000; i > -1; i--) {
s += i;
}
return s;
}
The second version is one byte longer:
public int loopZeroCond();
Code:
0: iconst_0
1: istore_1
2: sipush 1000
5: istore_2
6: iload_2
7: iflt 20 //
10: iload_1
11: iload_2
12: iadd
13: istore_1
14: iinc 2, -1
17: goto 6
20: iload_1
21: ireturn
public int loopM1Cond();
Code:
0: iconst_0
1: istore_1
2: sipush 1000
5: istore_2
6: iload_2
7: iconst_m1 //
8: if_icmple 21 //
11: iload_1
12: iload_2
13: iadd
14: istore_1
15: iinc 2, -1
18: goto 6
21: iload_1
22: ireturn
It is slightly more performant on my machine (to my surprise. I expected JIT to compile these loops into identical assembly.)
Benchmark Mode Thr Mean Mean error Units
t.LoopCond.loopM1Cond avgt 1 0,319 0,004 usec/op
t.LoopCond.loopZeroCond avgt 1 0,302 0,004 usec/op
Сonclusion
Compare with zero whenever sensible.
I'm doing a project that involves comparing programming languages. I'm computing the Ackermann function. I tested Java, Python, and Ruby, and got responses between 10 and 30 milliseconds. But C++ seems to take 125 milliseconds. Is this normal, or is it a problem with the gettimeofday()? Gettimeofday() is in time.h.
I'm testing on a (virtual) Ubuntu Natty Narwhal 32-bit. I'm not short processing power (Quad-core 2.13 GHz Intel Xeon).
My code is here:
#include <iostream>
#include <sys/time.h>
using namespace std;
int a(int m,int n) {
if (m == 0) {
return n + 1;
} else if (m > 0 and n == 0) {
return a(m-1,1);
} else if (m > 0 and n > 0) {
return a(m-1,a(m,n-1));
}
}
int main() {
timeval tim;
gettimeofday(&tim,NULL);
double t1 = tim.tv_usec;
int v = a(3,4);
gettimeofday(&tim,NULL);
double t2 = tim.tv_usec;
cout << v << endl << t2-t1;
return 0;
}
Assuming you're talking about the resolution of the data returned, the POSIX specification for gettimeofday states:
The resolution of the system clock is unspecified.
This is due to the fact that systems may have a widely varying capacity for tracking small time periods. Even the ISO standard clock() function includes caveats like this.
If you're talking about how long it takes to call it, the standard makes no guarantees about performance along those lines. An implementation is perfectly free to wait 125 minutes before giving you the time although I doubt such an implementation would have much market success :-)
As an example of the limited resolution, I typed in the following code to check it on my system:
#include <stdio.h>
#include <sys/time.h>
#define NUMBER 30
int main (void) {
struct timeval tv[NUMBER];
int count[NUMBER], i, diff;
gettimeofday (&tv[0], NULL);
for (i = 1; i < NUMBER; i++) {
gettimeofday (&tv[i], NULL);
count[i] = 1;
while ((tv[i].tv_sec == tv[i-1].tv_sec) &&
(tv[i].tv_usec == tv[i-1].tv_usec))
{
count[i]++;
gettimeofday (&tv[i], NULL);
}
}
printf ("%2d: secs = %d, usecs = %6d\n", 0, tv[0].tv_sec, tv[0].tv_usec);
for (i = 1; i < NUMBER; i++) {
diff = (tv[i].tv_sec - tv[i-1].tv_sec) * 1000000;
diff += tv[i].tv_usec - tv[i-1].tv_usec;
printf ("%2d: secs = %d, usecs = %6d, count = %5d, diff = %d\n",
i, tv[i].tv_sec, tv[i].tv_usec, count[i], diff);
}
return 0;
}
The code basically records the changes in the underlying time, keeping a count of how many calls it took to gettimeofday() for the time to actually change. This is on a reasonably powerful machine so it's not short on processing power (the count indicates how often it was able to call gettimeofday() for each time quantum, around the 5,800 mark, ignoring the first since we don't know when in that quantum we started the measurements).
The output was:
0: secs = 1318554836, usecs = 990820
1: secs = 1318554836, usecs = 991820, count = 5129, diff = 1000
2: secs = 1318554836, usecs = 992820, count = 5807, diff = 1000
3: secs = 1318554836, usecs = 993820, count = 5901, diff = 1000
4: secs = 1318554836, usecs = 994820, count = 5916, diff = 1000
5: secs = 1318554836, usecs = 995820, count = 5925, diff = 1000
6: secs = 1318554836, usecs = 996820, count = 5814, diff = 1000
7: secs = 1318554836, usecs = 997820, count = 5814, diff = 1000
8: secs = 1318554836, usecs = 998820, count = 5819, diff = 1000
9: secs = 1318554836, usecs = 999820, count = 5901, diff = 1000
10: secs = 1318554837, usecs = 820, count = 5815, diff = 1000
11: secs = 1318554837, usecs = 1820, count = 5866, diff = 1000
12: secs = 1318554837, usecs = 2820, count = 5849, diff = 1000
13: secs = 1318554837, usecs = 3820, count = 5857, diff = 1000
14: secs = 1318554837, usecs = 4820, count = 5867, diff = 1000
15: secs = 1318554837, usecs = 5820, count = 5852, diff = 1000
16: secs = 1318554837, usecs = 6820, count = 5865, diff = 1000
17: secs = 1318554837, usecs = 7820, count = 5867, diff = 1000
18: secs = 1318554837, usecs = 8820, count = 5885, diff = 1000
19: secs = 1318554837, usecs = 9820, count = 5864, diff = 1000
20: secs = 1318554837, usecs = 10820, count = 5918, diff = 1000
21: secs = 1318554837, usecs = 11820, count = 5869, diff = 1000
22: secs = 1318554837, usecs = 12820, count = 5866, diff = 1000
23: secs = 1318554837, usecs = 13820, count = 5875, diff = 1000
24: secs = 1318554837, usecs = 14820, count = 5925, diff = 1000
25: secs = 1318554837, usecs = 15820, count = 5870, diff = 1000
26: secs = 1318554837, usecs = 16820, count = 5877, diff = 1000
27: secs = 1318554837, usecs = 17820, count = 5868, diff = 1000
28: secs = 1318554837, usecs = 18820, count = 5874, diff = 1000
29: secs = 1318554837, usecs = 19820, count = 5862, diff = 1000
showing that the resolution seems to be limited to no better than one thousand microseconds. Of course, your system may be different to that, the bottom line is that it depends on your implementation and/or environment.
One way to get around this type of limitation is to not do something once but to do it N times and then divide the elapsed time by N.
For example, let's say you call your function and the timer says it took 125 milliseconds, something that you suspect seems a little high. I would suggest then calling it a thousand times in a loop, measuring the time it took for the entire thousand.
If that turns out to be 125 seconds then, yes, it's probably slow. However, if it takes only 27 seconds, that would indicate your timer resolution is what's causing the seemingly large times, since that would equate to 27 milliseconds per iteration, on par with what you're seeing from the other results.
Modifying your code to take this into account would be along the lines of:
int main() {
const int count = 1000;
timeval tim;
gettimeofday(&tim, NULL);
double t1 = 1.0e6 * tim.tv_sec + tim.tv_usec;
int v;
for (int i = 0; i < count; ++i)
v = a(3, 4);
gettimeofday(&tim, NULL);
double t2 = 1.0e6 * tim.tv_sec + tim.tv_usec;
cout << v << '\n' << ((t2 - t1) / count) << '\n';
return 0;
}