Kenny Powers -4 years ago 85
Python Question

# In python, how do you print a list of steps to transform a list of integers into a provided second list of integers?

Given This Input:

``````[2,2,2,1], [4,3,0,0]
``````

Output:
Steps to transform list

``````Move 2 from C_to_A
Move 1 from D_to_B
``````

The lists could be referenced in this manner for ease:

``````[A, B, C, D] #Just some means to reference the to and from of the move.
``````

What I have so far:

``````    locations = {
0: "A",
1: "B",
2: "C",
3: "D"
}

def get_steps_for_distribution(c, d):
print 'current: {} desired: {}'.format(c, d)
for i in range(0, len(c)):
diff = c[i] - d[i]
while diff > 0:
for j in range(1, len(c)):
next_index = (i + j) % len(c)
importer_diff = c[next_index] - d[next_index]
if importer_diff < 0:
number_to_move = min(diff, (0 - importer_diff))
diff -= number_to_move
importer_diff += number_to_move
c[i] -= number_to_move
d[i] += number_to_move
print_move_line(number_to_move, i, next_index)
``````

One problem, for example, is given this set:

``````get_steps([2,2,2,1], [4,3,0,0])
``````

Currently it provides steps to shift everything to location A, resulting in this, which is not an accurate representation of the second list provided.:

``````>>>Move 2 from C_to_A
>>>Move 0 from C_to_B
>>>Move 1 from D_to_A
>>>Move 0 from D_to_B
``````

I found it. The problem is that you don't update the master list of needs (c) and resource (d). In the bottom of your code, add a couple of lines to effect those updates:

``````               diff -= number_to_move
importer_diff += number_to_move
c[i] -= number_to_move
d[i] += number_to_move
``````

This gradually updates the resource list until it's equal to the needs list.

Note: there are a number of things you can improve, once you get this working:

• Variable names: make them more descriptive, and correspond nicely between "export" and "import", as well as within each group.
• Simplify your next_index computation with modulus:

next_index = (i + j) % len(c)

• You don't need to update importer_diff; you recompute it on the next loop, anyway.

MY SOLUTION

This produces the desired output:

``````locations = {
0: "A",
1: "B",
2: "C",
3: "D"
}

def print_move_line(number_to_move, exporter, importer):
line = "Move " + str(number_to_move) + " from " + locations.get(exporter, "bad location") + "_to_" + locations.get(importer, "bad location")
print line

def get_steps(have, want):
for exporter_index in range(0, len(have)):
diff = have[exporter_index] - want[exporter_index]

# Move 'diff' units from bin 'exporter_index' to others;
#   offer valid only while supplies last.
while diff > 0:
for j in range(1, len(have)):
# Start next to the exporter and wrap around.
importer_index = (exporter_index + j) % len(have)
print("  DEBUG: have", have, "want", want, "\t", exporter_index, "to", importer_index)
importer_diff = have[importer_index] - want[importer_index]

# If this bin needs units, move what we have.
if importer_diff < 0:
number_to_move = min(diff, (-importer_diff))
print("  DEBUG: bin", importer_index, "needs", importer_diff, "donor has", diff)
diff -= number_to_move
have[exporter_index] -= number_to_move
importer_diff -= number_to_move
have[importer_index] += number_to_move
print_move_line(number_to_move, exporter_index, importer_index)

get_steps([2, 2, 2, 1], [4, 3, 0, 0])
``````

Output:

``````('  DEBUG: have', [2, 2, 2, 1], 'want', [4, 3, 0, 0], '\t', 2, 'to', 3)
('  DEBUG: have', [2, 2, 2, 1], 'want', [4, 3, 0, 0], '\t', 2, 'to', 0)
('  DEBUG: bin', 0, 'needs', -2, 'donor has', 2)
Move 2 from C_to_A
('  DEBUG: have', [2, 2, 4, 1], 'want', [2, 3, 0, 0], '\t', 2, 'to', 1)
('  DEBUG: bin', 1, 'needs', -1, 'donor has', 0)
Move 0 from C_to_B
('  DEBUG: have', [2, 2, 4, 1], 'want', [2, 3, 0, 0], '\t', 3, 'to', 0)
('  DEBUG: have', [2, 2, 4, 1], 'want', [2, 3, 0, 0], '\t', 3, 'to', 1)
('  DEBUG: bin', 1, 'needs', -1, 'donor has', 1)
Move 1 from D_to_B
('  DEBUG: have', [2, 2, 4, 2], 'want', [2, 2, 0, 0], '\t', 3, 'to', 2)
[wdwickar@wdwickar-ws pyside]\$ python so.py
('  DEBUG: have', [2, 2, 2, 1], 'want', [4, 3, 0, 0], '\t', 2, 'to', 3)
('  DEBUG: have', [2, 2, 2, 1], 'want', [4, 3, 0, 0], '\t', 2, 'to', 0)
('  DEBUG: bin', 0, 'needs', -2, 'donor has', 2)
Move 2 from C_to_A
('  DEBUG: have', [4, 2, 0, 1], 'want', [4, 3, 0, 0], '\t', 2, 'to', 1)
('  DEBUG: bin', 1, 'needs', -1, 'donor has', 0)
Move 0 from C_to_B
('  DEBUG: have', [4, 2, 0, 1], 'want', [4, 3, 0, 0], '\t', 3, 'to', 0)
('  DEBUG: have', [4, 2, 0, 1], 'want', [4, 3, 0, 0], '\t', 3, 'to', 1)
('  DEBUG: bin', 1, 'needs', -1, 'donor has', 1)
Move 1 from D_to_B
('  DEBUG: have', [4, 3, 0, 0], 'want', [4, 3, 0, 0], '\t', 3, 'to', 2)
``````
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download