parent
a80f1ef819
commit
673000dfd2
@ -0,0 +1,358 @@ |
||||
#!/usr/bin/env python |
||||
|
||||
from aoc import get_input # AoC |
||||
import re # regex |
||||
|
||||
data = get_input(16).strip() |
||||
|
||||
stuff = data.split("\n\n") |
||||
|
||||
params = stuff[0].split("\n") |
||||
myticket = stuff[1].split("\n")[1] |
||||
tickets = stuff[2].split("\n") |
||||
tickets.pop(0) |
||||
|
||||
|
||||
def parseParam(param): |
||||
name, rnga1, rnga2, rngb1, rngb2 = re.match(r"([a-z\ ]+): ([0-9]+)-([0-9]+) or ([0-9]+)-([0-9]+)", param).groups() |
||||
|
||||
rng1 = range(int(rnga1), int(rnga2) + 1) |
||||
rng2 = range(int(rngb1), int(rngb2) + 1) |
||||
|
||||
return name, rng1, rng2 |
||||
|
||||
ranges = dict() |
||||
for i in range(len(params)): |
||||
par = params[i] |
||||
name, rng1, rng2 = parseParam(par) |
||||
ranges[name] = (rng1, rng2) |
||||
|
||||
|
||||
def parseTicket(ticket): |
||||
return [int(n) for n in ticket.split(",")] |
||||
|
||||
badvals = [] |
||||
|
||||
goodtickets = [ti for ti in tickets] |
||||
badtickets = [] |
||||
|
||||
for i in range(len(tickets)): |
||||
if( i > 0 ): |
||||
ticket = tickets[i] |
||||
vals = parseTicket(ticket) |
||||
|
||||
for v in vals: |
||||
checks = [] |
||||
for cl, rng in ranges.items(): |
||||
for r in rng: |
||||
checks.append( v in r ) |
||||
|
||||
valid = any(check for check in checks) |
||||
|
||||
if(not valid): |
||||
badvals.append(v) |
||||
break |
||||
|
||||
if( not valid ): |
||||
print(f"Bad: {ticket=} {any(checks)=}") |
||||
goodtickets.remove(ticket) |
||||
badtickets.append(ticket) |
||||
|
||||
|
||||
print("\nPart1:", sum(badvals)) |
||||
|
||||
# freeranges = ranges |
||||
|
||||
# def getClass(num): |
||||
# out = None |
||||
# for cl, rng in freeranges.items(): |
||||
# check1 = num in rng[0] |
||||
# check2 = num in rng[1] |
||||
# check = check1 or check2 |
||||
|
||||
# if(check): |
||||
# freeranges.pop(cl, None) |
||||
# out = cl |
||||
|
||||
# break |
||||
# else: |
||||
# continue |
||||
|
||||
# return out |
||||
|
||||
# def getClass2(num): |
||||
# out = None |
||||
# for cl, rng in ranges.items(): |
||||
# check1 = num in rng[0] |
||||
# check2 = num in rng[1] |
||||
# check = check1 or check2 |
||||
|
||||
# if(check): |
||||
# out = cl |
||||
|
||||
# break |
||||
# else: |
||||
# continue |
||||
|
||||
# return out |
||||
|
||||
# print( getClass(3) ) |
||||
# print( getClass(9) ) |
||||
# print( getClass(18) ) |
||||
# print("\n\n\n") |
||||
|
||||
import itertools |
||||
import operator |
||||
|
||||
def most_common(L): |
||||
SL = sorted((x, i) for i, x in enumerate(L)) |
||||
groups = itertools.groupby(SL, key=operator.itemgetter(0)) |
||||
def _auxfun(g): |
||||
item, iterable = g |
||||
count = 0 |
||||
min_index = len(L) |
||||
for _, where in iterable: |
||||
count += 1 |
||||
min_index = min(min_index, where) |
||||
return count, -min_index |
||||
return max(groups, key=_auxfun)[0] |
||||
|
||||
seenindex = [] |
||||
classIndex = dict() |
||||
|
||||
#goodtickets.insert( 0, myticket ) |
||||
print("####", len(goodtickets), "/" , len(tickets), "valid") |
||||
|
||||
goodtickets = [ parseTicket(t) for t in goodtickets ] |
||||
|
||||
|
||||
def possibleParams(num): |
||||
possible = [] |
||||
for cl, rng in ranges.items(): |
||||
check1 = num in rng[0] |
||||
check2 = num in rng[1] |
||||
check = check1 or check2 |
||||
|
||||
if(check): |
||||
print(f"POSSIBLE {num=} {cl=}") |
||||
possible.append(cl) |
||||
|
||||
return possible |
||||
|
||||
from collections import defaultdict as dd |
||||
|
||||
probIndex = dd(dict) |
||||
|
||||
#print("22222", goodtickets[0]) |
||||
|
||||
|
||||
# go through each param |
||||
# get possible indexs |
||||
# take least from possible |
||||
# add index to seen |
||||
|
||||
print(params) |
||||
|
||||
# for param, rng in ranges.items(): |
||||
# print("\nchecking param", param) |
||||
# possible = { |
||||
# 0: 0, |
||||
# 1: 0, |
||||
# 2: 0, |
||||
# 3: 0, |
||||
# 4: 0, |
||||
# 5: 0, |
||||
# 6: 0, |
||||
# 7: 0, |
||||
# 8: 0, |
||||
# 9: 0, |
||||
# 10: 0, |
||||
# 11: 0, |
||||
# 12: 0, |
||||
# 13: 0, |
||||
# 14: 0, |
||||
# 15: 0, |
||||
# 16: 0, |
||||
# 17: 0, |
||||
# 18: 0, |
||||
# 19: 0 |
||||
# } |
||||
|
||||
# for ticket in tickets: |
||||
# for i in range(len(parseTicket(ticket))): |
||||
# n = parseTicket(ticket)[i] |
||||
|
||||
# checks = [] |
||||
# for r in rng: |
||||
# checks.append( n in r ) |
||||
|
||||
# valid = any(check for check in checks) |
||||
|
||||
# print(f"Possible {rng=} {n=} {i=} {param=}", end="") |
||||
|
||||
# if(valid): |
||||
# print(" +1") |
||||
# possible[i] += 1 |
||||
# else: |
||||
# print("") |
||||
|
||||
# probIndex[param] = possible |
||||
|
||||
def numIsValid(num, rng): |
||||
checks = [] |
||||
for r in rng: |
||||
checks.append( num in r ) |
||||
|
||||
valid = any(check for check in checks) |
||||
return valid |
||||
|
||||
|
||||
for i in range( len(goodtickets[0]) ): |
||||
validcls = [] |
||||
|
||||
for ticket in goodtickets: |
||||
num = ticket[i] |
||||
|
||||
for cl, rng in ranges.items(): |
||||
valid = numIsValid(num, rng) |
||||
|
||||
if(valid): |
||||
validcls.append(cl) |
||||
|
||||
probIndex[i] = validcls |
||||
|
||||
|
||||
seenIndex = [] |
||||
seenValid = [] |
||||
paramPos = dict() |
||||
print("\n\nTHING") |
||||
|
||||
for chari in range( len(goodtickets[0]) ): |
||||
if( not chari in seenIndex ): |
||||
valids = probIndex[chari] |
||||
|
||||
least = 99999999 |
||||
leastparam = None |
||||
for v in valids: |
||||
if( valids.count(v) < least and not v in seenValid ): |
||||
least = valids.count(v) |
||||
leastparam = v |
||||
|
||||
print(f"{least=} {leastparam=} {valids=}") |
||||
|
||||
paramPos[chari] = leastparam |
||||
|
||||
seenIndex.append(chari) |
||||
seenValid.append(leastparam) |
||||
|
||||
print(paramPos) |
||||
|
||||
|
||||
# for param, pos in probIndex.items(): |
||||
# if(param in seen): |
||||
# continue |
||||
|
||||
# print("\n", param) |
||||
|
||||
# for i, val in probIndex[param].items(): |
||||
# print(i, val) |
||||
|
||||
|
||||
print(paramPos) |
||||
|
||||
# for i in range(len(goodtickets[0])): |
||||
# posParams = [ possibleParams( goodtickets[0][i] ) ] |
||||
|
||||
# for j in range(1, len(goodtickets)): |
||||
# tick = goodtickets[j] |
||||
# n = tick[i] |
||||
# pos = possibleParams( n ) |
||||
|
||||
# posParams.append(pos) |
||||
|
||||
# probIndex[i] = posParams |
||||
|
||||
|
||||
# print(len(probIndex[19])) |
||||
|
||||
# def checkParamForIndex(i, p): |
||||
# params = probIndex[i] |
||||
# # check = all( p in ticket for ticket in params ) |
||||
# # print("###############", check, len(params)) |
||||
|
||||
|
||||
|
||||
|
||||
# for i in range(len(goodtickets[0])): |
||||
# num = goodtickets[0][i] |
||||
# numcl = [ getClass(num) ] |
||||
|
||||
# for j in range(0, len(goodtickets)): |
||||
# tick = goodtickets[j] |
||||
# n = tick[i] |
||||
# nclass = getClass2(n) |
||||
# if(nclass): |
||||
# numcl.append(nclass) |
||||
|
||||
# common = most_common(numcl) |
||||
# same_count = numcl.count(common) |
||||
# r = (same_count / len(goodtickets)) * 100 |
||||
# print(f"{i=} {num=} {common=} {same_count=} {r=}% {numcl[0]=}") |
||||
# probIndex[common][i] = r |
||||
|
||||
# print(probIndex) |
||||
|
||||
# paramIndex = dict() |
||||
|
||||
# for parameter, probs in probIndex.items(): |
||||
# lastProb = 0 |
||||
# bestIndex = None |
||||
# for i, prob in probs.items(): |
||||
# if( prob > lastProb ): |
||||
# lastProb = prob |
||||
# bestIndex = i |
||||
|
||||
# paramIndex[parameter] = bestIndex |
||||
|
||||
# print("######", paramIndex) |
||||
|
||||
|
||||
# for ticket in tickets: |
||||
# if( ticket in badtickets ): |
||||
# continue |
||||
# #print(ticket) |
||||
|
||||
# p = parseTicket(ticket) |
||||
|
||||
# for i in range(len(p)): |
||||
# check = not i in seenindex |
||||
|
||||
# if( check ): |
||||
|
||||
# num = p[i] |
||||
# cl = getClass(num) |
||||
# classIndex[cl] = i |
||||
# seenindex.append(i) |
||||
|
||||
# continue |
||||
|
||||
|
||||
myticket = parseTicket(myticket) |
||||
thenums = [] |
||||
|
||||
# for cl, i in paramIndex.items(): |
||||
# if( "departure" in cl ): |
||||
# thenums.append( myticket[i] ) |
||||
|
||||
print(thenums) |
||||
|
||||
import math |
||||
|
||||
print(" 1409959524847 !=") |
||||
print("#",math.prod(thenums)) |
||||
print(" 21095351239483") |
||||
print(" 30145908219919 reverse") |
||||
|
||||
print(sum(thenums)) |
||||
|
||||
print(classIndex) |
Loading…
Reference in new issue