Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python
- import math
- import argparse
- import sys
- parser = argparse.ArgumentParser(description="Generate a fizzbuzz print function")
- parser.add_argument('--file', metavar='filename', nargs='?', type=argparse.FileType(mode="w"),
- help='The file to write to', default = "autogen.c")
- args = vars(parser.parse_args())
- number_bits = 27
- int_bits = 27
- # characters in the integer is given by the base 10 log of the maximum number
- # but since we're two's complement, we subtract 1 power of two
- int_chars = int(math.ceil(math.log(2**(int_bits-1),10)))
- frac_chars = 0
- int_loc = 0
- length = int_chars
- ########
- bits = [2**i for i in range(0, int_bits)]
- # Ensure the patterns are up to snuff
- fmt = "%%0%d.%df"%(length, frac_chars)
- dec_patterns = [fmt%(b) for b in bits]
- #generate the list of contributory things
- fraction_patterns = [s[int_chars:] for s in dec_patterns]
- int_patterns = [s[:int_chars] for s in dec_patterns]
- # make a dictionary of dictionaries for fraction patterns.
- # Top level key: character in fraction [0, frac_chars)
- # Second level key: contributory bit
- # Second level value: resulting decimal digit
- ints = {i: {bit: int_patterns[bit][i] for bit in range(len(int_patterns))} for i in range(int_chars)}
- def int_poly(n):
- patterns = [(k,v) for k, v in ints[n].iteritems()]
- terms = ["(%c * bit%d)"%(p, bit) for bit, p in patterns if p != "0"]
- return " + ".join(terms)
- with args["file"] as f:
- f.write(
- """
- #include <stdint.h>
- /*********
- * This file is autogenerated by generate_fizzbuzz.py.
- * Please don't modify it manually.
- *********/
- void fizzbuzz(char* buffer, int f) {
- uint8_t isfizz = (f % 3) == 0;
- uint8_t isbuzz = (f % 5) == 0;
- uint8_t isfizzonly = isfizz & (!isbuzz);
- uint8_t isbuzzonly = isbuzz & (!isfizz);
- uint8_t isfizzbuzz = isfizz | isbuzz;
- uint32_t carry = 0;
- uint32_t scratch = 0;
- """)
- f.write("\n".join([" uint8_t bit%d = (((f) >> (%d))&1);"%(i,i) for i in range(0,number_bits)]))
- f.write("\n")
- extra_polynomials = {
- 0: " + (isfizz * %d) + (isbuzzonly * %d)"%(ord('F'), ord(' ')),
- 1: " + (isfizz * %d) + (isbuzzonly * %d)"%(ord('i'), ord(' ')),
- 2: " + (isfizz * %d) + (isbuzzonly * %d)"%(ord('z'), ord(' ')),
- 3: " + (isfizz * %d) + (isbuzzonly * %d)"%(ord('z'), ord(' ')),
- 4: " + (isfizzonly * %d) + (isbuzz * %d)"%(ord(' '), ord('B')),
- 5: " + (isfizzonly * %d) + (isbuzz * %d)"%(ord(' '), ord('u')),
- 6: " + (isfizzonly * %d) + (isbuzz * %d)"%(ord(' '), ord('z')),
- 7: " + (isfizzonly * %d) + (isbuzz * %d)"%(ord(' '), ord('z')),
- }
- def get_extra_poly(n):
- return extra_polynomials.get(n, "+ (isfizzbuzz * %d)"%(ord(' ')))
- for position in reversed(range(int_chars)):
- poly = int_poly(position)
- f.write(" scratch = %s + carry;\n"%(poly))
- f.write(" buffer[%d] = ((%d + (scratch %% 10)) * (1-(isfizz | isbuzz))) %s;\n"%(int_loc + position, ord('0'),
- get_extra_poly(int_loc+position)))
- f.write("carry = scratch / 10;\n")
- f.write(" buffer[%d] = '\\0';"%(length))
- f.write("""
- }""")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement