151 lines
4.6 KiB
Python
151 lines
4.6 KiB
Python
from numba import jit
|
|
import numpy as np
|
|
from time import time
|
|
|
|
|
|
file = open("input.txt").readlines()
|
|
data = []
|
|
for i in file:
|
|
i = i.strip()
|
|
bla = []
|
|
for j in i:
|
|
bla.append(j)
|
|
data.append(bla)
|
|
np_data = np.asarray(data)
|
|
#1_000_000_000
|
|
Part_2 = True
|
|
@jit(nopython = True)
|
|
def roll(arr, n, part):
|
|
for i in range(n):
|
|
#roll north
|
|
for line in range(1,len(arr)):
|
|
for char in range(len(arr[line])):
|
|
if arr[line][char] == "O":
|
|
p1 = line
|
|
p2 = char
|
|
while p1-1 >= 0 and arr[p1-1][p2] == ".":
|
|
p1-=1
|
|
arr[line][char], arr[p1][p2] = arr[p1][p2], arr[line][char]
|
|
if part:
|
|
#roll west
|
|
for line in range(len(arr)):
|
|
for char in range(1, len(arr[line])):
|
|
if arr[line][char] == "O":
|
|
p1 = line
|
|
p2 = char
|
|
while p2-1 >= 0 and arr[p1][p2-1] == ".":
|
|
p2-=1
|
|
arr[line][char], arr[p1][p2] = arr[p1][p2], arr[line][char]
|
|
#roll south
|
|
for line in range(len(arr)-2,-1,-1):
|
|
for char in range(len(arr[line])):
|
|
if arr[line][char] == "O":
|
|
p1 = line
|
|
p2 = char
|
|
while p1+1 < len(arr) and arr[p1+1][p2] == ".":
|
|
p1+=1
|
|
arr[line][char], arr[p1][p2] = arr[p1][p2], arr[line][char]
|
|
#roll east
|
|
for line in range(len(arr)):
|
|
for char in range(len(arr[line])-2,-1,-1):
|
|
if arr[line][char] == "O":
|
|
p1 = line
|
|
p2 = char
|
|
while p2+1 < len(arr[line]) and arr[p1][p2+1] == ".":
|
|
p2+=1
|
|
arr[line][char], arr[p1][p2] = arr[p1][p2], arr[line][char]
|
|
|
|
result = 0
|
|
for line in range(len(arr)):
|
|
line_num = len(arr) - line
|
|
count_O = 0
|
|
for i in arr[line]:
|
|
if i == "O":
|
|
count_O+=1
|
|
result+=count_O*line_num
|
|
return result, arr
|
|
|
|
|
|
def finde_laengste_folge(lst):
|
|
n = len(lst)
|
|
|
|
if n == 0:
|
|
return [], []
|
|
|
|
aktuelle_folge = []
|
|
laengste_folge = []
|
|
aktuelle_indices = []
|
|
laengste_indices = []
|
|
|
|
for i in range(n):
|
|
curr_num = lst[i]
|
|
pointer = i + 1
|
|
aktuelle_folge.append(curr_num)
|
|
aktuelle_indices.append(i)
|
|
repeat = False
|
|
while pointer+1 < len(lst) and (lst[pointer+1] != curr_num or len(aktuelle_folge) < 4):
|
|
aktuelle_folge.append(lst[pointer])
|
|
aktuelle_indices.append(pointer)
|
|
pointer+=1
|
|
if len(aktuelle_folge) > 100:
|
|
aktuelle_folge = []
|
|
aktuelle_indices = []
|
|
repeat = True
|
|
break
|
|
|
|
if repeat:
|
|
continue
|
|
|
|
try:
|
|
aktuelle_folge.append(lst[pointer])
|
|
aktuelle_indices.append(pointer)
|
|
except IndexError:
|
|
aktuelle_folge.append(lst[-1])
|
|
aktuelle_indices.append(len(lst)-1)
|
|
korr_folge = True
|
|
p1 = 0
|
|
p2 = i+len(aktuelle_folge)
|
|
# Prüfe ob sich die gefundene Folge widerholt
|
|
while p1 < len(aktuelle_folge):
|
|
try:
|
|
if aktuelle_folge[p1] != lst[p2]:
|
|
korr_folge = False
|
|
break
|
|
except IndexError:
|
|
korr_folge = False
|
|
break
|
|
p1+=1
|
|
p2+=1
|
|
|
|
if len(aktuelle_folge) > len(laengste_folge) and korr_folge:
|
|
laengste_folge = aktuelle_folge
|
|
laengste_indices = aktuelle_indices
|
|
aktuelle_folge = []
|
|
aktuelle_indices = []
|
|
|
|
if len(aktuelle_folge) > len(laengste_folge) and lst[-1] != aktuelle_folge[-1]:
|
|
laengste_folge = aktuelle_folge
|
|
laengste_indices = aktuelle_indices
|
|
|
|
return laengste_folge, laengste_indices
|
|
|
|
|
|
all_iters = []
|
|
idx = 0
|
|
for i in range(500):
|
|
np_data = np.asarray(data)
|
|
result = roll(np_data, i, Part_2)
|
|
all_iters.append(result[0])
|
|
idx+=1
|
|
print(i)
|
|
print()
|
|
laengste_folge, laengste_indices = finde_laengste_folge(all_iters)
|
|
mod = laengste_indices[-1] - laengste_indices[0] + 1
|
|
result = laengste_folge[(999999999 - laengste_indices[-1]) % mod]
|
|
print("laengste_folge={}, laengste_indices={}".format(laengste_folge, laengste_indices))
|
|
Part_2 = False
|
|
np_data = np.asarray(data)
|
|
print("Part 1: {} \n".format(roll(np_data,1, Part_2)[0]))
|
|
print("Part 2: {}".format(result))
|
|
input("...")
|