Skip to content

Instantly share code, notes, and snippets.

@hrkrshnn
Created July 1, 2021 19:29
Show Gist options
  • Save hrkrshnn/b0e987602ce7bc406009e1137f77ee92 to your computer and use it in GitHub Desktop.
Save hrkrshnn/b0e987602ce7bc406009e1137f77ee92 to your computer and use it in GitHub Desktop.
"""
An approach for
https://github.com/ethereum/solidity/pull/11493/files#r651807831
"""
# stack is modelled by an array of characters
stackAfter = ['a', 'x', 'b', 'e', 'x', 'b', 'd', 'a', 'z', 'c']
# operation
# (a, b, c, d) -> (x, y, z)
operationAfter = ['x', 'y', 'z']
operationBefore = ['a', 'b', 'c', 'd']
permutedOperationAfter = []
def permute(i, j, xs):
"""Permute the i-th and j-th element of xs from behind.
swap0 can be omitted.
"""
if i == j:
pass
xs[-i], xs[-j] = xs[-j], xs[-i]
print("swap" + str(i - 1))
print("swap" + str(j - 1))
print("swap" + str(i - 1))
def pop(xs):
"""Pops the last element
"""
xs.pop()
print("pop")
def dup(n, xs):
"""Dup the nth element from behind
"""
xs.append(xs[-n])
print("dup" + str(n))
def swapAndPop():
"""The first step
Involves removing everything that's unnecessary in return values.
"""
stackAfterAsSet = set(stackAfter)
tmpOperationAfter = operationAfter
count = 0
for idx, s in enumerate(operationAfter[::-1]):
if s not in stackAfterAsSet:
permute(1, idx + 1 - count, tmpOperationAfter)
pop(tmpOperationAfter)
# Because pop removed an element from the array
count = count - 1
return tmpOperationAfter
afterSwapAndPop = swapAndPop()
def dupping(xs, _afterSwapAndPop):
"""Second step
Involves dupping the extra elements
"""
xsCounts = {}
for x in xs:
if x not in xsCounts:
xsCounts[x] = 1
else:
xsCounts[x] = xsCounts[x] + 1
print(xsCounts)
# Maybe we don't need to dup elements that end up being on top anyway?
# TODO figure this out
for idx, x in enumerate(_afterSwapAndPop[::-1]):
if xsCounts[x] > 1:
dup(idx + 1, _afterSwapAndPop)
return _afterSwapAndPop
afterDupping = dupping(stackAfter, afterSwapAndPop)
print(afterDupping)
def finalPermutations(_afterDupping, _stackAfter):
currentLength = len(_afterDupping)
actualLength = len(_stackAfter)
fillerArray = ['0' for i in range(0, actualLength - currentLength)] + _afterDupping
print("filler before")
print(fillerArray)
permutations = []
for idx, x in enumerate(_afterDupping[::-1]):
if _stackAfter[-(idx + 1)] != x:
idxInStackAfter = _stackAfter.index(x)
# So that this index won't be reused again
_stackAfter[idxInStackAfter] = '0'
permute(actualLength - idxInStackAfter, idx + 1, fillerArray)
permutations.append((actualLength - idxInStackAfter, idx + 1))
print("filler after")
print(fillerArray)
return permutations
permutations = finalPermutations(afterDupping, stackAfter.copy())
print(permutations)
print(afterDupping)
print(stackAfter)
stackBefore = stackAfter.copy()
for i, j in permutations:
permute(i, j, stackBefore)
print(stackAfter)
# The last elements need to be removed
# Add the arguments
print(stackBefore)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment