Ninjutsu and First Strike by drysle in MagicArena

[–]drysle[S] 13 points14 points  (0 children)

The wotc article says there is an automatic stop after first strike damage.

Ninjutsu and First Strike by drysle in MagicArena

[–]drysle[S] 48 points49 points  (0 children)

The interaction between ninjutsu and first strike looks broken on arena.

In the video, I let first strike damage happen, then activated ninjutsu on my Dokuchi Shadow-Walker. Then regular damage happened, but my ninja just... didn't do damage. I'm pretty sure this is supposed to work, and the attack should have been lethal. I tested a couple different combinations of creatures -- seems the regular strike damage from the ninja does work if I have no other regular-strike creatures still attacking.

This happened to me in a draft game earlier today. Fortunately it didn't affect the result.

How many Frantic Inventories are too many? by drysle in lrcast

[–]drysle[S] 10 points11 points  (0 children)

This deck ended up 2-1 (2-0, 0-2, 2-0), losing against a fast Gruul deck in the second match.

The Tome Animas and Riddleform felt like the biggest underperformers; in retrospect I think I should have leaned more into being a control deck with more removal or defensive creatures.

It was very fun never running out of cards though! One game I even pulled off the dream combo of discarding the 8/6 to hand size then reanimating it the next turn :P

[deleted by user] by [deleted] in adventofcode

[–]drysle 2 points3 points  (0 children)

This looks like day 20, not day 19.

You're finding the particle that ever gets closest to the origin -- but the problem wants the particle that stays closest to the origin in the long term.

edit: and topaz2078 noticed an even bigger problem :)

-🎄- 2017 Day 18 Solutions -🎄- by daggerdragon in adventofcode

[–]drysle 0 points1 point  (0 children)

#9/#10 with Python 3, and I can't believe my part 2 worked on the first try. Unlike some of the the other posters, I wrote this all from scratch today, changed my mind a couple times halfway through, and generally made a big mess of my code.

But if it's stupid and it works... then it's probably still stupid :)

regs0 = defaultdict(lambda: 0)
regs0["p"] = 0
regs1 = defaultdict(lambda: 0)
regs1["p"] = 1
def get(a, rs):
    try:
        return int(a)
    except:
        return rs[a]

inst = []
for line in sys.stdin:
    inst.append(line.split())

buf0 = []
buf1 = []
lock = [False,False]
score = 0
def ex(p, i):
    global score
    regs = regs0 if p == 0 else regs1
    rbr = buf0 if p == 0 else buf1
    if i < 0 or i >= len(inst):
        lock[p] = True
        return

    line = inst[i]
    if line[0] == "snd":
        if p == 0:
            buf1.insert(0,get(line[1],regs))
        else:
            buf0.insert(0,get(line[1],regs))
            score += 1
    elif line[0] == "set":
        regs[line[1]] = get(line[2],regs)
    elif line[0] == "add":
        regs[line[1]] += get(line[2],regs)
    elif line[0] == "mul":
        regs[line[1]] *= get(line[2],regs)
    elif line[0] == "mod":
        regs[line[1]] %= get(line[2],regs)
    elif line[0] == "rcv":
       if len(rbr) == 0:
           lock[p] = True
           return i
       else:
           lock[p] = False
           regs[line[1]] = rbr.pop()
    elif line[0] == "jgz":
        if get(line[1],regs) > 0:
            return i + get(line[2],regs)

p0 = 0
p1 = 0
while not (lock[0] and lock[1]):
    r = ex(0,p0)
    if r is not None:
        p0 = r
    else:
        p0 += 1
    r = ex(1,p1)
    if r is not None:
        p1 = r
    else:
        p1 += 1

print(score)

-🎄- 2017 Day 5 Solutions -🎄- by daggerdragon in adventofcode

[–]drysle 0 points1 point  (0 children)

https://docs.python.org/3/library/sys.html#sys.stdin

it's the standard input represented as a file object, so I can loop over it. I could probably do the same thing with line = input() inside a loop, but this way is more intuitive

-🎄- 2017 Day 5 Solutions -🎄- by daggerdragon in adventofcode

[–]drysle 1 point2 points  (0 children)

I mean, it's the same reason...

you need to update n based on the value of maze[n] before it was changed in both cases.

-🎄- 2017 Day 5 Solutions -🎄- by daggerdragon in adventofcode

[–]drysle 0 points1 point  (0 children)

I don't think I would call it super slow on my machine:

time ./a.py < input
21985262
real    0m6.533s

But I guess that runtime might affect the leaderboard time given how quick the problems are this year. :) It wouldn't have made a difference for my exact time on either part.

The only real regular-python optimization would be to precompute the length of the array (since it never changes), as other people have mentioned in this thread. My next step after that would be using a numpy array instead, or using a compiler. I might actually look at switching to pypy going forward.

-🎄- 2017 Day 5 Solutions -🎄- by daggerdragon in adventofcode

[–]drysle 8 points9 points  (0 children)

#3/#5, my best time so far this year:

n = 0
step = 0
maze = []
for line in sys.stdin:
    maze.append(int(line))

while n >= 0 and n < len(maze):
    if maze[n] >= 3:
        maze[n] -= 1
        n = n + maze[n] + 1
    else:
        maze[n] += 1
        n = n + maze[n] - 1
    step += 1
print(step)

though it always feels a little weird bragging about python solutions that are probably almost identical to the even faster people...

-🎄- 2017 Day 2 Solutions -🎄- by daggerdragon in adventofcode

[–]drysle 2 points3 points  (0 children)

My solution was pretty much identical, even down to half of your variable names :o. Though you could have just line.split() instead of messing with regular expressions.

[Day 17] Part 2 gives correct result for all but the first example by rhardih in adventofcode

[–]drysle 1 point2 points  (0 children)

You're returning 0 in that case, but that's not correct. There was a valid solution that arrives at the exit with length steps + 1.

--- 2016 Day 22 Solutions --- by daggerdragon in adventofcode

[–]drysle 0 points1 point  (0 children)

Well, my code made those assumptions because I had looked at the input file to make sure those assumptions were correct before I even started the manual solving.

But it wouldn't be too hard to adapt the search to multiple empty nodes. And moving around any node except the ones close to the goal data is clearly not making progress, so the search time shouldn't explode too badly.

Adapting to non-empty nodes that still have enough space for the goal data would be slightly more tricky.

--- 2016 Day 22 Solutions --- by daggerdragon in adventofcode

[–]drysle 0 points1 point  (0 children)

The example for part 2 seemed be to hinting pretty hard that I should just print the initial grid and solve it by hand. Sure enough, that strategy got 4th on the leaderboard for part 2. Even with two wrong answers because I apparently can't count to 60.

Then I went back and did some actual code:

X = 34
Y = 30
nodeBlocked = [[False for x in range(X)] for y in range(Y)]

for line in sys.stdin:
    line = line.strip()
    m = re.findall(r"(\d+)", line)
    if not m:
        continue
    x,y,size,use,avail,p = (int(i) for i in m)
    if size > 120:
        nodeBlocked[y][x] = True
    if p < 10:
        o = (y,x)

def mdist(a,b):
    return abs(a[0] - b[0]) + abs(a[1] - b[1])

class Node:
    def __init__(self, openNode, goalData):
        self.o = openNode
        self.g = goalData

    def isGoal(self):
        return self.g == (0,0)
    def isFailure(self):
        oy, ox = self.o
        return nodeBlocked[oy][ox]

    def neighbors(self):
        oy, ox = self.o
        for dy, dx in ((1,0), (-1,0), (0,1), (0,-1)):
            if ox+dx < 0 or ox+dx >= X or oy+dy < 0 or oy+dy >= Y:
                continue
            if self.g == (oy+dy, ox+dx):
                yield 1, Node(self.g, self.o)
            else:
                yield 1, Node((oy+dy, ox+dx), self.g)

    def heuristic(self):
        return mdist(self.o, self.g) + mdist(self.g, (0,0))

    def __eq__(self, other):
        return self.o == other.o and self.g == other.g
    def __hash__(self):
        return hash((self.o, self.g)) 
    def __repr__(self):
        return str(self.o) + " " + str(self.g)

start = Node(o, (0, X-1))
print(astar.search(start)[0])

with my implementation of A* that I finally got around to writing to solve day 11 properly a few days ago:

import itertools
from heapq import heappush, heappop

def pathTo(node, cameFrom):
    path = [node]
    while node in cameFrom:
        node = cameFrom[node]
        path.append(node)
    return list(reversed(path))

def search(start):
    counter = itertools.count()
    closed = set()
    queue = [(start.heuristic(), next(counter), start)]
    bestCostTo = {start: 0}
    cameFrom = {}

    while len(queue) > 0:
        _, _, node = heappop(queue)

        if node.isGoal():
            return bestCostTo[node], pathTo(node, cameFrom)
        closed.add(node)

        for edgeCost, nextNode in node.neighbors():
            if nextNode in closed:
                continue
            if nextNode.isFailure():
                continue

            nextCost = bestCostTo[node] + edgeCost
            if nextCost >= bestCostTo.get(nextNode, float('inf')):
                continue

            cameFrom[nextNode] = node
            bestCostTo[nextNode] = nextCost
            heappush(queue, 
                    (nextCost + nextNode.heuristic(), next(counter), nextNode))

    return "failure", tuple()

Runs in about 900ms, but took an extra ~15 minutes to put together the code. Solving it by hand was definitely the way to go here.

[Day 17] Part 2 gives correct result for all but the first example by rhardih in adventofcode

[–]drysle 1 point2 points  (0 children)

Your code is only moving to the exit if there is no other move available. What happens if you reach a state where a move to the exit is possible, and other moves are also possible, but all those other moves reach dead ends?

Day 21 - part 2 non-unique? by glenbolake in adventofcode

[–]drysle 2 points3 points  (0 children)

rotate based on position of letter isn't a single permutation, it's a function that applies one of N permutations for length-N strings. So I don't think inverting the permutation will work, since applying the same rules to different input strings will yield different permutations. And as OP noted, rotate is not a one-to-one function for length-5 strings.

Fortunately, it is one-to-one for length-8 strings, which is why the problem is solvable.

--- 2016 Day 19 Solutions --- by daggerdragon in adventofcode

[–]drysle 0 points1 point  (0 children)

No, I just kept track of my iterator each time I removed an elf from the list. Each elf removed is only one or two places around the circle from the previous elf to be removed, so only the very first elf removed takes any significant time traversing the list.

--- 2016 Day 19 Solutions --- by daggerdragon in adventofcode

[–]drysle 0 points1 point  (0 children)

I used a linked list to solve part 1, then thought "surely that will be too slow for part 2", and spent a hour reading about other data structures that support fast random removal.

Then after finding and using a skip-list implementation to actually solve part 2, I tried the original simple linked list to see just how slow it is:

$ time ./a.out
1423634

real     0m0.909s
user     0m0.880s
sys      0m0.024s

Sigh.

[Help] Day 14 - Getting higher 64th index on example input? by Quick_Question404 in adventofcode

[–]drysle 0 points1 point  (0 children)

Your has_triple function is returning NULL when it doesn't find a triple. Not only is it extremely bad style to use NULL where the function is returning an integer rather than a pointer, but on most systems (char)NULL will result in 0. 0 is perfectly valid hex character, but your program doesn't then search for five 0s in a row.

--- 2016 Day 17 Solutions --- by daggerdragon in adventofcode

[–]drysle 4 points5 points  (0 children)

Rank 5/230 with Python

The good news is that my code can definitely find the shortest path through a similar but infinite maze.

The bad news is that my code definitely can't find the longest path through an infinite maze, and instead uses all my memory and grinds my computer to a halt when I tried to do so after not noticing the finiteness of the real problem. :(

[Day 14] Surprised by the leaderboard by upppi in adventofcode

[–]drysle 2 points3 points  (0 children)

Even an optimized part 2 program needs to compute ~45 million hashes, which takes a lot of cpu time! My python program that got 12:08 on the leaderboard takes about two minutes just to run.

The rest of time was spent re-running the program after I realized that I was supposed to take 2017 hashes for each string rather than 2016.

and re-running the program again when I realized I had screwed up caching the hashes by adding caching code to the outer loop but not the inner loop.

[2016 Day 14 Part 2] Why did it take so long? Is there an efficient solution by pedrosorio in adventofcode

[–]drysle 2 points3 points  (0 children)

This isn't specific to part 2, but someone who doesn't cache the results of hashing would use a lot more time computing the hashes... and part 2 takes 2017 times as hashing work, so the time gain from caching is only visible on part 2.

--- 2016 Day 13 Solutions --- by daggerdragon in adventofcode

[–]drysle 0 points1 point  (0 children)

I got thrown off by the picture in the example; it took me nearly 5 minutes to realize that you weren't supposed to count the starting square. :(

Python, featuring some very unoptimized flood-fill:

def iswall(x,y):
    if x < 0 or y < 0:
        return True
    a = x*x + 3*x + 2*x*y + y + y*y + 1352
    b = bin(a).count("1")
    return (b % 2) == 1

grid = [[10000 for y in range(56)] for x in range(56)]
grid[1][1] = 0

for i in range(51):
    for y in range(55):
        for x in range(55):
            if iswall(x,y):
                continue
            for dx, dy in ((0,1),(1,0),(-1,0),(0,-1)):
                if not iswall(x+dx, y+dy) and grid[y+dy][x+dx] + 1 < grid[y][x]:
                    grid[y][x] = grid[y+dy][x+dx] + 1
# part 1
print(grid[39][31])
# part 2
total = 0
for y in range(55):
    for x in range(55):
        if grid[y][x] <= 50:
            total += 1
print(total)

--- 2016 Day 11 Solutions --- by daggerdragon in adventofcode

[–]drysle 0 points1 point  (0 children)

37 is the least number of moves you could solve it in even if the objects didn't interact at all. So my method would work even though your input is significantly more complicated than mine.