# Corruption Checksum — Python — #adventofcode Day 2

**Date:**

**Series:**Advent of Code 2017

Series

This post is part of the series Advent of Code 2017

- Reflections on #aoc2017
- The Halting Problem — Python — #adventofcode Day 25
- Electromagnetic Moat — Rust — #adventofcode Day 24
- Coprocessor Conflagration — Haskell — #adventofcode Day 23
- Sporifica Virus — Rust — #adventofcode Day 22
- Fractal Art — Python — #adventofcode Day 21
- Particle Swarm — Python — #adventofcode Day 20
- A Series of Tubes — Rust — #adventofcode Day 19
- Duet — Haskell — #adventofcode Day 18
- Spinlock — Rust/Python — #adventofcode Day 17
- Permutation Promenade — Julia — #adventofcode Day 16
- Dueling Generators — Rust — #adventofcode Day 15
- Disk Defragmentation — Haskell — #adventofcode Day 14
- Packet Scanners — Haskell — #adventofcode Day 13
- Digital Plumber — Python — #adventofcode Day 12
- Hex Ed — Python — #adventofcode Day 11
- Knot Hash — Haskell — #adventofcode Day 10
- Stream Processing — Haskell — #adventofcode Day 9
- I Heard You Like Registers — Python — #adventofcode Day 8
- Recursive Circus — Ruby — #adventofcode Day 7
- Memory Reallocation — Python — #adventofcode Day 6
- A Maze of Twisty Trampolines — C++ — #adventofcode Day 5
- High Entropy Passphrases — Python — #adventofcode Day 4
- Spiral Memory — Go — #adventofcode Day 3
- > Corruption Checksum — Python — #adventofcode Day 2 <
- Inverse Captcha — Coconut — #adventofcode Day 1
- Advent of Code 2017: introduction

Today’s challenge is to calculate a rather contrived “checksum” over a grid of numbers.

!!! commentary Today I went back to plain Python, and I didn’t do formal tests because only one test case was given for each part of the problem. I just got stuck in.

```
I did write part 2 out in as nested `for` loops as an intermediate step to working out the generator expression. I think that expanded version may have been more readable.
Having got that far, I couldn't then work out how to finally eliminate the need for an auxiliary function entirely without either sorting the same elements multiple times or sorting each row as it's read.
```

First we read in the input, split it and convert it to numbers. `fileinput.input()`

returns an iterator over the lines in all the files passed as command-line arguments, or over standard input if no files are given.

```
from fileinput import input
sheet = [[int(x) for x in l.split()] for l in input()]
```

Part 1 of the challenge calls for finding the difference between the largest and smallest number in each row, and then summing those differences:

```
print(sum(max(x) - min(x) for x in sheet))
```

Part 2 is a bit more involved: for each row we have to find the unique pair of elements that divide into each other without remainder, then sum the result of those divisions. We can make it a little easier by sorting each row; then we can take each number in turn and compare it only with the numbers *after* it (which are guaranteed to be larger). Doing this ensures we only make each comparison once.

```
def rowsum_div(row):
row = sorted(row)
return sum(y // x for i, x in enumerate(row) for y in row[i+1:] if y % x == 0)
print(sum(map(rowsum_div, sheet)))
```

We can make this code shorter (if not easier to read) by sorting each row as it’s read:

```
sheet = [sorted(int(x) for x in l.split()) for l in input()]
```

Then we can just use the first and last elements in each row for part 1, as we know those are the smallest and largest respectively in the sorted row:

```
print(sum(x[-1] - x[0] for x in sheet))
```

Part 2 then becomes a sum over a single generator expression:

```
print(sum(y // x for row in sheet
for i, x in enumerate(row)
for y in row[i+1:]
if y % x == 0))
```

Very satisfying!