Solution for Day 1 Challenge. - #12
Conversation
\# Release Notes * Scaffolding for `click` application. * Scaffolding for `behave` tests. * Scaffolding for `pytest` tests. * Rules to ignore compiled python files. \# GitHub Resolves #11
alexanderilyin
left a comment
There was a problem hiding this comment.
Come up with nicer structure for examples/inputs.
| "wayou.vscode-todo-highlight", | ||
| "DavidAnson.vscode-markdownlint", | ||
| "GitHub.vscode-pull-request-github" | ||
| "GitHub.vscode-pull-request-github", |
There was a problem hiding this comment.
Not really useful so far...
| "DavidAnson.vscode-markdownlint", | ||
| "GitHub.vscode-pull-request-github" | ||
| "GitHub.vscode-pull-request-github", | ||
| "alexkrechik.cucumberautocomplete" |
There was a problem hiding this comment.
This is for syntax highlight in .feature files.
| "editor.renderWhitespace": "all", | ||
| "files.trimTrailingWhitespace": true, | ||
| "files.insertFinalNewline": true, | ||
| "editor.rulers": [80], |
There was a problem hiding this comment.
This helps avoiding super extra long lines, especially in .md files.
| @click.command() | ||
| @click.option('--input', default='puzzles/day1/example.txt') | ||
| def day1(input: str): | ||
| click.echo('Input: %s' % input) | ||
| with open(input) as fh: | ||
| lines = fh.read().splitlines() | ||
|
|
||
| values = CalibrationValues() | ||
|
|
||
| for line in lines: | ||
| click.echo("Processing '%s'" % line) | ||
| value = CalibrationValue(line) | ||
| values.values.append(value) | ||
|
|
||
| for value in values.values: | ||
| click.echo(value.get_value()) | ||
|
|
||
| click.echo("Sum: %s" % values.get_sum()) |
There was a problem hiding this comment.
Individual commands should be in separate files.
| # def apply_map(self, value: str, start: int = 0) -> str: | ||
| # while start < len(value): | ||
| # # TODO: start should be "first not numeric symbol" | ||
| # size_min = 1 + start | ||
| # # TODO: Use self.MAP to get size_max | ||
| # size_max = 5 + start | ||
| # for size in range(size_min, size_max + 1): | ||
| # logging.error("Size: %s", size) | ||
| # substring = value[start:size] | ||
| # logging.error("Processing value[%s:%s] '%s'", start, size, substring) | ||
| # if substring in self.MAP.keys(): | ||
| # logging.error("Found: %s", substring) | ||
| # value = value.replace(substring, self.MAP[substring], 1) | ||
| # logging.error("Replaced: %s", value) | ||
| # start = self.get_first_letter_position(value) | ||
| # if start is None: | ||
| # return value | ||
| # logging.error("New start: %s", start) | ||
| # value = self.apply_map(value, start) | ||
| # break | ||
| # start += 1 |
There was a problem hiding this comment.
Cleanup, this implementation did not support oneight cases...
| # TODO: Make sure that there are at least 2 digits | ||
| # TODO: Add cache | ||
| def get_first_digit(self) -> str: | ||
| logging.error("Processing: %s", self.value) | ||
| for symbol in self.apply_map(self.value): | ||
| if symbol.isnumeric(): | ||
| return symbol | ||
| raise Exception("First digit not found") | ||
|
|
||
| # TODO: Make sure that there are at least 2 digits | ||
| # TODO: Add cache | ||
| def get_last_digit(self) -> str: | ||
| for symbol in self.apply_map(self.value)[::-1]: | ||
| if symbol.isnumeric(): | ||
| return symbol | ||
| raise Exception("Last digit not found") |
There was a problem hiding this comment.
Reduce duplication somehow?
| class CalibrationValues: | ||
| values: List[CalibrationValue] = field(default_factory=list) | ||
|
|
||
| # TODO: Do not return 0 for empty list |
There was a problem hiding this comment.
Add unit test.
| def test_get_sum(self): | ||
| # Part 1 | ||
| cvs = CalibrationValues( | ||
| [ | ||
| CalibrationValue("1abc2"), | ||
| CalibrationValue("pqr3stu8vwx"), | ||
| CalibrationValue("a1b2c3d4e5f"), | ||
| CalibrationValue("treb7uchet") | ||
| ], | ||
| ) | ||
| assert cvs.get_sum() == 142 | ||
|
|
||
| # Part 2 | ||
| cvs = CalibrationValues( | ||
| [ | ||
| CalibrationValue("two1nine"), | ||
| CalibrationValue("eightwothree"), | ||
| CalibrationValue("abcone2threexyz"), | ||
| CalibrationValue("xtwone3four"), | ||
| CalibrationValue("4nineeightseven2"), | ||
| CalibrationValue("zoneight234"), | ||
| CalibrationValue("7pqrstsixteen"), | ||
| ], | ||
| ) | ||
| assert cvs.get_sum() == 281 |
There was a problem hiding this comment.
Use pytest parametrization.
| Scenario: example | ||
| Given newly-improved calibration document | ||
| | VALUE | | ||
| | 1abc2 | | ||
| | pqr3stu8vwx | | ||
| | a1b2c3d4e5f | | ||
| | treb7uchet | | ||
| When combining the first digit and the last digit on each line | ||
| Then calibration values are | ||
| | VALUE | | ||
| | 12 | | ||
| | 38 | | ||
| | 15 | | ||
| | 77 | | ||
| And the sum of all of the calibration values is "142" |
There was a problem hiding this comment.
Add scenarios for 2nd example and final input.
Release Notes
clickapplication.behavetests.pytesttests.GitHub
Resolves #11