You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							105 lines
						
					
					
						
							2.5 KiB
						
					
					
				
			
		
		
	
	
							105 lines
						
					
					
						
							2.5 KiB
						
					
					
				#!/usr/bin/env julia
 | 
						|
 | 
						|
using Test
 | 
						|
 | 
						|
mutable struct Instruction
 | 
						|
  cycles :: UInt
 | 
						|
  add    :: Int
 | 
						|
end
 | 
						|
 | 
						|
function parse_instruction_line(line)
 | 
						|
  parts = split(line, limit=2)
 | 
						|
  if parts[1] == "noop"
 | 
						|
    return Instruction(1, 0)
 | 
						|
  elseif parts[1] == "addx"
 | 
						|
    return Instruction(2, parse(Int, parts[2]))
 | 
						|
  else
 | 
						|
    throw(DomainError("Unknown instruction: " * line))
 | 
						|
  end
 | 
						|
end
 | 
						|
 | 
						|
function signal_strength_sum(io; end_cycle=220)
 | 
						|
  X :: Int = 1
 | 
						|
  cycle :: Int = 1
 | 
						|
  signal_strength_sum :: Int = 0
 | 
						|
  next_test_cycle = 20
 | 
						|
  for line in eachline(io)
 | 
						|
    if mod(cycle - 20, 40) == 0 && cycle <= end_cycle
 | 
						|
      println(cycle, " ", X)
 | 
						|
      signal_strength_sum += cycle * X
 | 
						|
      next_test_cycle += 40
 | 
						|
    end
 | 
						|
    inst = parse_instruction_line(line)
 | 
						|
    new_cycle = cycle + inst.cycles
 | 
						|
    if new_cycle > next_test_cycle
 | 
						|
      signal_strength_sum += next_test_cycle * X
 | 
						|
      next_test_cycle += 40
 | 
						|
    end
 | 
						|
    cycle = new_cycle
 | 
						|
    X += inst.add
 | 
						|
  end
 | 
						|
  println("last inst cycle ", cycle)
 | 
						|
  signal_strength_sum += X * sum(filter(x -> x >= cycle, 20:40:end_cycle))
 | 
						|
  return signal_strength_sum
 | 
						|
end
 | 
						|
 | 
						|
function get_crt(io; end_cycle=240)
 | 
						|
  X :: Int = 2 # Note: add 1 to simplify 1-based indexing
 | 
						|
  pending_instruction :: Union{Instruction, Nothing} = nothing
 | 
						|
  screen = fill('.', (Int(ceil(end_cycle / 40)), 40))
 | 
						|
  nrows, ncols = size(screen)
 | 
						|
  for i in 1:nrows
 | 
						|
    for j in 1:ncols
 | 
						|
      if abs(X - j) <= 1
 | 
						|
        screen[i, j] = "#"[1]
 | 
						|
      else 
 | 
						|
        screen[i, j] = '.'
 | 
						|
      end
 | 
						|
 | 
						|
      if pending_instruction === nothing
 | 
						|
        if eof(io)
 | 
						|
          continue
 | 
						|
        end
 | 
						|
        inst = parse_instruction_line(readline(io))
 | 
						|
        pending_instruction = inst
 | 
						|
      end
 | 
						|
      pending_instruction.cycles -= 1
 | 
						|
      if pending_instruction.cycles == 0
 | 
						|
        X += pending_instruction.add
 | 
						|
        pending_instruction = nothing
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
  return join(reduce(*, screen, dims=2, init=""), "\n")
 | 
						|
end
 | 
						|
 | 
						|
function test()
 | 
						|
  @testset "signal strength sum" verbose=true begin
 | 
						|
    @test signal_strength_sum("example.txt") == 13140
 | 
						|
    @test signal_strength_sum("input.txt") == 13220
 | 
						|
  end
 | 
						|
  @testset "crt test" verbose=true begin
 | 
						|
    open("example.txt") do io
 | 
						|
      @test get_crt(io) == chomp(read("example_crt.txt", String))
 | 
						|
    end
 | 
						|
    open("input.txt") do io
 | 
						|
      @test get_crt(io) == chomp(read("input_crt.txt", String))
 | 
						|
    end
 | 
						|
  end
 | 
						|
end
 | 
						|
 | 
						|
function main()
 | 
						|
  if size(ARGS, 1) == 0
 | 
						|
    test()
 | 
						|
  else
 | 
						|
    infile = ARGS[1]
 | 
						|
    println("infile = ", infile)
 | 
						|
    println("signal strength sum = ", signal_strength_sum(infile))
 | 
						|
    open(infile, "r") do io
 | 
						|
      println(get_crt(io))
 | 
						|
    end
 | 
						|
  end
 | 
						|
end
 | 
						|
 | 
						|
main()
 |