• API
• FAQ
• Tools
• Archive
SHARE
TWEET

# sanitycheck.py

a guest Jul 19th, 2019 175 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
1. import re
2.
3. # Parses ostr into a list of boards
4. def parse(instr, ostr):
5.     numlines = instr.count('\n')+1
6.     i = 0
7.     boards = []
8.
9.     # Kinda hacky solution of counting each numlines lines as a board, due to flexible delimiting
10.     while i<len(ostr):
11.         currboard = ''
12.         for _ in range(numlines):
13.             if i>=len(ostr):
14.                 print("Incorrect formatting -- can't parse boards; weird number of non-empty lines")
15.                 exit(0)
16.             currboard += '\n' + ostr[i]
17.             i += 1
18.         boards.append(currboard.strip())
19.
20.     return boards
21.
22. # Makes sure the board is of the correct format
23. def check_format(instr, board):
24.     regex = instr.replace('v', '[v^]')
25.     return re.fullmatch(regex.strip(), board.strip())
26.
27. # Util function for check_combinations
28. def board_to_bitarray(board):
29.     switches = re.sub(r'[\n\-]', '', board)
30.     switches = switches.replace('v', '0').replace('^', '1')
31.     return int(switches, 2)
32.
33. # Makes sure we have all of the boards
34. def check_combinations(boards, numswitches):
35.     allnums = range(2**numswitches)
36.     counts = {num:0 for num in allnums}
37.     for board in boards:
38.         counts[board_to_bitarray(board)] += 1
39.
40.     missings = [num for num in allnums if counts[num]==0]
41.     extras = {num:counts[num] for num in allnums if counts[num]>1}
42.
43.     return missings, extras
44.
45. # Util for more useful error messages
46. # [bitarray_to_board(i, instr) for i in range(2**instr.count('v'))] is actually a valid solution to this challenge
47. def bitarray_to_board(bitarray, instr):
48.     swidxs = [match.start() for match in re.finditer('v', instr)]
49.     newboard = [char for char in instr] # because python strings are immutable
50.
51.     while bitarray!=0: # flip switches by bitshifting
52.         currbit = bitarray & 1
53.         if currbit:
54.             newboard[swidxs[-1]] = '^'
55.         swidxs = swidxs[:-1]
56.         bitarray = bitarray >> 1
57.
58.     return ''.join(newboard)
59.
60. if __name__=='__main__':
61.     # Get input and output
62.     with open('input') as fi:
64.     with open('output') as fo:
66.     ostr = [line.strip() for line in ostr if not line=='\n']
67.
68.     # Read boards from output; check for formatting
69.     boards = parse(instr, ostr)
70.     for idx, board in enumerate(boards):
71.         if not check_format(instr, board):
72.             print('Board incorrectly formatted:\n' + board
73.                     + ' starting at line ' + str(idx*(instr.count('\n')+1)+1) + '\n')
74.             exit(0)
75.
76.     # Check for correctness
77.     missings, extras = check_combinations(boards, instr.count('v'))
78.     if len(missings) > 0:
79.         for bitarray in missings:
80.             print('Missing board:\n' + bitarray_to_board(bitarray, instr) + '\n')
81.     if len(extras) > 0:
82.         for bitarray, count in extras.items():
83.             print('Extra boards:\n' + bitarray_to_board(bitarray, instr)
84.                     + ' appeared ' + str(count) + ' times\n')
85.     if len(missings)==0 and len(extras)==0:
86.         print('All correct!')
87.
88.     # Sample solution
89.     # with open('input') as fi: