12 votes

Day 10: Cathode-Ray Tube

Today's problem description: https://adventofcode.com/2022/day/10

Please post your solutions in your own top-level comment. Here's a template you can copy-paste into your comment to format it nicely, with the code collapsed by default inside an expandable section with syntax highlighting (you can replace python with any of the "short names" listed in this page of supported languages):

<details>
<summary>Part 1</summary>

```python
Your code here.
```

</details>

14 comments

  1. Crestwave
    Link
    I initially found part 2's instructions a bit confusing, but this was a cute one. Part 1 #!/usr/bin/awk -f function cycle(n,i) { for (i = 1; i <= n; ++i) { t += 1 if ((t - 20) % 40 == 0) sum += X...

    I initially found part 2's instructions a bit confusing, but this was a cute one.

    Part 1
    #!/usr/bin/awk -f
    function cycle(n,	i) {
    	for (i = 1; i <= n; ++i) {
    		t += 1
    		if ((t - 20) % 40 == 0)
    			sum += X * t
    	}
    }
    
    BEGIN { X = 1 }
    
    /noop/ { cycle(1) }
    /addx/ {
    	cycle(2)
    	X += $2
    }
    
    END { print(sum) }
    
    Part 2
    #!/usr/bin/awk -f
    function cycle(n,	i, j) {
    	for (i = 1; i <= n; ++i) {
    		j = t % 40
    
    		if (X == j - 1 || X == j || X == j + 1)
    			str = str "#"
    		else
    			str = str "."
    
    		if (j == 39)
    			str = str "\n"
    
    		t += 1
    	}
    }
    
    BEGIN { X = 1 }
    
    /noop/ { cycle(1) }
    /addx/ {
    	cycle(2)
    	X += $2
    }
    
    END { printf("%s", str) }
    
    5 votes
  2. primordial-soup
    (edited )
    Link
    Part 1, in Python-ish c, x = 0, 1 scores = [] def cycle(): global c c += 1 scores.append(c * x) for l in ls: cycle() if l != "noop": cycle() x += int(l.split()[1]) sum(scores[c] for c in (20 + 40...
    Part 1, in Python-ish
    c, x = 0, 1
    scores = []
    def cycle():
        global c
        c += 1
        scores.append(c * x)
    for l in ls:
        cycle()
        if l != "noop":
            cycle()
            x += int(l.split()[1])
    sum(scores[c] for c in (20 + 40 * i - 1 for i in range(6)))
    
    Python code generated from the above
    import sys
    from pyp import pypprint
    lines = [x.rstrip('\n') for x in sys.stdin]
    ls = lines
    (c, x) = (0, 1)
    scores = []
    
    def cycle():
        global c
        c += 1
        scores.append(c * x)
    for l in ls:
        cycle()
        if l != 'noop':
            cycle()
            x += int(l.split()[1])
    output = sum((scores[c] for c in (20 + 40 * i - 1 for i in range(6))))
    if output is not None:
        pypprint(output)
    
    Part 2, in Python-ish
    c, x = 0, 1
    screen = np.full((6, 40), False)
    def cycle():
        global c
        c += 1
        i, j = np.unravel_index(c - 1, screen.shape)
        screen[i, j] = x - 1 <= j <= x + 1
    for l in ls:
        cycle()
        if l != "noop":
            cycle()
            x += int(l.split()[1])
    for i in range(screen.shape[0]):
        for j in range(screen.shape[1]):
            print(" #"[screen[i, j]], end="")
        print()
    
    Python code generated from the above
    import sys
    import numpy as np
    lines = [x.rstrip('\n') for x in sys.stdin]
    ls = lines
    (c, x) = (0, 1)
    screen = np.full((6, 40), False)
    
    def cycle():
        global c
        c += 1
        (i, j) = np.unravel_index(c - 1, screen.shape)
        screen[i, j] = x - 1 <= j <= x + 1
    for l in ls:
        cycle()
        if l != 'noop':
            cycle()
            x += int(l.split()[1])
    for i in range(screen.shape[0]):
        for j in range(screen.shape[1]):
            print(' #'[screen[i, j]], end='')
        print()
    
    4 votes
  3. [4]
    primordial-soup
    Link
    the problem title appears to be missing from the tildes title today.

    the problem title appears to be missing from the tildes title today.

    2 votes
    1. [3]
      cfabbro
      Link Parent
      I usually edit it in once they get posted at midnight my time. I wasn't around though. It's done now.

      I usually edit it in once they get posted at midnight my time. I wasn't around though. It's done now.

      2 votes
      1. [2]
        primordial-soup
        Link Parent
        ah! i assumed it was done automatically. thanks for doing this :)

        ah! i assumed it was done automatically. thanks for doing this :)

        2 votes
        1. cfabbro
          Link Parent
          No prob. My pleasure. :)

          No prob. My pleasure. :)

          2 votes
  4. tomf
    (edited )
    Link
    This was an alright one. I think most sheetheads™️ will have a similar set of formulas. Part 1 and 2's inputs This in G2 if you're playing along at home. =ARRAYFORMULA( {1; SCAN(1,...

    This was an alright one. I think most sheetheads™️ will have a similar set of formulas.

    Part 1 and 2's inputs

    This in G2 if you're playing along at home.

    =ARRAYFORMULA(
      {1;
       SCAN(1,
        FILTER(FLATTEN(SPLIT(A2:A," ")),FLATTEN(SPLIT(A2:A," "))<>""),
        LAMBDA(a,v,a+IFERROR(--v)))}+{0,1})
    
    Part 1
    =SUM(BYROW(SEQUENCE(20,1,20,40),LAMBDA(x,x*INDEX(G2:G,x))))
    
    Part 2

    Merging a few columns, this will spit out the answer nicely, instead of spread out over a 6x40

    =ARRAYFORMULA(
      JOIN(
       CHAR(10),
       BYROW(
        SEQUENCE(6),
         LAMBDA(
          x,
          CONCATENATE(
           IFERROR(
            IF(
             ABS(
              SEQUENCE(40)-
              OFFSET(
               H2,
               x*40-40,0,40))<=1,
             "█"," ")))))))
    
    2 votes
  5. bhrgunatha
    (edited )
    Link
    Part 1 (define (part-01 input) (define xs (execute input)) (for/sum ([c (in-range 20 240 40)]) (* c (hash-ref xs c 0)))) (define (execute input) (for/fold ([x 1] [xs (hash 1 1)] [cycle 1] #:result...
    Part 1
    (define (part-01 input)
      (define xs (execute input))
      (for/sum ([c (in-range 20 240 40)])
        (* c (hash-ref xs c 0))))
    
    (define (execute input)
      (for/fold ([x 1]
                 [xs (hash 1 1)]
                 [cycle 1]
                 #:result xs)
                ([ins (in-list input)])
        (match (string-split ins)
          [(list "noop") (values x (hash-set xs (add1 cycle) x) (add1 cycle))]
          [(list "addx" n)
           (define x+ (+ x (string->number n)))
           (define cycle+ (+ cycle 2))
           (define xs+ (hash-set (hash-set xs (add1 cycle) x)
                                 cycle+ x+))
           (values x+ xs+ cycle+)])))
    
    Part 2

    At first I thought it was going to be a nightmare of off-by-ones, and decoding the timing, but it turned our to be really straightforward.
    I wrote my own letter decoder which I use in my answer here, but of course I drew the screen as well to check the example given. Both are included.

    (define (draw-screen screen)
      (for ([y (in-range 6)])
        (for ([x (in-range 40)])
          (printf "~a" (if (set-member? screen (list x y))
                           "#" ".")))
        (newline))
      (newline))
    
    (define ((pixel-on? screen) p) (set-member? screen p))
    (define (part-02 input)
      (define cpu (execute input))
      (for/fold ([screen (set)]
                 #:result (decode-letters-6x4 screen (pixel-on? screen) (bounds 0 39 0 5)))
                ([c (in-inclusive-range 1 240)])
        (define-values (y x) (quotient/remainder (sub1 c) 40))
        (define sprite (hash-ref cpu c))
        (if (<= (sub1 sprite) x (add1 sprite))
            (set-add screen (list x y))
            screen)))
    
    Speedrun

    Attempt 1: ~80% elapsed time
    The obvious thing again is to calculate the cpu state once and use that to determine the screen and the signal strength.

    (define (both-parts)
        (define cpu (execute input))
        (define letters
          (for/fold ([screen (set)]
                     #:result (decode-letters-6x4 screen (pixel-on? screen) (bounds 0 39 0 5)))
                    ([c (in-inclusive-range 1 240)])
            (define-values (y x) (quotient/remainder (sub1 c) 40))
            (define sprite (hash-ref cpu c))
            (if (<= (sub1 sprite) x (add1 sprite))
                (set-add screen (list x y))
                screen)))
        (list (for/sum ([c (in-range 20 240 40)])
                (* c (hash-ref cpu c 0)))
              letters))
    

    Attempt 2: ~65-70% elapsed time
    After a bit of thought, the signal strength can be calculated as the file is being read. This turned out to be conceptually simpler than I thought since the noop means we have to update the screen and potentially the signal strength, so always calculate those. If the instructions is an addx then update the screen and signal strength again for cycle + 1. I also changed the screen from a set of pixels co-ordinates to numbers since the cycle uniquely the co-ordinates.

    (with-input-from-file "day10.input"
         (thunk
          (for/fold ([sprite 1]
                     [cycle 1]
                     [signal 0]
                     [screen (seteq)]
                     #:result
                     (list signal
                           (decode-letters-6x4 screen (pixel2-on? screen) (bounds 0 39 0 5))))
                    ([ins (in-lines)])
            ;; common operations for addx & noop
            (define screen+ (update-screen screen cycle sprite))
            (define signal+ (update-signal signal cycle sprite))
            (define cycle+ (add1 cycle))
            (match (string-split ins)
              [(list "noop") (values sprite cycle+ signal+ screen+)]
              [(list "addx" n)
               ;; update both the screen and the signal a 2nd time for cycle + 1
               (values (+ sprite (string->number n))
                       (add1 cycle+)
                       (update-signal signal+ cycle+ sprite)
                       (update-screen screen+ cycle+ sprite))]))))
    

    Attempt 3: ~ 20% 33% elapsed time
    I'm a dirty liar! I miscalculated the increase it's not 20% it's 33%.

    Instead of keeping a set of on pixels, used a vector [240] and instead of using my slow-as-a-snail library to decode the string, use the vector to build up a full 40x6 string of pixels.

    (define on  (string-ref "▓" 0))
    (define off (string-ref "░" 0))
    
    (define (update-screen! screen cycle sprite)
      (define x (remainder (sub1 cycle) 40))
      (when (<= (sub1 sprite) x (add1 sprite))
        (vector-set! screen (sub1 cycle) on)))
    
    (define (update-signal signal cycle sprite)
      (if (zero? (remainder (+ cycle 20) 40))
          (+ signal (* cycle sprite))
          signal))
    
    (define (screen->string screen)
      (list->string
       (reverse
        (for/fold ([out null])
                  ([c (in-vector screen)]
                   [i (in-naturals)])
          (if (zero? (remainder i 40))
              (cons c (cons #\newline out))
              (cons c out))))))
    
    (with-input-from-file "day10.input"
      (thunk
       (define screen (make-vector 240 off))
       (for/fold ([sprite 1] [cycle 1] [signal 0]
                             #:result (list signal (screen->string screen)))
                 ([ins (in-lines)])
         ;; common operations for addx & noop
         (update-screen! screen cycle sprite)
         (define signal+ (update-signal signal cycle sprite))
         (define cycle+ (add1 cycle))
         (match (string-split ins)
           [(list "noop") (values sprite cycle+ signal+)]
           [(list "addx" n)
            ;; update both the screen and the signal a 2nd time for cycle + 1
            (update-screen! screen cycle+ sprite)
            (values (+ sprite (string->number n))
                    (add1 cycle+)
                    (update-signal signal+ cycle+ sprite))]))))
    

    And here's my output:

    14820
    ▓▓▓░░▓▓▓▓░▓▓▓▓░▓░░▓░▓▓▓▓░▓▓▓▓░▓░░▓░░▓▓░░
    ▓░░▓░░░░▓░▓░░░░▓░▓░░▓░░░░▓░░░░▓░░▓░▓░░▓░
    ▓░░▓░░░▓░░▓▓▓░░▓▓░░░▓▓▓░░▓▓▓░░▓▓▓▓░▓░░▓░
    ▓▓▓░░░▓░░░▓░░░░▓░▓░░▓░░░░▓░░░░▓░░▓░▓▓▓▓░
    ▓░▓░░▓░░░░▓░░░░▓░▓░░▓░░░░▓░░░░▓░░▓░▓░░▓░
    ▓░░▓░▓▓▓▓░▓▓▓▓░▓░░▓░▓▓▓▓░▓░░░░▓░░▓░▓░░▓░
    
    2 votes
  6. Eabryt
    Link
    Found this one pretty easy. I'm not a particularly fancy programmer, so my code tends to be pretty straightforward. Parts 1 and 2 from queue import Queue def part1(lines): print(f"Part 1!") x = 1...

    Found this one pretty easy. I'm not a particularly fancy programmer, so my code tends to be pretty straightforward.

    Parts 1 and 2
    from queue import Queue
    
    def part1(lines):
        print(f"Part 1!")
        x = 1
        q = Queue()
        for line in lines:
            if "noop" in line:
                q.put(0)
            if "addx" in line:
                amt = line.split()[1]
                q.put(0)
                q.put(int(amt))
        idx = 1
        sum = 0
        while not q.empty():
            num = q.get()
            x += num
            idx += 1
            if idx % 40 == 20:
                print(f"{idx} strength: {x * idx}")
                sum += x * idx
        print(f"Total Sum: {sum}")
    
    
    
    
    
    
    def part2(lines):
        print(f"Part 2!")
        x = 1
        q = Queue()
        for line in lines:
            if "noop" in line:
                q.put(0)
            if "addx" in line:
                amt = line.split()[1]
                q.put(0)
                q.put(int(amt))
        idx = 1
        crt = [[0 for z in range(40)] for y in range(6)]
        row = 0
        window = range(0,2)
        while not q.empty():
            num = q.get()
            x += num
            if ((idx-1) % 40) in window:
                crt[row][(idx-1) % 40] = '#'
            else:
                crt[row][(idx - 1) % 40] = '.'
            window = range(x-1, x + 2)
            if idx % 40 == 0:
                row += 1
            idx += 1
        print('\n'.join([''.join(['{:4}'.format(item) for item in row])
                         for row in crt]))
    
    
    
    def openFile():
        return open("input.txt", "r").readlines()
    
    
    def main():
        f = openFile()
        part1(f)
        part2(f)
    
    
    if __name__ == '__main__':
        main()
    
    2 votes
  7. kari
    Link
    I just finished day 7 last night and figured I'd do 10 before 8 and 9 since it seemed fairly easy. Well, part 1 was, but part 2's logic was confusing me for a bit... anyways. nim (both parts)...

    I just finished day 7 last night and figured I'd do 10 before 8 and 9 since it seemed fairly easy.

    Well, part 1 was, but part 2's logic was confusing me for a bit... anyways.

    nim (both parts)
    import std/strutils
    
    proc checkSignalStrength(cycle, regX: int): int {.inline.} =
      if (cycle - 20) mod 40 == 0:
        return cycle * regX
      return 0
    
    proc checkIfVisible(cycle, width, regX: int): char {.inline.} =
      if ((cycle - 1) mod width) in regX-1 .. regX+1:
        return '#'
      else:
        return '.'
    
    proc getRowCol(cycle, width: int): (int, int) {.inline.} =
      let row = (cycle - 1) div width
      let col = (cycle - 1) mod width
      return (row, col)
    
    proc day10*() =
      let
        height = 6
        width = 40
      var
        sumSignalStrengths = 0
        curCycle = 0
        regX = 1
        display: array[6, array[40, char]]
        row, col: int
    
      # Need to initialize the display
      for i in 0 ..< height:
        for j in 0 ..< width:
          display[i][j] = '.'
    
      for line in lines("inputs/day10.in"):
        let splitLine = line.splitWhitespace()
    
        # Invalid instructions are ignored
        # Assumes addx's 1st param is always an int (so it won't crash)
        # I could probably make more procs to make this nicer, but I'm lazy
        case splitLine[0]:
          of "noop":
            # 1st cycle
            curCycle += 1
    
            sumSignalStrengths += checkSignalStrength(curCycle, regX)
    
            (row, col) = getRowCol(curCycle, width)
            display[row][col] = checkIfVisible(curCycle, width, regX)
    
          of "addx":
            # 1st cycle
            curCycle += 1
    
            sumSignalStrengths += checkSignalStrength(curCycle, regX)
    
            (row, col) = getRowCol(curCycle, width)
            display[row][col] = checkIfVisible(curCycle, width, regX)
    
            # 2nd cycle
            curCycle += 1
    
            sumSignalStrengths += checkSignalStrength(curCycle, regX)
    
            (row, col) = getRowCol(curCycle, width)
            display[row][col] = checkIfVisible(curCycle, width, regX)
    
            # Operation
            regX += parseInt(splitLine[1])
          else:
            break
    
      echo "Part 1: " & $sumSignalStrengths
      echo "Part 2:"
      for row in display:
        var rowStr: string
        for col in row:
          rowStr &= col
        echo rowStr
    
    2 votes
  8. wycy
    Link
    Rust Rust use std::env; use std::io::{self, prelude::*, BufReader}; use std::fs::File; enum Status { Waiting, Processing, Done, } enum InstKind { Noop, Addx, } struct Instruction { kind: InstKind,...

    Rust

    Rust
    use std::env;
    use std::io::{self, prelude::*, BufReader};
    use std::fs::File;
    
    enum Status {
        Waiting,
        Processing,
        Done,
    }
    enum InstKind {
        Noop,
        Addx,
    }
    struct Instruction {
        kind: InstKind,
        value: Option<i64>,
        status: Status,
    }
    impl Instruction {
        fn from(s: &String) -> Self {
            let parts: Vec<_> = s.split(" ").collect();
            match parts[0] {
                "noop" => Self { kind: InstKind::Noop, value: None, status: Status::Waiting },
                "addx" => Self { kind: InstKind::Addx, value: Some(parts[1].parse().unwrap()), status: Status::Waiting },
                other => panic!("Unknown instruction: {other}"),
            }
        }
    }
    
    fn solve(input: &str) -> io::Result<()> {
        let file = File::open(input).expect("Input file not found.");
        let reader = BufReader::new(file);
    
        // Input
        let input: Vec<String> = match reader.lines().collect() {
            Err(err) => panic!("Unknown error reading input: {}", err),
            Ok(result) => result,
        };
    
        // Initializations
        let mut instructions: Vec<_> = input.iter().map(Instruction::from).collect();
        let mut reg: i64 = 1;
        let mut instr: usize = 0;
        let mut part1: i64 = 0;
        const PIX_PER_ROW: usize = 40;
        const NUM_ROWS: usize = 6;
        let mut screen = [[false; PIX_PER_ROW]; NUM_ROWS];
    
        // Processing
        'main_lp: for cyc in 1.. {
            if instr >= instructions.len() { break 'main_lp; }
            let ins = &instructions[instr];
    
            // Gather signal strengths
            match cyc {
                20 | 60 | 100 | 140 | 180 | 220 => {
                    println!("Cycle {cyc}, reg: {reg}, signal={}",cyc*reg);
                    part1 += cyc * reg;
                },
                _ => {},
            }
    
            // Handle instruction
            match ins.kind {
                InstKind::Noop => { instr += 1 },
                InstKind::Addx => {
                    match ins.status {
                        Status::Waiting => {
                            instructions[instr].status = Status::Processing;
                            },
                        Status::Processing => {
                            reg += ins.value.unwrap();
                            instructions[instr].status = Status::Done;
                            instr += 1; 
                            },
                        _ => panic!("Shouldn't be able to get here"),
                    }
                },
            }
    
            // Render image
            let row: usize = cyc as usize / PIX_PER_ROW;
            let col: usize = cyc as usize % PIX_PER_ROW;
            let coli = col as i64;
            let (px0,px1,px2) = (reg - 1, reg, reg + 1);
            if coli == px0 || coli == px1 || coli == px2 { screen[row][col] = true; }
        }
        println!("Part 1: {part1}"); // 13480
    
        // Part 2 Output: EGJBGCFK
        for y in 0..NUM_ROWS {
            for x in 0..PIX_PER_ROW {
                if screen[y][x] { print!("█"); } else { print!(" "); }
            }
            println!();
        }
    
        Ok(())
    }
    
    fn main() {
        let args: Vec<String> = env::args().collect();
        let filename = &args[1];
        solve(&filename).unwrap();
    }
    
    1 vote
  9. jzimbel
    Link
    Elixir Fun with streams! First time I've used Stream.transform/3. A bit tricky, but it made my code to get the signal value at each cycle super concise. Both parts defmodule...

    Elixir

    Fun with streams! First time I've used Stream.transform/3. A bit tricky, but it made my code to get the signal value at each cycle super concise.

    Both parts
    defmodule AdventOfCode.Solution.Year2022.Day10 do
      def part1(input) do
        input
        |> String.split("\n", trim: true)
        |> Stream.transform(1, &parse_cycles/2)
        |> Stream.drop(19)
        |> Stream.take_every(40)
        |> Stream.take(6)
        |> Enum.with_index(fn v, i -> (20 + 40 * i) * v end)
        |> Enum.sum()
      end
    
      def part2(input) do
        input
        |> String.split("\n", trim: true)
        |> Stream.transform(1, &parse_cycles/2)
        |> Stream.zip(Stream.cycle(0..39))
        |> Stream.map(fn
          {signal, draw} when abs(draw - signal) <= 1 -> ?#
          _ -> ?.
        end)
        |> Stream.chunk_every(40)
        |> Enum.intersperse(?\n)
        |> to_string()
      end
    
      defp parse_cycles("noop", v), do: {[v], v}
      defp parse_cycles(<<"addx ", n::binary>>, v), do: {[v, v], v + String.to_integer(n)}
    end
    
    1 vote
  10. Gyrfalcon
    Link
    This one I think I got a good handle on. I had some trouble with part 2 because I initially thought I would need to do something special to handle the order of events, but it turned out that...

    This one I think I got a good handle on. I had some trouble with part 2 because I initially thought I would need to do something special to handle the order of events, but it turned out that didn't matter, but what did matter was me forgetting that upper bounds are non inclusive and also that formatting multiline strings can be hard.

    Part 1 and 2, Python
    current_dir = os.path.realpath(os.path.dirname(__file__))
    INPUT_FILE = "/".join([current_dir, "input.txt"])
    TEST_FILE_1 = "/".join([current_dir, "test1.txt"])
    TEST_RESULTS_1 = (
        13140,
        (   
            "##..##..##..##..##..##..##..##..##..##..\n"
            "###...###...###...###...###...###...###.\n"
            "####....####....####....####....####....\n"
            "#####.....#####.....#####.....#####.....\n"
            "######......######......######......####\n"
            "#######.......#######.......#######....."
        ),
    )
    
    
    def process_command(command: List[str], signal_strength: int) -> List[int]:
    
        if command[0] == "noop":
            return [signal_strength]
    
        return [signal_strength, signal_strength + int(command[1])]
    
    
    def run_computer(commands: List[List[str]]) -> List[int]:
        
        signal_history = [1]
        signal_strength = 1
    
        for command in commands:
            signal_history.extend(process_command(command, signal_strength))
            signal_strength = signal_history[-1]
    
        return signal_history
    
    
    def analyze_signal(signal_history: List[int]) -> int:
    
        return sum((signal_history[idx] * (idx + 1) for idx in range(19, 220, 40)))
    
    
    def draw_screen(signal_history: List[int]) -> str:
        
        pixels: List[str] = []
        for idx in range(240):
            if abs((len(pixels) % 40) - signal_history[idx]) < 2:
                pixels.append("#")
            else:
                pixels.append(".")
    
        grid = ["".join(pixels[0 + idx : 40 + idx]) for idx in range(0, 201, 40)]
    
        return "\n".join(grid)
    
    
    def main(filepath: str) -> Tuple[int, str]:
    
        commands = [line.split() for line in load_file.load_cleaned_lines(filepath)]
        signal_history = run_computer(commands)
    
        return (analyze_signal(signal_history), draw_screen(signal_history))
    
    1 vote
  11. asterisk
    Link
    I had black out from 9 Dec to 22 Dec, yeah. But Iʼll try to do something. Python instructions: str = open("input.txt").read().split("\n") def execution(points: list, draw: bool = True): x: int = 1...

    I had black out from 9 Dec to 22 Dec, yeah. But Iʼll try to do something.

    Python
    instructions: str = open("input.txt").read().split("\n")
    
    
    def execution(points: list, draw: bool = True):
        x: int = 1
        cycles: int = 1
        output = str() if draw else int()
    
        for instruction in instructions:
            instruction = instruction.split(" ")
    
            for _ in instruction:
                if cycles in points:
                    if draw:
                        points.pop(0)
                    else:
                        output += x * cycles
    
                if draw:
                    if cycles - 1 - points[0] in range(x - 1, x + 1 + 1):
                        output += "#"
                    else:
                        output += "."
    
                cycles += 1
    
            if len(instruction) > 1:
                x += int(instruction[1])
    
        if draw:
            for h in range(high):
                print(output[h * wide : h * wide + wide])
        else:
            print(output)
    
    
    execution([20, 60, 100, 140, 180, 220], False)  # Part One: 15360
    
    wide: int = 40
    high: int = 6
    execution([x for x in range(0, wide * high, wide)])  # Part Two: PHLHJGZA
    
    1 vote