master
E. Almqvist 4 years ago
parent 673000dfd2
commit d3c088bd1f
  1. 311
      2020/16.py

@ -34,7 +34,6 @@ def parseTicket(ticket):
badvals = [] badvals = []
goodtickets = [ti for ti in tickets] goodtickets = [ti for ti in tickets]
badtickets = []
for i in range(len(tickets)): for i in range(len(tickets)):
if( i > 0 ): if( i > 0 ):
@ -56,293 +55,86 @@ for i in range(len(tickets)):
if( not valid ): if( not valid ):
print(f"Bad: {ticket=} {any(checks)=}") print(f"Bad: {ticket=} {any(checks)=}")
goodtickets.remove(ticket) goodtickets.remove(ticket)
badtickets.append(ticket)
print("\nPart1:", sum(badvals)) 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 = [] tickets = [parseTicket(t) for t in goodtickets]
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(): ticketlen = len(tickets[0])
# 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 = [] # make seen list for param and index
# for r in rng: #
# checks.append( n in r ) # go through all indexes, i=0
# make list of possibleParams for that i
# # go through all tickets for i
# # # go through all params
# # # # check if ticket[i] is in param range
# # # # # if not then remove param from iparams
# # # # # else next param
# take first param
# exclude param from list and exclude index from list
# next index
# valid = any(check for check in checks)
# print(f"Possible {rng=} {n=} {i=} {param=}", end="")
# if(valid): seenparams = []
# print(" +1") seenindex = []
# 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
paramsIndex = dict()
for i in range( len(goodtickets[0]) ): def getPosParams(i):
validcls = [] iparams = dict()
possibleParams = []
for p in params:
paramclass, rng1, rng2 = parseParam(p)
iparams[paramclass] = (rng1, rng2)
possibleParams.append(paramclass)
for ticket in goodtickets: for t in goodtickets:
ticket = parseTicket(t)
num = ticket[i] num = ticket[i]
for cl, rng in ranges.items(): for param, rng in iparams.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) check = num in rng[0] or num in rng[1]
if(not check and param in possibleParams):
possibleParams.remove(param)
else:
continue
return possibleParams
# for param, pos in probIndex.items():
# if(param in seen):
# continue
# print("\n", param) for i in range(ticketlen):
posparam = getPosParams(i)
posparam.sort(key=len)
print(posparam)
# for i, val in probIndex[param].items(): thisparam = None
# print(i, val)
for cl in posparam:
if(not cl in seenparams):
thisparam = cl
seenparams.append(cl)
break
print(paramPos) paramsIndex[i] = thisparam
# for i in range(len(goodtickets[0])): print("####", paramsIndex)
# posParams = [ possibleParams( goodtickets[0][i] ) ] thenums = []
# 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] for i, cl in paramsIndex.items():
# cl = getClass(num) print(f"{cl}: {parseTicket(myticket)[i]}")
# classIndex[cl] = i
# seenindex.append(i)
# continue if(cl):
if( "departure" in cl ):
thenums.append(parseTicket(myticket)[i])
myticket = parseTicket(myticket)
thenums = []
# for cl, i in paramIndex.items():
# if( "departure" in cl ):
# thenums.append( myticket[i] )
print(thenums) print(thenums)
@ -355,4 +147,3 @@ print(" 30145908219919 reverse")
print(sum(thenums)) print(sum(thenums))
print(classIndex)

Loading…
Cancel
Save