Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Christian Burns Developer Challenge #19

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
# Captivation Software Developer Challenge
# Captivation Software Developer Challenge - Christian Burns

## Installation Instructions

> The minimum required versions of [Python](https://www.python.org/) are 2.6 and 3.0.

You can check which version of Python you have installed via `python --version` or `python3 --version`.

This application can then run via `python /path/to/submission.py` or `python3 /path/to/submission.py` correspondingly.

## Your Task
Develop an application that:
Expand Down
61 changes: 61 additions & 0 deletions submission.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Captivation Software Developer Challenge Submission

This application reads a stream of 1's and 0's from STDIN and decodes the input
characters into single zero-padded ASCII text. When the application finds the
word "CAPTIVATION" within the input stream, it will print out the next one hundred
decoded characters following "CAPTIVATION" to STDOUT. This process repeats forever.

Author: Christian Burns
Date: June 30, 2021
See: https://github.com/captivationsoftware/DeveloperChallenge
"""

import sys
from collections import deque

preamble_string = 'CAPTIVATION' # Keyword to search for
num_characters_to_print = 100 # Number of characters to print after keyword

# Converting the preamble_string into its binary equivalent
preamble_binary = ''.join(format(ord(c), '08b') for c in preamble_string)
preamble_deque = deque(preamble_binary)
max_input_len = len(preamble_binary)

# --- Decode input stream from STDIN --- #

while True:

# --- Search for the preamble string --- #

rolling_input = None # Rolling queue of the last {max_input_len} binary values
preamble_found = False # True when rolling_input matches preamble_deque

while not preamble_found:
# Bulk read/insert the next {max_input_len} characters to avoid wasting
# time comparing queues prior to the queues reaching equal lengths.
if rolling_input is None:
characters = sys.stdin.read(max_input_len)
rolling_input = deque(characters, maxlen=max_input_len)

# Since the bits for the preamble message are not guaranteed to be well-aligned,
# we must iterate through STDIN one character at a time. For this reason, we
# utilize Python's builtin collections.deque list which has a time complexity
# of O(1) for inserting and removing items at either end to improve performance.
else:
character = sys.stdin.read(1)
rolling_input.append(character)

# We compare the rolling_input to a predefined preamble_deque
# to avoid unnecessary string manipulation/conversion.
if rolling_input == preamble_deque:
preamble_found = True

# --- Decode and print the next {num_characters_to_print} characters --- #

for _ in range(num_characters_to_print):
input_buffer = sys.stdin.read(8) # Each character is represented by 8 bits
ascii_number = int(input_buffer, 2) # Converting the bits into an ascii value
sys.stdout.write(chr(ascii_number)) # Converting the ascii value to character