Al_Iskander Al_Iskander - 29 days ago 12
Python Question

generate a loop to arrive at certain result

I have kind of a brain fog trying to solve the following structure and maybe someone can assist in solving this issue.

10 11 12 00 11 12 13 01 12 13 14 02 13 14 15 03 14 15 16 04 15 16 17 05

10 11 12 20 11 12 13 21 12 13 14 22 13 14 15 23 14 15 16 24 15 16 17 25

10 11 12 02 11 12 13 03 12 13 14 04 13 14 15 05 14 15 16 06 15 16 17 07

10 11 12 22 11 12 13 23 12 13 14 24 13 14 15 25 14 15 16 26 15 16 17 27


How would an algorithm/set of loops look like that generates this table? The order of appearance is not important. Just all bundles of four pairs should pop up. The pairs need actually to be individual digits, i.e. a
10
is a
1
and a
0
, not a
ten
!

EDIT: there is certainly a pattern in the numbers. But I did not manage to create an appropriate loop to 'catch' the pattern.

one pattern in first row is (if only this can be solved would help already):

x = 1
i = 0
xi x(i+1) x(i+2) (x-1)i x(i+1) x(i+2) x(i+3) (x-1)(i+1) ...

Answer

This code generates the desired data as a 3D list of strings.

a = (0, 0), (2, 0), (0, 2), (2, 2)
b = 10, 11, 12
result = [
    [
        [str(i + j) for j in b] + [str(u) + str(v+i)] for i in range(6)
    ] for u, v in a
]

# Display the resulting list in a relatively compact way    
for row in result:
    print([' '.join(u) for u in row])

output

['10 11 12 00', '11 12 13 01', '12 13 14 02', '13 14 15 03', '14 15 16 04', '15 16 17 05']
['10 11 12 20', '11 12 13 21', '12 13 14 22', '13 14 15 23', '14 15 16 24', '15 16 17 25']
['10 11 12 02', '11 12 13 03', '12 13 14 04', '13 14 15 05', '14 15 16 06', '15 16 17 07']
['10 11 12 22', '11 12 13 23', '12 13 14 24', '13 14 15 25', '14 15 16 26', '15 16 17 27']

If these pairs are actually supposed to be pairs of integers we need a slightly different strategy:

from pprint import pprint

a = (0, 0), (2, 0), (0, 2), (2, 2)
b = 10, 11, 12
result = [
    [
        [divmod(i + j, 10) for j in b] + [(u, v+i)] for i in range(6)
    ] for u, v in a
]

pprint(result)

output

[[[(1, 0), (1, 1), (1, 2), (0, 0)],
  [(1, 1), (1, 2), (1, 3), (0, 1)],
  [(1, 2), (1, 3), (1, 4), (0, 2)],
  [(1, 3), (1, 4), (1, 5), (0, 3)],
  [(1, 4), (1, 5), (1, 6), (0, 4)],
  [(1, 5), (1, 6), (1, 7), (0, 5)]],
 [[(1, 0), (1, 1), (1, 2), (2, 0)],
  [(1, 1), (1, 2), (1, 3), (2, 1)],
  [(1, 2), (1, 3), (1, 4), (2, 2)],
  [(1, 3), (1, 4), (1, 5), (2, 3)],
  [(1, 4), (1, 5), (1, 6), (2, 4)],
  [(1, 5), (1, 6), (1, 7), (2, 5)]],
 [[(1, 0), (1, 1), (1, 2), (0, 2)],
  [(1, 1), (1, 2), (1, 3), (0, 3)],
  [(1, 2), (1, 3), (1, 4), (0, 4)],
  [(1, 3), (1, 4), (1, 5), (0, 5)],
  [(1, 4), (1, 5), (1, 6), (0, 6)],
  [(1, 5), (1, 6), (1, 7), (0, 7)]],
 [[(1, 0), (1, 1), (1, 2), (2, 2)],
  [(1, 1), (1, 2), (1, 3), (2, 3)],
  [(1, 2), (1, 3), (1, 4), (2, 4)],
  [(1, 3), (1, 4), (1, 5), (2, 5)],
  [(1, 4), (1, 5), (1, 6), (2, 6)],
  [(1, 5), (1, 6), (1, 7), (2, 7)]]]

Here's a variation of the 2nd solution that uses "traditional" for loops instead of nested list comprehensions. Hopefully, it's a little easier to read. :)

a = (0, 0), (2, 0), (0, 2), (2, 2)
b = 10, 11, 12
result = []
for u, v in a:
    row = []
    for i in range(6):
        row.append([divmod(i + j, 10) for j in b] + [(u, v+i)])
    result.append(row)

The built-in divmod function performs division and modulus on its arguments, so when a and b are integers divmod(a, b) is equivalent to a // b, a % b. If x is a two digit integer `divmod(x, 10) returns a tuple containing those 2 digits.