Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

154
Views
Iterar sobre pares en orden de suma de valores absolutos

Quiero iterar sobre pares de enteros en el orden de la suma de sus valores absolutos. La lista debería verse así:

 (0,0) (-1,0) (0,1) (0,-1) (1,0) (-2,0) (-1,1) (-1,-1) (0,2) (0,-2) (1,1) (1,-1) (2,0) [...]

Para pares con la misma suma de valores absolutos, no me importa en qué orden vienen.

Idealmente, me gustaría poder crear los pares para siempre para poder usar cada uno por turno. Como puedes hacer eso?

Para un rango fijo puedo hacer la lista de pares de forma fea con:

 sorted([(x,y)for x in range(-20,21)for y in range(-20,21)if abs(x)+abs(y)<21],key=lambda x:sum(map(abs,x))

Esto no me permite iterar para siempre y tampoco me da un par a la vez.

over 4 years ago · Santiago Trujillo
7 answers
Answer question

0

Esto lo hará. Si realmente desea que sea infinito, elimine la primera instrucción if .

 import itertools def makepairs(count=3): yield (0,0) for base in itertools.count(1): if base > count: # optional escape return # optional escape for i in range(base+1): yield (i, base-i) if base != i: yield (i, i-base) if i: yield (-i, base-i) if base != i: yield (-i, i-base) print(list(makepairs(9)))
over 4 years ago · Santiago Trujillo Report

0

(Espero haber entendido los requisitos) Usé el producto itertools :

 >>> for i in sorted(itertools.product(range(-5, 4), range(-5, 4)), key=lambda tup: abs(tup[0]) + abs(tup[1])): print(i) ... (0, 0) (-1, 0) (0, -1) (0, 1) (1, 0) (-2, 0) (-1, -1) (-1, 1) (0, -2) (0, 2) (1, -1) (1, 1) (2, 0) (-3, 0) (-2, -1) (-2, 1) (-1, -2) (-1, 2) (0, -3) (0, 3) (1, -2) (1, 2) (2, -1) ...
over 4 years ago · Santiago Trujillo Report

0

Esto parece hacer el truco:

 from itertools import count # Creates infinite iterator def abs_value_pairs(): for absval in count(): # Generate all possible sums of absolute values for a in range(-absval, absval + 1): # Generate all possible first values b = abs(a) - absval # Compute matching second value (arbitrarily do negative first) yield a, b if b: # If first b is zero, don't output again, otherwise, output positive b yield a, -b

Esto se ejecuta para siempre y funciona de manera eficiente (evitando volver a calcular nada innecesariamente).

over 4 years ago · Santiago Trujillo Report

0

La siguiente solución produce un flujo de suma con tuplas de cualquier longitud:

 from itertools import count def pairs(l = 2): def groups(d, s, c = []): if not d and sum(map(abs, c)) == s: yield tuple(c) elif d: for i in [j for k in d[0] for j in {k, -1*k}]: yield from groups(d[1:], s, c +[i]) for i in count(): yield from groups([range(i+1) for _ in range(l)], i) p = pairs() for _ in range(10): print(next(p))
over 4 years ago · Santiago Trujillo Report

0

Podrías hacer una función generadora infinita:

 def pairSums(s = 0): # base generation on target sum to get pairs in order while True: # s parameter allows starting from a given sum for i in range(s//2+1): # partitions yield from {(i,si),(si,i),(is,-i),(-i,is)} # no duplicates s += 1 # next target sum

Producción:

 for p in pairSums(): print(p) (0, 0) (0, 1) (0, -1) (1, 0) (-1, 0) (2, 0) (-2, 0) (0, -2) (0, 2) (1, 1) (-1, -1) (3, 0) (0, 3) (0, -3) (-3, 0) (1, 2) (-1, -2) (2, 1) ...
over 4 years ago · Santiago Trujillo Report

0

Primero observe que puede colocar sus totales en una cuadrícula para valores no negativos:

 x 3|3 2|23 1|123 0|0123 -+---- |0123y

Aquí podemos ver un patrón donde las diagonales son tus totales. Tracemos una línea sistemática a través de ellos. A continuación se muestra un orden en el que podría caminar a través de ellos:

 x 3|6 2|37 1|148 0|0259 -+---- |0123y

Aquí la matriz contiene el orden de las iteraciones.

Esto resuelve su problema para valores no negativos de x e y. Para obtener el resto, simplemente puede negar x e y, asegurándose de no hacerlo cuando sean cero. Algo como esto:

 def generate_triplets(n): yield 0, (0, 0) for t in range(1, n + 1): # Iterate over totals t for x in range(0, t + 1): # Iterate over component x y = t - x # Calclulate component y yield t, (x, y) # Default case is non-negative if y > 0: yield t, (x, -y) if x > 0: yield t, (-x, y) if x > 0 and y > 0: yield t, (-x, -y) def generate_pairs(n): yield from (pair for t, pair in generate_triplets(n)) # for pair in generate_pairs(10): # print(pair) for t, (x, y) in generate_triplets(3): print(f'{t} = abs({x}) + abs({y})')

Esto produce

 0 = abs(0) + abs(0) 1 = abs(0) + abs(1) 1 = abs(0) + abs(-1) 1 = abs(1) + abs(0) 1 = abs(-1) + abs(0) 2 = abs(0) + abs(2) 2 = abs(0) + abs(-2) 2 = abs(1) + abs(1) 2 = abs(1) + abs(-1) 2 = abs(-1) + abs(1) 2 = abs(-1) + abs(-1) 2 = abs(2) + abs(0) 2 = abs(-2) + abs(0) 3 = abs(0) + abs(3) 3 = abs(0) + abs(-3) 3 = abs(1) + abs(2) 3 = abs(1) + abs(-2) 3 = abs(-1) + abs(2) 3 = abs(-1) + abs(-2) 3 = abs(2) + abs(1) 3 = abs(2) + abs(-1) 3 = abs(-2) + abs(1) 3 = abs(-2) + abs(-1) 3 = abs(3) + abs(0) 3 = abs(-3) + abs(0)

O en parejas:

 (0, 0) (0, 1) (0, -1) (1, 0) (-1, 0) (0, 2) (0, -2) (1, 1) (1, -1) (-1, 1) (-1, -1) (2, 0) (-2, 0) ...
over 4 years ago · Santiago Trujillo Report

0

Para cada suma, recorra la diagonal en un cuadrante y rote cada coordenada en los otros cuadrantes:

 from itertools import count def coordinates(): yield 0, 0 for sum in count(1): for x in range(sum): y = sum - x yield x, y yield y, -x yield -x, -y yield -y, x
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!