import sys
import time
from copy import copy, deepcopy
from os import system, name


with open("17_input.txt") as f:
    content = f.readlines()

input_val = 2
screen = []
screen_row = []
lines = 0

var_MAIN = 'A,B,A,C,A,B,C,A,B,C\n'
var_A = 'R,8,R,10,R,10\n'
var_B = 'R,4,R,8,R,10,R,12\n'
var_C= 'R,12,R,4,L,12,L,12\n'
input_ALL = [65,44,66,44,65,44,67,44,65,44,66,44,67,44,65,44,66,44,67,10,82,44,56,44,82,44,49,48,44,82,44,49,48,10,82,44,52,44,82,44,56,44,82,44,49,48,44,82,44,49,50,10,82,44,49,50,44,82,44,52,44,76,44,49,50,44,76,44,49,50,10,121,10]
input_idx = 0
output_str = ''

prog = []
content = [x.strip() for x in content]
for line in content:
  values = line.split(',')
  for v in values:
    prog.append(long(v))

for i in range(0, 10000):
  prog.append(0)

pc = 0
base = 0
prog[0]=2

orig_prog = list(prog)
prog = list(orig_prog)

def get_intersections():
  global screen
  ap_sum = 0
  for y in range(0, len(screen)-2):
    for x in range(0, len(screen[0])):
      if x > 0 and x < len(screen[0]):
        if y > 0 and y < len(screen)-2:
          if screen[y][x] == '#' and screen[y-1][x] == '#' and screen[y+1][x] == '#' and screen[y][x-1] == '#' and screen[y][x+1] == '#':
            print "  INTERSECTION AT x=" + str(x) + " , y=" + str(y) + " ; AP = " + str(x*y)
            ap_sum += x*y
  print "TOTAL AP"
  print ap_sum

def print_char(a):
  global screen
  global screen_row
  if a == 10:
    screen.append(deepcopy(screen_row))
    screen_row = []
  else:
    screen_row.append(chr(a))
  return

def print_screen():
  global screen
  for r in screen:
    for c in r:
      sys.stdout.write(c)
    print ''
  get_intersections()
 
def get_arg(arg):
  global pc
  global prog
  global base
  global p1_mode
  global p2_mode
  global p3_mode

  #print "GET ARG " + str(arg) + " mode = " + str(p1_mode) + " base=" + str(base)
  if arg == 1:
    if p1_mode == 0:
      p = prog[prog[pc+1]]
    elif p1_mode == 2:
      p = prog[prog[pc+1]+base] 
    else:
      p = prog[pc+1]
  if arg == 2:
    if p2_mode == 0:
      p = prog[prog[pc+2]]
    elif p2_mode == 2:
      p = prog[prog[pc+2]+base]
    else:
      p = prog[pc+2]
  return p

def get_loc(arg):
  global pc
  global prog
  global base
  global p1_mode
  global p2_mode
  global p3_mode

  if arg == 1:
    if p1_mode == 0:
      p = prog[pc+1]
    else:
      p = prog[pc+1]+base
      #print "Returning : " + str(p)
  if arg == 3:
    if p3_mode == 0:
      p = prog[pc+3]
    else:
      p = prog[pc+3]+base
      #print "Returning : " + str(p)
  return p

pc = 0
while True:
  #print prog
  op = prog[pc]

  # Decode 5-digit op-code
  op_str = str(op)
  while len(op_str) < 5:
    op_str = '0' + op_str

  op_both = op_str[3] + op_str[4]
  op_both_int = long(op_both)

  op_code = long(op_str[3]+op_str[4])
  p1_mode = long(op_str[2])
  p2_mode = long(op_str[1])
  p3_mode = long(op_str[0])

  #print op_str
  #print "        " + str(prog[pc+1]) + " " + str(prog[pc+2]) + " " + str(prog[pc+3]) 

  if op == 99:
      print "EXIT"
      print_screen()
      sys.exit()

  if op_code == 1:
    p1 = get_arg(1)
    p2 = get_arg(2)
    out = get_loc(3)
    prog[out] = p1 + p2
    #print "   1: Add  (" + str(p1) + " + " + str(p2) + ") to " + str(out)
    pc = pc +4 
    continue

  if op_code == 2:
    p1 = get_arg(1)
    p2 = get_arg(2)
    out = get_loc(3)
    prog[out] = p1 * p2
    #print "   2: Mult (" + str(p1) + " * " + str(p2) + ") to " + str(out)
    pc = pc +4
    continue

  if op_code == 3:
    p1 = get_loc(1)
    input_val = var_MAIN
    var_MAIN = ''
    if input_val == '':
      input_val = var_A
      var_A = ''
    if input_val == '':
      input_val = var_B
      var_B = ''
    if input_val == '':
      input_val = var_C
      var_C = ''
    if input_val == '':
      input_val = 'n\n'

    input_val = input_ALL[input_idx]
    input_idx += 1
    prog[p1] = input_val
    if input_val == 121:
      lines = 0
    print "   3: Set [" + str(prog[pc+1]) + "] to " + str(input_val)
    pc = pc +2
    continue

  if op_code == 4:
    p1 = get_arg(1)
    print "   4: OUTPUT " + str(p1)
    output_str = output_str + chr(p1)
    if p1 == 10:
      print output_str.strip()
      lines += 1
      if lines > 43:
        #time.sleep(.05)
        #system('clear')
        lines = 0
        
      output_str = ''
    pc = pc +2
    continue

  # JUMP-IF-TRUE
  if op_code == 5:
    p1 = get_arg(1)
    p2 = get_arg(2)
    if p1 != 0:
      #print "   5: JUMP TAKEN"
      pc = p2
    else:
      #print "   5: Jump skipped"
      pc = pc + 3
    continue

  # JUMP-IF-FALSE
  if op_code == 6:
    p1 = get_arg(1)
    p2 = get_arg(2)
    if p1 == 0:
      #print "   6: JUMP TAKEN"
      pc = p2
    else:
      #print "   6: Jump skipped"
      pc = pc + 3
    continue

  # LESS THAN
  if op_code == 7:
    p1 = get_arg(1)
    p2 = get_arg(2)
    p3 = get_loc(3)
    if p1 < p2:
      #print "   7: Less Than True"
      prog[p3] = 1
    else:
      #print "   7: Less Than False"
      prog[p3] = 0
    pc = pc +4
    continue

  # EQUALS
  if op_code == 8:
    p1 = get_arg(1)
    p2 = get_arg(2)
    p3 = get_loc(3)
    if p1 == p2:
      #print "   8: Equals True, put 1 in " + str(p3)
      prog[p3] = 1
    else:
      #print "   8: Equals False, put 0 in " + str(p3)
      prog[p3] = 0
    pc = pc +4
    continue

  # ADJUST RELATIVE BASE OFFSET
  if op_code == 9:
    p1 = get_arg(1)
    base = base + p1
    pc = pc +2
    continue

